mirror of
https://github.com/myronblair/kino-app
synced 2026-07-29 05:54:01 -05:00
Fix 8 code-review findings across transcode queue, requests, cleanup, music
- Episode transcode (single + bulk) now accepts storage_type=scan, matching stream_episode and the movie-transcode endpoint — Library-Scan-imported TV episodes can finally be transcoded, not just streamed. - retry_job now forwards content_type, fixing retry for failed/cancelled episode jobs (was silently treating them as movies and failing again). - cancel_job now updates the correct collection (movies vs episodes) based on content_type instead of always writing to db.movies. - approve_request atomically claims the request (pending -> approving) before contacting Radarr/Sonarr, so a double-click or two concurrent admins can't both add the same content; releases the claim back to pending on any failure so a fixable error can be retried. - Music enrichment's update_many now re-checks album_art_url is still empty, so it no longer clobbers art an admin manually set via PATCH. - Library Cleanup's dangling-refs scan now also checks episode_progress for rows referencing a deleted episode (previously only watchlist/ progress against movie_id were checked). - Settings now surfaces a failed bulk-TMDB-enrich run as an error instead of a false "Enrichment done" success summary. - Music player's isPlaying now syncs from the audio element's native play/pause events instead of only being set inside togglePlay/track- change, so it can't drift from actual playback state (buffering stalls, OS media-key pauses, etc).
This commit is contained in:
@@ -41,29 +41,36 @@ export const MusicPlayerProvider = ({ children }) => {
|
||||
const audio = audioRef.current;
|
||||
if (!current) { audio.pause(); return; }
|
||||
audio.src = getTrackStreamUrl(current);
|
||||
audio.play().then(() => setIsPlaying(true)).catch(() => setIsPlaying(false));
|
||||
audio.play().catch(() => {}); // isPlaying reflects reality via the native play/pause listeners below
|
||||
}, [current]);
|
||||
|
||||
// isPlaying always mirrors the audio element's own state, so it stays correct through anything
|
||||
// that changes playback outside togglePlay — a stall, an OS media-key pause, autoplay being blocked.
|
||||
useEffect(() => {
|
||||
const audio = audioRef.current;
|
||||
const onTime = () => setProgress({ position: audio.currentTime, duration: audio.duration || 0 });
|
||||
const onEnded = () => {
|
||||
if (index >= 0 && index < queue.length - 1) setIndex(index + 1);
|
||||
else setIsPlaying(false);
|
||||
};
|
||||
const onPlay = () => setIsPlaying(true);
|
||||
const onPause = () => setIsPlaying(false);
|
||||
audio.addEventListener("timeupdate", onTime);
|
||||
audio.addEventListener("ended", onEnded);
|
||||
audio.addEventListener("play", onPlay);
|
||||
audio.addEventListener("pause", onPause);
|
||||
return () => {
|
||||
audio.removeEventListener("timeupdate", onTime);
|
||||
audio.removeEventListener("ended", onEnded);
|
||||
audio.removeEventListener("play", onPlay);
|
||||
audio.removeEventListener("pause", onPause);
|
||||
};
|
||||
}, [index, queue]);
|
||||
|
||||
const togglePlay = useCallback(() => {
|
||||
const audio = audioRef.current;
|
||||
if (!current) return;
|
||||
if (audio.paused) audio.play().then(() => setIsPlaying(true));
|
||||
else { audio.pause(); setIsPlaying(false); }
|
||||
if (audio.paused) audio.play().catch(() => {});
|
||||
else audio.pause();
|
||||
}, [current]);
|
||||
|
||||
const next = useCallback(() => {
|
||||
|
||||
Reference in New Issue
Block a user