From fbc32bcd22342fad236c7ef0fc12e5bbb7d2dc66 Mon Sep 17 00:00:00 2001 From: chrisk325 Date: Sun, 22 Mar 2026 15:43:55 +0530 Subject: [PATCH] feat: add player lock button --- src/components/player/AndroidVideoPlayer.tsx | 167 +++++++++++-------- 1 file changed, 93 insertions(+), 74 deletions(-) diff --git a/src/components/player/AndroidVideoPlayer.tsx b/src/components/player/AndroidVideoPlayer.tsx index 6623f9d9..cb18028b 100644 --- a/src/components/player/AndroidVideoPlayer.tsx +++ b/src/components/player/AndroidVideoPlayer.tsx @@ -30,6 +30,7 @@ import { useSettings } from '../../hooks/useSettings'; // Shared Components import { GestureControls, PauseOverlay, SpeedActivatedOverlay } from './components'; +import { LockOverlay, LockOverlayRef } from './modals/LockOverlay'; import LoadingOverlay from './modals/LoadingOverlay'; import PlayerControls from './controls/PlayerControls'; import { AudioTrackModal } from './modals/AudioTrackModal'; @@ -91,6 +92,8 @@ const AndroidVideoPlayer: React.FC = () => { const mpvPlayerRef = useRef(null); const exoPlayerRef = useRef(null); const pinchRef = useRef(null); + const lockOverlayRef = useRef(null); + const [isLocked, setIsLocked] = useState(false); const tracksHook = usePlayerTracks(); const [currentStreamUrl, setCurrentStreamUrl] = useState(uri); @@ -271,7 +274,6 @@ const AndroidVideoPlayer: React.FC = () => { const nextEpisodeHook = useNextEpisode(type, season, episode, groupedEpisodes, (metadataResult as any)?.groupedEpisodes, episodeId); - const { segments: skipIntervals, outroSegment } = useSkipSegments({ imdbId: resolvedImdbId || (id?.startsWith('tt') ? id : undefined), type, @@ -1047,29 +1049,31 @@ const AndroidVideoPlayer: React.FC = () => { controlsVisible={playerState.showControls} controlsExtraOffset={100} /> - { - const state = e.nativeEvent.state; - if (state === 5 || state === 3 || state === 1) { // END, CANCELLED, FAILED - speedControl.deactivateSpeedBoost(); - } - }} - toggleControls={toggleControls} - showControls={playerState.showControls} - hideControls={hideControls} - volume={volume} - controlsTimeout={controlsTimeout} - resizeMode={playerState.resizeMode} - skip={controlsHook.skip} - currentTime={playerState.currentTime} - duration={playerState.duration} - seekToTime={controlsHook.seekToTime} - formatTime={formatTime} - /> + + { + const state = e.nativeEvent.state; + if (state === 5 || state === 3 || state === 1) { // END, CANCELLED, FAILED + speedControl.deactivateSpeedBoost(); + } + }} + toggleControls={toggleControls} + showControls={playerState.showControls} + hideControls={hideControls} + volume={volume} + controlsTimeout={controlsTimeout} + resizeMode={playerState.resizeMode} + skip={controlsHook.skip} + currentTime={playerState.currentTime} + duration={playerState.duration} + seekToTime={controlsHook.seekToTime} + formatTime={formatTime} + /> + {/* Buffering Indicator (Visible when controls are hidden) */} {playerState.isBuffering && !playerState.showControls && ( @@ -1078,58 +1082,73 @@ const AndroidVideoPlayer: React.FC = () => { )} - { - const speeds = [0.5, 1, 1.25, 1.5, 2]; - const idx = speeds.indexOf(speedControl.playbackSpeed); - const next = speeds[(idx + 1) % speeds.length]; - speedControl.setPlaybackSpeed(next); + + { + const speeds = [0.5, 1, 1.25, 1.5, 2]; + const idx = speeds.indexOf(speedControl.playbackSpeed); + const next = speeds[(idx + 1) % speeds.length]; + speedControl.setPlaybackSpeed(next); + }} + currentPlaybackSpeed={speedControl.playbackSpeed} + setShowAudioModal={modals.setShowAudioModal} + setShowSubtitleModal={modals.setShowSubtitleModal} + setShowSpeedModal={modals.setShowSpeedModal} + setShowSubmitIntroModal={modals.setShowSubmitIntroModal} + isSubtitleModalOpen={modals.showSubtitleModal} + setShowSourcesModal={modals.setShowSourcesModal} + setShowEpisodesModal={type === 'series' ? modals.setShowEpisodesModal : undefined} + onSliderValueChange={(val) => { playerState.isDragging.current = true; }} + onSlidingStart={() => { playerState.isDragging.current = true; }} + onSlidingComplete={(val) => { + playerState.isDragging.current = false; + controlsHook.seekToTime(val); + }} + buffered={playerState.buffered} + formatTime={formatTime} + playerBackend={useExoPlayer ? 'ExoPlayer' : 'MPV'} + onSwitchToMPV={handleManualSwitchToMPV} + useExoPlayer={useExoPlayer} + canEnterPictureInPicture={canShowPipButton} + onEnterPictureInPicture={handleEnterPictureInPicture} + isBuffering={playerState.isBuffering} + imdbId={resolvedImdbId} + onLock={() => lockOverlayRef.current?.lock()} + /> + + + { + setIsLocked(true); + playerState.setShowControls(false); }} - currentPlaybackSpeed={speedControl.playbackSpeed} - setShowAudioModal={modals.setShowAudioModal} - setShowSubtitleModal={modals.setShowSubtitleModal} - setShowSpeedModal={modals.setShowSpeedModal} - setShowSubmitIntroModal={modals.setShowSubmitIntroModal} - isSubtitleModalOpen={modals.showSubtitleModal} - setShowSourcesModal={modals.setShowSourcesModal} - setShowEpisodesModal={type === 'series' ? modals.setShowEpisodesModal : undefined} - onSliderValueChange={(val) => { playerState.isDragging.current = true; }} - onSlidingStart={() => { playerState.isDragging.current = true; }} - onSlidingComplete={(val) => { - playerState.isDragging.current = false; - controlsHook.seekToTime(val); + onShowControls={() => { + setIsLocked(false); + playerState.setShowControls(true); }} - buffered={playerState.buffered} - formatTime={formatTime} - playerBackend={useExoPlayer ? 'ExoPlayer' : 'MPV'} - onSwitchToMPV={handleManualSwitchToMPV} - useExoPlayer={useExoPlayer} - canEnterPictureInPicture={canShowPipButton} - onEnterPictureInPicture={handleEnterPictureInPicture} - isBuffering={playerState.isBuffering} - imdbId={resolvedImdbId} />