/* * 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 { type Audio, type Episode, type Subtitle, getLocalSetting, useAccount } from "@kyoo/models"; import { useSnackbar } from "@kyoo/primitives"; import { atom, useAtom, useAtomValue, useSetAtom } from "jotai"; import { useAtomCallback } from "jotai/utils"; import { type ElementRef, memo, useCallback, useEffect, useLayoutEffect, useRef, useState, } from "react"; import { useTranslation } from "react-i18next"; import { Platform } from "react-native"; import NativeVideo, { canPlay, type VideoProps } from "./video"; export const playAtom = atom(true); export const loadAtom = atom(false); export enum PlayMode { Direct, Hls, } export const playModeAtom = atom( getLocalSetting("playmode", "direct") !== "auto" ? PlayMode.Direct : PlayMode.Hls, ); export const bufferedAtom = atom(0); export const durationAtom = atom(undefined); export const progressAtom = atom( (get) => get(privateProgressAtom), (get, set, update: number | ((value: number) => number)) => { const run = (value: number) => { set(privateProgressAtom, value); set(publicProgressAtom, value); }; if (typeof update === "function") run(update(get(privateProgressAtom))); else run(update); }, ); const privateProgressAtom = atom(0); const publicProgressAtom = atom(0); export const volumeAtom = atom(100); export const mutedAtom = atom(false); export const fullscreenAtom = atom( (get) => get(privateFullscreen), (get, set, update: boolean | ((value: boolean) => boolean)) => { const run = async (value: boolean) => { try { if (value) { await document.body.requestFullscreen({ navigationUI: "hide", }); set(privateFullscreen, true); // @ts-expect-error Firefox does not support this so ts complains await screen.orientation.lock("landscape"); } else { if (document.fullscreenElement) await document.exitFullscreen(); set(privateFullscreen, false); screen.orientation.unlock(); } } catch (e) { console.error(e); } }; if (typeof update === "function") run(update(get(privateFullscreen))); else run(update); }, ); const privateFullscreen = atom(false); export const subtitleAtom = atom(null); export const audioAtom = atom