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 { useHistory } from "react-router-dom"; import { getIfBookmarkedFromPortable, useBookmarkContext, } from "state/bookmark"; import { getWatchedFromPortable, useWatchedContext } from "state/watched"; import { NotFoundChecks } from "./notfound/NotFoundChecks"; interface StyledMediaViewProps { media: MWMedia; stream: MWMediaStream; provider: MWMediaProvider; } function StyledMediaView(props: StyledMediaViewProps) { const watchedStore = useWatchedContext(); const startAtTime: number | undefined = getWatchedFromPortable( watchedStore.watched.items, 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 } watchedStore.updateProgress(props.media, el.currentTime, el.duration); } return ( <>
{props.media.title}
setItemBookmark(props.media, !isBookmarked)} clickable />
); } function LoadingMediaView(props: { error?: boolean }) { return ( <>
); } function MediaViewContent(props: { portable: MWPortableMedia }) { const mediaPortable = props.portable; 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, fetchAllData]); let content: ReactNode; if (loading) content = ; else if (error) content = ; else if (mediaPortable && media && streamUrl) content = ( ); return <>{content}; } export function MediaView() { const mediaPortable: MWPortableMedia | undefined = usePortableMedia(); const reactHistory = useHistory(); return (
{ reactHistory.action !== "POP" ? reactHistory.goBack() : reactHistory.push("/"); }} direction="left" linkText="Go back" />
); }