feat: Add emoji and alot of other fixes
This commit is contained in:
@@ -3,6 +3,7 @@ import {
|
||||
ElementRef,
|
||||
HostListener,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
ViewChild,
|
||||
computed,
|
||||
input,
|
||||
@@ -20,6 +21,11 @@ import {
|
||||
lucideVolume2,
|
||||
lucideVolumeX
|
||||
} from '@ng-icons/lucide';
|
||||
import {
|
||||
MEDIA_SEEK_SLIDER_STEPS,
|
||||
mediaSeekSliderValue,
|
||||
mediaSeekTimeFromSliderValue
|
||||
} from './chat-video-player-seek.rules';
|
||||
|
||||
@Component({
|
||||
selector: 'app-chat-video-player',
|
||||
@@ -40,14 +46,14 @@ import {
|
||||
styleUrl: './chat-video-player.component.scss'
|
||||
})
|
||||
/* eslint-disable @typescript-eslint/member-ordering */
|
||||
export class ChatVideoPlayerComponent implements OnDestroy {
|
||||
export class ChatVideoPlayerComponent implements OnInit, OnDestroy {
|
||||
src = input.required<string>();
|
||||
filename = input.required<string>();
|
||||
sizeLabel = input<string>('');
|
||||
downloadRequested = output<undefined>();
|
||||
|
||||
private readonly SINGLE_CLICK_DELAY_MS = 300;
|
||||
private readonly FULLSCREEN_IDLE_MS = 2200;
|
||||
private readonly CONTROLS_IDLE_MS = 2200;
|
||||
|
||||
@ViewChild('playerRoot') playerRoot?: ElementRef<HTMLDivElement>;
|
||||
@ViewChild('videoEl') videoRef?: ElementRef<HTMLVideoElement>;
|
||||
@@ -63,6 +69,8 @@ export class ChatVideoPlayerComponent implements OnDestroy {
|
||||
private singleClickTimer: ReturnType<typeof setTimeout> | null = null;
|
||||
private controlsHideTimer: ReturnType<typeof setTimeout> | null = null;
|
||||
|
||||
readonly seekSliderSteps = MEDIA_SEEK_SLIDER_STEPS;
|
||||
|
||||
progressPercent = computed(() => {
|
||||
const duration = this.durationSeconds();
|
||||
|
||||
@@ -71,16 +79,8 @@ export class ChatVideoPlayerComponent implements OnDestroy {
|
||||
|
||||
return (this.currentTimeSeconds() / duration) * 100;
|
||||
});
|
||||
seekTrackBackground = computed(() => {
|
||||
const progress = Math.max(0, Math.min(100, this.progressPercent()));
|
||||
|
||||
return this.buildSliderBackground(progress);
|
||||
});
|
||||
volumeTrackBackground = computed(() => {
|
||||
const volume = Math.max(0, Math.min(100, this.isMuted() ? 0 : this.volumePercent()));
|
||||
|
||||
return this.buildSliderBackground(volume);
|
||||
});
|
||||
seekSliderValue = computed(() => mediaSeekSliderValue(this.currentTimeSeconds(), this.durationSeconds()));
|
||||
volumeProgressPercent = computed(() => Math.max(0, Math.min(100, this.isMuted() ? 0 : this.volumePercent())));
|
||||
|
||||
@HostListener('document:fullscreenchange')
|
||||
onFullscreenChange(): void {
|
||||
@@ -89,13 +89,11 @@ export class ChatVideoPlayerComponent implements OnDestroy {
|
||||
|
||||
this.isFullscreen.set(isFullscreen);
|
||||
|
||||
if (isFullscreen) {
|
||||
this.revealControlsTemporarily();
|
||||
return;
|
||||
}
|
||||
this.revealControlsTemporarily();
|
||||
}
|
||||
|
||||
this.controlsVisible.set(true);
|
||||
this.clearControlsHideTimer();
|
||||
ngOnInit(): void {
|
||||
this.revealControlsTemporarily();
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
@@ -104,9 +102,6 @@ export class ChatVideoPlayerComponent implements OnDestroy {
|
||||
}
|
||||
|
||||
onPlayerMouseMove(): void {
|
||||
if (!this.isFullscreen())
|
||||
return;
|
||||
|
||||
this.revealControlsTemporarily();
|
||||
}
|
||||
|
||||
@@ -184,11 +179,13 @@ export class ChatVideoPlayerComponent implements OnDestroy {
|
||||
if (!video)
|
||||
return;
|
||||
|
||||
const nextTime = Number((event.target as HTMLInputElement).value);
|
||||
const sliderValue = Number((event.target as HTMLInputElement).value);
|
||||
|
||||
if (!Number.isFinite(nextTime))
|
||||
if (!Number.isFinite(sliderValue))
|
||||
return;
|
||||
|
||||
const nextTime = mediaSeekTimeFromSliderValue(sliderValue, this.durationSeconds());
|
||||
|
||||
video.currentTime = nextTime;
|
||||
this.currentTimeSeconds.set(nextTime);
|
||||
this.revealControlsTemporarily();
|
||||
@@ -272,27 +269,12 @@ export class ChatVideoPlayerComponent implements OnDestroy {
|
||||
this.revealControlsTemporarily();
|
||||
}
|
||||
|
||||
private buildSliderBackground(fillPercent: number): string {
|
||||
return [
|
||||
'linear-gradient(90deg, ',
|
||||
'hsl(var(--primary)) 0%, ',
|
||||
`hsl(var(--primary)) ${fillPercent}%, `,
|
||||
`hsl(var(--secondary)) ${fillPercent}%, `,
|
||||
'hsl(var(--secondary)) 100%)'
|
||||
].join('');
|
||||
}
|
||||
|
||||
private revealControlsTemporarily(): void {
|
||||
if (!this.isFullscreen()) {
|
||||
this.controlsVisible.set(true);
|
||||
return;
|
||||
}
|
||||
|
||||
this.controlsVisible.set(true);
|
||||
this.clearControlsHideTimer();
|
||||
this.controlsHideTimer = setTimeout(() => {
|
||||
this.controlsVisible.set(false);
|
||||
}, this.FULLSCREEN_IDLE_MS);
|
||||
}, this.CONTROLS_IDLE_MS);
|
||||
}
|
||||
|
||||
private clearControlsHideTimer(): void {
|
||||
|
||||
Reference in New Issue
Block a user