/* * 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; const setSelected = (selected: number) => { _setSelected(selected); setSecureItem("selected", selected.toString()); }; useEffect(() => { async function check() { setVerified({status: "loading"}); const selAcc = accounts![selected!]; setApiUrl(selAcc.apiUrl); const verif = await loginFunc("refresh", selAcc.refresh_token, undefined, 5_000); 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", accounts, selected, error: verified.error, setSelected, retry: () => { setVerified({ status: "loading" }); setRetryCount((x) => x + 1); }, } as const; } return { type: "ok", accounts, selected, setSelected, } as const; };