fix: episode history save

This commit is contained in:
Kentai Radiquum 2025-04-12 21:03:10 +05:00
parent 0b66614ccf
commit bc7c799f3c
Signed by: Radiquum
GPG key ID: 858E8EE696525EED
2 changed files with 101 additions and 67 deletions

View file

@ -12,6 +12,7 @@ import "swiper/css/navigation";
import "swiper/css/mousewheel"; import "swiper/css/mousewheel";
import "swiper/css/scrollbar"; import "swiper/css/scrollbar";
import { Navigation, Mousewheel, Scrollbar } from "swiper/modules"; import { Navigation, Mousewheel, Scrollbar } from "swiper/modules";
import { usePreferencesStore } from "#/store/preferences";
const DropdownTheme = { const DropdownTheme = {
floating: { floating: {
@ -132,6 +133,7 @@ export const ReleasePlayer = (props: { id: number }) => {
setSelectedSource(player); setSelectedSource(player);
preferredVoiceoverStore.setPreferredPlayer(props.id, player.name); preferredVoiceoverStore.setPreferredPlayer(props.id, player.name);
}; };
const preferenceStore = usePreferencesStore();
function _setError(error: string) { function _setError(error: string) {
setVoiceoverInfo(null); setVoiceoverInfo(null);
@ -244,25 +246,48 @@ export const ReleasePlayer = (props: { id: number }) => {
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [props.id, selectedSource, userStore.token]); }, [props.id, selectedSource, userStore.token]);
async function _addToHistory(episode: any) { function _addToHistory(episode: any) {
if (episode && userStore.token) { if (props.id && selectedSource && selectedVoiceover && episode) {
_fetch( const anonEpisodesWatched = getAnonEpisodesWatched(
props.id,
selectedSource.id,
selectedVoiceover.id
);
if (
preferenceStore.flags.saveWatchHistory &&
!episode.is_watched &&
!Object.keys(
anonEpisodesWatched[props.id][selectedSource.id][selectedVoiceover.id]
).includes(episode.position.toString())
) {
episode.is_watched = true;
saveAnonEpisodeWatched(
props.id,
selectedSource.id,
selectedVoiceover.id,
episode.position
);
if (userStore.token) {
fetch(
`${ENDPOINTS.statistic.addHistory}/${props.id}/${selectedSource.id}/${episode.position}?token=${userStore.token}` `${ENDPOINTS.statistic.addHistory}/${props.id}/${selectedSource.id}/${episode.position}?token=${userStore.token}`
); );
_fetch( fetch(
`${ENDPOINTS.statistic.markWatched}/${props.id}/${selectedSource.id}/${episode.position}?token=${userStore.token}` `${ENDPOINTS.statistic.markWatched}/${props.id}/${selectedSource.id}/${episode.position}?token=${userStore.token}`
); );
} }
} }
}
}
return ( return (
<Card> <Card>
{!voiceoverInfo || !sourcesInfo || !episodeInfo ? ( {!voiceoverInfo || !sourcesInfo || !episodeInfo ?
<div className="flex items-center justify-center w-full aspect-video"> <div className="flex items-center justify-center w-full aspect-video">
{!error ? <Spinner /> : <p>{error}</p>} {!error ?
<Spinner />
: <p>{error}</p>}
</div> </div>
) : ( : <>
<>
<div className="flex flex-wrap gap-2"> <div className="flex flex-wrap gap-2">
<Dropdown <Dropdown
label={`Озвучка: ${selectedVoiceover.name}`} label={`Озвучка: ${selectedVoiceover.name}`}
@ -296,15 +321,13 @@ export const ReleasePlayer = (props: { id: number }) => {
</Dropdown> </Dropdown>
</div> </div>
<div className="aspect-video"> <div className="aspect-video">
{selectedEpisode ? ( {selectedEpisode ?
<iframe <iframe
allowFullScreen={true} allowFullScreen={true}
src={selectedEpisode.url} src={selectedEpisode.url}
className="w-full h-full rounded-md" className="w-full h-full rounded-md"
></iframe> ></iframe>
) : ( : <p>Ошибка загрузки плеера</p>}
<p>Ошибка загрузки плеера</p>
)}
</div> </div>
<div> <div>
<Swiper <Swiper
@ -335,51 +358,48 @@ export const ReleasePlayer = (props: { id: number }) => {
> >
<Button <Button
color={ color={
selectedEpisode.position === episode.position selectedEpisode.position === episode.position ?
? "blue" "blue"
: "light" : "light"
} }
theme={{ base: "w-full disabled:opacity-100" }} theme={{ base: "w-full disabled:opacity-100" }}
onClick={() => { onClick={() => {
setSelectedEpisode(episode); setSelectedEpisode(episode);
episode.is_watched = true;
_addToHistory(episode); _addToHistory(episode);
saveAnonEpisodeWatched(
props.id,
selectedSource.id,
selectedVoiceover.id,
episode.position
);
}} }}
disabled={selectedEpisode.position === episode.position} disabled={selectedEpisode.position === episode.position}
> >
{episode.name {episode.name ?
? episode.name episode.name
: `${ : `${
(
!["Sibnet", "Sibnet (не работает)"].includes( !["Sibnet", "Sibnet (не работает)"].includes(
selectedSource.name selectedSource.name
) )
? episode.position ) ?
episode.position
: episode.position + 1 : episode.position + 1
} серия`} } серия`
{episode.is_watched || }
{(
episode.is_watched ||
getAnonCurrentEpisodeWatched( getAnonCurrentEpisodeWatched(
props.id, props.id,
selectedSource.id, selectedSource.id,
selectedVoiceover.id, selectedVoiceover.id,
episode.position episode.position
) ? ( )
) ?
<span className="w-5 h-5 ml-2 iconify material-symbols--check-circle"></span> <span className="w-5 h-5 ml-2 iconify material-symbols--check-circle"></span>
) : ( : <span className="w-5 h-5 ml-2 opacity-10 iconify material-symbols--check-circle"></span>
<span className="w-5 h-5 ml-2 opacity-10 iconify material-symbols--check-circle"></span> }
)}
</Button> </Button>
</SwiperSlide> </SwiperSlide>
))} ))}
</Swiper> </Swiper>
</div> </div>
</> </>
)} }
</Card> </Card>
); );
}; };

