diff --git a/front/apps/mobile/app/(app)/_layout.tsx b/front/apps/mobile/app/(app)/_layout.tsx
new file mode 100644
index 00000000..4412d2a8
--- /dev/null
+++ b/front/apps/mobile/app/(app)/_layout.tsx
@@ -0,0 +1,57 @@
+/*
+ * Kyoo - A portable and vast media library solution.
+ * Copyright (c) Kyoo.
+ *
+ * See AUTHORS.md and LICENSE file in the project root for full license information.
+ *
+ * Kyoo is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * Kyoo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Kyoo. If not, see .
+ */
+
+import { ConnectionErrorContext, useAccount } from "@kyoo/models";
+import { NavbarRight, NavbarTitle } from "@kyoo/ui";
+import { LoadingIndicator } from "@kyoo/ui/src/player/components/hover";
+import { Redirect, Stack } from "expo-router";
+import { useContext, useRef } from "react";
+import { useTheme } from "yoshiki/native";
+
+export default function SignGuard() {
+ const theme = useTheme();
+ // TODO: support guest accounts on mobile too.
+ const account = useAccount();
+ const { loading, error } = useContext(ConnectionErrorContext);
+ const wasRendered = useRef(false);
+
+ // While loading, keep the splashcreen if possible. if not, display a spinner.
+ if (loading) return wasRendered.current ? : null;
+ wasRendered.current = true;
+
+ if (error) return ;
+ if (!account) return ;
+
+ return (
+ ,
+ headerRight: () => ,
+ contentStyle: {
+ backgroundColor: theme.background,
+ },
+ headerStyle: {
+ backgroundColor: theme.accent,
+ },
+ headerTintColor: theme.colors.white,
+ }}
+ />
+ );
+}
diff --git a/front/apps/mobile/app/browse/index.tsx b/front/apps/mobile/app/(app)/browse/index.tsx
similarity index 100%
rename from front/apps/mobile/app/browse/index.tsx
rename to front/apps/mobile/app/(app)/browse/index.tsx
diff --git a/front/apps/mobile/app/collection/[slug]/index.tsx b/front/apps/mobile/app/(app)/collection/[slug]/index.tsx
similarity index 100%
rename from front/apps/mobile/app/collection/[slug]/index.tsx
rename to front/apps/mobile/app/(app)/collection/[slug]/index.tsx
diff --git a/front/apps/mobile/app/movie/[slug]/index.tsx b/front/apps/mobile/app/(app)/movie/[slug]/index.tsx
similarity index 100%
rename from front/apps/mobile/app/movie/[slug]/index.tsx
rename to front/apps/mobile/app/(app)/movie/[slug]/index.tsx
diff --git a/front/apps/mobile/app/movie/[slug]/watch.tsx b/front/apps/mobile/app/(app)/movie/[slug]/watch.tsx
similarity index 100%
rename from front/apps/mobile/app/movie/[slug]/watch.tsx
rename to front/apps/mobile/app/(app)/movie/[slug]/watch.tsx
diff --git a/front/apps/mobile/app/search/index.tsx b/front/apps/mobile/app/(app)/search/index.tsx
similarity index 100%
rename from front/apps/mobile/app/search/index.tsx
rename to front/apps/mobile/app/(app)/search/index.tsx
diff --git a/front/apps/mobile/app/show/[slug].tsx b/front/apps/mobile/app/(app)/show/[slug].tsx
similarity index 100%
rename from front/apps/mobile/app/show/[slug].tsx
rename to front/apps/mobile/app/(app)/show/[slug].tsx
diff --git a/front/apps/mobile/app/watch/[slug].tsx b/front/apps/mobile/app/(app)/watch/[slug].tsx
similarity index 100%
rename from front/apps/mobile/app/watch/[slug].tsx
rename to front/apps/mobile/app/(app)/watch/[slug].tsx
diff --git a/front/apps/mobile/app/_layout.tsx b/front/apps/mobile/app/_layout.tsx
index 6bd77913..980123f3 100644
--- a/front/apps/mobile/app/_layout.tsx
+++ b/front/apps/mobile/app/_layout.tsx
@@ -22,11 +22,10 @@ import "react-native-reanimated";
import { PortalProvider } from "@gorhom/portal";
import { ThemeSelector } from "@kyoo/primitives";
-import { NavbarRight, NavbarTitle } from "@kyoo/ui";
-import { AccountProvider, createQueryClient, useAccount } from "@kyoo/models";
+import { AccountProvider, createQueryClient } from "@kyoo/models";
import { QueryClientProvider } from "@tanstack/react-query";
import i18next from "i18next";
-import { Stack } from "expo-router";
+import { Slot } from "expo-router";
import { getLocales } from "expo-localization";
import { SplashScreen } from "expo-router";
import {
@@ -38,8 +37,6 @@ import {
import { useEffect, useState } from "react";
import { useColorScheme } from "react-native";
import { initReactI18next } from "react-i18next";
-import { useTheme } from "yoshiki/native";
-import { useRouter } from "solito/router";
import "intl-pluralrules";
import "@formatjs/intl-locale/polyfill";
import "@formatjs/intl-displaynames/polyfill";
@@ -62,51 +59,6 @@ i18next.use(initReactI18next).init({
},
});
-export const ConnectionError = () => {
- const router = useRouter();
-
- useEffect(() => {
- router.replace("/connection-error", undefined, {
- experimental: { nativeBehavior: "stack-replace", isNestedNavigator: false },
- });
- }, [router]);
- return null;
-};
-
-const ThemedStack = ({ onLayout }: { onLayout?: () => void }) => {
- const theme = useTheme();
-
- return (
- ,
- headerRight: () => ,
- contentStyle: {
- backgroundColor: theme.background,
- },
- headerStyle: {
- backgroundColor: theme.accent,
- },
- headerTintColor: theme.colors.white,
- }}
- />
- );
-};
-
-const AuthGuard = () => {
- const router = useRouter();
- // TODO: support guest accounts on mobile too.
- const account = useAccount();
-
- useEffect(() => {
- if (account === null)
- router.replace("/login", undefined, {
- experimental: { nativeBehavior: "stack-replace", isNestedNavigator: false },
- });
- }, [account, router]);
- return null;
-};
-
SplashScreen.preventAutoHideAsync();
export default function Root() {
@@ -132,11 +84,7 @@ export default function Root() {
>
- <>
-
-
-
- >
+
diff --git a/front/apps/mobile/utils.tsx b/front/apps/mobile/app/utils.tsx
similarity index 100%
rename from front/apps/mobile/utils.tsx
rename to front/apps/mobile/app/utils.tsx
diff --git a/front/packages/models/src/accounts.tsx b/front/packages/models/src/accounts.tsx
index 0dceb4ed..c603d614 100644
--- a/front/packages/models/src/accounts.tsx
+++ b/front/packages/models/src/accounts.tsx
@@ -50,8 +50,9 @@ export type Account = z.infer;
const AccountContext = createContext<(Account & { select: () => void; remove: () => void })[]>([]);
export const ConnectionErrorContext = createContext<{
error: KyooErrors | null;
+ loading: boolean;
retry?: () => void;
-}>({ error: null });
+}>({ error: null, loading: true });
/* eslint-disable react-hooks/rules-of-hooks */
export const AccountProvider = ({
@@ -70,6 +71,7 @@ export const AccountProvider = ({
{
queryClient.invalidateQueries({ queryKey: ["auth", "me"] });
},
@@ -126,6 +128,7 @@ export const AccountProvider = ({
{
queryClient.invalidateQueries({ queryKey: ["auth", "me"] });
},