import { createContext, type ReactNode, useContext, useEffect, useEffectEvent, useRef, useState, } from "react"; import { NitroModules } from "react-native-nitro-modules"; import type { OmniPlayer as NativeOmniPlayer, OmniPlayerFactory, } from "./specs/omni-player.nitro"; import type { AndroidBackend, OmniPlayer, PlayerBackend } from "./types/player"; import type { CastOptions, Source } from "./types/source"; const ProviderFactory = NitroModules.createHybridObject("OmniPlayerFactory"); const PlayerCtx = createContext(null!); export const OmniProvider = ({ children, source, backend = { android: "vlc" }, showNotification = false, cast, }: { source?: Source; cast?: CastOptions; backend?: PlayerBackend; children: ReactNode; showNotification?: boolean; }) => { const [player, setPlayer] = useState(null); const createPlayer = useEffectEvent((aBackend: AndroidBackend) => ProviderFactory.createPlayer({ android: aBackend }, cast), ); useEffect(() => { setPlayer(createPlayer(backend.android ?? "vlc")); }, [backend.android]); useEffect(() => { if (!player) return; return () => player.abandon(); }, [player]); const inited = useRef(null); useEffect(() => { if (!player) return; if (inited.current !== player) { inited.current = player; if (source == null) return; } player.source = source; }, [player, source]); useEffect(() => { if (player) player.showNotification = showNotification; }, [player, showNotification]); if (!player) return null; return {children}; }; export const usePlayer = () => { return useContext(PlayerCtx); };