diff --git a/front/packages/models/src/accounts.tsx b/front/packages/models/src/accounts.tsx
new file mode 100644
index 00000000..327ed0fe
--- /dev/null
+++ b/front/packages/models/src/accounts.tsx
@@ -0,0 +1,85 @@
+/*
+ * 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 { getSecureItem, setSecureItem, storage } from "./secure-store";
+import { setApiUrl } from "./query";
+import { createContext, useEffect, useState } from "react";
+import { useMMKVListener } from "react-native-mmkv";
+import { Account, loginFunc } from "./login";
+
+export const AccountContext = createContext>({ type: "loading" });
+
+export const useAccounts = () => {
+ const [accounts, setAccounts] = useState(JSON.parse(getSecureItem("accounts") ?? "[]"));
+ const [verified, setVerified] = useState<{
+ status: "ok" | "error" | "loading" | "unverified";
+ error?: string;
+ }>({ status: "loading" });
+ const [retryCount, setRetryCount] = useState(0);
+
+ const sel = getSecureItem("selected");
+ let [selected, setSelected] = useState(
+ sel ? parseInt(sel) : accounts.length > 0 ? 0 : null,
+ );
+ if (selected === null && accounts.length > 0) selected = 0;
+ if (accounts.length === 0) selected = null;
+
+ useEffect(() => {
+ async function check() {
+ setVerified({status: "loading"});
+ const selAcc = accounts![selected!];
+ setApiUrl(selAcc.apiUrl);
+ const verif = await loginFunc("refresh", selAcc.refresh_token);
+ setVerified(verif.ok ? { status: "ok" } : { status: "error", error: verif.error });
+ }
+
+ if (accounts.length && selected !== null) check();
+ else setVerified({ status: "unverified" });
+ // Use the length of the array and not the array directly because we don't care if the refresh token changes.
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [accounts.length, selected, retryCount]);
+
+ useMMKVListener((key) => {
+ if (key === "accounts") setAccounts(JSON.parse(getSecureItem("accounts") ?? "[]"));
+ }, storage);
+
+ if (verified.status === "loading") return { type: "loading" } as const;
+ if (accounts.length && verified.status === "unverified") return { type: "loading" } as const;
+ if (verified.status === "error") {
+ return {
+ type: "error",
+ error: verified.error,
+ retry: () => {
+ setVerified({ status: "loading" });
+ setRetryCount((x) => x + 1);
+ },
+ } as const;
+ }
+ return {
+ type: "ok",
+ accounts,
+ selected,
+ setSelected: (selected: number) => {
+ setSelected(selected);
+ setSecureItem("selected", selected.toString());
+ },
+ } as const;
+};
+
diff --git a/front/packages/models/src/accounts.web.ts b/front/packages/models/src/accounts.web.ts
new file mode 100644
index 00000000..a2111fdf
--- /dev/null
+++ b/front/packages/models/src/accounts.web.ts
@@ -0,0 +1,23 @@
+/*
+ * 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 .
+ */
+
+export const useAccounts = () => {}
+
+export const AccountContext = 0;
diff --git a/front/packages/models/src/index.ts b/front/packages/models/src/index.ts
index 337d2c57..cfbd8dbe 100644
--- a/front/packages/models/src/index.ts
+++ b/front/packages/models/src/index.ts
@@ -18,6 +18,7 @@
* along with Kyoo. If not, see .
*/
+export * from "./accounts";
export * from "./resources";
export * from "./traits";
export * from "./page";
diff --git a/front/packages/models/src/login.ts b/front/packages/models/src/login.ts
index 595c3835..4e457ff1 100644
--- a/front/packages/models/src/login.ts
+++ b/front/packages/models/src/login.ts
@@ -19,13 +19,11 @@
*/
import { z } from "zod";
-import { deleteSecureItem, getSecureItem, setSecureItem, storage } from "./secure-store";
+import { deleteSecureItem, getSecureItem, setSecureItem } from "./secure-store";
import { zdate } from "./utils";
-import { queryFn, setApiUrl } from "./query";
+import { queryFn } from "./query";
import { KyooErrors } from "./kyoo-errors";
import { Platform } from "react-native";
-import { createContext, useEffect, useState } from "react";
-import { useMMKVListener } from "react-native-mmkv";
const TokenP = z.object({
token_type: z.literal("Bearer"),
@@ -42,65 +40,6 @@ type Result =
export type Account = Token & { apiUrl: string; username: string };
-export const AccountContext = createContext>({ type: "loading" });
-
-export const useAccounts = () => {
- const [accounts, setAccounts] = useState(JSON.parse(getSecureItem("accounts") ?? "[]"));
- const [verified, setVerified] = useState<{
- status: "ok" | "error" | "loading" | "unverified";
- error?: string;
- }>({ status: "loading" });
- const [retryCount, setRetryCount] = useState(0);
-
- const sel = getSecureItem("selected");
- let [selected, setSelected] = useState(
- sel ? parseInt(sel) : accounts.length > 0 ? 0 : null,
- );
- if (selected === null && accounts.length > 0) selected = 0;
- if (accounts.length === 0) selected = null;
-
- useEffect(() => {
- async function check() {
- setVerified({status: "loading"});
- const selAcc = accounts![selected!];
- setApiUrl(selAcc.apiUrl);
- const verif = await loginFunc("refresh", selAcc.refresh_token);
- setVerified(verif.ok ? { status: "ok" } : { status: "error", error: verif.error });
- }
-
- if (accounts.length && selected !== null) check();
- else setVerified({ status: "unverified" });
- // Use the length of the array and not the array directly because we don't care if the refresh token changes.
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [accounts.length, selected, retryCount]);
-
- useMMKVListener((key) => {
- if (key === "accounts") setAccounts(JSON.parse(getSecureItem("accounts") ?? "[]"));
- }, storage);
-
- if (verified.status === "loading") return { type: "loading" } as const;
- if (accounts.length && verified.status === "unverified") return { type: "loading" } as const;
- if (verified.status === "error") {
- return {
- type: "error",
- error: verified.error,
- retry: () => {
- setVerified({ status: "loading" });
- setRetryCount((x) => x + 1);
- },
- } as const;
- }
- return {
- type: "ok",
- accounts,
- selected,
- setSelected: (selected: number) => {
- setSelected(selected);
- setSecureItem("selected", selected.toString());
- },
- } as const;
-};
-
const addAccount = (token: Token, apiUrl: string, username: string | null) => {
const accounts: Account[] = JSON.parse(getSecureItem("accounts") ?? "[]");
if (accounts.find((x) => x.username === username && x.apiUrl === apiUrl)) return;