mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-01-15 15:48:05 +00:00
fix: offline checking (#989)
This commit is contained in:
@@ -11,7 +11,6 @@ import {
|
||||
getUserLibraryApi,
|
||||
getUserViewsApi,
|
||||
} from "@jellyfin/sdk/lib/utils/api";
|
||||
import NetInfo from "@react-native-community/netinfo";
|
||||
import { type QueryFunction, useQuery } from "@tanstack/react-query";
|
||||
import { useNavigation, useRouter, useSegments } from "expo-router";
|
||||
import { useAtomValue } from "jotai";
|
||||
@@ -33,6 +32,7 @@ import { ScrollingCollectionList } from "@/components/home/ScrollingCollectionLi
|
||||
import { Loader } from "@/components/Loader";
|
||||
import { MediaListSection } from "@/components/medialists/MediaListSection";
|
||||
import { Colors } from "@/constants/Colors";
|
||||
import { useNetworkStatus } from "@/hooks/useNetworkStatus";
|
||||
import { useInvalidatePlaybackProgressCache } from "@/hooks/useRevalidatePlaybackProgressCache";
|
||||
import { useDownload } from "@/providers/DownloadProvider";
|
||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||
@@ -72,9 +72,6 @@ export const HomeIndex = () => {
|
||||
refreshStreamyfinPluginSettings,
|
||||
] = useSettings(null);
|
||||
|
||||
const [isConnected, setIsConnected] = useState<boolean | null>(null);
|
||||
const [loadingRetry, setLoadingRetry] = useState(false);
|
||||
|
||||
const navigation = useNavigation();
|
||||
|
||||
const insets = useSafeAreaInsets();
|
||||
@@ -83,6 +80,7 @@ export const HomeIndex = () => {
|
||||
|
||||
const { getDownloadedItems, cleanCacheDirectory } = useDownload();
|
||||
const prevIsConnected = useRef<boolean | null>(false);
|
||||
const { isConnected, loading: retryLoading, retryCheck } = useNetworkStatus();
|
||||
const invalidateCache = useInvalidatePlaybackProgressCache();
|
||||
useEffect(() => {
|
||||
// Only invalidate cache when transitioning from offline to online
|
||||
@@ -137,29 +135,6 @@ export const HomeIndex = () => {
|
||||
};
|
||||
}, [segments]);
|
||||
|
||||
const checkConnection = useCallback(async () => {
|
||||
setLoadingRetry(true);
|
||||
const state = await NetInfo.fetch();
|
||||
setIsConnected(state.isConnected);
|
||||
setLoadingRetry(false);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribe = NetInfo.addEventListener((state) => {
|
||||
if (state.isConnected === false || state.isInternetReachable === false)
|
||||
setIsConnected(false);
|
||||
else setIsConnected(true);
|
||||
});
|
||||
|
||||
NetInfo.fetch().then((state) => {
|
||||
setIsConnected(state.isConnected);
|
||||
});
|
||||
|
||||
return () => {
|
||||
unsubscribe();
|
||||
};
|
||||
}, []);
|
||||
|
||||
const {
|
||||
data,
|
||||
isError: e1,
|
||||
@@ -397,30 +372,30 @@ export const HomeIndex = () => {
|
||||
{t("home.no_internet_message")}
|
||||
</Text>
|
||||
<View className='mt-4'>
|
||||
<Button
|
||||
color='purple'
|
||||
onPress={() => router.push("/(auth)/downloads")}
|
||||
justify='center'
|
||||
iconRight={
|
||||
<Ionicons name='arrow-forward' size={20} color='white' />
|
||||
}
|
||||
>
|
||||
{t("home.go_to_downloads")}
|
||||
</Button>
|
||||
{!Platform.isTV && (
|
||||
<Button
|
||||
color='purple'
|
||||
onPress={() => router.push("/(auth)/downloads")}
|
||||
justify='center'
|
||||
iconRight={
|
||||
<Ionicons name='arrow-forward' size={20} color='white' />
|
||||
}
|
||||
>
|
||||
{t("home.go_to_downloads")}
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
color='black'
|
||||
onPress={() => {
|
||||
checkConnection();
|
||||
}}
|
||||
onPress={retryCheck}
|
||||
justify='center'
|
||||
className='mt-2'
|
||||
iconRight={
|
||||
loadingRetry ? null : (
|
||||
retryLoading ? null : (
|
||||
<Ionicons name='refresh' size={20} color='white' />
|
||||
)
|
||||
}
|
||||
>
|
||||
{loadingRetry ? (
|
||||
{retryLoading ? (
|
||||
<ActivityIndicator size={"small"} color={"white"} />
|
||||
) : (
|
||||
"Retry"
|
||||
|
||||
30
hooks/useNetworkStatus.ts
Normal file
30
hooks/useNetworkStatus.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import NetInfo from "@react-native-community/netinfo";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
export function useNetworkStatus() {
|
||||
const [isConnected, setIsConnected] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
// Manual check (optional)
|
||||
const retryCheck = useCallback(async () => {
|
||||
setLoading(true);
|
||||
const state = await NetInfo.fetch();
|
||||
setIsConnected(!!state.isConnected && !!state.isInternetReachable);
|
||||
setLoading(false);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribe = NetInfo.addEventListener((state) => {
|
||||
setIsConnected(!!state.isConnected && !!state.isInternetReachable);
|
||||
});
|
||||
|
||||
// Initial state
|
||||
NetInfo.fetch().then((state) => {
|
||||
setIsConnected(!!state.isConnected && !!state.isInternetReachable);
|
||||
});
|
||||
|
||||
return () => unsubscribe();
|
||||
}, []);
|
||||
|
||||
return { isConnected, loading, retryCheck };
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client";
|
||||
import { getPlaystateApi, getTvShowsApi } from "@jellyfin/sdk/lib/utils/api";
|
||||
import { useNetInfo } from "@react-native-community/netinfo";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useAtomValue } from "jotai";
|
||||
import { useMemo } from "react";
|
||||
import { useDownload } from "@/providers/DownloadProvider";
|
||||
import { DownloadedItem } from "@/providers/Downloads/types";
|
||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||
import { useNetworkStatus } from "./useNetworkStatus";
|
||||
|
||||
interface PlaybackManagerProps {
|
||||
item?: BaseItemDto | null;
|
||||
@@ -65,12 +65,12 @@ export const usePlaybackManager = ({
|
||||
}: PlaybackManagerProps = {}) => {
|
||||
const api = useAtomValue(apiAtom);
|
||||
const user = useAtomValue(userAtom);
|
||||
const netInfo = useNetInfo();
|
||||
const { isConnected } = useNetworkStatus();
|
||||
const { getDownloadedItemById, updateDownloadedItem, getDownloadedItems } =
|
||||
useDownload();
|
||||
|
||||
/** Whether the device is online. actually it's connected to the internet. */
|
||||
const isOnline = useMemo(() => netInfo.isConnected, [netInfo.isConnected]);
|
||||
const isOnline = isConnected;
|
||||
|
||||
// Adjacent episodes logic
|
||||
const { data: adjacentItems } = useQuery({
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { getItemsApi, getUserLibraryApi } from "@jellyfin/sdk/lib/utils/api";
|
||||
import { useNetInfo } from "@react-native-community/netinfo";
|
||||
import { useAtomValue } from "jotai";
|
||||
import { useDownload } from "@/providers/DownloadProvider";
|
||||
import { apiAtom, userAtom } from "../providers/JellyfinProvider";
|
||||
import { useNetworkStatus } from "./useNetworkStatus";
|
||||
|
||||
/**
|
||||
* This hook is used to sync the playback state of a downloaded item with the server
|
||||
@@ -11,8 +11,8 @@ import { apiAtom, userAtom } from "../providers/JellyfinProvider";
|
||||
export const useTwoWaySync = () => {
|
||||
const api = useAtomValue(apiAtom);
|
||||
const user = useAtomValue(userAtom);
|
||||
const netInfo = useNetInfo();
|
||||
const { getDownloadedItemById, updateDownloadedItem } = useDownload();
|
||||
const { isConnected } = useNetworkStatus();
|
||||
|
||||
/**
|
||||
* Syncs the playback state of an offline item with the server.
|
||||
@@ -21,7 +21,7 @@ export const useTwoWaySync = () => {
|
||||
* @returns A Promise<boolean> indicating whether a server update was made (true) or not (false).
|
||||
*/
|
||||
const syncPlaybackState = async (itemId: string): Promise<boolean> => {
|
||||
if (!api || !user || !netInfo.isConnected) {
|
||||
if (!api || !user || !isConnected) {
|
||||
// Cannot sync if offline or not logged in
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user