From cd02f6d7a3be25dc2a3eb6ee7d3898148328e90b Mon Sep 17 00:00:00 2001 From: Ashutosh Shinde Date: Sat, 6 Jan 2024 13:40:04 +0530 Subject: [PATCH] fixed #614 multiple captions of the same language all appeared as selected when selecting only one --- .../player/atoms/settings/CaptionsView.tsx | 23 ++++++++++--------- .../player/display/displayInterface.ts | 1 + src/components/player/hooks/useCaptions.ts | 19 +++++++++++++++ src/components/player/utils/captions.ts | 1 + src/stores/player/slices/source.ts | 2 ++ 5 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/components/player/atoms/settings/CaptionsView.tsx b/src/components/player/atoms/settings/CaptionsView.tsx index dc9a112f..3d89655d 100644 --- a/src/components/player/atoms/settings/CaptionsView.tsx +++ b/src/components/player/atoms/settings/CaptionsView.tsx @@ -75,6 +75,7 @@ function CustomCaptionOption() { setCaption({ language: "custom", srtData: converted, + id: "custom-caption", }); setCustomSubs(); }); @@ -115,22 +116,22 @@ function useSubtitleList(subs: CaptionListItem[], searchQuery: string) { export function CaptionsView({ id }: { id: string }) { const { t } = useTranslation(); const router = useOverlayRouter(id); - const lang = usePlayerStore((s) => s.caption.selected?.language); + const selectedCaptionId = usePlayerStore((s) => s.caption.selected?.id); const [currentlyDownloading, setCurrentlyDownloading] = useState< string | null >(null); - const { selectLanguage, disable } = useCaptions(); + const { selectCaptionById, disable } = useCaptions(); const captionList = usePlayerStore((s) => s.captionList); const [searchQuery, setSearchQuery] = useState(""); const subtitleList = useSubtitleList(captionList, searchQuery); const [downloadReq, startDownload] = useAsyncFn( - async (language: string) => { - setCurrentlyDownloading(language); - return selectLanguage(language); + async (captionId: string) => { + setCurrentlyDownloading(captionId); + return selectCaptionById(captionId); }, - [selectLanguage, setCurrentlyDownloading], + [selectCaptionById, setCurrentlyDownloading], ); const content = subtitleList.map((v, i) => { @@ -140,14 +141,14 @@ export function CaptionsView({ id }: { id: string }) { // eslint-disable-next-line react/no-array-index-key key={`${i}-${v.url}`} countryCode={v.language} - selected={lang === v.language} - loading={v.language === currentlyDownloading && downloadReq.loading} + selected={v.id === selectedCaptionId} + loading={v.id === currentlyDownloading && downloadReq.loading} error={ - v.language === currentlyDownloading && downloadReq.error + v.id === currentlyDownloading && downloadReq.error ? downloadReq.error.toString() : undefined } - onClick={() => startDownload(v.language)} + onClick={() => startDownload(v.id)} > {v.languageName} @@ -176,7 +177,7 @@ export function CaptionsView({ id }: { id: string }) { - disable()} selected={!lang}> + disable()} selected={!selectedCaptionId}> {t("player.menus.subtitles.offChoice")} diff --git a/src/components/player/display/displayInterface.ts b/src/components/player/display/displayInterface.ts index 604bdeca..8ba8480a 100644 --- a/src/components/player/display/displayInterface.ts +++ b/src/components/player/display/displayInterface.ts @@ -41,6 +41,7 @@ export interface DisplayMeta { } export interface DisplayCaption { + id: string; srtData: string; language: string; url?: string; diff --git a/src/components/player/hooks/useCaptions.ts b/src/components/player/hooks/useCaptions.ts index 9f96c41c..0f79aa51 100644 --- a/src/components/player/hooks/useCaptions.ts +++ b/src/components/player/hooks/useCaptions.ts @@ -14,12 +14,30 @@ export function useCaptions() { const lastSelectedLanguage = useSubtitleStore((s) => s.lastSelectedLanguage); const captionList = usePlayerStore((s) => s.captionList); + const selectCaptionById = useCallback( + async (captionId: string) => { + const caption = captionList.find((v) => v.id === captionId); + if (!caption) return; + const srtData = await downloadCaption(caption); + setCaption({ + id: caption.id, + language: caption.language, + srtData, + url: caption.url, + }); + resetSubtitleSpecificSettings(); + setLanguage(caption.language); + }, + [setLanguage, captionList, setCaption, resetSubtitleSpecificSettings], + ); + const selectLanguage = useCallback( async (language: string) => { const caption = captionList.find((v) => v.language === language); if (!caption) return; const srtData = await downloadCaption(caption); setCaption({ + id: caption.id, language: caption.language, srtData, url: caption.url, @@ -56,5 +74,6 @@ export function useCaptions() { selectLastUsedLanguage, toggleLastUsed, selectLastUsedLanguageIfEnabled, + selectCaptionById, }; } diff --git a/src/components/player/utils/captions.ts b/src/components/player/utils/captions.ts index abccee9f..bc2079db 100644 --- a/src/components/player/utils/captions.ts +++ b/src/components/player/utils/captions.ts @@ -80,6 +80,7 @@ export function convertProviderCaption( captions: RunOutput["stream"]["captions"], ): CaptionListItem[] { return captions.map((v) => ({ + id: v.id, language: v.language, url: v.url, needsProxy: v.hasCorsRestrictions, diff --git a/src/stores/player/slices/source.ts b/src/stores/player/slices/source.ts index 56e84f74..1e26abc2 100644 --- a/src/stores/player/slices/source.ts +++ b/src/stores/player/slices/source.ts @@ -42,12 +42,14 @@ export interface PlayerMeta { } export interface Caption { + id: string; language: string; url?: string; srtData: string; } export interface CaptionListItem { + id: string; language: string; url: string; needsProxy: boolean;