Fix private calls
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
<section class="mt-2 max-w-xl overflow-hidden rounded-md border border-border bg-card shadow-sm">
|
||||
<div class="flex items-center justify-between gap-3 border-b border-border px-3 py-2">
|
||||
<div class="min-w-0">
|
||||
<p class="truncate text-sm font-medium text-foreground">{{ filename() }}</p>
|
||||
<p class="text-xs text-muted-foreground">{{ sizeLabel() }}</p>
|
||||
</div>
|
||||
|
||||
<div class="flex shrink-0 items-center gap-1">
|
||||
<button
|
||||
type="button"
|
||||
class="grid h-8 w-8 place-items-center rounded-md text-muted-foreground transition-colors hover:bg-secondary hover:text-foreground"
|
||||
title="Download"
|
||||
aria-label="Download"
|
||||
(click)="requestDownload()"
|
||||
>
|
||||
<ng-icon
|
||||
name="lucideDownload"
|
||||
class="h-4 w-4"
|
||||
/>
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="grid h-8 w-8 place-items-center rounded-md text-muted-foreground transition-colors hover:bg-secondary hover:text-foreground"
|
||||
title="Close"
|
||||
aria-label="Close"
|
||||
(click)="close()"
|
||||
>
|
||||
<ng-icon
|
||||
name="lucideX"
|
||||
class="h-4 w-4"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="relative min-h-72 bg-black">
|
||||
<div
|
||||
#playerMount
|
||||
class="min-h-72 w-full"
|
||||
></div>
|
||||
|
||||
@if (status() === 'loading') {
|
||||
<div class="absolute inset-0 grid place-items-center bg-black/80 px-4 text-sm text-white/80">Loading experimental player...</div>
|
||||
}
|
||||
|
||||
@if (status() === 'error') {
|
||||
<div class="absolute inset-0 flex flex-col items-center justify-center gap-3 bg-black/85 px-6 text-center">
|
||||
<p class="max-w-md text-sm text-white/80">{{ errorMessage() }}</p>
|
||||
<div class="flex flex-wrap justify-center gap-2">
|
||||
<button
|
||||
type="button"
|
||||
class="inline-flex items-center gap-2 rounded-md bg-white/10 px-3 py-1.5 text-xs font-medium text-white transition-colors hover:bg-white/20"
|
||||
(click)="retry()"
|
||||
>
|
||||
<ng-icon
|
||||
name="lucideRefreshCw"
|
||||
class="h-3.5 w-3.5"
|
||||
/>
|
||||
Retry
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="inline-flex items-center gap-2 rounded-md bg-white px-3 py-1.5 text-xs font-medium text-black transition-colors hover:bg-white/90"
|
||||
(click)="requestDownload()"
|
||||
>
|
||||
<ng-icon
|
||||
name="lucideDownload"
|
||||
class="h-3.5 w-3.5"
|
||||
/>
|
||||
Download
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</section>
|
||||
@@ -0,0 +1,109 @@
|
||||
import {
|
||||
AfterViewInit,
|
||||
Component,
|
||||
ElementRef,
|
||||
OnDestroy,
|
||||
ViewChild,
|
||||
inject,
|
||||
input,
|
||||
output,
|
||||
signal
|
||||
} from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { NgIcon, provideIcons } from '@ng-icons/core';
|
||||
import {
|
||||
lucideDownload,
|
||||
lucideRefreshCw,
|
||||
lucideX
|
||||
} from '@ng-icons/lucide';
|
||||
|
||||
import {
|
||||
ExperimentalVlcPlayerHandle,
|
||||
ExperimentalVlcRuntimeService
|
||||
} from '../../infrastructure/services/experimental-vlc-runtime.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-experimental-vlc-player',
|
||||
standalone: true,
|
||||
imports: [CommonModule, NgIcon],
|
||||
viewProviders: [
|
||||
provideIcons({
|
||||
lucideDownload,
|
||||
lucideRefreshCw,
|
||||
lucideX
|
||||
})
|
||||
],
|
||||
templateUrl: './experimental-vlc-player.component.html'
|
||||
})
|
||||
export class ExperimentalVlcPlayerComponent implements AfterViewInit, OnDestroy {
|
||||
@ViewChild('playerMount') playerMount?: ElementRef<HTMLDivElement>;
|
||||
|
||||
src = input.required<string>();
|
||||
filename = input.required<string>();
|
||||
mime = input.required<string>();
|
||||
sizeLabel = input<string>('');
|
||||
|
||||
closed = output<void>();
|
||||
downloadRequested = output<void>();
|
||||
|
||||
private readonly runtime = inject(ExperimentalVlcRuntimeService);
|
||||
private playerHandle: ExperimentalVlcPlayerHandle | null = null;
|
||||
|
||||
readonly status = signal<'loading' | 'ready' | 'error'>('loading');
|
||||
readonly errorMessage = signal('');
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
void this.loadPlayer();
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.destroyPlayer();
|
||||
}
|
||||
|
||||
retry(): void {
|
||||
this.destroyPlayer();
|
||||
void this.loadPlayer();
|
||||
}
|
||||
|
||||
close(): void {
|
||||
this.closed.emit();
|
||||
}
|
||||
|
||||
requestDownload(): void {
|
||||
this.downloadRequested.emit();
|
||||
}
|
||||
|
||||
private async loadPlayer(): Promise<void> {
|
||||
const container = this.playerMount?.nativeElement;
|
||||
|
||||
if (!container) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.status.set('loading');
|
||||
this.errorMessage.set('');
|
||||
container.replaceChildren();
|
||||
|
||||
try {
|
||||
this.playerHandle = await this.runtime.createPlayer({
|
||||
container,
|
||||
sourceUrl: this.src(),
|
||||
filename: this.filename(),
|
||||
mime: this.mime()
|
||||
});
|
||||
this.status.set('ready');
|
||||
} catch (error) {
|
||||
this.status.set('error');
|
||||
this.errorMessage.set(error instanceof Error ? error.message : 'Experimental VLC.js playback failed to start.');
|
||||
}
|
||||
}
|
||||
|
||||
private destroyPlayer(): void {
|
||||
try {
|
||||
this.playerHandle?.destroy?.();
|
||||
} catch {}
|
||||
|
||||
this.playerHandle = null;
|
||||
this.playerMount?.nativeElement.replaceChildren();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user