View file

@ -40,7 +40,10 @@ import { Episode, EpisodeSelectorMenu } from "./EpisodeSelectorMenu";
import HlsVideo from "hls-video-element/react"; import HlsVideo from "hls-video-element/react";
import VideoJS from "videojs-video-element/react"; import VideoJS from "videojs-video-element/react";
import { ENDPOINTS } from "#/api/config"; import { ENDPOINTS } from "#/api/config";
import { saveAnonEpisodeWatched } from "./ReleasePlayer"; import {
getAnonEpisodesWatched,
saveAnonEpisodeWatched,
} from "./ReleasePlayer";
import { usePreferencesStore } from "#/store/preferences"; import { usePreferencesStore } from "#/store/preferences";
export const ReleasePlayerCustom = (props: { export const ReleasePlayerCustom = (props: {
@ -147,20 +150,30 @@ export const ReleasePlayerCustom = (props: {
}, []); }, []);
function saveEpisodeToHistory() { function saveEpisodeToHistory() {
if (props.id && source.selected && voiceover.selected && episode.selected) {
const anonEpisodesWatched = getAnonEpisodesWatched(
props.id,
source.selected.id,
voiceover.selected.id
);
if ( if (
preferenceStore.flags.saveWatchHistory && preferenceStore.flags.saveWatchHistory &&
episode.selected && !episode.selected.is_watched &&
!episode.selected.is_watched !Object.keys(
anonEpisodesWatched[props.id][source.selected.id][
voiceover.selected.id
]
).includes(episode.selected.position.toString())
) { ) {
const objectToReplace = episode.available.find( const objectToReplace = episode.available.find(
(arrayItem: Episode) => arrayItem.position === episode.selected.position (arrayItem: Episode) =>
arrayItem.position === episode.selected.position
); );
const newObject = { const newObject = {
...episode.selected, ...episode.selected,
is_watched: true, is_watched: true,
}; };
Object.assign(objectToReplace, newObject); Object.assign(objectToReplace, newObject);
saveAnonEpisodeWatched( saveAnonEpisodeWatched(
props.id, props.id,
source.selected.id, source.selected.id,
@ -177,6 +190,7 @@ export const ReleasePlayerCustom = (props: {
} }
} }
} }
}
function _prevEpisode() { function _prevEpisode() {
if (!episode.available || !episode.selected) return; if (!episode.available || !episode.selected) return;