import { Fragment, lazy, Suspense, useCallback, useEffect, useRef, useState } from "react"; import { qk } from "../lib/queryKeys"; import { createPortal } from "react-dom"; import { useTranslation } from "react-i18next"; import { plexLang } from "../i18n"; import { useQuery, useQueryClient } from "@tanstack/react-query"; import Hls from "hls.js"; import { ArrowLeft, Clock, Download, Gauge, Info, Keyboard, Languages, Loader2, Maximize, Minimize, Pause, Play, RotateCcw, Settings, SkipBack, SkipForward, Square, Volume2, VolumeX, X, } from "lucide-react"; import { api, HttpError } from "../lib/api"; import { audioOrdForLang, clamp01, clockParts, DEFAULT_PREFS, fmt, HLS_SUB_LAG, subOrdForLang, subShadowCss, type PlexPlayerPrefs, } from "../lib/plexPlayerPrefs"; import { Ctrl, PanelHead, Skip10 } from "./plexPlayerControls"; import { PlexPlayerSettings } from "./PlexPlayerSettings"; import { PlexStatsOverlay } from "./PlexStatsOverlay"; import { UpNextCard } from "./UpNextCard"; import { useAutoSkip, useControlsVisibility, useFullscreen, usePlayerVolume, usePlexProgress, usePlexTracks, useWallClock, } from "../lib/plexPlayerHooks"; import { fullscreenElement } from "../lib/fullscreen"; import { LS, useAccountPersistedObject } from "../lib/storage"; import { useDismiss } from "../lib/useDismiss"; import { useScrollFade } from "../lib/useScrollFade"; import { useBackToClose } from "../lib/history"; import { pushLayer, removeLayer, anyLayerAbove, escapeHandled } from "../lib/layerStack"; // The rich info overlay (poster/cast/ratings) reuses the same component as the card's info page. const PlexInfo = lazy(() => import("./PlexInfo")); // The Plex module's rich, full-page player. Plays the LOCAL file: direct-playable files stream raw // (native