diff --git a/app/components/ReleasePlayer/ReleasePlayer.tsx b/app/components/ReleasePlayer/ReleasePlayer.tsx index 11bfd6e..e077b9b 100644 --- a/app/components/ReleasePlayer/ReleasePlayer.tsx +++ b/app/components/ReleasePlayer/ReleasePlayer.tsx @@ -2,6 +2,7 @@ import { Spinner } from "#/components/Spinner/Spinner"; import { useUserStore } from "#/store/auth"; +import { useUserPlayerPreferencesStore } from "#/store/player"; import { Card, Dropdown, Button } from "flowbite-react"; import { ENDPOINTS } from "#/api/config"; import { useState, useEffect } from "react"; @@ -38,27 +39,14 @@ const getAnonEpisodesWatched = ( ) => { const anonEpisodesWatched = JSON.parse(localStorage.getItem("anonEpisodesWatched")) || {}; - console.log("anonEpisodesWatched", anonEpisodesWatched); if (!anonEpisodesWatched.hasOwnProperty(Release)) { - console.log( - `no key found for R: ${Release}`, - anonEpisodesWatched.hasOwnProperty(Release) - ); anonEpisodesWatched[Release] = {}; } if (!anonEpisodesWatched[Release].hasOwnProperty(Source)) { - console.log( - `no key found for R: ${Release} S: ${Source}`, - anonEpisodesWatched.hasOwnProperty(Release) - ); anonEpisodesWatched[Release][Source] = {}; } if (!anonEpisodesWatched[Release][Source].hasOwnProperty(Voiceover)) { - console.log( - `no key found for R: ${Release} S: ${Source} V: ${Voiceover}`, - anonEpisodesWatched.hasOwnProperty(Release) - ); anonEpisodesWatched[Release][Source][Voiceover] = {}; } @@ -75,33 +63,17 @@ const getAnonCurrentEpisodeWatched = ( JSON.parse(localStorage.getItem("anonEpisodesWatched")) || {}; if (!anonEpisodesWatched.hasOwnProperty(Release)) { - console.log( - `no key found for R: ${Release}`, - anonEpisodesWatched.hasOwnProperty(Release) - ); return false; } if (!anonEpisodesWatched[Release].hasOwnProperty(Source)) { - console.log( - `no key found for R: ${Release} S: ${Source}`, - anonEpisodesWatched.hasOwnProperty(Release) - ); return false; } if (!anonEpisodesWatched[Release][Source].hasOwnProperty(Voiceover)) { - console.log( - `no key found for R: ${Release} S: ${Source} V: ${Voiceover}`, - anonEpisodesWatched.hasOwnProperty(Release) - ); return false; } if ( !anonEpisodesWatched[Release][Source][Voiceover].hasOwnProperty(Episode) ) { - console.log( - `no key found for R: ${Release} S: ${Source} V: ${Voiceover} E: ${Episode}`, - anonEpisodesWatched.hasOwnProperty(Release) - ); return false; } @@ -139,65 +111,148 @@ const saveAnonEpisodeWatched = ( export const ReleasePlayer = (props: { id: number }) => { const userStore = useUserStore(); + const preferredVoiceoverStore = useUserPlayerPreferencesStore(); + const storedPreferredVoiceover = + preferredVoiceoverStore.getPreferredVoiceover(props.id); + const storedPreferredPlayer = preferredVoiceoverStore.getPreferredPlayer( + props.id + ); const [voiceoverInfo, setVoiceoverInfo] = useState(null); const [selectedVoiceover, setSelectedVoiceover] = useState(null); const [sourcesInfo, setSourcesInfo] = useState(null); const [selectedSource, setSelectedSource] = useState(null); const [episodeInfo, setEpisodeInfo] = useState(null); const [selectedEpisode, setSelectedEpisode] = useState(null); + const [error, setError] = useState(null); + const setSelectedVoiceoverAndSaveAsPreferred = (voiceover: any) => { + setSelectedVoiceover(voiceover); + preferredVoiceoverStore.setPreferredVoiceover(props.id, voiceover.name); + }; + const setSelectedPlayerAndSaveAsPreferred = (player: any) => { + setSelectedSource(player); + preferredVoiceoverStore.setPreferredPlayer(props.id, player.name); + }; - useEffect(() => { - async function _fetchInfo() { - const voiceover = await _fetch( - `${ENDPOINTS.release.episode}/${props.id}` - ); - setVoiceoverInfo(voiceover.types); - setSelectedVoiceover(voiceover.types[0]); + function _setError(error: string) { + setVoiceoverInfo(null); + setSelectedVoiceover(null); + setSourcesInfo(null); + setSelectedSource(null); + setEpisodeInfo(null); + setSelectedEpisode(null); + setError(error); + } + + async function _fetchInfo( + url: string, + type: "voiceover" | "sources" | "episodes" + ) { + let data: any = {}; + data = await fetch(url) + .then((res) => { + if (res.ok) { + return res.json(); + } else { + throw new Error("Error fetching data"); + } + }) + .catch((err) => { + console.log(err); + _setError("Ошибка получение ответа от сервера"); + return; + }); + + if (data && Object.keys(data).length == 0) { + _setError("Ошибка получение данных с сервера"); } - _fetchInfo(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - useEffect(() => { - async function _fetchInfo() { - const sources = await _fetch( - `${ENDPOINTS.release.episode}/${props.id}/${selectedVoiceover.id}` - ); - setSourcesInfo(sources.sources); - setSelectedSource(sources.sources[0]); - } - if (selectedVoiceover) { - _fetchInfo(); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [selectedVoiceover]); - - useEffect(() => { - async function _fetchInfo(url: string) { - const episodes = await _fetch(url); - - if (episodes.episodes.length === 0) { + if (type == "voiceover") { + if (data.types.length > 0) { + setVoiceoverInfo(data.types); + const preferredVoiceover = + data.types.find( + (voiceover: any) => voiceover.name === storedPreferredVoiceover + ) || data.types[0]; + setSelectedVoiceover(preferredVoiceover); + } else { + _setError("Ошибка получения озвучек"); + } + } else if (type == "sources") { + if (data.sources.length > 0) { + setSourcesInfo(data.sources); + const preferredSource = + data.sources.find( + (source: any) => source.name === storedPreferredPlayer + ) || data.sources[0]; + setSelectedSource(preferredSource); + } else { + _setError("Ошибка получения источников"); + } + } else if (type == "episodes") { + if (data.episodes.length === 0) { const remSources = sourcesInfo.filter( (source) => source.id !== selectedSource.id ); setSourcesInfo(remSources); setSelectedSource(remSources[0]); - return; - } + } else if (data.episodes.length > 0) { + setEpisodeInfo(data.episodes); + setSelectedEpisode(data.episodes[0]); - setEpisodeInfo(episodes.episodes); - setSelectedEpisode(episodes.episodes[0]); + const WatchedEpisodes = getAnonEpisodesWatched( + props.id, + selectedSource.id, + selectedVoiceover.id + ); + if ( + Object.keys( + WatchedEpisodes[props.id][selectedSource.id][selectedVoiceover.id] + ).length != 0 + ) { + const watchedEpisodes = + WatchedEpisodes[props.id][selectedSource.id][selectedVoiceover.id]; + let lastWatchedEpisode = Number(Object.keys(watchedEpisodes).pop()); + if ( + !["Sibnet", "Sibnet (не работает)"].includes(selectedSource.name) + ) { + lastWatchedEpisode = Number(lastWatchedEpisode) - 1; + } + setSelectedEpisode(data.episodes[lastWatchedEpisode]); + } + } else { + _setError("Ошибка получения эпизодов"); + } + } else { + _setError("Неизвестный тип запроса"); } + } + + useEffect(() => { + _fetchInfo(`${ENDPOINTS.release.episode}/${props.id}`, "voiceover"); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [props.id]); + + useEffect(() => { + if (selectedVoiceover) { + _fetchInfo( + `${ENDPOINTS.release.episode}/${props.id}/${selectedVoiceover.id}`, + "sources" + ); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [props.id, selectedVoiceover]); + + useEffect(() => { if (selectedSource) { let url = `${ENDPOINTS.release.episode}/${props.id}/${selectedVoiceover.id}/${selectedSource.id}`; if (userStore.token) { url = `${ENDPOINTS.release.episode}/${props.id}/${selectedVoiceover.id}/${selectedSource.id}?token=${userStore.token}`; } - _fetchInfo(url); + _fetchInfo(url, "episodes"); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [selectedSource, userStore.token]); + }, [props.id, selectedSource, userStore.token]); async function _addToHistory(episode: any) { if (episode && userStore.token) { @@ -214,7 +269,7 @@ export const ReleasePlayer = (props: { id: number }) => { {!voiceoverInfo || !sourcesInfo || !episodeInfo ? (
- + {!error ? :

{error}

}
) : ( <> @@ -227,7 +282,9 @@ export const ReleasePlayer = (props: { id: number }) => { {voiceoverInfo.map((voiceover: any) => ( setSelectedVoiceover(voiceover)} + onClick={() => + setSelectedVoiceoverAndSaveAsPreferred(voiceover) + } > {voiceover.name} @@ -241,7 +298,7 @@ export const ReleasePlayer = (props: { id: number }) => { {sourcesInfo.map((source: any) => ( setSelectedSource(source)} + onClick={() => setSelectedPlayerAndSaveAsPreferred(source)} > {source.name} @@ -249,11 +306,15 @@ export const ReleasePlayer = (props: { id: number }) => {
- + {selectedEpisode ? ( + + ) : ( +

Ошибка загрузки плеера

+ )}
{ {episode.name ? episode.name : `${ - selectedSource.name != "Sibnet" + !["Sibnet", "Sibnet (не работает)"].includes( + selectedSource.name + ) ? episode.position : episode.position + 1 } серия`} diff --git a/app/store/player.ts b/app/store/player.ts new file mode 100644 index 0000000..369f604 --- /dev/null +++ b/app/store/player.ts @@ -0,0 +1,39 @@ +"use client"; +import { create } from "zustand"; +import { persist } from "zustand/middleware"; + +interface userPlayerPreferencesState { + voiceover: Record; + player: Record; + getPreferredVoiceover: (id: number) => string | undefined; + setPreferredVoiceover: (id: number, voiceover: string) => void; + getPreferredPlayer: (id: number) => string | undefined; + setPreferredPlayer: (id: number, player: string) => void; +} + +export const useUserPlayerPreferencesStore = + create()( + persist( + (set, get) => ({ + voiceover: {}, + player: {}, + getPreferredVoiceover: (id: number) => get().voiceover[id], + setPreferredVoiceover: (id: number, voiceover: string) => { + set({ + voiceover: { ...get().voiceover, [id]: voiceover }, + player: get().player, + }); + }, + getPreferredPlayer: (id: number) => get().player[id], + setPreferredPlayer: (id: number, player: string) => { + set({ + player: { ...get().player, [id]: player }, + voiceover: get().voiceover, + }); + }, + }), + { + name: "player-preferences", + } + ) + );