tv完善弹幕以及各种焦点
This commit is contained in:
@@ -30,8 +30,17 @@ function isVisible(element: HTMLElement) {
|
||||
}
|
||||
|
||||
function getFocusableElements() {
|
||||
const scope = document.querySelector<HTMLElement>('[data-tv-focus-scope="active"]');
|
||||
if (scope) {
|
||||
return Array.from(scope.querySelectorAll<HTMLElement>(focusableSelector))
|
||||
.filter((element) => !element.closest('[data-tv-remote]'))
|
||||
.filter((element) => !element.closest('[data-tv-no-focus="true"]'))
|
||||
.filter(isVisible);
|
||||
}
|
||||
|
||||
return Array.from(document.querySelectorAll<HTMLElement>(focusableSelector))
|
||||
.filter((element) => !element.closest('[data-tv-remote]'))
|
||||
.filter((element) => !element.closest('[data-tv-no-focus="true"]'))
|
||||
.filter(isVisible);
|
||||
}
|
||||
|
||||
@@ -232,6 +241,25 @@ export default function TVVirtualRemote() {
|
||||
if (event.defaultPrevented) return;
|
||||
|
||||
if (event.key === 'ArrowUp' || event.key === 'ArrowDown' || event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
|
||||
const active = document.activeElement;
|
||||
if (active instanceof HTMLElement && active.closest('[data-tv-danmaku-settings]')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
active instanceof HTMLInputElement &&
|
||||
active.type === 'range' &&
|
||||
active.closest('[data-tv-danmaku-settings]')
|
||||
) {
|
||||
if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (active instanceof HTMLInputElement && active.type === 'range' && active.closest('[data-tv-no-focus="true"]')) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
const direction = event.key.replace('Arrow', '').toLowerCase() as 'up' | 'down' | 'left' | 'right';
|
||||
moveSpatialFocus(direction, lastFocusedRef.current);
|
||||
@@ -239,6 +267,11 @@ export default function TVVirtualRemote() {
|
||||
}
|
||||
|
||||
if (event.key === 'Enter') {
|
||||
const playerRoot = document.querySelector<HTMLElement>('[data-tv-player-root]');
|
||||
if (playerRoot?.dataset.tvControlsOpen === 'false') {
|
||||
return;
|
||||
}
|
||||
|
||||
const active = document.activeElement;
|
||||
if (active instanceof HTMLElement && !active.closest('input, textarea, select') && !active.closest('[data-tv-remote]')) {
|
||||
event.preventDefault();
|
||||
|
||||
@@ -235,14 +235,18 @@ export default function TVNativeVideo({
|
||||
|
||||
attach();
|
||||
|
||||
let seekedInitialTime = false;
|
||||
let triedInitialSeek = false;
|
||||
const seekToInitialTime = () => {
|
||||
if (live || seekedInitialTime || !startTime || startTime <= 1) return;
|
||||
if (live || triedInitialSeek || !startTime || startTime <= 1) return;
|
||||
if ((videoEl.currentTime || 0) > 1) {
|
||||
triedInitialSeek = true;
|
||||
return;
|
||||
}
|
||||
const duration = videoEl.duration || 0;
|
||||
const safeTime = duration > 30 ? Math.min(startTime, Math.max(0, duration - 8)) : startTime;
|
||||
try {
|
||||
videoEl.currentTime = safeTime;
|
||||
seekedInitialTime = true;
|
||||
triedInitialSeek = true;
|
||||
} catch {
|
||||
// ignore unsupported seek state
|
||||
}
|
||||
@@ -289,7 +293,7 @@ export default function TVNativeVideo({
|
||||
videoEl.addEventListener('waiting', onBuffering);
|
||||
videoEl.addEventListener('stalled', onBuffering);
|
||||
videoEl.addEventListener('seeking', onBuffering);
|
||||
videoEl.addEventListener('seeked', onLoaded);
|
||||
videoEl.addEventListener('seeked', clearBuffering);
|
||||
videoEl.addEventListener('error', onError);
|
||||
videoEl.addEventListener('timeupdate', onTimeUpdate);
|
||||
|
||||
@@ -305,7 +309,7 @@ export default function TVNativeVideo({
|
||||
videoEl.removeEventListener('waiting', onBuffering);
|
||||
videoEl.removeEventListener('stalled', onBuffering);
|
||||
videoEl.removeEventListener('seeking', onBuffering);
|
||||
videoEl.removeEventListener('seeked', onLoaded);
|
||||
videoEl.removeEventListener('seeked', clearBuffering);
|
||||
videoEl.removeEventListener('error', onError);
|
||||
videoEl.removeEventListener('timeupdate', onTimeUpdate);
|
||||
clearBuffering();
|
||||
|
||||
Reference in New Issue
Block a user