fix: update if conditions to allow for updates after changing episodes

This commit is contained in:
qtchaos 2024-02-09 17:51:47 +02:00
parent a2a3066bc7
commit 761e952ce2
No known key found for this signature in database
GPG Key ID: 7DA98B2B9EF06A90

View File

@ -5,10 +5,6 @@ import { usePlayerStore } from "@/stores/player/store";
import { usePlayerMeta } from "../hooks/usePlayerMeta"; import { usePlayerMeta } from "../hooks/usePlayerMeta";
export function MediaSession() { export function MediaSession() {
const display = usePlayerStore((s) => s.display);
const mediaPlaying = usePlayerStore((s) => s.mediaPlaying);
const meta = usePlayerStore((s) => s.meta);
const progress = usePlayerStore((s) => s.progress);
const { setDirectMeta } = usePlayerMeta(); const { setDirectMeta } = usePlayerMeta();
const setShouldStartFromBeginning = usePlayerStore( const setShouldStartFromBeginning = usePlayerStore(
(s) => s.setShouldStartFromBeginning, (s) => s.setShouldStartFromBeginning,
@ -17,117 +13,107 @@ export function MediaSession() {
const shouldUpdatePositionState = useRef(false); const shouldUpdatePositionState = useRef(false);
const lastPlaybackPosition = useRef(0); const lastPlaybackPosition = useRef(0);
const dataRef = useRef({ const data = usePlayerStore.getState();
display,
mediaPlaying,
progress,
meta,
});
useEffect(() => {
dataRef.current = {
display,
mediaPlaying,
progress,
meta,
};
}, [display, mediaPlaying, progress, meta]);
const changeEpisode = useCallback( const changeEpisode = useCallback(
(change: number) => { (change: number) => {
const nextEp = meta?.episodes?.find( const nextEp = data.meta?.episodes?.find(
(v) => v.number === (meta?.episode?.number ?? 0) + change, (v) => v.number === (data.meta?.episode?.number ?? 0) + change,
); );
if (!meta || !nextEp) return; if (!data.meta || !nextEp) return;
const metaCopy = { ...meta }; const metaCopy = { ...data.meta };
metaCopy.episode = nextEp; metaCopy.episode = nextEp;
setShouldStartFromBeginning(true); setShouldStartFromBeginning(true);
setDirectMeta(metaCopy); setDirectMeta(metaCopy);
}, },
[setDirectMeta, meta, setShouldStartFromBeginning], [data.meta, setDirectMeta, setShouldStartFromBeginning],
); );
const updatePositionState = useCallback((position: number) => { const updatePositionState = useCallback(
// If the updated position needs to be buffered, queue an update (position: number) => {
if (position > dataRef.current.progress.buffered) { // If the updated position needs to be buffered, queue an update
shouldUpdatePositionState.current = true; if (position > data.progress.buffered) {
} shouldUpdatePositionState.current = true;
if (position > dataRef.current.progress.duration) return; }
if (position > data.progress.duration) return;
lastPlaybackPosition.current = dataRef.current.progress.time; lastPlaybackPosition.current = data.progress.time;
navigator.mediaSession.setPositionState({ navigator.mediaSession.setPositionState({
duration: dataRef.current.progress.duration, duration: data.progress.duration,
playbackRate: dataRef.current.mediaPlaying.playbackRate, playbackRate: data.mediaPlaying.playbackRate,
position, position,
}); });
}, []); },
[
data.mediaPlaying.playbackRate,
data.progress.buffered,
data.progress.duration,
data.progress.time,
],
);
useEffect(() => { useEffect(() => {
if (!("mediaSession" in navigator)) return; if (!("mediaSession" in navigator)) return;
// If the media is paused, update the navigator // If the media is paused, update the navigator
if (mediaPlaying.isPaused) { if (data.mediaPlaying.isPaused) {
navigator.mediaSession.playbackState = "paused"; navigator.mediaSession.playbackState = "paused";
} else { } else {
navigator.mediaSession.playbackState = "playing"; navigator.mediaSession.playbackState = "playing";
} }
}, [mediaPlaying.isPaused]); }, [data.mediaPlaying.isPaused]);
useEffect(() => { useEffect(() => {
if (!("mediaSession" in navigator)) return; if (!("mediaSession" in navigator)) return;
updatePositionState(dataRef.current.progress.time); updatePositionState(data.progress.time);
}, [mediaPlaying.playbackRate, updatePositionState]); }, [data.progress.time, data.mediaPlaying.playbackRate, updatePositionState]);
useEffect(() => { useEffect(() => {
if (!("mediaSession" in navigator)) return; if (!("mediaSession" in navigator)) return;
// If not already updating the position state, and the media is loading, queue an update // If not already updating the position state, and the media is loading, queue an update
if ( if (!shouldUpdatePositionState.current && data.mediaPlaying.isLoading) {
!shouldUpdatePositionState.current &&
dataRef.current.mediaPlaying.isLoading
) {
shouldUpdatePositionState.current = true; shouldUpdatePositionState.current = true;
} }
// If the user has skipped (or MediaSession desynced) by more than 5 seconds, queue an update // If the user has skipped (or MediaSession desynced) by more than 5 seconds, queue an update
if ( if (
Math.abs(progress.time - lastPlaybackPosition.current) >= 5 && Math.abs(data.progress.time - lastPlaybackPosition.current) >= 5 &&
!dataRef.current.mediaPlaying.isLoading && !data.mediaPlaying.isLoading &&
!shouldUpdatePositionState.current !shouldUpdatePositionState.current
) { ) {
shouldUpdatePositionState.current = true; shouldUpdatePositionState.current = true;
} }
// If not loading and the position state is queued, update it // If not loading and the position state is queued, update it
if ( if (shouldUpdatePositionState.current && !data.mediaPlaying.isLoading) {
shouldUpdatePositionState.current &&
!dataRef.current.mediaPlaying.isLoading
) {
shouldUpdatePositionState.current = false; shouldUpdatePositionState.current = false;
updatePositionState(progress.time); updatePositionState(data.progress.time);
} }
lastPlaybackPosition.current = progress.time; lastPlaybackPosition.current = data.progress.time;
}, [updatePositionState, progress.time]); }, [updatePositionState, data.progress.time, data.mediaPlaying.isLoading]);
useEffect(() => { useEffect(() => {
if ( if (
!("mediaSession" in navigator) || !("mediaSession" in navigator) ||
dataRef.current.mediaPlaying.hasPlayedOnce || (!data.mediaPlaying.isLoading &&
dataRef.current.progress.duration === 0 data.mediaPlaying.isPlaying &&
!data.display)
) )
return; return;
const title = meta?.episode?.title ?? meta?.title ?? ""; const title = data.meta?.episode?.title ?? data.meta?.title ?? "";
const artist = meta?.type === "movie" ? undefined : meta?.title ?? ""; const artist =
data.meta?.type === "movie" ? undefined : data.meta?.title ?? "";
navigator.mediaSession.metadata = new MediaMetadata({ navigator.mediaSession.metadata = new MediaMetadata({
title, title,
artist, artist,
artwork: [ artwork: [
{ {
src: meta?.poster ?? "", src: data.meta?.poster ?? "",
sizes: "342x513", sizes: "342x513",
type: "image/png", type: "image/png",
}, },
@ -135,26 +121,26 @@ export function MediaSession() {
}); });
navigator.mediaSession.setActionHandler("play", () => { navigator.mediaSession.setActionHandler("play", () => {
if (dataRef.current.mediaPlaying.isLoading) return; if (data.mediaPlaying.isLoading) return;
dataRef.current.display?.play(); data.display?.play();
updatePositionState(dataRef.current.progress.time); updatePositionState(data.progress.time);
}); });
navigator.mediaSession.setActionHandler("pause", () => { navigator.mediaSession.setActionHandler("pause", () => {
if (dataRef.current.mediaPlaying.isLoading) return; if (data.mediaPlaying.isLoading) return;
dataRef.current.display?.pause(); data.display?.pause();
updatePositionState(dataRef.current.progress.time); updatePositionState(data.progress.time);
}); });
navigator.mediaSession.setActionHandler("seekto", (e) => { navigator.mediaSession.setActionHandler("seekto", (e) => {
if (!e.seekTime) return; if (!e.seekTime) return;
dataRef.current.display?.setTime(e.seekTime); data.display?.setTime(e.seekTime);
updatePositionState(e.seekTime); updatePositionState(e.seekTime);
}); });
if ((dataRef.current.meta?.episode?.number ?? 1) !== 1) { if ((data.meta?.episode?.number ?? 1) !== 1) {
navigator.mediaSession.setActionHandler("previoustrack", () => { navigator.mediaSession.setActionHandler("previoustrack", () => {
changeEpisode(-1); changeEpisode(-1);
}); });
@ -162,16 +148,28 @@ export function MediaSession() {
navigator.mediaSession.setActionHandler("previoustrack", null); navigator.mediaSession.setActionHandler("previoustrack", null);
} }
if ( if (data.meta?.episode?.number !== data.meta?.episodes?.length) {
dataRef.current.meta?.episode?.number !==
dataRef.current.meta?.episodes?.length
) {
navigator.mediaSession.setActionHandler("nexttrack", () => { navigator.mediaSession.setActionHandler("nexttrack", () => {
changeEpisode(1); changeEpisode(1);
}); });
} else { } else {
navigator.mediaSession.setActionHandler("nexttrack", null); navigator.mediaSession.setActionHandler("nexttrack", null);
} }
}, [changeEpisode, updatePositionState, meta]); }, [
changeEpisode,
updatePositionState,
data.mediaPlaying.hasPlayedOnce,
data.mediaPlaying.isLoading,
data.progress.duration,
data.progress.time,
data.meta?.episode?.number,
data.meta?.episodes?.length,
data.display,
data.mediaPlaying,
data.meta?.episode?.title,
data.meta?.title,
data.meta?.type,
data.meta?.poster,
]);
return null; return null;
} }