From 39498f78b79e7656619cfe8a0a326f8dad38d7aa Mon Sep 17 00:00:00 2001 From: tapframe Date: Wed, 24 Dec 2025 21:38:02 +0530 Subject: [PATCH] removed dead code --- libmpv-android | 1 + mpv-android | 1 + src/components/player/hooks/usePlayerSetup.ts | 19 ++- .../player/ios/hooks/useCustomSubtitles.ts | 58 ------- .../player/ios/hooks/useNextEpisode.ts | 58 ------- .../player/ios/hooks/useOpeningAnimation.ts | 149 ------------------ .../player/ios/hooks/usePlayerControls.ts | 63 -------- .../player/ios/hooks/usePlayerModals.ts | 34 ---- .../player/ios/hooks/usePlayerSetup.ts | 103 ------------ .../player/ios/hooks/usePlayerState.ts | 83 ---------- .../player/ios/hooks/usePlayerTracks.ts | 38 ----- .../player/ios/hooks/useSpeedControl.ts | 93 ----------- .../player/ios/hooks/useWatchProgress.ts | 120 -------------- 13 files changed, 15 insertions(+), 805 deletions(-) create mode 160000 libmpv-android create mode 160000 mpv-android delete mode 100644 src/components/player/ios/hooks/useCustomSubtitles.ts delete mode 100644 src/components/player/ios/hooks/useNextEpisode.ts delete mode 100644 src/components/player/ios/hooks/useOpeningAnimation.ts delete mode 100644 src/components/player/ios/hooks/usePlayerControls.ts delete mode 100644 src/components/player/ios/hooks/usePlayerModals.ts delete mode 100644 src/components/player/ios/hooks/usePlayerSetup.ts delete mode 100644 src/components/player/ios/hooks/usePlayerState.ts delete mode 100644 src/components/player/ios/hooks/usePlayerTracks.ts delete mode 100644 src/components/player/ios/hooks/useSpeedControl.ts delete mode 100644 src/components/player/ios/hooks/useWatchProgress.ts diff --git a/libmpv-android b/libmpv-android new file mode 160000 index 00000000..8c4778b5 --- /dev/null +++ b/libmpv-android @@ -0,0 +1 @@ +Subproject commit 8c4778b5aad441bb0449a7f9b3d6d827fd3d6a2a diff --git a/mpv-android b/mpv-android new file mode 160000 index 00000000..118cd1ed --- /dev/null +++ b/mpv-android @@ -0,0 +1 @@ +Subproject commit 118cd1ed3d498265e44230e5dbb015bdd59f9dad diff --git a/src/components/player/hooks/usePlayerSetup.ts b/src/components/player/hooks/usePlayerSetup.ts index f293611c..3b43f6ad 100644 --- a/src/components/player/hooks/usePlayerSetup.ts +++ b/src/components/player/hooks/usePlayerSetup.ts @@ -81,22 +81,29 @@ export const usePlayerSetup = (config: PlayerSetupConfig) => { }; }, [isOpeningAnimationComplete]); - // Handle Orientation (Lock to Landscape after opening) + const orientationLocked = useRef(false); + useEffect(() => { - if (isOpeningAnimationComplete) { + if (isOpeningAnimationComplete && !orientationLocked.current) { const task = InteractionManager.runAfterInteractions(() => { ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.LANDSCAPE) .then(() => { - if (__DEV__) logger.log('[VideoPlayer] Locked to landscape orientation'); + orientationLocked.current = true; }) - .catch((error) => { - logger.warn('[VideoPlayer] Failed to lock orientation:', error); - }); + .catch(() => { }); }); return () => task.cancel(); } }, [isOpeningAnimationComplete]); + useEffect(() => { + return () => { + ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.DEFAULT) + .then(() => ScreenOrientation.unlockAsync()) + .catch(() => { }); + }; + }, []); + // Handle App State useEffect(() => { const onAppStateChange = (state: string) => { diff --git a/src/components/player/ios/hooks/useCustomSubtitles.ts b/src/components/player/ios/hooks/useCustomSubtitles.ts deleted file mode 100644 index a7ff132b..00000000 --- a/src/components/player/ios/hooks/useCustomSubtitles.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { useState } from 'react'; -import { - DEFAULT_SUBTITLE_SIZE, - SubtitleCue, - SubtitleSegment, - WyzieSubtitle -} from '../../utils/playerTypes'; - -export const useCustomSubtitles = () => { - // Data State - const [customSubtitles, setCustomSubtitles] = useState([]); - const [currentSubtitle, setCurrentSubtitle] = useState(''); - const [currentFormattedSegments, setCurrentFormattedSegments] = useState([]); - const [availableSubtitles, setAvailableSubtitles] = useState([]); - const [useCustomSubtitles, setUseCustomSubtitles] = useState(false); - - // Loading State - const [isLoadingSubtitles, setIsLoadingSubtitles] = useState(false); - const [isLoadingSubtitleList, setIsLoadingSubtitleList] = useState(false); - - // Styling State - const [subtitleSize, setSubtitleSize] = useState(DEFAULT_SUBTITLE_SIZE); - const [subtitleBackground, setSubtitleBackground] = useState(false); - const [subtitleTextColor, setSubtitleTextColor] = useState('#FFFFFF'); - const [subtitleBgOpacity, setSubtitleBgOpacity] = useState(0.7); - const [subtitleTextShadow, setSubtitleTextShadow] = useState(true); - const [subtitleOutline, setSubtitleOutline] = useState(true); - const [subtitleOutlineColor, setSubtitleOutlineColor] = useState('#000000'); - const [subtitleOutlineWidth, setSubtitleOutlineWidth] = useState(4); - const [subtitleAlign, setSubtitleAlign] = useState<'center' | 'left' | 'right'>('center'); - const [subtitleBottomOffset, setSubtitleBottomOffset] = useState(10); - const [subtitleLetterSpacing, setSubtitleLetterSpacing] = useState(0); - const [subtitleLineHeightMultiplier, setSubtitleLineHeightMultiplier] = useState(1.2); - const [subtitleOffsetSec, setSubtitleOffsetSec] = useState(0); - - return { - customSubtitles, setCustomSubtitles, - currentSubtitle, setCurrentSubtitle, - currentFormattedSegments, setCurrentFormattedSegments, - availableSubtitles, setAvailableSubtitles, - useCustomSubtitles, setUseCustomSubtitles, - isLoadingSubtitles, setIsLoadingSubtitles, - isLoadingSubtitleList, setIsLoadingSubtitleList, - subtitleSize, setSubtitleSize, - subtitleBackground, setSubtitleBackground, - subtitleTextColor, setSubtitleTextColor, - subtitleBgOpacity, setSubtitleBgOpacity, - subtitleTextShadow, setSubtitleTextShadow, - subtitleOutline, setSubtitleOutline, - subtitleOutlineColor, setSubtitleOutlineColor, - subtitleOutlineWidth, setSubtitleOutlineWidth, - subtitleAlign, setSubtitleAlign, - subtitleBottomOffset, setSubtitleBottomOffset, - subtitleLetterSpacing, setSubtitleLetterSpacing, - subtitleLineHeightMultiplier, setSubtitleLineHeightMultiplier, - subtitleOffsetSec, setSubtitleOffsetSec - }; -}; diff --git a/src/components/player/ios/hooks/useNextEpisode.ts b/src/components/player/ios/hooks/useNextEpisode.ts deleted file mode 100644 index 63e28464..00000000 --- a/src/components/player/ios/hooks/useNextEpisode.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { useMemo } from 'react'; - -export const useNextEpisode = ( - type: string | undefined, - season: number | undefined, - episode: number | undefined, - groupedEpisodes: any, - metadataGroupedEpisodes: any, - episodeId: string | undefined -) => { - // Current description - const currentEpisodeDescription = useMemo(() => { - try { - if (type !== 'series') return ''; - const allEpisodes = Object.values(groupedEpisodes || {}).flat() as any[]; - if (!allEpisodes || allEpisodes.length === 0) return ''; - - let match: any | null = null; - if (episodeId) { - match = allEpisodes.find(ep => ep?.stremioId === episodeId || String(ep?.id) === String(episodeId)); - } - if (!match && season && episode) { - match = allEpisodes.find(ep => ep?.season_number === season && ep?.episode_number === episode); - } - return (match?.overview || '').trim(); - } catch { - return ''; - } - }, [type, groupedEpisodes, episodeId, season, episode]); - - // Next Episode - const nextEpisode = useMemo(() => { - try { - if (type !== 'series' || !season || !episode) return null; - const sourceGroups = groupedEpisodes && Object.keys(groupedEpisodes || {}).length > 0 - ? groupedEpisodes - : (metadataGroupedEpisodes || {}); - - const allEpisodes = Object.values(sourceGroups || {}).flat() as any[]; - if (!allEpisodes || allEpisodes.length === 0) return null; - - let nextEp = allEpisodes.find((ep: any) => - ep.season_number === season && ep.episode_number === episode + 1 - ); - - if (!nextEp) { - nextEp = allEpisodes.find((ep: any) => - ep.season_number === season + 1 && ep.episode_number === 1 - ); - } - return nextEp; - } catch { - return null; - } - }, [type, season, episode, groupedEpisodes, metadataGroupedEpisodes]); - - return { currentEpisodeDescription, nextEpisode }; -}; diff --git a/src/components/player/ios/hooks/useOpeningAnimation.ts b/src/components/player/ios/hooks/useOpeningAnimation.ts deleted file mode 100644 index 8dd087ef..00000000 --- a/src/components/player/ios/hooks/useOpeningAnimation.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { useRef, useState, useEffect } from 'react'; -import { Animated, InteractionManager } from 'react-native'; -import FastImage from '@d11/react-native-fast-image'; -import { logger } from '../../../../utils/logger'; - -export const useOpeningAnimation = (backdrop: string | undefined, metadata: any) => { - // Animation Values - const fadeAnim = useRef(new Animated.Value(1)).current; - const openingFadeAnim = useRef(new Animated.Value(0)).current; - const openingScaleAnim = useRef(new Animated.Value(0.8)).current; - const backgroundFadeAnim = useRef(new Animated.Value(1)).current; - const backdropImageOpacityAnim = useRef(new Animated.Value(0)).current; - const logoScaleAnim = useRef(new Animated.Value(0.8)).current; - const logoOpacityAnim = useRef(new Animated.Value(0)).current; - const pulseAnim = useRef(new Animated.Value(1)).current; - - const [isOpeningAnimationComplete, setIsOpeningAnimationComplete] = useState(false); - const [shouldHideOpeningOverlay, setShouldHideOpeningOverlay] = useState(false); - const [isBackdropLoaded, setIsBackdropLoaded] = useState(false); - - // Prefetch Background - useEffect(() => { - const task = InteractionManager.runAfterInteractions(() => { - if (backdrop && typeof backdrop === 'string') { - setIsBackdropLoaded(false); - backdropImageOpacityAnim.setValue(0); - try { - FastImage.preload([{ uri: backdrop }]); - setIsBackdropLoaded(true); - Animated.timing(backdropImageOpacityAnim, { - toValue: 1, - duration: 400, - useNativeDriver: true, - }).start(); - } catch (error) { - setIsBackdropLoaded(true); - backdropImageOpacityAnim.setValue(1); - } - } else { - setIsBackdropLoaded(true); - backdropImageOpacityAnim.setValue(0); - } - }); - return () => task.cancel(); - }, [backdrop]); - - // Prefetch Logo - useEffect(() => { - const task = InteractionManager.runAfterInteractions(() => { - const logoUrl = metadata?.logo; - if (logoUrl && typeof logoUrl === 'string') { - try { - FastImage.preload([{ uri: logoUrl }]); - } catch (error) { } - } - }); - return () => task.cancel(); - }, [metadata]); - - const startOpeningAnimation = () => { - Animated.parallel([ - Animated.timing(logoOpacityAnim, { - toValue: 1, - duration: 300, - useNativeDriver: true, - }), - Animated.spring(logoScaleAnim, { - toValue: 1, - tension: 80, - friction: 8, - useNativeDriver: true, - }), - ]).start(); - - const createPulseAnimation = () => { - return Animated.sequence([ - Animated.timing(pulseAnim, { - toValue: 1.05, - duration: 800, - useNativeDriver: true, - }), - Animated.timing(pulseAnim, { - toValue: 1, - duration: 800, - useNativeDriver: true, - }), - ]); - }; - - const loopPulse = () => { - createPulseAnimation().start(() => { - if (!isOpeningAnimationComplete) { - loopPulse(); - } - }); - }; - loopPulse(); - }; - - const completeOpeningAnimation = () => { - pulseAnim.stopAnimation(); - - Animated.parallel([ - Animated.timing(openingFadeAnim, { - toValue: 1, - duration: 300, - useNativeDriver: true, - }), - Animated.timing(openingScaleAnim, { - toValue: 1, - duration: 350, - useNativeDriver: true, - }), - Animated.timing(backgroundFadeAnim, { - toValue: 0, - duration: 400, - useNativeDriver: true, - }), - ]).start(() => { - setIsOpeningAnimationComplete(true); - setTimeout(() => { - setShouldHideOpeningOverlay(true); - }, 450); - }); - - setTimeout(() => { - if (!isOpeningAnimationComplete) { - // logger.warn('[VideoPlayer] Opening animation fallback triggered'); - setIsOpeningAnimationComplete(true); - } - }, 1000); - }; - - return { - fadeAnim, - openingFadeAnim, - openingScaleAnim, - backgroundFadeAnim, - backdropImageOpacityAnim, - logoScaleAnim, - logoOpacityAnim, - pulseAnim, - isOpeningAnimationComplete, - shouldHideOpeningOverlay, - isBackdropLoaded, - startOpeningAnimation, - completeOpeningAnimation - }; -}; diff --git a/src/components/player/ios/hooks/usePlayerControls.ts b/src/components/player/ios/hooks/usePlayerControls.ts deleted file mode 100644 index 1b92ddb5..00000000 --- a/src/components/player/ios/hooks/usePlayerControls.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { useRef, useCallback } from 'react'; -import { Platform } from 'react-native'; -import { logger } from '../../../../utils/logger'; - -const DEBUG_MODE = false; -const END_EPSILON = 0.3; - -export const usePlayerControls = ( - ksPlayerRef: any, - paused: boolean, - setPaused: (paused: boolean) => void, - currentTime: number, - duration: number, - isSeeking: React.MutableRefObject, - isMounted: React.MutableRefObject -) => { - // iOS seeking helpers - const iosWasPausedDuringSeekRef = useRef(null); - - const togglePlayback = useCallback(() => { - setPaused(!paused); - }, [paused, setPaused]); - - const seekToTime = useCallback((rawSeconds: number) => { - const timeInSeconds = Math.max(0, Math.min(rawSeconds, duration > 0 ? duration - END_EPSILON : rawSeconds)); - - if (ksPlayerRef.current && duration > 0 && !isSeeking.current) { - if (DEBUG_MODE) logger.log(`[usePlayerControls] Seeking to ${timeInSeconds}`); - - isSeeking.current = true; - - // iOS optimization: pause while seeking for smoother experience - iosWasPausedDuringSeekRef.current = paused; - if (!paused) setPaused(true); - - // Actually perform the seek - ksPlayerRef.current.seek(timeInSeconds); - - // Debounce the seeking state reset - setTimeout(() => { - if (isMounted.current && isSeeking.current) { - isSeeking.current = false; - // Resume if it was playing - if (iosWasPausedDuringSeekRef.current === false) { - setPaused(false); - iosWasPausedDuringSeekRef.current = null; - } - } - }, 500); - } - }, [duration, paused, setPaused, ksPlayerRef, isSeeking, isMounted]); - - const skip = useCallback((seconds: number) => { - seekToTime(currentTime + seconds); - }, [currentTime, seekToTime]); - - return { - togglePlayback, - seekToTime, - skip, - iosWasPausedDuringSeekRef - }; -}; diff --git a/src/components/player/ios/hooks/usePlayerModals.ts b/src/components/player/ios/hooks/usePlayerModals.ts deleted file mode 100644 index 2f98c01f..00000000 --- a/src/components/player/ios/hooks/usePlayerModals.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { useState } from 'react'; -import { Episode } from '../../../../types/metadata'; - -export const usePlayerModals = () => { - const [showAudioModal, setShowAudioModal] = useState(false); - const [showSubtitleModal, setShowSubtitleModal] = useState(false); - const [showSpeedModal, setShowSpeedModal] = useState(false); - const [showSourcesModal, setShowSourcesModal] = useState(false); - const [showEpisodesModal, setShowEpisodesModal] = useState(false); - const [showEpisodeStreamsModal, setShowEpisodeStreamsModal] = useState(false); - const [showErrorModal, setShowErrorModal] = useState(false); - const [showSubtitleLanguageModal, setShowSubtitleLanguageModal] = useState(false); - const [showCastDetails, setShowCastDetails] = useState(false); - - // Some modals have associated data - const [selectedEpisodeForStreams, setSelectedEpisodeForStreams] = useState(null); - const [errorDetails, setErrorDetails] = useState(''); - const [selectedCastMember, setSelectedCastMember] = useState(null); - - return { - showAudioModal, setShowAudioModal, - showSubtitleModal, setShowSubtitleModal, - showSpeedModal, setShowSpeedModal, - showSourcesModal, setShowSourcesModal, - showEpisodesModal, setShowEpisodesModal, - showEpisodeStreamsModal, setShowEpisodeStreamsModal, - showErrorModal, setShowErrorModal, - showSubtitleLanguageModal, setShowSubtitleLanguageModal, - showCastDetails, setShowCastDetails, - selectedEpisodeForStreams, setSelectedEpisodeForStreams, - errorDetails, setErrorDetails, - selectedCastMember, setSelectedCastMember - }; -}; diff --git a/src/components/player/ios/hooks/usePlayerSetup.ts b/src/components/player/ios/hooks/usePlayerSetup.ts deleted file mode 100644 index b09a2aa3..00000000 --- a/src/components/player/ios/hooks/usePlayerSetup.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { useEffect, useRef, useCallback } from 'react'; -import { StatusBar, Dimensions, AppState, InteractionManager } from 'react-native'; -import * as Brightness from 'expo-brightness'; -import * as ScreenOrientation from 'expo-screen-orientation'; -import { logger } from '../../../../utils/logger'; -import { useFocusEffect } from '@react-navigation/native'; - -export const usePlayerSetup = ( - setScreenDimensions: (dim: any) => void, - setVolume: (vol: number) => void, - setBrightness: (bri: number) => void, - isOpeningAnimationComplete: boolean -) => { - const isAppBackgrounded = useRef(false); - - const enableImmersiveMode = () => { - StatusBar.setHidden(true, 'none'); - }; - - const disableImmersiveMode = () => { - StatusBar.setHidden(false, 'fade'); - }; - - useFocusEffect( - useCallback(() => { - if (isOpeningAnimationComplete) { - enableImmersiveMode(); - } - return () => { }; - }, [isOpeningAnimationComplete]) - ); - - useEffect(() => { - // Initial Setup - const subscription = Dimensions.addEventListener('change', ({ screen }) => { - setScreenDimensions(screen); - if (isOpeningAnimationComplete) { - enableImmersiveMode(); - } - }); - - StatusBar.setHidden(true, 'none'); - if (isOpeningAnimationComplete) { - enableImmersiveMode(); - } - - // Initialize volume (KSPlayer uses 0-100) - setVolume(100); - - // Initialize Brightness - const initBrightness = () => { - InteractionManager.runAfterInteractions(async () => { - try { - const currentBrightness = await Brightness.getBrightnessAsync(); - setBrightness(currentBrightness); - } catch (error) { - logger.warn('[usePlayerSetup] Error getting initial brightness:', error); - setBrightness(1.0); - } - }); - }; - initBrightness(); - - return () => { - subscription?.remove(); - disableImmersiveMode(); - }; - }, [isOpeningAnimationComplete]); - - // Handle Orientation (Lock to Landscape after opening) - useEffect(() => { - if (isOpeningAnimationComplete) { - const task = InteractionManager.runAfterInteractions(() => { - ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.LANDSCAPE) - .then(() => { - if (__DEV__) logger.log('[VideoPlayer] Locked to landscape orientation'); - }) - .catch((error) => { - logger.warn('[VideoPlayer] Failed to lock orientation:', error); - }); - }); - return () => task.cancel(); - } - }, [isOpeningAnimationComplete]); - - // Handle App State - useEffect(() => { - const onAppStateChange = (state: string) => { - if (state === 'active') { - isAppBackgrounded.current = false; - if (isOpeningAnimationComplete) { - enableImmersiveMode(); - } - } else if (state === 'background' || state === 'inactive') { - isAppBackgrounded.current = true; - } - }; - const sub = AppState.addEventListener('change', onAppStateChange); - return () => sub.remove(); - }, [isOpeningAnimationComplete]); - - return { isAppBackgrounded }; -}; diff --git a/src/components/player/ios/hooks/usePlayerState.ts b/src/components/player/ios/hooks/usePlayerState.ts deleted file mode 100644 index 2cd2ab84..00000000 --- a/src/components/player/ios/hooks/usePlayerState.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { useState, useRef } from 'react'; -import { Dimensions, Platform } from 'react-native'; - -// Use a specific type for resizeMode that matches what KSPlayerComponent supports -type PlayerResizeMode = 'contain' | 'cover' | 'stretch'; - -export const usePlayerState = () => { - // Playback State - const [paused, setPaused] = useState(false); - const [currentTime, setCurrentTime] = useState(0); - const [duration, setDuration] = useState(0); - const [buffered, setBuffered] = useState(0); - const [isBuffering, setIsBuffering] = useState(false); - const [isVideoLoaded, setIsVideoLoaded] = useState(false); - const [isPlayerReady, setIsPlayerReady] = useState(false); - - // UI State - const [showControls, setShowControls] = useState(true); - const [resizeMode, setResizeMode] = useState('contain'); - const [videoAspectRatio, setVideoAspectRatio] = useState(null); - const [is16by9Content, setIs16by9Content] = useState(false); - const screenData = Dimensions.get('screen'); - const [screenDimensions, setScreenDimensions] = useState(screenData); - - // Zoom State - const [zoomScale, setZoomScale] = useState(1); - const [zoomTranslateX, setZoomTranslateX] = useState(0); - const [zoomTranslateY, setZoomTranslateY] = useState(0); - const [lastZoomScale, setLastZoomScale] = useState(1); - const [lastTranslateX, setLastTranslateX] = useState(0); - const [lastTranslateY, setLastTranslateY] = useState(0); - - // AirPlay State - const [isAirPlayActive, setIsAirPlayActive] = useState(false); - const [allowsAirPlay, setAllowsAirPlay] = useState(true); - - // Logic State - const isSeeking = useRef(false); - const isDragging = useRef(false); - const isMounted = useRef(true); - const seekDebounceTimer = useRef(null); - const pendingSeekValue = useRef(null); - const lastSeekTime = useRef(0); - const wasPlayingBeforeDragRef = useRef(false); - - // Helper for iPad/macOS fullscreen - const isIPad = Platform.OS === 'ios' && (screenData.width > 1000 || screenData.height > 1000); - const isMacOS = Platform.OS === 'ios' && Platform.isPad === true; - const shouldUseFullscreen = isIPad || isMacOS; - const windowData = Dimensions.get('window'); - const effectiveDimensions = shouldUseFullscreen ? windowData : screenDimensions; - - return { - paused, setPaused, - currentTime, setCurrentTime, - duration, setDuration, - buffered, setBuffered, - isBuffering, setIsBuffering, - isVideoLoaded, setIsVideoLoaded, - isPlayerReady, setIsPlayerReady, - showControls, setShowControls, - resizeMode, setResizeMode, - videoAspectRatio, setVideoAspectRatio, - is16by9Content, setIs16by9Content, - screenDimensions, setScreenDimensions, - zoomScale, setZoomScale, - zoomTranslateX, setZoomTranslateX, - zoomTranslateY, setZoomTranslateY, - lastZoomScale, setLastZoomScale, - lastTranslateX, setLastTranslateX, - lastTranslateY, setLastTranslateY, - isAirPlayActive, setIsAirPlayActive, - allowsAirPlay, setAllowsAirPlay, - isSeeking, - isDragging, - isMounted, - seekDebounceTimer, - pendingSeekValue, - lastSeekTime, - wasPlayingBeforeDragRef, - effectiveDimensions - }; -}; diff --git a/src/components/player/ios/hooks/usePlayerTracks.ts b/src/components/player/ios/hooks/usePlayerTracks.ts deleted file mode 100644 index 76f0d219..00000000 --- a/src/components/player/ios/hooks/usePlayerTracks.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { useState, useMemo, useCallback } from 'react'; -import { AudioTrack, TextTrack } from '../../utils/playerTypes'; - -export const usePlayerTracks = () => { - const [audioTracks, setAudioTracks] = useState([]); - const [selectedAudioTrack, setSelectedAudioTrack] = useState(null); - const [textTracks, setTextTracks] = useState([]); - const [selectedTextTrack, setSelectedTextTrack] = useState(-1); - - const [ksAudioTracks, setKsAudioTracks] = useState>([]); - const [ksTextTracks, setKsTextTracks] = useState>([]); - - // Derived states or logic - const hasAudioTracks = audioTracks.length > 0; - const hasTextTracks = textTracks.length > 0; - - // Track selection functions - const selectAudioTrack = useCallback((trackId: number) => { - setSelectedAudioTrack(trackId); - }, []); - - const selectTextTrack = useCallback((trackId: number) => { - setSelectedTextTrack(trackId); - }, []); - - return { - audioTracks, setAudioTracks, - selectedAudioTrack, setSelectedAudioTrack, - textTracks, setTextTracks, - selectedTextTrack, setSelectedTextTrack, - ksAudioTracks, setKsAudioTracks, - ksTextTracks, setKsTextTracks, - hasAudioTracks, - hasTextTracks, - selectAudioTrack, - selectTextTrack - }; -}; diff --git a/src/components/player/ios/hooks/useSpeedControl.ts b/src/components/player/ios/hooks/useSpeedControl.ts deleted file mode 100644 index d185f0e6..00000000 --- a/src/components/player/ios/hooks/useSpeedControl.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { useState, useRef, useCallback, useEffect } from 'react'; -import { Animated } from 'react-native'; -import { mmkvStorage } from '../../../../services/mmkvStorage'; -import { logger } from '../../../../utils/logger'; - -const SPEED_SETTINGS_KEY = '@nuvio_speed_settings'; - -export const useSpeedControl = (initialSpeed: number = 1.0) => { - const [playbackSpeed, setPlaybackSpeed] = useState(initialSpeed); - const [holdToSpeedEnabled, setHoldToSpeedEnabled] = useState(true); - const [holdToSpeedValue, setHoldToSpeedValue] = useState(2.0); - const [isSpeedBoosted, setIsSpeedBoosted] = useState(false); - const [originalSpeed, setOriginalSpeed] = useState(initialSpeed); - const [showSpeedActivatedOverlay, setShowSpeedActivatedOverlay] = useState(false); - - const speedActivatedOverlayOpacity = useRef(new Animated.Value(0)).current; - - // Load Settings - useEffect(() => { - const loadSettings = async () => { - try { - const saved = await mmkvStorage.getItem(SPEED_SETTINGS_KEY); - if (saved) { - const settings = JSON.parse(saved); - if (typeof settings.holdToSpeedEnabled === 'boolean') setHoldToSpeedEnabled(settings.holdToSpeedEnabled); - if (typeof settings.holdToSpeedValue === 'number') setHoldToSpeedValue(settings.holdToSpeedValue); - } - } catch (e) { - logger.warn('[useSpeedControl] Error loading settings', e); - } - }; - loadSettings(); - }, []); - - // Save Settings - useEffect(() => { - const saveSettings = async () => { - try { - await mmkvStorage.setItem(SPEED_SETTINGS_KEY, JSON.stringify({ - holdToSpeedEnabled, - holdToSpeedValue - })); - } catch (e) { } - }; - saveSettings(); - }, [holdToSpeedEnabled, holdToSpeedValue]); - - const activateSpeedBoost = useCallback(() => { - if (!holdToSpeedEnabled || isSpeedBoosted || playbackSpeed === holdToSpeedValue) return; - - setOriginalSpeed(playbackSpeed); - setPlaybackSpeed(holdToSpeedValue); - setIsSpeedBoosted(true); - setShowSpeedActivatedOverlay(true); - - Animated.timing(speedActivatedOverlayOpacity, { - toValue: 1, - duration: 200, - useNativeDriver: true - }).start(); - - setTimeout(() => { - Animated.timing(speedActivatedOverlayOpacity, { - toValue: 0, - duration: 300, - useNativeDriver: true - }).start(() => setShowSpeedActivatedOverlay(false)); - }, 2000); - - }, [holdToSpeedEnabled, isSpeedBoosted, playbackSpeed, holdToSpeedValue]); - - const deactivateSpeedBoost = useCallback(() => { - if (isSpeedBoosted) { - setPlaybackSpeed(originalSpeed); - setIsSpeedBoosted(false); - Animated.timing(speedActivatedOverlayOpacity, { toValue: 0, duration: 100, useNativeDriver: true }).start(); - } - }, [isSpeedBoosted, originalSpeed]); - - return { - playbackSpeed, - setPlaybackSpeed, - holdToSpeedEnabled, - setHoldToSpeedEnabled, - holdToSpeedValue, - setHoldToSpeedValue, - isSpeedBoosted, - activateSpeedBoost, - deactivateSpeedBoost, - showSpeedActivatedOverlay, - speedActivatedOverlayOpacity - }; -}; diff --git a/src/components/player/ios/hooks/useWatchProgress.ts b/src/components/player/ios/hooks/useWatchProgress.ts deleted file mode 100644 index fa61406a..00000000 --- a/src/components/player/ios/hooks/useWatchProgress.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { useState, useEffect, useRef } from 'react'; -import { storageService } from '../../../../services/storageService'; -import { logger } from '../../../../utils/logger'; -import { useSettings } from '../../../../hooks/useSettings'; - -export const useWatchProgress = ( - id: string | undefined, - type: string | undefined, - episodeId: string | undefined, - currentTime: number, - duration: number, - paused: boolean, - traktAutosync: any, - seekToTime: (time: number) => void -) => { - const [resumePosition, setResumePosition] = useState(null); - const [savedDuration, setSavedDuration] = useState(null); - const [initialPosition, setInitialPosition] = useState(null); - const [showResumeOverlay, setShowResumeOverlay] = useState(false); - const [progressSaveInterval, setProgressSaveInterval] = useState(null); - - const { settings: appSettings } = useSettings(); - const initialSeekTargetRef = useRef(null); - - // Values refs for unmount cleanup - const currentTimeRef = useRef(currentTime); - const durationRef = useRef(duration); - - useEffect(() => { - currentTimeRef.current = currentTime; - }, [currentTime]); - - useEffect(() => { - durationRef.current = duration; - }, [duration]); - - // Load Watch Progress - useEffect(() => { - const loadWatchProgress = async () => { - if (id && type) { - try { - const savedProgress = await storageService.getWatchProgress(id, type, episodeId); - if (savedProgress) { - const progressPercent = (savedProgress.currentTime / savedProgress.duration) * 100; - - if (progressPercent < 85) { - setResumePosition(savedProgress.currentTime); - setSavedDuration(savedProgress.duration); - - if (appSettings.alwaysResume) { - setInitialPosition(savedProgress.currentTime); - initialSeekTargetRef.current = savedProgress.currentTime; - seekToTime(savedProgress.currentTime); - } else { - setShowResumeOverlay(true); - } - } - } - } catch (error) { - logger.error('[useWatchProgress] Error loading watch progress:', error); - } - } - }; - loadWatchProgress(); - }, [id, type, episodeId, appSettings.alwaysResume]); - - const saveWatchProgress = async () => { - if (id && type && currentTimeRef.current > 0 && durationRef.current > 0) { - const progress = { - currentTime: currentTimeRef.current, - duration: durationRef.current, - lastUpdated: Date.now() - }; - try { - await storageService.setWatchProgress(id, type, progress, episodeId); - await traktAutosync.handleProgressUpdate(currentTimeRef.current, durationRef.current); - } catch (error) { - logger.error('[useWatchProgress] Error saving watch progress:', error); - } - } - }; - - // Save Interval - useEffect(() => { - if (id && type && !paused && duration > 0) { - if (progressSaveInterval) clearInterval(progressSaveInterval); - - const interval = setInterval(() => { - saveWatchProgress(); - }, 10000); - - setProgressSaveInterval(interval); - return () => { - clearInterval(interval); - setProgressSaveInterval(null); - }; - } - }, [id, type, paused, currentTime, duration]); - - // Unmount Save - useEffect(() => { - return () => { - if (id && type && durationRef.current > 0) { - saveWatchProgress(); - traktAutosync.handlePlaybackEnd(currentTimeRef.current, durationRef.current, 'unmount'); - } - }; - }, [id, type]); - - return { - resumePosition, - savedDuration, - initialPosition, - setInitialPosition, - showResumeOverlay, - setShowResumeOverlay, - saveWatchProgress, - initialSeekTargetRef - }; -};