pstream is dead; long live pstream taciturnaxolotl.github.io/pstream-ng/
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

wait untill subtitles are loaded before picking one for reenabling

Pas 8d8d4659 a467dbbe

+51 -7
+7
src/components/player/hooks/useCaptions.ts
··· 24 24 const setIsOpenSubtitles = useSubtitleStore((s) => s.setIsOpenSubtitles); 25 25 26 26 const captionList = usePlayerStore((s) => s.captionList); 27 + const isLoadingExternalSubtitles = usePlayerStore( 28 + (s) => s.isLoadingExternalSubtitles, 29 + ); 27 30 const getHlsCaptionList = usePlayerStore((s) => s.display?.getCaptionList); 28 31 const source = usePlayerStore((s) => s.source); 29 32 const selectedCaption = usePlayerStore((s) => s.caption.selected); ··· 185 188 useEffect(() => { 186 189 if (!selectedCaption) return; 187 190 191 + // Don't clear while external subtitles are still loading - the caption might appear 192 + if (isLoadingExternalSubtitles) return; 193 + 188 194 // Skip validation for custom/pasted captions that aren't in the caption list 189 195 const isCustomCaption = 190 196 selectedCaption.id === "custom-caption" || ··· 226 232 setCaption, 227 233 selectCaptionById, 228 234 currentTranslateTask, 235 + isLoadingExternalSubtitles, 229 236 ]); 230 237 231 238 return {
+44 -7
src/components/player/hooks/useInitializePlayer.ts
··· 1 - import { useCallback, useEffect, useMemo, useRef } from "react"; 1 + import { useCallback, useEffect, useMemo, useRef, useState } from "react"; 2 2 3 3 import { usePlayerStore } from "@/stores/player/store"; 4 + import { useSubtitleStore } from "@/stores/subtitles"; 4 5 import { useVolumeStore } from "@/stores/volume"; 5 6 6 7 import { useCaptions } from "./useCaptions"; ··· 24 25 () => (source ? JSON.stringify(source) : null), 25 26 [source], 26 27 ); 28 + const captionList = usePlayerStore((s) => s.captionList); 29 + const isLoadingExternalSubtitles = usePlayerStore( 30 + (s) => s.isLoadingExternalSubtitles, 31 + ); 32 + const getHlsCaptionList = usePlayerStore((s) => s.display?.getCaptionList); 33 + const enabled = useSubtitleStore((s) => s.enabled); 27 34 const { selectLastUsedLanguageIfEnabled } = useCaptions(); 28 35 29 - // Only select subtitles on initial load, not when source changes 30 - const hasInitializedRef = useRef(false); 36 + // Trigger re-run when HLS tracks may have loaded (they load after manifest) 37 + const [hlsRetryTrigger, setHlsRetryTrigger] = useState(0); 38 + const hasRetriedForSourceRef = useRef<string | null>(null); 31 39 32 40 useEffect(() => { 33 - if (sourceIdentifier && !hasInitializedRef.current) { 34 - hasInitializedRef.current = true; 35 - selectLastUsedLanguageIfEnabled(); 41 + if (!sourceIdentifier || !enabled) return; 42 + 43 + // Wait for external subtitles to finish loading before selecting 44 + // This ensures we have the full caption list (provider + external) before picking 45 + if (isLoadingExternalSubtitles) return; 46 + 47 + const captions = 48 + captionList.length > 0 ? captionList : (getHlsCaptionList?.() ?? []); 49 + if (captions.length === 0) { 50 + // For HLS sources, tracks may load after manifest - retry once per source 51 + const alreadyRetried = 52 + hasRetriedForSourceRef.current === sourceIdentifier; 53 + if (source?.type === "hls" && !alreadyRetried) { 54 + hasRetriedForSourceRef.current = sourceIdentifier; 55 + const retryTimer = setTimeout( 56 + () => setHlsRetryTrigger((n) => n + 1), 57 + 2000, 58 + ); 59 + return () => clearTimeout(retryTimer); 60 + } 61 + return; 36 62 } 37 - }, [sourceIdentifier, selectLastUsedLanguageIfEnabled]); 63 + 64 + selectLastUsedLanguageIfEnabled(); 65 + }, [ 66 + sourceIdentifier, 67 + source?.type, 68 + enabled, 69 + isLoadingExternalSubtitles, 70 + captionList, 71 + getHlsCaptionList, 72 + selectLastUsedLanguageIfEnabled, 73 + hlsRetryTrigger, 74 + ]); 38 75 }