sudo-archive/src/views/Movie.js

192 lines
7.3 KiB
JavaScript
Raw Normal View History

import React, { useCallback } from 'react'
import { useRouteMatch, useHistory } from 'react-router-dom'
2021-08-02 13:15:24 +00:00
import { Helmet } from 'react-helmet';
2021-07-13 22:31:37 +00:00
import { Title } from '../components/Title'
import { Card } from '../components/Card'
import { useMovie } from '../hooks/useMovie'
import { VideoElement } from '../components/VideoElement'
2021-07-14 22:09:42 +00:00
import { EpisodeSelector } from '../components/EpisodeSelector'
2021-07-20 10:20:56 +00:00
import { getStreamUrl } from '../lib/index'
2021-07-14 22:09:42 +00:00
import './Movie.css'
2021-07-13 22:31:37 +00:00
export function MovieView(props) {
const baseRouteMatch = useRouteMatch('/:type/:source/:title/:slug');
const showRouteMatch = useRouteMatch('/:type/:source/:title/:slug/season/:season/episode/:episode');
const history = useHistory();
2021-07-14 22:09:42 +00:00
const { streamUrl, streamData, setStreamUrl } = useMovie();
const [ seasonList, setSeasonList ] = React.useState([]);
const [ episodeLists, setEpisodeList ] = React.useState([]);
const [ loading, setLoading ] = React.useState(false);
const [ selectedSeason, setSelectedSeason ] = React.useState("1");
const season = showRouteMatch?.params.season || "1";
const episode = showRouteMatch?.params.episode || "1";
2021-07-14 22:09:42 +00:00
// eslint-disable-next-line react-hooks/exhaustive-deps
function setEpisode({ season, episode }) {
// getStream(title, slug, type, source, year);
// console.log(season, episode)
let tmpSeason = showRouteMatch.params.season;
let tmpEpisode = showRouteMatch.params.episode;
if (tmpSeason != season && tmpEpisode != episode)
history.replace(`${baseRouteMatch.url}/season/${season}/episode/${episode}`);
}
React.useEffect(() => {
// Cache streamData continue watching on home page
let movieCache = JSON.parse(localStorage.getItem("movie-cache") || "{}");
if (!movieCache[streamData.source]) movieCache[streamData.source] = {}
movieCache[streamData.source][streamData.slug] = {
cachedAt: Date.now()
}
localStorage.setItem("movie-cache", JSON.stringify(movieCache));
// Set season and episode list for GUI
if (streamData.type === "show") {
setSeasonList(streamData.seasons);
setSelectedSeason(streamData.seasons[0])
// TODO load from localstorage last watched
setEpisode({ episode: streamData.episodes[streamData.seasons[0]][0], season: streamData.seasons[0] })
setEpisodeList(streamData.episodes[streamData.seasons[0]]);
}
}, [streamData, setEpisode])
2021-07-14 22:09:42 +00:00
React.useEffect(() => {
setEpisodeList(streamData.episodes[selectedSeason]);
}, [selectedSeason, streamData.episodes])
2021-07-14 22:09:42 +00:00
React.useEffect(() => {
if (streamData.type === "show") {
setSeasonList(streamData.seasons);
// TODO load from localstorage last watched
setEpisodeList(streamData.episodes[streamData.seasons[0]]);
}
}, [streamData])
React.useEffect(() => {
if (streamData.type === "show" && !showRouteMatch) history.replace(`${baseRouteMatch.url}/season/1/episode/1`);
}, [streamData, showRouteMatch, history, baseRouteMatch.url]);
React.useEffect(() => {
if (streamData.type === "show" && showRouteMatch) setSelectedSeason(showRouteMatch.params.season.toString());
}, [showRouteMatch, streamData]);
2021-07-14 22:09:42 +00:00
React.useEffect(() => {
let cancel = false;
// ignore if not a show
if (streamData.type !== "show") return () => {
cancel = true;
};
if (!episode) {
2021-07-14 22:09:42 +00:00
setLoading(false);
setStreamUrl('');
return;
}
setLoading(true);
getStreamUrl(streamData.slug, streamData.type, streamData.source, season, episode)
2021-07-14 22:09:42 +00:00
.then(({url}) => {
if (cancel) return;
setStreamUrl(url)
setLoading(false);
})
.catch(e => {
if (cancel) return;
console.error(e)
})
2021-07-14 22:09:42 +00:00
return () => {
cancel = true;
}
}, [episode, streamData, setStreamUrl, season]);
React.useEffect(() => {
// Cache streamData continue watching on home page
let movieCache = JSON.parse(localStorage.getItem("movie-cache") || "{}");
if(!movieCache[streamData.source]) movieCache[streamData.source] = {}
movieCache[streamData.source][streamData.slug] = {
cachedAt: Date.now()
}
localStorage.setItem("movie-cache", JSON.stringify(movieCache));
// Set season and episode list for GUI
if (streamData.type === "show") {
setSeasonList(streamData.seasons);
setSelectedSeason(streamData.seasons[0])
// TODO load from localstorage last watched
setEpisode({ episode: streamData.episodes[streamData.seasons[0]][0], season: streamData.seasons[0] })
setEpisodeList(streamData.episodes[streamData.seasons[0]]);
}
}, [streamData, setEpisode])
2021-07-13 22:31:37 +00:00
2021-07-15 18:34:25 +00:00
const setProgress = (evt) => {
let ls = JSON.parse(localStorage.getItem("video-progress") || "{}")
console.log(streamData);
2021-07-21 10:29:18 +00:00
if(!ls[streamData.source]) ls[streamData.source] = {}
if(!ls[streamData.source][streamData.type]) ls[streamData.source][streamData.type] = {}
if(!ls[streamData.source][streamData.type][streamData.slug]) {
ls[streamData.source][streamData.type][streamData.slug] = {}
2021-07-15 18:34:25 +00:00
}
// Store real data
let key = streamData.type === "show" ? `${season}-${episode.episode}` : "full"
2021-07-21 10:29:18 +00:00
ls[streamData.source][streamData.type][streamData.slug][key] = {
2021-07-15 18:34:25 +00:00
currentlyAt: Math.floor(evt.currentTarget.currentTime),
totalDuration: Math.floor(evt.currentTarget.duration),
updatedAt: Date.now(),
meta: streamData
2021-07-15 18:34:25 +00:00
}
if(streamData.type === "show") {
2021-07-21 10:29:18 +00:00
ls[streamData.source][streamData.type][streamData.slug][key].show = {
2021-07-15 18:34:25 +00:00
season,
episode: episode.episode
2021-07-15 18:34:25 +00:00
}
}
localStorage.setItem("video-progress", JSON.stringify(ls))
}
2021-07-13 22:31:37 +00:00
return (
2021-07-14 22:09:42 +00:00
<div className={`cardView showType-${streamData.type}`}>
2021-08-02 13:15:24 +00:00
<Helmet>
2021-08-02 13:22:13 +00:00
<title>{streamData.title}{streamData.type === 'show' ? ` | S${season}E${episode}` : ''} | movie-web</title>
2021-08-02 13:15:24 +00:00
</Helmet>
2021-07-13 22:31:37 +00:00
<Card fullWidth>
<Title accent="Return to home" accentLink="search">
2021-07-14 22:09:42 +00:00
{streamData.title}
2021-07-13 22:31:37 +00:00
</Title>
2021-07-14 22:09:42 +00:00
{streamData.type === "show" ? <Title size="small">
Season {season}: Episode {episode}
2021-07-14 22:09:42 +00:00
</Title> : undefined}
2021-07-15 18:34:25 +00:00
<VideoElement streamUrl={streamUrl} loading={loading} setProgress={setProgress} />
2021-07-14 22:09:42 +00:00
{streamData.type === "show" ?
<EpisodeSelector
setSelectedSeason={setSelectedSeason}
selectedSeason={selectedSeason}
2021-07-14 22:09:42 +00:00
setEpisode={setEpisode}
2021-07-14 22:09:42 +00:00
seasons={seasonList}
episodes={episodeLists}
2021-07-14 22:09:42 +00:00
currentSeason={season}
currentEpisode={episode}
2021-07-20 22:49:33 +00:00
source={streamData.source}
2021-07-14 22:09:42 +00:00
/>
: ''}
2021-07-13 22:31:37 +00:00
</Card>
</div>
)
}