mirror of
https://github.com/movie-web/movie-web.git
synced 2025-01-11 23:19:10 +01:00
Add URL routing to show episode selector
This commit is contained in:
parent
6a8af72f81
commit
a48c77a1cb
@ -3,10 +3,8 @@ import { TypeSelector } from './TypeSelector';
|
|||||||
import { NumberSelector } from './NumberSelector';
|
import { NumberSelector } from './NumberSelector';
|
||||||
import './EpisodeSelector.css'
|
import './EpisodeSelector.css'
|
||||||
|
|
||||||
export function EpisodeSelector({ setSeason, setEpisode, seasons, season, episodes, currentSeason, currentEpisode, slug, source }) {
|
export function EpisodeSelector({ setSelectedSeason, setEpisode, seasons, selectedSeason, season, episodes, currentSeason, currentEpisode, source }) {
|
||||||
|
const choices = episodes ? episodes.map(v => {
|
||||||
const choices = episodes.map(v => {
|
|
||||||
|
|
||||||
let progressData = JSON.parse(localStorage.getItem('video-progress') || "{}")
|
let progressData = JSON.parse(localStorage.getItem('video-progress') || "{}")
|
||||||
|
|
||||||
let currentlyAt = 0;
|
let currentlyAt = 0;
|
||||||
@ -25,12 +23,12 @@ export function EpisodeSelector({ setSeason, setEpisode, seasons, season, episod
|
|||||||
label: v,
|
label: v,
|
||||||
percentage
|
percentage
|
||||||
}
|
}
|
||||||
})
|
}) : [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="episodeSelector">
|
<div className="episodeSelector">
|
||||||
<TypeSelector setType={setSeason} choices={seasons.map(v=>({ value: v.toString(), label: `Season ${v}`}))} selected={currentSeason}/><br></br>
|
<TypeSelector setType={setSelectedSeason} choices={seasons.map(v=>({ value: v.toString(), label: `Season ${v}`}))} selected={selectedSeason}/><br></br>
|
||||||
<NumberSelector setType={(e) => setEpisode({episode: e, season: currentSeason})} choices={choices} selected={currentEpisode.season === currentSeason?currentEpisode.episode:null}/>
|
<NumberSelector setType={(e) => setEpisode({episode: e, season: selectedSeason})} choices={choices} selected={(selectedSeason.toString() === currentSeason) ? currentEpisode : null} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
import { useRouteMatch, useHistory } from 'react-router-dom'
|
||||||
import { Title } from '../components/Title'
|
import { Title } from '../components/Title'
|
||||||
import { Card } from '../components/Card'
|
import { Card } from '../components/Card'
|
||||||
import { useMovie } from '../hooks/useMovie'
|
import { useMovie } from '../hooks/useMovie'
|
||||||
@ -9,41 +10,57 @@ import { getStreamUrl } from '../lib/index'
|
|||||||
import './Movie.css'
|
import './Movie.css'
|
||||||
|
|
||||||
export function MovieView(props) {
|
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();
|
||||||
const { streamUrl, streamData, setStreamUrl } = useMovie();
|
const { streamUrl, streamData, setStreamUrl } = useMovie();
|
||||||
const [season, setSeason] = React.useState("1");
|
|
||||||
const [seasonList, setSeasonList] = React.useState([]);
|
const [seasonList, setSeasonList] = React.useState([]);
|
||||||
const [episodeLists, setEpisodeList] = React.useState([]);
|
const [episodeLists, setEpisodeList] = React.useState([]);
|
||||||
const [episode, setEpisode] = React.useState({ episode: null, season: null });
|
|
||||||
const [loading, setLoading] = React.useState(false);
|
const [loading, setLoading] = React.useState(false);
|
||||||
|
const [ selectedSeason, setSelectedSeason ] = React.useState("1");
|
||||||
|
|
||||||
|
const season = showRouteMatch?.params.season || "1";
|
||||||
|
const episode = showRouteMatch?.params.episode || "1";
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
setEpisodeList(streamData.episodes[season]);
|
setEpisodeList(streamData.episodes[selectedSeason]);
|
||||||
}, [season, streamData.episodes])
|
}, [selectedSeason, streamData.episodes])
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (streamData.type === "show") {
|
if (streamData.type === "show") {
|
||||||
setSeasonList(streamData.seasons);
|
setSeasonList(streamData.seasons);
|
||||||
setSeason(streamData.seasons[0])
|
|
||||||
// TODO load from localstorage last watched
|
// TODO load from localstorage last watched
|
||||||
setEpisode({ episode: streamData.episodes[streamData.seasons[0]][0], season: streamData.seasons[0] })
|
|
||||||
setEpisodeList(streamData.episodes[streamData.seasons[0]]);
|
setEpisodeList(streamData.episodes[streamData.seasons[0]]);
|
||||||
}
|
}
|
||||||
}, [streamData])
|
}, [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) 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());
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
let cancel = false;
|
let cancel = false;
|
||||||
// ignore if not a show
|
// ignore if not a show
|
||||||
if (streamData.type !== "show") return () => {
|
if (streamData.type !== "show") return () => {
|
||||||
cancel = true;
|
cancel = true;
|
||||||
};
|
};
|
||||||
if (!episode.episode) {
|
if (!episode) {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
setStreamUrl('');
|
setStreamUrl('');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
getStreamUrl(streamData.slug, streamData.type, streamData.source, episode.season, episode.episode)
|
getStreamUrl(streamData.slug, streamData.type, streamData.source, season, episode)
|
||||||
.then(({url}) => {
|
.then(({url}) => {
|
||||||
if (cancel) return;
|
if (cancel) return;
|
||||||
setStreamUrl(url)
|
setStreamUrl(url)
|
||||||
@ -56,7 +73,11 @@ export function MovieView(props) {
|
|||||||
return () => {
|
return () => {
|
||||||
cancel = true;
|
cancel = true;
|
||||||
}
|
}
|
||||||
}, [episode, streamData, setStreamUrl])
|
}, [episode, streamData, setStreamUrl, season]);
|
||||||
|
|
||||||
|
function setEpisode({ season, episode }) {
|
||||||
|
history.push(`${baseRouteMatch.url}/season/${season}/episode/${episode}`);
|
||||||
|
}
|
||||||
|
|
||||||
const setProgress = (evt) => {
|
const setProgress = (evt) => {
|
||||||
let ls = JSON.parse(localStorage.getItem("video-progress") || "{}")
|
let ls = JSON.parse(localStorage.getItem("video-progress") || "{}")
|
||||||
@ -69,7 +90,7 @@ export function MovieView(props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Store real data
|
// Store real data
|
||||||
let key = streamData.type === "show" ? `${season}-${episode.episode}` : "full"
|
let key = streamData.type === "show" ? `${season}-${episode}` : "full"
|
||||||
ls[streamData.source][streamData.type][streamData.slug][key] = {
|
ls[streamData.source][streamData.type][streamData.slug][key] = {
|
||||||
currentlyAt: Math.floor(evt.currentTarget.currentTime),
|
currentlyAt: Math.floor(evt.currentTarget.currentTime),
|
||||||
totalDuration: Math.floor(evt.currentTarget.duration),
|
totalDuration: Math.floor(evt.currentTarget.duration),
|
||||||
@ -79,7 +100,7 @@ export function MovieView(props) {
|
|||||||
if(streamData.type === "show") {
|
if(streamData.type === "show") {
|
||||||
ls[streamData.source][streamData.type][streamData.slug][key].show = {
|
ls[streamData.source][streamData.type][streamData.slug][key].show = {
|
||||||
season,
|
season,
|
||||||
episode: episode.episode
|
episode: episode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,19 +114,22 @@ export function MovieView(props) {
|
|||||||
{streamData.title}
|
{streamData.title}
|
||||||
</Title>
|
</Title>
|
||||||
{streamData.type === "show" ? <Title size="small">
|
{streamData.type === "show" ? <Title size="small">
|
||||||
Season {episode.season}: Episode {episode.episode}
|
Season {season}: Episode {episode}
|
||||||
</Title> : undefined}
|
</Title> : undefined}
|
||||||
<VideoElement streamUrl={streamUrl} loading={loading} setProgress={setProgress} />
|
<VideoElement streamUrl={streamUrl} loading={loading} setProgress={setProgress} />
|
||||||
{streamData.type === "show" ?
|
{streamData.type === "show" ?
|
||||||
<EpisodeSelector
|
<EpisodeSelector
|
||||||
setSeason={setSeason}
|
setSelectedSeason={setSelectedSeason}
|
||||||
|
selectedSeason={selectedSeason}
|
||||||
|
|
||||||
setEpisode={setEpisode}
|
setEpisode={setEpisode}
|
||||||
season={season}
|
|
||||||
seasons={seasonList}
|
seasons={seasonList}
|
||||||
episodes={episodeLists}
|
episodes={episodeLists}
|
||||||
slug={streamData.slug}
|
|
||||||
currentSeason={season}
|
currentSeason={season}
|
||||||
currentEpisode={episode}
|
currentEpisode={episode}
|
||||||
|
|
||||||
source={streamData.source}
|
source={streamData.source}
|
||||||
/>
|
/>
|
||||||
: ''}
|
: ''}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user