"use client"; import dynamic from "next/dynamic"; import { createContext, useCallback, useContext, useEffect, useMemo, useReducer, useRef, useState, type ComponentProps, type ReactNode, } from "react"; import type ReactPlayerType from "react-player"; import { fetchTranscript } from "./transcriptCache"; import { fetchSubs } from "./subsCache"; import { fetchDigest, hasDigest } from "./digestCache"; import type { VideoDigest } from "../lib/digests"; import { useUrlParams, writeUrlParams } from "./urlState"; import type { ModalMode } from "./urlState"; import { formatDate, formatDuration } from "../lib/format"; import { cuesToSrt, cuesToText } from "../lib/vtt"; import { transcriptToMarkdown } from "../lib/transcriptToMarkdown"; import type { Platform } from "../lib/transcripts"; import { vodExpiry } from "../lib/vodExpiry"; import { cuesOfTrack, recordTracks, type TrackFields } from "../lib/captionTracks"; import { VodExpiredBadge } from "./badges"; import type { RumblePlayerHandle } from "./RumblePlayer"; import type { OdyseePlayerHandle } from "./OdyseePlayer"; import type { TwitchPlayerHandle } from "./TwitchPlayer"; import type { KickPlayerHandle } from "./KickPlayer"; import type { FilePlayerHandle } from "./FilePlayer"; const ReactPlayer = dynamic(() => import("react-player/youtube"), { ssr: false, }); const RumblePlayer = dynamic(() => import("./RumblePlayer"), { ssr: false, }); const OdyseePlayer = dynamic(() => import("./OdyseePlayer"), { ssr: false, }); const TwitchPlayer = dynamic(() => import("./TwitchPlayer"), { ssr: false, }); // Kick VODs have no iframe embed; they play from a persisted HLS manifest in a // native