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.

scroll to active subtitle and add random button

Pas 6242d787 ee317b80

+56 -6
+51 -2
src/components/player/atoms/settings/LanguageSubtitlesView.tsx
··· 1 - import { useMemo, useState } from "react"; 1 + import { useEffect, useMemo, useState } from "react"; 2 2 import { useTranslation } from "react-i18next"; 3 3 import { useAsyncFn } from "react-use"; 4 4 5 5 import { FlagIcon } from "@/components/FlagIcon"; 6 + import { Icon, Icons } from "@/components/Icon"; 6 7 import { useCaptions } from "@/components/player/hooks/useCaptions"; 7 8 import { Menu } from "@/components/player/internals/ContextMenu"; 8 9 import { useOverlayRouter } from "@/hooks/useOverlayRouter"; ··· 30 31 const [currentlyDownloading, setCurrentlyDownloading] = useState< 31 32 string | null 32 33 >(null); 34 + const [scrollTrigger, setScrollTrigger] = useState(0); 33 35 const captionList = usePlayerStore((s) => s.captionList); 36 + 37 + // Trigger scroll when selected caption changes 38 + useEffect(() => { 39 + if (selectedCaptionId) { 40 + setScrollTrigger((prev) => prev + 1); 41 + } 42 + }, [selectedCaptionId]); 43 + 44 + // Manual scroll function with smooth behavior 45 + const scrollToActiveCaption = () => { 46 + const active = document.querySelector("[data-active-link]"); 47 + if (!active) return; 48 + 49 + active.scrollIntoView({ 50 + behavior: "smooth", 51 + block: "center", 52 + }); 53 + }; 54 + 34 55 const getHlsCaptionList = usePlayerStore((s) => s.display?.getCaptionList); 35 56 const isLoadingExternalSubtitles = usePlayerStore( 36 57 (s) => s.isLoadingExternalSubtitles, ··· 58 79 [selectCaptionById, setCurrentlyDownloading], 59 80 ); 60 81 82 + // Random subtitle selection 83 + const handleRandomSelect = async () => { 84 + if (languageCaptions.length === 0) return; 85 + 86 + const randomIndex = Math.floor(Math.random() * languageCaptions.length); 87 + const randomCaption = languageCaptions[randomIndex]; 88 + 89 + await startDownload(randomCaption.id); 90 + 91 + // Scroll to the newly selected caption after a brief delay to ensure DOM updates 92 + setTimeout(() => scrollToActiveCaption(), 100); 93 + }; 94 + 61 95 // Render subtitle option 62 96 const renderSubtitleOption = (v: CaptionListItem) => { 63 97 const handleDoubleClick = async () => { ··· 119 153 onClick={() => 120 154 router.navigate(overlayBackLink ? "/captionsOverlay" : "/captions") 121 155 } 156 + rightSide={ 157 + languageCaptions.length > 0 && ( 158 + <button 159 + type="button" 160 + onClick={handleRandomSelect} 161 + className="-mr-2 -my-1 px-2 p-[0.4em] rounded tabbable hover:bg-video-context-light hover:bg-opacity-10" 162 + title="Pick random subtitle" 163 + > 164 + <Icon icon={Icons.REPEAT} className="text-lg" /> 165 + </button> 166 + ) 167 + } 122 168 > 123 169 <span className="flex items-center"> 124 170 <FlagIcon langCode={language} /> ··· 126 172 </span> 127 173 </Menu.BackLink> 128 174 129 - <Menu.ScrollToActiveSection className="!pt-1 mt-2 pb-3"> 175 + <Menu.ScrollToActiveSection 176 + className="!pt-1 mt-2 pb-3" 177 + loaded={scrollTrigger > 0} 178 + > 130 179 {languageCaptions.length > 0 ? ( 131 180 languageCaptions.map(renderSubtitleOption) 132 181 ) : (
+5 -4
src/components/player/internals/ContextMenu/Sections.tsx
··· 52 52 53 53 const activeYPos = activeLinkRect.top - boxRect.top; 54 54 55 - scrollingContainer.current?.scrollTo( 56 - 0, 57 - activeYPos - boxRect.height / 2 + activeLinkRect.height / 2, 58 - ); 55 + scrollingContainer.current?.scrollTo({ 56 + top: activeYPos - boxRect.height / 2 + activeLinkRect.height / 2, 57 + left: 0, 58 + behavior: "smooth", 59 + }); 59 60 }, [props.loaded]); 60 61 61 62 return (