Replace video player with a fully custom fake-fullscreen HUD

Single fullscreen player state everywhere (desktop/Android/iOS/feed) instead
of the old modal-vs-native-fullscreen split, with custom controls: draggable
timeline with buffered range, dynamically-escalating skip buttons (double-tap
zones too), per-video format switching, favorites, PiP with auto-PiP on
backgrounding, volume swipe, TikTok-style HUD auto-hide, and swipe-down/
back-button/close-button dismissal. Reels feed reuses the same skip/format/
PiP logic via the new customPlayer.js shared module.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Simon
2026-07-01 19:08:21 +00:00
parent 5d739bec12
commit 7207e36510
9 changed files with 1605 additions and 326 deletions

View File

@@ -49,15 +49,16 @@ App.version = App.version || {};
return changed;
}
// A reload is "safe" when the user isn't mid-playback: no open video modal,
// no active reels feed, and no playing <video>. App state survives a reload
// because it is restored from localStorage on boot.
// A reload is "safe" when the user isn't mid-playback: no open custom
// player, no active reels feed, and no playing <video>. App state survives
// a reload because it is restored from localStorage on boot.
function isSafeToReload() {
if (App.state && App.state.feedOpen) return false;
const modal = document.getElementById('video-modal');
if (modal && modal.style.display && modal.style.display !== 'none') return false;
const player = document.getElementById('player');
if (player && !player.paused && !player.ended) return false;
const player = document.getElementById('custom-player');
if (player && player.classList.contains('open')) {
const video = player.querySelector('.cp-video');
if (video && !video.paused && !video.ended) return false;
}
return true;
}
@@ -128,11 +129,12 @@ App.version = App.version || {};
check();
}
});
// Re-attempt a deferred reload whenever a video finishes/pauses.
const player = document.getElementById('player');
if (player) {
player.addEventListener('pause', tryReloadWhenSafe);
player.addEventListener('ended', tryReloadWhenSafe);
}
// Re-attempt a deferred reload whenever a video finishes/pauses. The
// custom player's <video> is torn down and rebuilt on every open(), so
// bind on the capture phase at the document level instead of to a
// specific element (media events don't bubble, but capture still sees
// them on ancestors).
document.addEventListener('pause', tryReloadWhenSafe, true);
document.addEventListener('ended', tryReloadWhenSafe, true);
};
})();