mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-06-02 12:08:37 +01:00
feat(autoplay): add shared AutoplayCountdown overlay
This commit is contained in:
103
components/player/AutoplayCountdown.tsx
Normal file
103
components/player/AutoplayCountdown.tsx
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
/**
|
||||||
|
* Player-agnostic "next episode" countdown card. The parent owns the timer and
|
||||||
|
* positioning — this component only renders the next episode's poster, title,
|
||||||
|
* the remaining seconds, and the Play-now / Cancel actions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
|
||||||
|
import { Image } from "expo-image";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { Pressable, View } from "react-native";
|
||||||
|
import { Text } from "@/components/common/Text";
|
||||||
|
|
||||||
|
interface AutoplayCountdownProps {
|
||||||
|
/** The episode that will play next. */
|
||||||
|
nextEpisode: BaseItemDto;
|
||||||
|
/** Poster image URL for the next episode, or null. */
|
||||||
|
posterUrl: string | null;
|
||||||
|
/** Seconds left before the next episode plays. */
|
||||||
|
secondsRemaining: number;
|
||||||
|
/** Play the next episode immediately. */
|
||||||
|
onPlayNow: () => void;
|
||||||
|
/** Cancel autoplay — the next episode will not play. */
|
||||||
|
onCancel: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function AutoplayCountdown({
|
||||||
|
nextEpisode,
|
||||||
|
posterUrl,
|
||||||
|
secondsRemaining,
|
||||||
|
onPlayNow,
|
||||||
|
onCancel,
|
||||||
|
}: AutoplayCountdownProps) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
flexDirection: "row",
|
||||||
|
gap: 12,
|
||||||
|
width: 320,
|
||||||
|
padding: 12,
|
||||||
|
borderRadius: 12,
|
||||||
|
backgroundColor: "rgba(20, 20, 20, 0.94)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{posterUrl && (
|
||||||
|
<Image
|
||||||
|
source={{ uri: posterUrl }}
|
||||||
|
style={{ width: 62, height: 93, borderRadius: 6 }}
|
||||||
|
contentFit='cover'
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<View style={{ flex: 1, justifyContent: "space-between" }}>
|
||||||
|
<View style={{ gap: 2 }}>
|
||||||
|
<Text style={{ color: "#999", fontSize: 12 }}>
|
||||||
|
{t("player.up_next")}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
style={{ color: "#fff", fontSize: 15, fontWeight: "600" }}
|
||||||
|
numberOfLines={2}
|
||||||
|
>
|
||||||
|
{nextEpisode.Name}
|
||||||
|
</Text>
|
||||||
|
<Text style={{ color: "#a855f7", fontSize: 13 }}>
|
||||||
|
{t("player.next_episode_in", { seconds: secondsRemaining })}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View style={{ flexDirection: "row", gap: 8, marginTop: 8 }}>
|
||||||
|
<Pressable
|
||||||
|
onPress={onPlayNow}
|
||||||
|
accessibilityRole='button'
|
||||||
|
style={{
|
||||||
|
flex: 1,
|
||||||
|
paddingVertical: 8,
|
||||||
|
borderRadius: 8,
|
||||||
|
backgroundColor: "#a855f7",
|
||||||
|
alignItems: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={{ color: "#fff", fontWeight: "600" }}>
|
||||||
|
{t("player.play_now")}
|
||||||
|
</Text>
|
||||||
|
</Pressable>
|
||||||
|
<Pressable
|
||||||
|
onPress={onCancel}
|
||||||
|
accessibilityRole='button'
|
||||||
|
style={{
|
||||||
|
flex: 1,
|
||||||
|
paddingVertical: 8,
|
||||||
|
borderRadius: 8,
|
||||||
|
backgroundColor: "#333",
|
||||||
|
alignItems: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text style={{ color: "#fff", fontWeight: "600" }}>
|
||||||
|
{t("player.cancel")}
|
||||||
|
</Text>
|
||||||
|
</Pressable>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -47,7 +47,11 @@
|
|||||||
"downloaded_file_message": "Do you want to play the downloaded file?",
|
"downloaded_file_message": "Do you want to play the downloaded file?",
|
||||||
"downloaded_file_yes": "Yes",
|
"downloaded_file_yes": "Yes",
|
||||||
"downloaded_file_no": "No",
|
"downloaded_file_no": "No",
|
||||||
"downloaded_file_cancel": "Cancel"
|
"downloaded_file_cancel": "Cancel",
|
||||||
|
"up_next": "Up next",
|
||||||
|
"next_episode_in": "Next episode in {{seconds}}s",
|
||||||
|
"play_now": "Play now",
|
||||||
|
"cancel": "Cancel"
|
||||||
},
|
},
|
||||||
"casting_player": {
|
"casting_player": {
|
||||||
"buffering": "Buffering...",
|
"buffering": "Buffering...",
|
||||||
|
|||||||
Reference in New Issue
Block a user