import { IconPatch } from "components/buttons/IconPatch"; import { Icons } from "components/Icon"; import { Navigation } from "components/layout/Navigation"; import { Paper } from "components/layout/Paper"; import { SkeletonVideoPlayer, VideoPlayer } from "components/media/VideoPlayer"; import { ArrowLink } from "components/text/ArrowLink"; import { DotList } from "components/text/DotList"; import { Title } from "components/text/Title"; import { useLoading } from "hooks/useLoading"; import { usePortableMedia } from "hooks/usePortableMedia"; import { MWPortableMedia, getStream, MWMediaStream, MWMedia, convertPortableToMedia, getProviderFromId, MWMediaProvider, } from "providers"; import { ReactNode, useEffect, useState } from "react"; import { getIfBookmarkedFromPortable, useBookmarkContext, } from "state/bookmark"; import { getWatchedFromPortable, useWatchedContext } from "state/watched"; interface StyledMediaViewProps { media: MWMedia; stream: MWMediaStream; provider: MWMediaProvider; } function StyledMediaView(props: StyledMediaViewProps) { const store = useWatchedContext(); const startAtTime: number | undefined = getWatchedFromPortable( store.watched, props.media )?.progress; const { setItemBookmark, getFilteredBookmarks } = useBookmarkContext(); const isBookmarked = getIfBookmarkedFromPortable( getFilteredBookmarks(), props.media ); function updateProgress(e: Event) { if (!props.media) return; const el: HTMLVideoElement = e.currentTarget as HTMLVideoElement; if (el.currentTime <= 30) { return; // Don't update stored progress if less than 30s into the video } store.updateProgress(props.media, el.currentTime, el.duration); } return ( <> {props.media.title} setItemBookmark(props.media, !isBookmarked)} clickable /> > ); } function LoadingMediaView(props: { error?: boolean }) { return ( <> > ); } export function MediaView() { const mediaPortable: MWPortableMedia | undefined = usePortableMedia(); const [streamUrl, setStreamUrl] = useState(); const [media, setMedia] = useState(); const [fetchAllData, loading, error] = useLoading((mediaPortable) => { const streamPromise = getStream(mediaPortable); const mediaPromise = convertPortableToMedia(mediaPortable); return Promise.all([streamPromise, mediaPromise]); }); useEffect(() => { (async () => { if (mediaPortable) { const resultData = await fetchAllData(mediaPortable); if (!resultData) return; setStreamUrl(resultData[0]); setMedia(resultData[1]); } })(); }, [mediaPortable, setStreamUrl]); let content: ReactNode; if (loading) content = ; else if (error) content = ; else if (mediaPortable && media && streamUrl) content = ( ); return ( window.history.back()} direction="left" linkText="Go back" /> {content} ); }