/*
* 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