add 15 UI enhancements

This commit is contained in:
2026-02-19 17:01:01 +02:00
parent ac07f69ace
commit e5265a970d
9 changed files with 660 additions and 22 deletions

View File

@@ -32,6 +32,7 @@ import {
updateSeekFill, updateVolFill, updateVideoOverlay, updateSpeedIcon,
setVolume, setPlaybackRate, buildSpeedMenu, isPlaying, getVideoTime,
getVideoDuration, getPlayer, isVolDragging,
toggleMute, toggleFullscreen, showSeekFeedback, cycleSpeed,
} from './player';
import { initPlaylist, renderList, isDragging } from './playlist';
@@ -209,8 +210,37 @@ async function tick(): Promise<void> {
// ---- Keyboard shortcuts ----
// ---- Shortcut help dialog ----
let shortcutHelpOpen = false;
function toggleShortcutHelp(): void {
const el = document.getElementById('shortcutHelp');
if (!el) return;
shortcutHelpOpen = !shortcutHelpOpen;
if (shortcutHelpOpen) {
el.style.display = 'flex';
document.getElementById('zoomRoot')?.setAttribute('aria-hidden', 'true');
// Focus trap: focus the panel
const panel = el.querySelector('.shortcutHelpPanel') as HTMLElement | null;
if (panel) { panel.tabIndex = -1; panel.focus(); }
} else {
el.style.display = 'none';
document.getElementById('zoomRoot')?.removeAttribute('aria-hidden');
}
}
function initKeyboard(): void {
window.addEventListener('keydown', (e) => {
// Close shortcut help on Escape or ?
if (shortcutHelpOpen) {
if (e.key === 'Escape' || e.key === '?') {
e.preventDefault();
toggleShortcutHelp();
}
return; // trap focus while dialog is open
}
// Don't capture when typing in textarea/input
const tag = (e.target as HTMLElement).tagName;
if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return;
@@ -218,18 +248,24 @@ function initKeyboard(): void {
switch (e.key) {
case ' ':
e.preventDefault();
const player = getPlayer();
if (player.paused || player.ended) player.play();
else player.pause();
updatePlayPauseIcon();
{ const player = getPlayer();
if (player.paused || player.ended) player.play();
else player.pause();
updatePlayPauseIcon(); }
break;
case 'ArrowLeft':
e.preventDefault();
try { getPlayer().currentTime = Math.max(0, getPlayer().currentTime - 5); } catch (_) {}
try {
getPlayer().currentTime = Math.max(0, getPlayer().currentTime - 5);
showSeekFeedback(-5);
} catch (_) {}
break;
case 'ArrowRight':
e.preventDefault();
try { getPlayer().currentTime = Math.min(getPlayer().duration || 0, getPlayer().currentTime + 5); } catch (_) {}
try {
getPlayer().currentTime = Math.min(getPlayer().duration || 0, getPlayer().currentTime + 5);
showSeekFeedback(+5);
} catch (_) {}
break;
case 'ArrowUp':
e.preventDefault();
@@ -247,8 +283,36 @@ function initKeyboard(): void {
setVolume(p.volume);
} catch (_) {}
break;
case 'f':
e.preventDefault();
toggleFullscreen();
break;
case 'm':
e.preventDefault();
toggleMute();
break;
case '[':
e.preventDefault();
cycleSpeed(-1);
break;
case ']':
e.preventDefault();
cycleSpeed(+1);
break;
case '?':
e.preventDefault();
toggleShortcutHelp();
break;
}
});
// Backdrop click closes shortcut help
const helpEl = document.getElementById('shortcutHelp');
if (helpEl) {
helpEl.querySelector('.shortcutHelpBackdrop')?.addEventListener('click', () => {
if (shortcutHelpOpen) toggleShortcutHelp();
});
}
}
// ---- Start ----