diff --git a/app/(auth)/player/direct-player.tsx b/app/(auth)/player/direct-player.tsx index be5bf96c..2ea2d756 100644 --- a/app/(auth)/player/direct-player.tsx +++ b/app/(auth)/player/direct-player.tsx @@ -1,10 +1,11 @@ import { BITRATES } from "@/components/BitrateSelector"; import { Text } from "@/components/common/Text"; import { Loader } from "@/components/Loader"; -import { getDownloadedFileUrl } from "@/hooks/useDownloadedFileOpener"; import { Controls } from "@/components/video-player/controls/Controls"; +import { getDownloadedFileUrl } from "@/hooks/useDownloadedFileOpener"; import { useOrientation } from "@/hooks/useOrientation"; import { useOrientationSettings } from "@/hooks/useOrientationSettings"; +import { useRevalidatePlaybackProgressCache } from "@/hooks/useRevalidatePlaybackProgressCache"; import { useWebSocket } from "@/hooks/useWebsockets"; import { VlcPlayerView } from "@/modules/vlc-player"; import { @@ -20,32 +21,18 @@ import { writeToLog } from "@/utils/log"; import native from "@/utils/profiles/native"; import { msToTicks, ticksToSeconds } from "@/utils/time"; import { Api } from "@jellyfin/sdk"; -import { - BaseItemDto, - MediaSourceType, -} from "@jellyfin/sdk/lib/generated-client"; +import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client"; import { getPlaystateApi, getUserLibraryApi, } from "@jellyfin/sdk/lib/utils/api"; -import { useQuery } from "@tanstack/react-query"; +import { useQuery, useQueryClient } from "@tanstack/react-query"; import * as Haptics from "expo-haptics"; -import { - useFocusEffect, - useGlobalSearchParams, - useLocalSearchParams, -} from "expo-router"; +import { useFocusEffect, useGlobalSearchParams } from "expo-router"; import { useAtomValue } from "jotai"; -import React, { - useCallback, - useEffect, - useMemo, - useRef, - useState, -} from "react"; +import React, { useCallback, useMemo, useRef, useState } from "react"; import { Alert, Pressable, View } from "react-native"; import { useSharedValue } from "react-native-reanimated"; -import { SafeAreaView } from "react-native-safe-area-context"; export default function page() { const videoRef = useRef(null); @@ -64,6 +51,7 @@ export default function page() { const cacheProgress = useSharedValue(0); const { getDownloadedItem } = useDownload(); + const revalidateProgressCache = useRevalidatePlaybackProgressCache(); const { itemId, @@ -253,6 +241,8 @@ export default function page() { positionTicks: currentTimeInTicks, playSessionId: stream?.sessionId!, }); + + revalidateProgressCache(); }, [api, item, mediaSourceId, stream]); const reportPlaybackStart = useCallback(async () => { diff --git a/app/(auth)/player/transcoding-player.tsx b/app/(auth)/player/transcoding-player.tsx index 68608c99..9efc4732 100644 --- a/app/(auth)/player/transcoding-player.tsx +++ b/app/(auth)/player/transcoding-player.tsx @@ -37,6 +37,7 @@ import Video, { } from "react-native-video"; import { Controls } from "@/components/video-player/controls/Controls"; import transcoding from "@/utils/profiles/transcoding"; +import { useRevalidatePlaybackProgressCache } from "@/hooks/useRevalidatePlaybackProgressCache"; const Player = () => { const api = useAtomValue(apiAtom); @@ -45,7 +46,7 @@ const Player = () => { const videoRef = useRef(null); const firstTime = useRef(true); - const dimensions = useWindowDimensions(); + const revalidateProgressCache = useRevalidatePlaybackProgressCache(); const [isPlaybackStopped, setIsPlaybackStopped] = useState(false); const [showControls, setShowControls] = useState(true); @@ -239,6 +240,7 @@ const Player = () => { positionTicks: Math.floor(progress.value), playSessionId: stream?.sessionId, }); + revalidateProgressCache(); }; const reportPlaybackStart = async () => { diff --git a/components/PlayedStatus.tsx b/components/PlayedStatus.tsx index 82e9057d..0d483858 100644 --- a/components/PlayedStatus.tsx +++ b/components/PlayedStatus.tsx @@ -41,9 +41,6 @@ export const PlayedStatus: React.FC = ({ item, ...props }) => { queryClient.invalidateQueries({ queryKey: ["seasons"], }); - queryClient.invalidateQueries({ - queryKey: ["nextUp-all"], - }); queryClient.invalidateQueries({ queryKey: ["home"], }); diff --git a/hooks/useRevalidatePlaybackProgressCache.ts b/hooks/useRevalidatePlaybackProgressCache.ts new file mode 100644 index 00000000..082870d9 --- /dev/null +++ b/hooks/useRevalidatePlaybackProgressCache.ts @@ -0,0 +1,29 @@ +import { useQueryClient } from "@tanstack/react-query"; + +/** + * useRevalidatePlaybackProgressCache invalidates queries related to playback progress. + */ +export function useRevalidatePlaybackProgressCache() { + const queryClient = useQueryClient(); + + const revalidate = () => { + // List of all the queries to invalidate + const queriesToInvalidate = [ + ["item"], + ["resumeItems"], + ["continueWatching"], + ["nextUp-all"], + ["nextUp"], + ["episodes"], + ["seasons"], + ["home"], + ]; + + // Invalidate each query + queriesToInvalidate.forEach((queryKey) => { + queryClient.invalidateQueries({ queryKey }); + }); + }; + + return revalidate; +}