fix: QA round 2 — playhead guard, controls position, caption lift, Tauri fullscreen, timeline sync
- Guard drawPlayhead on session.duration > 0 in PlayerTimeline - Move floating controls pill from bottom: 24px to 48px - Add playerControlsVisible prop to VideoPlayer; captions slide up 160px when controls visible - Replace web Fullscreen API with Tauri getCurrentWindow().setFullscreen() (WKWebView compat) - Add core:window:allow-set-fullscreen and core:window:allow-is-fullscreen permissions - Tie PlayerTimeline visibility to showPlayerControls; remove unused proximity logic Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -115,11 +115,9 @@
|
||||
}, 100);
|
||||
}
|
||||
|
||||
function handleFullscreen() {
|
||||
toggleFullscreen();
|
||||
setTimeout(() => {
|
||||
fullscreenActive = isFullscreenActive();
|
||||
}, 100);
|
||||
async function handleFullscreen() {
|
||||
await toggleFullscreen();
|
||||
fullscreenActive = await isFullscreenActive();
|
||||
}
|
||||
|
||||
function handleCCContextMenu(e: MouseEvent) {
|
||||
@@ -129,9 +127,9 @@
|
||||
|
||||
// Sync PiP/fullscreen/rate state periodically
|
||||
$effect(() => {
|
||||
const interval = setInterval(() => {
|
||||
const interval = setInterval(async () => {
|
||||
pipActive = isPiPActive();
|
||||
fullscreenActive = isFullscreenActive();
|
||||
fullscreenActive = await isFullscreenActive();
|
||||
currentRate = getPlaybackRate();
|
||||
}, 500);
|
||||
return () => clearInterval(interval);
|
||||
@@ -279,7 +277,7 @@
|
||||
<style>
|
||||
.player-controls-overlay {
|
||||
position: absolute;
|
||||
bottom: 24px;
|
||||
bottom: 48px;
|
||||
left: 15%;
|
||||
right: 15%;
|
||||
pointer-events: none;
|
||||
|
||||
@@ -56,7 +56,9 @@
|
||||
}
|
||||
|
||||
// Draw playhead
|
||||
drawPlayhead(ctx, timelineState, session.currentTime);
|
||||
if (session.duration > 0) {
|
||||
drawPlayhead(ctx, timelineState, session.currentTime);
|
||||
}
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
@@ -20,8 +20,10 @@
|
||||
|
||||
let {
|
||||
captionsEnabled = $bindable(true),
|
||||
playerControlsVisible = false,
|
||||
}: {
|
||||
captionsEnabled?: boolean;
|
||||
playerControlsVisible?: boolean;
|
||||
} = $props();
|
||||
|
||||
let videoElement = $state<HTMLVideoElement | null>(null);
|
||||
@@ -232,7 +234,7 @@
|
||||
<track kind="captions" />
|
||||
</video>
|
||||
{#if activeCues.length > 0}
|
||||
<div class="caption-overlay" style={captionPosition}>
|
||||
<div class="caption-overlay" class:lifted={isPlayerMode && playerControlsVisible} style={captionPosition}>
|
||||
{#each activeCues as cue}
|
||||
<span
|
||||
class="caption-text"
|
||||
@@ -325,6 +327,11 @@
|
||||
pointer-events: none;
|
||||
z-index: 5;
|
||||
padding: 0 10%;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.caption-overlay.lifted {
|
||||
transform: translateY(-160px);
|
||||
}
|
||||
|
||||
.caption-text {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { session } from '$lib/stores/videoSession.svelte';
|
||||
import { getCurrentWindow } from '@tauri-apps/api/window';
|
||||
|
||||
let _videoEl: HTMLVideoElement | null = null;
|
||||
|
||||
@@ -116,25 +117,22 @@ export function isPiPActive(): boolean {
|
||||
return !!document.pictureInPictureElement;
|
||||
}
|
||||
|
||||
export function toggleFullscreen(): void {
|
||||
if (document.fullscreenElement) {
|
||||
document.exitFullscreen().catch((e) => {
|
||||
console.error('Exit fullscreen failed:', e);
|
||||
});
|
||||
} else {
|
||||
const el = document.documentElement;
|
||||
if (el.requestFullscreen) {
|
||||
el.requestFullscreen().catch((e) => {
|
||||
console.error('Fullscreen request failed:', e);
|
||||
});
|
||||
} else if ((el as HTMLElement & { webkitRequestFullscreen?: () => void }).webkitRequestFullscreen) {
|
||||
(el as HTMLElement & { webkitRequestFullscreen: () => void }).webkitRequestFullscreen();
|
||||
}
|
||||
export async function toggleFullscreen(): Promise<void> {
|
||||
try {
|
||||
const win = getCurrentWindow();
|
||||
const isFs = await win.isFullscreen();
|
||||
await win.setFullscreen(!isFs);
|
||||
} catch (e) {
|
||||
console.error('Fullscreen toggle failed:', e);
|
||||
}
|
||||
}
|
||||
|
||||
export function isFullscreenActive(): boolean {
|
||||
return !!document.fullscreenElement;
|
||||
export async function isFullscreenActive(): Promise<boolean> {
|
||||
try {
|
||||
return await getCurrentWindow().isFullscreen();
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function setPlaybackRate(rate: number): void {
|
||||
|
||||
Reference in New Issue
Block a user