diff --git a/app/(auth)/items/[id]/page.tsx b/app/(auth)/items/[id]/page.tsx index a770f38f..a9bcea02 100644 --- a/app/(auth)/items/[id]/page.tsx +++ b/app/(auth)/items/[id]/page.tsx @@ -26,7 +26,10 @@ import CastContext, { } from "react-native-google-cast"; import { chromecastProfile } from "@/utils/profiles/chromecast"; import ios12 from "@/utils/profiles/ios12"; -import { currentlyPlayingItemAtom } from "@/components/CurrentlyPlayingBar"; +import { + currentlyPlayingItemAtom, + triggerPlayAtom, +} from "@/components/CurrentlyPlayingBar"; import { AudioTrackSelector } from "@/components/AudioTrackSelector"; import { SubtitleTrackSelector } from "@/components/SubtitleTrackSelector"; import { NextEpisodeButton } from "@/components/series/NextEpisodeButton"; @@ -130,6 +133,7 @@ const page: React.FC = () => { const [, setCp] = useAtom(currentlyPlayingItemAtom); const client = useRemoteMediaClient(); + const [, setPlayTrigger] = useAtom(triggerPlayAtom); const onPressPlay = useCallback( async (type: "device" | "cast" = "device") => { @@ -159,6 +163,9 @@ const page: React.FC = () => { item, playbackUrl, }); + + // Use this trigger to initiate playback in another component (CurrentlyPlayingBar) + setPlayTrigger((prev) => prev + 1); } }, [playbackUrl, item], diff --git a/components/CurrentlyPlayingBar.tsx b/components/CurrentlyPlayingBar.tsx index 0160fcd2..e2ba26df 100644 --- a/components/CurrentlyPlayingBar.tsx +++ b/components/CurrentlyPlayingBar.tsx @@ -6,7 +6,15 @@ import { } from "react-native"; import { Text } from "./common/Text"; import { Ionicons } from "@expo/vector-icons"; -import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { + Ref, + RefObject, + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from "react"; import Video, { OnProgressData, VideoRef } from "react-native-video"; import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models"; import { atom, useAtom } from "jotai"; @@ -34,6 +42,8 @@ export const currentlyPlayingItemAtom = atom<{ playbackUrl: string; } | null>(null); +export const triggerPlayAtom = atom(0); + export const CurrentlyPlayingBar: React.FC = () => { const [api] = useAtom(apiAtom); const [user] = useAtom(userAtom); @@ -41,7 +51,7 @@ export const CurrentlyPlayingBar: React.FC = () => { const queryClient = useQueryClient(); const segments = useSegments(); - const [settings, updateSettings] = useSettings(); + const [settings] = useSettings(); const videoRef = useRef(null); const [paused, setPaused] = useState(true); @@ -191,12 +201,29 @@ export const CurrentlyPlayingBar: React.FC = () => { [item], ); + /** + * These two useEffects are used to start playing the + * video when the playbackUrl is available. + * + * The trigger playback is triggered from the button component. + */ useEffect(() => { if (cp?.playbackUrl) { play(); + if (settings?.openFullScreenVideoPlayerByDefault) { + videoRef.current?.presentFullscreenPlayer(); + } } }, [cp?.playbackUrl]); + const [triggerPlay] = useAtom(triggerPlayAtom); + useEffect(() => { + play(); + if (settings?.openFullScreenVideoPlayerByDefault) { + videoRef.current?.presentFullscreenPlayer(); + } + }, [triggerPlay]); + if (!cp || !api) return null; return ( diff --git a/components/settings/SettingToggles.tsx b/components/settings/SettingToggles.tsx index 258a84ce..64fa083f 100644 --- a/components/settings/SettingToggles.tsx +++ b/components/settings/SettingToggles.tsx @@ -15,6 +15,15 @@ export const SettingToggles: React.FC = () => { onValueChange={(value) => updateSettings({ autoRotate: value })} /> + + Start videos in fullscreen + + updateSettings({ openFullScreenVideoPlayerByDefault: value }) + } + /> + ); }; diff --git a/utils/atoms/settings.ts b/utils/atoms/settings.ts index 708f0063..80dfd624 100644 --- a/utils/atoms/settings.ts +++ b/utils/atoms/settings.ts @@ -5,6 +5,7 @@ import { useEffect } from "react"; type Settings = { autoRotate?: boolean; forceLandscapeInVideoPlayer?: boolean; + openFullScreenVideoPlayerByDefault?: boolean; }; /**