mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-01-15 23:59:08 +00:00
chore
This commit is contained in:
@@ -1,12 +1,14 @@
|
|||||||
import { Chromecast } from "@/components/Chromecast";
|
import { Chromecast } from "@/components/Chromecast";
|
||||||
import { HeaderBackButton } from "@/components/common/HeaderBackButton";
|
import { HeaderBackButton } from "@/components/common/HeaderBackButton";
|
||||||
import { nestedTabPageScreenOptions } from "@/components/stacks/NestedTabPageStack";
|
import { nestedTabPageScreenOptions } from "@/components/stacks/NestedTabPageStack";
|
||||||
|
import { useDownload } from "@/providers/DownloadProvider";
|
||||||
import { Feather } from "@expo/vector-icons";
|
import { Feather } from "@expo/vector-icons";
|
||||||
import { Stack, useRouter } from "expo-router";
|
import { Stack, useRouter } from "expo-router";
|
||||||
import { Platform, TouchableOpacity, View } from "react-native";
|
import { Platform, TouchableOpacity, View } from "react-native";
|
||||||
|
|
||||||
export default function IndexLayout() {
|
export default function IndexLayout() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack>
|
<Stack>
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
|
|||||||
@@ -4,9 +4,11 @@ import { LargeMovieCarousel } from "@/components/home/LargeMovieCarousel";
|
|||||||
import { ScrollingCollectionList } from "@/components/home/ScrollingCollectionList";
|
import { ScrollingCollectionList } from "@/components/home/ScrollingCollectionList";
|
||||||
import { Loader } from "@/components/Loader";
|
import { Loader } from "@/components/Loader";
|
||||||
import { MediaListSection } from "@/components/medialists/MediaListSection";
|
import { MediaListSection } from "@/components/medialists/MediaListSection";
|
||||||
|
import { Colors } from "@/constants/Colors";
|
||||||
|
import { useDownload } from "@/providers/DownloadProvider";
|
||||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||||
import { useSettings } from "@/utils/atoms/settings";
|
import { useSettings } from "@/utils/atoms/settings";
|
||||||
import { Ionicons } from "@expo/vector-icons";
|
import { Feather, Ionicons } from "@expo/vector-icons";
|
||||||
import { Api } from "@jellyfin/sdk";
|
import { Api } from "@jellyfin/sdk";
|
||||||
import {
|
import {
|
||||||
BaseItemDto,
|
BaseItemDto,
|
||||||
@@ -21,13 +23,15 @@ import {
|
|||||||
} from "@jellyfin/sdk/lib/utils/api";
|
} from "@jellyfin/sdk/lib/utils/api";
|
||||||
import NetInfo from "@react-native-community/netinfo";
|
import NetInfo from "@react-native-community/netinfo";
|
||||||
import { QueryFunction, useQuery, useQueryClient } from "@tanstack/react-query";
|
import { QueryFunction, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
import { useRouter } from "expo-router";
|
import { useNavigation, useRouter } from "expo-router";
|
||||||
import { useAtom } from "jotai";
|
import { useAtom } from "jotai";
|
||||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import {
|
import {
|
||||||
ActivityIndicator,
|
ActivityIndicator,
|
||||||
|
Platform,
|
||||||
RefreshControl,
|
RefreshControl,
|
||||||
ScrollView,
|
ScrollView,
|
||||||
|
TouchableOpacity,
|
||||||
View,
|
View,
|
||||||
} from "react-native";
|
} from "react-native";
|
||||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||||
@@ -61,6 +65,29 @@ export default function index() {
|
|||||||
const [isConnected, setIsConnected] = useState<boolean | null>(null);
|
const [isConnected, setIsConnected] = useState<boolean | null>(null);
|
||||||
const [loadingRetry, setLoadingRetry] = useState(false);
|
const [loadingRetry, setLoadingRetry] = useState(false);
|
||||||
|
|
||||||
|
const { downloadedFiles } = useDownload();
|
||||||
|
const navigation = useNavigation();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const hasDownloads = downloadedFiles && downloadedFiles.length > 0;
|
||||||
|
navigation.setOptions({
|
||||||
|
headerLeft: () => (
|
||||||
|
<TouchableOpacity
|
||||||
|
onPress={() => {
|
||||||
|
router.push("/(auth)/downloads");
|
||||||
|
}}
|
||||||
|
className="p-2"
|
||||||
|
>
|
||||||
|
<Feather
|
||||||
|
name="download"
|
||||||
|
color={hasDownloads ? Colors.primary : "white"}
|
||||||
|
size={22}
|
||||||
|
/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}, [downloadedFiles, navigation, router]);
|
||||||
|
|
||||||
const checkConnection = useCallback(async () => {
|
const checkConnection = useCallback(async () => {
|
||||||
setLoadingRetry(true);
|
setLoadingRetry(true);
|
||||||
const state = await NetInfo.fetch();
|
const state = await NetInfo.fetch();
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import {
|
|||||||
useSharedValue,
|
useSharedValue,
|
||||||
} from "react-native-reanimated";
|
} from "react-native-reanimated";
|
||||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||||
import Video, { OnProgressData } from "react-native-video";
|
import Video, { OnProgressData, ReactVideoProps } from "react-native-video";
|
||||||
import { Text } from "./common/Text";
|
import { Text } from "./common/Text";
|
||||||
import { itemRouter } from "./common/TouchableItemRouter";
|
import { itemRouter } from "./common/TouchableItemRouter";
|
||||||
import { Loader } from "./Loader";
|
import { Loader } from "./Loader";
|
||||||
@@ -199,8 +199,8 @@ export const FullScreenVideoPlayer: React.FC = () => {
|
|||||||
});
|
});
|
||||||
}, [currentlyPlaying?.item, api]);
|
}, [currentlyPlaying?.item, api]);
|
||||||
|
|
||||||
const videoSource = useMemo(() => {
|
const videoSource: ReactVideoProps["source"] = useMemo(() => {
|
||||||
if (!api || !currentlyPlaying || !poster) return null;
|
if (!api || !currentlyPlaying || !poster) return undefined;
|
||||||
const startPosition = currentlyPlaying.item?.UserData?.PlaybackPositionTicks
|
const startPosition = currentlyPlaying.item?.UserData?.PlaybackPositionTicks
|
||||||
? Math.round(currentlyPlaying.item.UserData.PlaybackPositionTicks / 10000)
|
? Math.round(currentlyPlaying.item.UserData.PlaybackPositionTicks / 10000)
|
||||||
: 0;
|
: 0;
|
||||||
@@ -342,24 +342,25 @@ export const FullScreenVideoPlayer: React.FC = () => {
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
{videoSource && (
|
<Video
|
||||||
<Video
|
ref={videoRef}
|
||||||
ref={videoRef}
|
source={videoSource}
|
||||||
source={videoSource}
|
style={{ width: "100%", height: "100%" }}
|
||||||
style={{ width: "100%", height: "100%" }}
|
resizeMode={ignoreSafeArea ? "cover" : "contain"}
|
||||||
resizeMode={ignoreSafeArea ? "cover" : "contain"}
|
onProgress={handleVideoProgress}
|
||||||
onProgress={handleVideoProgress}
|
onLoad={(data) => (max.value = secondsToTicks(data.duration))}
|
||||||
onLoad={(data) => (max.value = secondsToTicks(data.duration))}
|
onError={handleVideoError}
|
||||||
onError={handleVideoError}
|
playWhenInactive={true}
|
||||||
playWhenInactive={true}
|
allowsExternalPlayback={true}
|
||||||
allowsExternalPlayback={true}
|
playInBackground={true}
|
||||||
playInBackground={true}
|
pictureInPicture={true}
|
||||||
pictureInPicture={true}
|
showNotificationControls={true}
|
||||||
showNotificationControls={true}
|
ignoreSilentSwitch="ignore"
|
||||||
ignoreSilentSwitch="ignore"
|
fullscreen={false}
|
||||||
fullscreen={false}
|
onVideoTracks={(d) => {
|
||||||
/>
|
console.log("onVideoTracks ~", d);
|
||||||
)}
|
}}
|
||||||
|
/>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
|
|
||||||
{(showControls || isBuffering) && (
|
{(showControls || isBuffering) && (
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ const tintColorLight = "#0a7ea4";
|
|||||||
const tintColorDark = "#fff";
|
const tintColorDark = "#fff";
|
||||||
|
|
||||||
export const Colors = {
|
export const Colors = {
|
||||||
|
primary: "#9334E9",
|
||||||
text: "#ECEDEE",
|
text: "#ECEDEE",
|
||||||
background: "#151718",
|
background: "#151718",
|
||||||
tint: tintColorDark,
|
tint: tintColorDark,
|
||||||
|
|||||||
@@ -79,7 +79,7 @@
|
|||||||
"react-native-svg": "15.2.0",
|
"react-native-svg": "15.2.0",
|
||||||
"react-native-url-polyfill": "^2.0.0",
|
"react-native-url-polyfill": "^2.0.0",
|
||||||
"react-native-uuid": "^2.0.2",
|
"react-native-uuid": "^2.0.2",
|
||||||
"react-native-video": "^6.6.3",
|
"react-native-video": "^6.6.4",
|
||||||
"react-native-web": "~0.19.10",
|
"react-native-web": "~0.19.10",
|
||||||
"sonner-native": "^0.14.2",
|
"sonner-native": "^0.14.2",
|
||||||
"tailwindcss": "3.3.2",
|
"tailwindcss": "3.3.2",
|
||||||
|
|||||||
Reference in New Issue
Block a user