'use client'; import { IVod } from "@/app/lib/vods"; import { useRef, useState, useEffect, useCallback } from "react"; import { VideoPlayer } from "./video-player"; import { Tagger } from './tagger'; import { ITimestamp, getTimestampsForVod } from "@/app/lib/timestamps"; import { TimestampsList } from "./timestamps-list"; import { ITagVodRelation } from "@/app/lib/tag-vod-relations"; import { VideoContext } from "./video-context"; import { getVodTitle } from "./vod-page"; import { useSearchParams } from 'next/navigation'; import type VideoApiElement from "@mux/mux-player"; import { parseUrlTimestamp } from "@/app/lib/dates"; import { faTags, faNoteSticky, faClock } from "@fortawesome/free-solid-svg-icons"; import { Tag } from './tag'; import VodNav from './vod-nav'; import LinkableHeading from "./linkable-heading"; export interface IVideoInteractiveProps { vod: IVod; } function secondsToHumanReadable(timestampInSeconds: number): string { const hours = Math.floor(timestampInSeconds / 3600); const minutes = Math.floor((timestampInSeconds % 3600) / 60); const seconds = timestampInSeconds % 60; return `${hours}h${minutes}m${seconds}s`; } function humanReadableTimestampToSeconds(timestamp: string): number | null { const parts = timestamp.split(':'); if (parts.length !== 3) { // Invalid format, return null or throw an error as appropriate return null; } const hours = parseInt(parts[0], 10); const minutes = parseInt(parts[1], 10); const seconds = parseInt(parts[2], 10); if (isNaN(hours) || isNaN(minutes) || isNaN(seconds)) { // Invalid numeric values, return null or throw an error as appropriate return null; } const totalSeconds = hours * 3600 + minutes * 60 + seconds; return totalSeconds; } export function VideoInteractive({ vod }: IVideoInteractiveProps): React.JSX.Element { const [timeStamp, setTimeStamp] = useState(0); const [tvrs, setTvrs] = useState([]); const [isPlayerReady, setIsPlayerReady] = useState(false); const [timestamps, setTimestamps] = useState([]); const [currentTsPage, setCurrentTsPage] = useState(1); const getTimestampPage = useCallback(async (page: number) => { const timestamps = await getTimestampsForVod(vod.id, page); setTimestamps(timestamps); }, [vod.id, setTimestamps]); // IGNORE TS LINTER! DO NOT PUT timestamps HERE! IT CAUSES SELF-DDOS! const ref = useRef(null); const searchParams = useSearchParams(); const t = searchParams.get('t'); useEffect(() => { getTimestampPage(currentTsPage); }, [vod.id, getTimestampPage, currentTsPage]); useEffect(() => { if (!t) return; if (!ref?.current) return; const videoRef = ref.current as VideoApiElement; const seconds = parseUrlTimestamp(t) if (seconds === null) return; videoRef.currentTime = seconds; }, [t, isPlayerReady, ref]) return (

{getVodTitle(vod)}

{vod.attributes.note && ( <>
{vod.attributes.note}
)}
{vod.attributes.tagVodRelations.data.length === 0 &&

This vod has no tags

} {vod.attributes.tagVodRelations.data.map((tvr: ITagVodRelation) => ( ))}
) }