From 349fc1f21e41924673fa9124f92a19817c84b459 Mon Sep 17 00:00:00 2001 From: Fredrik Burmester Date: Fri, 16 Aug 2024 19:06:06 +0200 Subject: [PATCH] fix: refactor --- app/(auth)/items/[id].tsx | 46 +++---- app/_layout.tsx | 189 ++++++++++++++--------------- components/CurrentlyPlayingBar.tsx | 148 +++++++++++----------- components/PlayButton.tsx | 2 + 4 files changed, 195 insertions(+), 190 deletions(-) diff --git a/app/(auth)/items/[id].tsx b/app/(auth)/items/[id].tsx index 7110659a..024d0fce 100644 --- a/app/(auth)/items/[id].tsx +++ b/app/(auth)/items/[id].tsx @@ -28,6 +28,7 @@ import { chromecastProfile } from "@/utils/profiles/chromecast"; import ios12 from "@/utils/profiles/ios12"; import { currentlyPlayingItemAtom, + playingAtom, triggerPlayAtom, } from "@/components/CurrentlyPlayingBar"; import { AudioTrackSelector } from "@/components/AudioTrackSelector"; @@ -47,6 +48,10 @@ const page: React.FC = () => { const castDevice = useCastDevice(); + const [, setCurrentlyPlying] = useAtom(currentlyPlayingItemAtom); + const [, setPlaying] = useAtom(playingAtom); + + const client = useRemoteMediaClient(); const chromecastReady = useMemo(() => !!castDevice?.deviceId, [castDevice]); const [selectedAudioStream, setSelectedAudioStream] = useState(-1); const [selectedSubtitleStream, setSelectedSubtitleStream] = @@ -68,22 +73,6 @@ const page: React.FC = () => { staleTime: 60, }); - const backdropUrl = useMemo( - () => - getBackdropUrl({ - api, - item, - quality: 90, - width: 1000, - }), - [item], - ); - - const logoUrl = useMemo( - () => (item?.Type === "Movie" ? getLogoImageUrlById({ api, item }) : null), - [item], - ); - const { data: sessionData } = useQuery({ queryKey: ["sessionData", item?.Id], queryFn: async () => { @@ -131,10 +120,6 @@ const page: React.FC = () => { staleTime: 0, }); - const [, setCp] = useAtom(currentlyPlayingItemAtom); - const client = useRemoteMediaClient(); - const [, setPlayTrigger] = useAtom(triggerPlayAtom); - const onPressPlay = useCallback( async (type: "device" | "cast" = "device") => { if (!playbackUrl || !item) return; @@ -159,18 +144,33 @@ const page: React.FC = () => { } }); } else { - setCp({ + setCurrentlyPlying({ item, playbackUrl, }); - // Use this trigger to initiate playback in another component (CurrentlyPlayingBar) - setPlayTrigger((prev) => prev + 1); + setPlaying(true); } }, [playbackUrl, item], ); + const backdropUrl = useMemo( + () => + getBackdropUrl({ + api, + item, + quality: 90, + width: 1000, + }), + [item], + ); + + const logoUrl = useMemo( + () => (item?.Type === "Movie" ? getLogoImageUrlById({ api, item }) : null), + [item], + ); + if (l1) return ( diff --git a/app/_layout.tsx b/app/_layout.tsx index fe72c7c3..5a889ba7 100644 --- a/app/_layout.tsx +++ b/app/_layout.tsx @@ -15,7 +15,6 @@ import { useJobProcessor } from "@/utils/atoms/queue"; import { JobQueueProvider } from "@/providers/JobQueueProvider"; import { useKeepAwake } from "expo-keep-awake"; import { useSettings } from "@/utils/atoms/settings"; -import { StreamProvider } from "@/providers/StreamProvider"; // Prevent the splash screen from auto-hiding before asset loading is complete. SplashScreen.preventAutoHideAsync(); @@ -79,101 +78,99 @@ function Layout() { - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/components/CurrentlyPlayingBar.tsx b/components/CurrentlyPlayingBar.tsx index 56a3a431..be4483f8 100644 --- a/components/CurrentlyPlayingBar.tsx +++ b/components/CurrentlyPlayingBar.tsx @@ -44,17 +44,21 @@ export const currentlyPlayingItemAtom = atom<{ export const triggerPlayAtom = atom(0); -export const CurrentlyPlayingBar: React.FC = () => { - const [api] = useAtom(apiAtom); - const [user] = useAtom(userAtom); - const [cp, setCp] = useAtom(currentlyPlayingItemAtom); +export const playingAtom = atom(false); +export const CurrentlyPlayingBar: React.FC = () => { const queryClient = useQueryClient(); const segments = useSegments(); const [settings] = useSettings(); + const [api] = useAtom(apiAtom); + const [user] = useAtom(userAtom); + const [playing, setPlaying] = useAtom(playingAtom); + const [currentlyPlaying, setCurrentlyPlaying] = useAtom( + currentlyPlayingItemAtom, + ); + const videoRef = useRef(null); - const [paused, setPaused] = useState(true); const [progress, setProgress] = useState(0); const [fullScreen, setFullScreen] = useState(false); @@ -113,81 +117,83 @@ export const CurrentlyPlayingBar: React.FC = () => { // }, [settings, fullScreen]); const { data: item } = useQuery({ - queryKey: ["item", cp?.item.Id], + queryKey: ["item", currentlyPlaying?.item.Id], queryFn: async () => await getUserItemData({ api, userId: user?.Id, - itemId: cp?.item.Id, + itemId: currentlyPlaying?.item.Id, }), - enabled: !!cp?.item.Id && !!api, + enabled: !!currentlyPlaying?.item.Id && !!api, staleTime: 60, }); const { data: sessionData } = useQuery({ - queryKey: ["sessionData", cp?.item.Id], + queryKey: ["sessionData", currentlyPlaying?.item.Id], queryFn: async () => { - if (!cp?.item.Id) return null; + if (!currentlyPlaying?.item.Id) return null; const playbackData = await getMediaInfoApi(api!).getPlaybackInfo({ - itemId: cp?.item.Id, + itemId: currentlyPlaying?.item.Id, userId: user?.Id, }); return playbackData.data; }, - enabled: !!cp?.item.Id && !!api && !!user?.Id, + enabled: !!currentlyPlaying?.item.Id && !!api && !!user?.Id, staleTime: 0, }); const onProgress = useCallback( ({ currentTime }: OnProgressData) => { - if (!currentTime || !sessionData?.PlaySessionId || paused) return; + if ( + !currentTime || + !sessionData?.PlaySessionId || + !playing || + !api || + !currentlyPlaying?.item.Id + ) + return; const newProgress = currentTime * 10000000; setProgress(newProgress); reportPlaybackProgress({ api, - itemId: cp?.item.Id, + itemId: currentlyPlaying?.item.Id, positionTicks: newProgress, sessionId: sessionData.PlaySessionId, }); }, - [sessionData?.PlaySessionId, item, api, paused] + [sessionData?.PlaySessionId, api, playing, currentlyPlaying?.item.Id], ); - const play = () => { - if (videoRef.current) { - videoRef.current.resume(); - setPaused(false); - } - }; + useEffect(() => { + if (playing) { + videoRef.current?.resume(); + } else { + videoRef.current?.pause(); + if (progress > 0 && sessionData?.PlaySessionId && api) + reportPlaybackStopped({ + api, + itemId: item?.Id, + positionTicks: progress, + sessionId: sessionData?.PlaySessionId, + }); - const pause = useCallback(() => { - videoRef.current?.pause(); - setPaused(true); - - if (progress > 0) - reportPlaybackStopped({ - api, - itemId: item?.Id, - positionTicks: progress, - sessionId: sessionData?.PlaySessionId, + queryClient.invalidateQueries({ + queryKey: ["nextUp", item?.SeriesId], + refetchType: "all", }); - - queryClient.invalidateQueries({ - queryKey: ["nextUp", item?.SeriesId], - refetchType: "all", - }); - queryClient.invalidateQueries({ - queryKey: ["episodes"], - refetchType: "all", - }); - }, [api, item, progress, sessionData, queryClient]); + queryClient.invalidateQueries({ + queryKey: ["episodes"], + refetchType: "all", + }); + } + }, [playing, progress, item, sessionData]); const startPosition = useMemo( () => item?.UserData?.PlaybackPositionTicks ? Math.round(item.UserData.PlaybackPositionTicks / 10000) : 0, - [item] + [item], ); const backdropUrl = useMemo( @@ -198,7 +204,7 @@ export const CurrentlyPlayingBar: React.FC = () => { quality: 70, width: 200, }), - [item] + [item], ); /** @@ -207,24 +213,24 @@ export const CurrentlyPlayingBar: React.FC = () => { * * The trigger playback is triggered from the button component. */ - useEffect(() => { - if (cp?.playbackUrl) { - play(); - if (settings?.openFullScreenVideoPlayerByDefault) { - videoRef.current?.presentFullscreenPlayer(); - } - } - }, [cp?.playbackUrl]); + // useEffect(() => { + // if (currentlyPlaying?.playbackUrl) { + // play(); + // if (settings?.openFullScreenVideoPlayerByDefault) { + // videoRef.current?.presentFullscreenPlayer(); + // } + // } + // }, [currentlyPlaying?.playbackUrl]); - const [triggerPlay] = useAtom(triggerPlayAtom); - useEffect(() => { - play(); - if (settings?.openFullScreenVideoPlayerByDefault) { - videoRef.current?.presentFullscreenPlayer(); - } - }, [triggerPlay]); + // const [triggerPlay] = useAtom(triggerPlayAtom); + // useEffect(() => { + // setPlaying(true) + // if (settings?.openFullScreenVideoPlayerByDefault) { + // videoRef.current?.presentFullscreenPlayer(); + // } + // }, [triggerPlay]); - if (!cp || !api) return null; + if (!currentlyPlaying || !api) return null; return ( { ${item?.Type === "Audio" ? "aspect-square" : "aspect-video"} `} > - {cp.playbackUrl && ( + {currentlyPlaying.playbackUrl && (