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.

update atoms settings style

Pas c0b97d84 5eb15d8f

+94 -43
+5 -2
src/assets/locales/en.json
··· 498 498 "playbackItem": "Playback settings", 499 499 "audioItem": "Audio", 500 500 "qualityItem": "Quality", 501 - "sourceItem": "Video sources", 502 - "subtitleItem": "Subtitle settings", 501 + "sourceItem": "Source", 502 + "subtitleItem": "Subtitles", 503 503 "videoSection": "Video settings" 504 504 }, 505 505 "sources": { ··· 544 544 "watchpartyItem": "Watch Party", 545 545 "notice": "Legacy Watch Party might not be available for some sources", 546 546 "legacyWatchparty": "Use legacy Watch Party" 547 + }, 548 + "audio": { 549 + "default": "Default" 547 550 } 548 551 }, 549 552 "metadata": {
+4 -2
src/components/overlays/OverlayRouter.tsx
··· 77 77 style={dimensions} 78 78 className="overflow-hidden relative z-10 max-h-full" 79 79 > 80 - <Flare.Base className="group w-full bg-video-context-border h-full rounded-2xl transition-colors duration-100 text-video-context-type-main"> 80 + <Flare.Base className="group w-full bg-video-context-border bg-opacity-50 backdrop-blur-md h-full rounded-2xl transition-colors duration-100 text-video-context-type-main"> 81 81 <Flare.Light 82 82 flareSize={400} 83 83 cssColorVar="--colors-video-context-light" 84 84 backgroundClass="bg-video-context-background duration-100" 85 - className="rounded-2xl opacity-100" 85 + className="rounded-2xl opacity-80" 86 + gradientOpacity={0.3} 87 + gradientSpread={60} 86 88 /> 87 89 <Flare.Child className="pointer-events-auto relative transition-transform duration-100 h-full"> 88 90 {props.children}
+2 -2
src/components/player/atoms/settings/PlaybackSettingsView.tsx
··· 12 12 onClick: (v: any) => void; 13 13 }) { 14 14 return ( 15 - <div className="flex items-center bg-video-context-buttons-list p-1 rounded-lg"> 15 + <div className="flex items-center bg-video-context-light/10 p-1 rounded-lg"> 16 16 {props.options.map((option) => { 17 17 return ( 18 18 <button ··· 20 20 className={classNames( 21 21 "w-full px-2 py-1 rounded-md tabbable", 22 22 props.selected === option 23 - ? "bg-video-context-buttons-active text-white" 23 + ? "bg-video-context-light/20 text-white" 24 24 : null, 25 25 )} 26 26 onClick={() => props.onClick(option)}
+39 -22
src/components/player/atoms/settings/SettingsMenu.tsx
··· 48 48 49 49 return ( 50 50 <Menu.Card> 51 - <Menu.SectionTitle> 52 - {t("player.menus.settings.videoSection")} 53 - </Menu.SectionTitle> 54 - <Menu.Section> 51 + <Menu.Section grid> 55 52 <Menu.ChevronLink 53 + box 56 54 onClick={() => router.navigate("/quality")} 57 55 rightText={currentQuality ? qualityToString(currentQuality) : ""} 58 56 > 59 57 {t("player.menus.settings.qualityItem")} 58 + <span className="text-type-secondary"> 59 + {currentQuality ? qualityToString(currentQuality) : ""} 60 + </span> 60 61 </Menu.ChevronLink> 61 - {currentAudioTrack && ( 62 + <Menu.ChevronLink 63 + box 64 + onClick={() => router.navigate("/source")} 65 + rightText={sourceName} 66 + > 67 + {t("player.menus.settings.sourceItem")} 68 + <span className="text-type-secondary">{sourceName}</span> 69 + </Menu.ChevronLink> 70 + <Menu.ChevronLink 71 + box 72 + onClick={() => router.navigate("/captions")} 73 + rightText={sourceName} 74 + > 75 + {t("player.menus.settings.subtitleItem")} 76 + <span className="text-type-secondary"> 77 + {selectedLanguagePretty ?? t("player.menus.subtitles.offChoice")} 78 + </span> 79 + </Menu.ChevronLink> 80 + {currentAudioTrack ? ( 62 81 <Menu.ChevronLink 82 + box 63 83 onClick={() => router.navigate("/audio")} 64 84 rightText={selectedAudioLanguagePretty ?? undefined} 65 85 > 66 86 {t("player.menus.settings.audioItem")} 67 87 </Menu.ChevronLink> 88 + ) : ( 89 + <Menu.ChevronLink 90 + box 91 + onClick={() => router.navigate("/audio")} 92 + disabled 93 + > 94 + {t("player.menus.settings.audioItem")} 95 + <span className="text-type-secondary"> 96 + {t("player.menus.audio.default")} 97 + </span> 98 + </Menu.ChevronLink> 68 99 )} 69 - 70 - <Menu.ChevronLink 71 - onClick={() => router.navigate("/source")} 72 - rightText={sourceName} 73 - > 74 - {t("player.menus.settings.sourceItem")} 75 - </Menu.ChevronLink> 100 + </Menu.Section> 101 + <Menu.Section> 76 102 <Menu.Link 77 103 clickable 78 104 onClick={() => ··· 94 120 {t("player.menus.watchparty.watchpartyItem")} (Beta) 95 121 </Menu.Link> 96 122 </Menu.Section> 97 - 98 - <Menu.SectionTitle> 99 - {t("player.menus.settings.experienceSection")} 100 - </Menu.SectionTitle> 123 + <Menu.SectionTitle /> 101 124 <Menu.Section> 102 125 <Menu.Link 103 126 rightSide={ ··· 109 132 > 110 133 {t("player.menus.settings.enableSubtitles")} 111 134 </Menu.Link> 112 - <Menu.ChevronLink 113 - onClick={() => router.navigate("/captions")} 114 - rightText={selectedLanguagePretty ?? undefined} 115 - > 116 - {t("player.menus.settings.subtitleItem")} 117 - </Menu.ChevronLink> 118 135 <Menu.ChevronLink onClick={() => router.navigate("/playback")}> 119 136 {t("player.menus.settings.playbackItem")} 120 137 </Menu.ChevronLink>
+1 -1
src/components/player/internals/ContextMenu/Cards.tsx
··· 1 1 export function Card(props: { children: React.ReactNode }) { 2 2 return ( 3 3 <div className="h-full grid grid-rows-[1fr]"> 4 - <div className="px-6 h-full flex flex-col justify-start overflow-y-auto overflow-x-hidden pb-4"> 4 + <div className="px-6 h-full flex flex-col justify-start overflow-y-auto overflow-x-hidden pb-4 scrollbar-none"> 5 5 {props.children} 6 6 </div> 7 7 </div>
+27 -9
src/components/player/internals/ContextMenu/Links.tsx
··· 17 17 export function LinkTitle(props: { 18 18 children: React.ReactNode; 19 19 textClass?: string; 20 + box?: boolean; 20 21 }) { 21 22 return ( 22 23 <span 23 24 className={classNames([ 24 25 "font-medium text-left", 26 + props.box ? "flex flex-col items-center justify-center h-full" : "", 25 27 props.textClass || "text-video-context-type-main", 26 28 ])} 27 29 > ··· 78 80 onClick?: () => void; 79 81 children?: ReactNode; 80 82 className?: string; 83 + box?: boolean; 84 + disabled?: boolean; 81 85 }) { 82 - const classes = classNames("flex py-2 px-3 rounded-lg w-full -ml-3", { 83 - "cursor-default": !props.clickable, 84 - "hover:bg-video-context-hoverColor hover:bg-opacity-50 cursor-pointer tabbable": 85 - props.clickable, 86 - "bg-video-context-hoverColor bg-opacity-50": props.active, 87 - }); 86 + const classes = classNames( 87 + "flex py-2 transition-colors duration-100 rounded-lg", 88 + props.box ? "bg-video-context-light/10 h-20" : "", 89 + { 90 + "cursor-default": !props.clickable, 91 + "hover:bg-video-context-light hover:bg-opacity-20 cursor-pointer tabbable": 92 + props.clickable, 93 + "bg-video-context-light bg-opacity-20": props.active, 94 + "-ml-3 px-3 w-full": !props.box, 95 + "opacity-50 pointer-events-none": props.disabled, 96 + }, 97 + ); 88 98 const styles = { width: "calc(100% + 1.5rem)" }; 89 99 90 100 const content = ( ··· 110 120 <button 111 121 type="button" 112 122 className={classes} 113 - style={styles} 123 + style={props.box ? {} : styles} 114 124 onClick={props.onClick} 115 125 data-active-link={props.active ? true : undefined} 126 + disabled={props.disabled} 116 127 > 117 128 {content} 118 129 </button> ··· 124 135 onClick?: () => void; 125 136 children?: ReactNode; 126 137 active?: boolean; 138 + box?: boolean; 139 + disabled?: boolean; 127 140 }) { 128 141 const rightContent = <Chevron>{props.rightText}</Chevron>; 129 142 return ( ··· 131 144 onClick={props.onClick} 132 145 active={props.active} 133 146 clickable 134 - rightSide={rightContent} 147 + rightSide={props.box ? null : rightContent} 148 + className={props.box ? "flex flex-col items-center justify-center" : ""} 149 + box={props.box} 150 + disabled={props.disabled} 135 151 > 136 - <LinkTitle>{props.children}</LinkTitle> 152 + <LinkTitle box={props.box}>{props.children}</LinkTitle> 137 153 </Link> 138 154 ); 139 155 } ··· 145 161 children?: ReactNode; 146 162 disabled?: boolean; 147 163 error?: ReactNode; 164 + box?: boolean; 148 165 }) { 149 166 let rightContent; 150 167 if (props.selected) { ··· 168 185 onClick={props.onClick} 169 186 clickable={!props.disabled} 170 187 rightSide={rightContent} 188 + box={props.box} 171 189 > 172 190 <LinkTitle 173 191 textClass={classNames({
+10 -3
src/components/player/internals/ContextMenu/Sections.tsx
··· 2 2 import { useEffect, useRef } from "react"; 3 3 4 4 export function SectionTitle(props: { 5 - children: React.ReactNode; 5 + children?: React.ReactNode; 6 6 className?: string; 7 7 }) { 8 8 return ( 9 9 <h3 10 10 className={classNames( 11 - "uppercase font-bold text-video-context-type-secondary text-xs pt-8 pl-1 pb-2.5 border-b border-video-context-border", 11 + "uppercase font-bold text-type-secondary text-xs pl-1 pb-2.5 border-b border-type-secondary/40", 12 + props.children ? "pt-8" : "pt-4", 12 13 props.className, 13 14 )} 14 15 > ··· 20 21 export function Section(props: { 21 22 children: React.ReactNode; 22 23 className?: string; 24 + grid?: boolean; 23 25 }) { 24 26 return ( 25 - <div className={classNames("pt-4 space-y-1", props.className)}> 27 + <div 28 + className={classNames( 29 + props.grid ? "grid grid-cols-2 gap-3 pt-6" : "pt-4 space-y-1", 30 + props.className, 31 + )} 32 + > 26 33 {props.children} 27 34 </div> 28 35 );
+6 -2
src/components/utils/Flare.tsx
··· 8 8 flareSize?: number; 9 9 cssColorVar?: string; 10 10 enabled?: boolean; 11 + gradientOpacity?: number; 12 + gradientSpread?: number; 11 13 } 12 14 13 15 const SIZE_DEFAULT = 200; ··· 38 40 const outerRef = useRef<HTMLDivElement>(null); 39 41 const size = props.flareSize ?? SIZE_DEFAULT; 40 42 const cssVar = props.cssColorVar ?? CSS_VAR_DEFAULT; 43 + const opacity = props.gradientOpacity ?? 1; 44 + const spread = props.gradientSpread ?? 70; 41 45 42 46 useEffect(() => { 43 47 function mouseMove(e: MouseEvent) { ··· 69 73 }, 70 74 )} 71 75 style={{ 72 - backgroundImage: `radial-gradient(circle at center, rgba(var(${cssVar}) / 1), rgba(var(${cssVar}) / 0) 70%)`, 76 + backgroundImage: `radial-gradient(circle at center, rgba(var(${cssVar}) / ${opacity}), rgba(var(${cssVar}) / 0) ${spread}%)`, 73 77 backgroundPosition: `var(--bg-x) var(--bg-y)`, 74 78 backgroundRepeat: "no-repeat", 75 79 backgroundSize: `${size.toFixed(0)}px ${size.toFixed(0)}px`, ··· 85 89 <div 86 90 className="absolute inset-0 opacity-10" 87 91 style={{ 88 - background: `radial-gradient(circle at center, rgba(var(${cssVar}) / 1), rgba(var(${cssVar}) / 0) 70%)`, 92 + backgroundImage: `radial-gradient(circle at center, rgba(var(${cssVar}) / ${opacity}), rgba(var(${cssVar}) / 0) ${spread}%)`, 89 93 backgroundPosition: `var(--bg-x) var(--bg-y)`, 90 94 backgroundRepeat: "no-repeat", 91 95 backgroundSize: `${size.toFixed(0)}px ${size.toFixed(0)}px`,