mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-06-03 05:34:23 -04:00
Handle offline mode
This commit is contained in:
parent
4a035327ef
commit
022cd239d5
@ -21,6 +21,7 @@
|
|||||||
import { ConnectionErrorContext, useAccount } from "@kyoo/models";
|
import { ConnectionErrorContext, useAccount } from "@kyoo/models";
|
||||||
import { CircularProgress } from "@kyoo/primitives";
|
import { CircularProgress } from "@kyoo/primitives";
|
||||||
import { NavbarRight, NavbarTitle } from "@kyoo/ui";
|
import { NavbarRight, NavbarTitle } from "@kyoo/ui";
|
||||||
|
import { useNetInfo } from "@react-native-community/netinfo";
|
||||||
import { Redirect, SplashScreen, Stack } from "expo-router";
|
import { Redirect, SplashScreen, Stack } from "expo-router";
|
||||||
import { useContext, useEffect } from "react";
|
import { useContext, useEffect } from "react";
|
||||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||||
@ -32,13 +33,14 @@ export default function SignGuard() {
|
|||||||
// TODO: support guest accounts on mobile too.
|
// TODO: support guest accounts on mobile too.
|
||||||
const account = useAccount();
|
const account = useAccount();
|
||||||
const { loading, error } = useContext(ConnectionErrorContext);
|
const { loading, error } = useContext(ConnectionErrorContext);
|
||||||
|
const netInfo = useNetInfo();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!loading) SplashScreen.hideAsync();
|
if (!loading) SplashScreen.hideAsync();
|
||||||
}, [loading]);
|
}, [loading]);
|
||||||
|
|
||||||
if (loading) return <CircularProgress />;
|
if (loading) return <CircularProgress />;
|
||||||
if (error) return <Redirect href={"/connection-error"} />;
|
if (error && netInfo.isConnected) return <Redirect href={"/connection-error"} />;
|
||||||
if (!account) return <Redirect href="/login" />;
|
if (!account) return <Redirect href="/login" />;
|
||||||
return (
|
return (
|
||||||
<Stack
|
<Stack
|
||||||
|
@ -22,7 +22,7 @@ import { Page, QueryIdentifier, useInfiniteFetch } from "@kyoo/models";
|
|||||||
import { useBreakpointMap, HR } from "@kyoo/primitives";
|
import { useBreakpointMap, HR } from "@kyoo/primitives";
|
||||||
import { ContentStyle, FlashList } from "@shopify/flash-list";
|
import { ContentStyle, FlashList } from "@shopify/flash-list";
|
||||||
import { ComponentProps, ComponentType, isValidElement, ReactElement, useRef } from "react";
|
import { ComponentProps, ComponentType, isValidElement, ReactElement, useRef } from "react";
|
||||||
import { EmptyView, ErrorView, Layout, WithLoading, addHeader } from "./fetch";
|
import { EmptyView, ErrorView, Layout, OfflineView, WithLoading, addHeader } from "./fetch";
|
||||||
import { FlatList, View, ViewStyle } from "react-native";
|
import { FlatList, View, ViewStyle } from "react-native";
|
||||||
|
|
||||||
const emulateGap = (
|
const emulateGap = (
|
||||||
@ -90,10 +90,11 @@ export const InfiniteFetchList = <Data, Props, _, Kind extends number | string>(
|
|||||||
}): JSX.Element | null => {
|
}): JSX.Element | null => {
|
||||||
const { numColumns, size, gap } = useBreakpointMap(layout);
|
const { numColumns, size, gap } = useBreakpointMap(layout);
|
||||||
const oldItems = useRef<Data[] | undefined>();
|
const oldItems = useRef<Data[] | undefined>();
|
||||||
let { items, error, fetchNextPage, isFetching, refetch, isRefetching } = query;
|
let { items, isPaused, error, fetchNextPage, isFetching, refetch, isRefetching } = query;
|
||||||
if (incremental && items) oldItems.current = items;
|
if (incremental && items) oldItems.current = items;
|
||||||
|
|
||||||
if (error) return <ErrorView error={error} />;
|
if (error) return <ErrorView error={error} />;
|
||||||
|
if (isPaused) return <OfflineView />
|
||||||
if (empty && items && items.length === 0) {
|
if (empty && items && items.length === 0) {
|
||||||
if (typeof empty !== "string") return addHeader(Header, empty, headerProps);
|
if (typeof empty !== "string") return addHeader(Header, empty, headerProps);
|
||||||
return addHeader(Header, <EmptyView message={empty} />, headerProps);
|
return addHeader(Header, <EmptyView message={empty} />, headerProps);
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
import { Page, QueryIdentifier, useFetch, KyooErrors } from "@kyoo/models";
|
import { Page, QueryIdentifier, useFetch, KyooErrors } from "@kyoo/models";
|
||||||
import { Breakpoint, P } from "@kyoo/primitives";
|
import { Breakpoint, P } from "@kyoo/primitives";
|
||||||
import { ComponentType, ReactElement, isValidElement } from "react";
|
import { ComponentType, ReactElement, isValidElement } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
import { View } from "react-native";
|
import { View } from "react-native";
|
||||||
import { useYoshiki } from "yoshiki/native";
|
import { useYoshiki } from "yoshiki/native";
|
||||||
|
|
||||||
@ -43,7 +44,7 @@ export type WithError<Item> =
|
|||||||
const isPage = <T = unknown,>(obj: unknown): obj is Page<T> =>
|
const isPage = <T = unknown,>(obj: unknown): obj is Page<T> =>
|
||||||
(typeof obj === "object" && obj && "items" in obj) || false;
|
(typeof obj === "object" && obj && "items" in obj) || false;
|
||||||
|
|
||||||
export const FetchNE = <Data,>({
|
export const Fetch = <Data,>({
|
||||||
query,
|
query,
|
||||||
placeholderCount = 1,
|
placeholderCount = 1,
|
||||||
children,
|
children,
|
||||||
@ -57,10 +58,10 @@ export const FetchNE = <Data,>({
|
|||||||
i: number,
|
i: number,
|
||||||
) => JSX.Element | null;
|
) => JSX.Element | null;
|
||||||
}): JSX.Element | null => {
|
}): JSX.Element | null => {
|
||||||
const { data, error } = useFetch(query);
|
const { data, isPaused, error } = useFetch(query);
|
||||||
|
|
||||||
// @ts-ignore
|
if (error) return <ErrorView error={error} />;
|
||||||
if (error) return children({ isError: true, error }, 0);
|
if (isPaused) return <OfflineView />;
|
||||||
if (!data) {
|
if (!data) {
|
||||||
const placeholders = [...Array(placeholderCount)].map((_, i) =>
|
const placeholders = [...Array(placeholderCount)].map((_, i) =>
|
||||||
children({ isLoading: true } as any, i),
|
children({ isLoading: true } as any, i),
|
||||||
@ -72,24 +73,21 @@ export const FetchNE = <Data,>({
|
|||||||
return <>{data.items.map((item, i) => children({ ...item, isLoading: false } as any, i))}</>;
|
return <>{data.items.map((item, i) => children({ ...item, isLoading: false } as any, i))}</>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Fetch = <Data,>({
|
export const OfflineView = () => {
|
||||||
children,
|
const { css } = useYoshiki();
|
||||||
...params
|
const { t } = useTranslation();
|
||||||
}: {
|
|
||||||
query: QueryIdentifier<Data>;
|
|
||||||
placeholderCount?: number;
|
|
||||||
children: (
|
|
||||||
item: Data extends Page<infer Item> ? WithLoading<Item> : WithLoading<Data>,
|
|
||||||
i: number,
|
|
||||||
) => JSX.Element | null;
|
|
||||||
}): JSX.Element | null => {
|
|
||||||
return (
|
return (
|
||||||
<FetchNE {...params}>
|
<View
|
||||||
{({ isError, error, ...item }, i) =>
|
{...css({
|
||||||
// @ts-ignore
|
flexGrow: 1,
|
||||||
isError ? <ErrorView error={error} /> : children(item, i)
|
flexShrink: 1,
|
||||||
}
|
justifyContent: "center",
|
||||||
</FetchNE>
|
alignItems: "center",
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<P {...css({ color: (theme) => theme.colors.white })}>{t("errors.offline")}</P>
|
||||||
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -121,6 +121,7 @@
|
|||||||
"connection-tips": "Troublshotting tips:\n - Are you connected to internet?\n - Is your kyoo's server online?\n - Have your account been banned?",
|
"connection-tips": "Troublshotting tips:\n - Are you connected to internet?\n - Is your kyoo's server online?\n - Have your account been banned?",
|
||||||
"unknown": "Unknown error",
|
"unknown": "Unknown error",
|
||||||
"try-again": "Try again",
|
"try-again": "Try again",
|
||||||
"re-login": "Re login"
|
"re-login": "Re login",
|
||||||
|
"offline": "You are not connected to internet. Try again later."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,6 +121,7 @@
|
|||||||
"connection-tips": "Possible causes:\n - Etes-vous connecté a internet ?\n - Votre serveur kyoo est-il allumé ?\n - Votre compte est-il bannis ?",
|
"connection-tips": "Possible causes:\n - Etes-vous connecté a internet ?\n - Votre serveur kyoo est-il allumé ?\n - Votre compte est-il bannis ?",
|
||||||
"unknown": "Erreur inconnue",
|
"unknown": "Erreur inconnue",
|
||||||
"try-again": "Réessayer",
|
"try-again": "Réessayer",
|
||||||
"re-login": "Se reconnecter"
|
"re-login": "Se reconnecter",
|
||||||
|
"offline": "Vous n'êtes pas connecté à Internet. Réessayez plus tard."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user