update atoms settings style

This commit is contained in:
Pas 2025-06-04 19:05:45 -06:00
parent 5eb15d8fb6
commit c0b97d848c
8 changed files with 94 additions and 43 deletions

View file

@ -498,8 +498,8 @@
"playbackItem": "Playback settings",
"audioItem": "Audio",
"qualityItem": "Quality",
"sourceItem": "Video sources",
"subtitleItem": "Subtitle settings",
"sourceItem": "Source",
"subtitleItem": "Subtitles",
"videoSection": "Video settings"
},
"sources": {
@ -544,6 +544,9 @@
"watchpartyItem": "Watch Party",
"notice": "Legacy Watch Party might not be available for some sources",
"legacyWatchparty": "Use legacy Watch Party"
},
"audio": {
"default": "Default"
}
},
"metadata": {

View file

@ -77,12 +77,14 @@ function RouterBase(props: { id: string; children: ReactNode }) {
style={dimensions}
className="overflow-hidden relative z-10 max-h-full"
>
<Flare.Base className="group w-full bg-video-context-border h-full rounded-2xl transition-colors duration-100 text-video-context-type-main">
<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">
<Flare.Light
flareSize={400}
cssColorVar="--colors-video-context-light"
backgroundClass="bg-video-context-background duration-100"
className="rounded-2xl opacity-100"
className="rounded-2xl opacity-80"
gradientOpacity={0.3}
gradientSpread={60}
/>
<Flare.Child className="pointer-events-auto relative transition-transform duration-100 h-full">
{props.children}

View file

@ -12,7 +12,7 @@ function ButtonList(props: {
onClick: (v: any) => void;
}) {
return (
<div className="flex items-center bg-video-context-buttons-list p-1 rounded-lg">
<div className="flex items-center bg-video-context-light/10 p-1 rounded-lg">
{props.options.map((option) => {
return (
<button
@ -20,7 +20,7 @@ function ButtonList(props: {
className={classNames(
"w-full px-2 py-1 rounded-md tabbable",
props.selected === option
? "bg-video-context-buttons-active text-white"
? "bg-video-context-light/20 text-white"
: null,
)}
onClick={() => props.onClick(option)}

View file

@ -48,31 +48,57 @@ export function SettingsMenu({ id }: { id: string }) {
return (
<Menu.Card>
<Menu.SectionTitle>
{t("player.menus.settings.videoSection")}
</Menu.SectionTitle>
<Menu.Section>
<Menu.Section grid>
<Menu.ChevronLink
box
onClick={() => router.navigate("/quality")}
rightText={currentQuality ? qualityToString(currentQuality) : ""}
>
{t("player.menus.settings.qualityItem")}
<span className="text-type-secondary">
{currentQuality ? qualityToString(currentQuality) : ""}
</span>
</Menu.ChevronLink>
{currentAudioTrack && (
<Menu.ChevronLink
box
onClick={() => router.navigate("/source")}
rightText={sourceName}
>
{t("player.menus.settings.sourceItem")}
<span className="text-type-secondary">{sourceName}</span>
</Menu.ChevronLink>
<Menu.ChevronLink
box
onClick={() => router.navigate("/captions")}
rightText={sourceName}
>
{t("player.menus.settings.subtitleItem")}
<span className="text-type-secondary">
{selectedLanguagePretty ?? t("player.menus.subtitles.offChoice")}
</span>
</Menu.ChevronLink>
{currentAudioTrack ? (
<Menu.ChevronLink
box
onClick={() => router.navigate("/audio")}
rightText={selectedAudioLanguagePretty ?? undefined}
>
{t("player.menus.settings.audioItem")}
</Menu.ChevronLink>
) : (
<Menu.ChevronLink
box
onClick={() => router.navigate("/audio")}
disabled
>
{t("player.menus.settings.audioItem")}
<span className="text-type-secondary">
{t("player.menus.audio.default")}
</span>
</Menu.ChevronLink>
)}
<Menu.ChevronLink
onClick={() => router.navigate("/source")}
rightText={sourceName}
>
{t("player.menus.settings.sourceItem")}
</Menu.ChevronLink>
</Menu.Section>
<Menu.Section>
<Menu.Link
clickable
onClick={() =>
@ -94,10 +120,7 @@ export function SettingsMenu({ id }: { id: string }) {
{t("player.menus.watchparty.watchpartyItem")} (Beta)
</Menu.Link>
</Menu.Section>
<Menu.SectionTitle>
{t("player.menus.settings.experienceSection")}
</Menu.SectionTitle>
<Menu.SectionTitle />
<Menu.Section>
<Menu.Link
rightSide={
@ -109,12 +132,6 @@ export function SettingsMenu({ id }: { id: string }) {
>
{t("player.menus.settings.enableSubtitles")}
</Menu.Link>
<Menu.ChevronLink
onClick={() => router.navigate("/captions")}
rightText={selectedLanguagePretty ?? undefined}
>
{t("player.menus.settings.subtitleItem")}
</Menu.ChevronLink>
<Menu.ChevronLink onClick={() => router.navigate("/playback")}>
{t("player.menus.settings.playbackItem")}
</Menu.ChevronLink>

View file

@ -1,7 +1,7 @@
export function Card(props: { children: React.ReactNode }) {
return (
<div className="h-full grid grid-rows-[1fr]">
<div className="px-6 h-full flex flex-col justify-start overflow-y-auto overflow-x-hidden pb-4">
<div className="px-6 h-full flex flex-col justify-start overflow-y-auto overflow-x-hidden pb-4 scrollbar-none">
{props.children}
</div>
</div>

View file

@ -17,11 +17,13 @@ export function Chevron(props: { children?: React.ReactNode }) {
export function LinkTitle(props: {
children: React.ReactNode;
textClass?: string;
box?: boolean;
}) {
return (
<span
className={classNames([
"font-medium text-left",
props.box ? "flex flex-col items-center justify-center h-full" : "",
props.textClass || "text-video-context-type-main",
])}
>
@ -78,13 +80,21 @@ export function Link(props: {
onClick?: () => void;
children?: ReactNode;
className?: string;
box?: boolean;
disabled?: boolean;
}) {
const classes = classNames("flex py-2 px-3 rounded-lg w-full -ml-3", {
"cursor-default": !props.clickable,
"hover:bg-video-context-hoverColor hover:bg-opacity-50 cursor-pointer tabbable":
props.clickable,
"bg-video-context-hoverColor bg-opacity-50": props.active,
});
const classes = classNames(
"flex py-2 transition-colors duration-100 rounded-lg",
props.box ? "bg-video-context-light/10 h-20" : "",
{
"cursor-default": !props.clickable,
"hover:bg-video-context-light hover:bg-opacity-20 cursor-pointer tabbable":
props.clickable,
"bg-video-context-light bg-opacity-20": props.active,
"-ml-3 px-3 w-full": !props.box,
"opacity-50 pointer-events-none": props.disabled,
},
);
const styles = { width: "calc(100% + 1.5rem)" };
const content = (
@ -110,9 +120,10 @@ export function Link(props: {
<button
type="button"
className={classes}
style={styles}
style={props.box ? {} : styles}
onClick={props.onClick}
data-active-link={props.active ? true : undefined}
disabled={props.disabled}
>
{content}
</button>
@ -124,6 +135,8 @@ export function ChevronLink(props: {
onClick?: () => void;
children?: ReactNode;
active?: boolean;
box?: boolean;
disabled?: boolean;
}) {
const rightContent = <Chevron>{props.rightText}</Chevron>;
return (
@ -131,9 +144,12 @@ export function ChevronLink(props: {
onClick={props.onClick}
active={props.active}
clickable
rightSide={rightContent}
rightSide={props.box ? null : rightContent}
className={props.box ? "flex flex-col items-center justify-center" : ""}
box={props.box}
disabled={props.disabled}
>
<LinkTitle>{props.children}</LinkTitle>
<LinkTitle box={props.box}>{props.children}</LinkTitle>
</Link>
);
}
@ -145,6 +161,7 @@ export function SelectableLink(props: {
children?: ReactNode;
disabled?: boolean;
error?: ReactNode;
box?: boolean;
}) {
let rightContent;
if (props.selected) {
@ -168,6 +185,7 @@ export function SelectableLink(props: {
onClick={props.onClick}
clickable={!props.disabled}
rightSide={rightContent}
box={props.box}
>
<LinkTitle
textClass={classNames({

View file

@ -2,13 +2,14 @@ import classNames from "classnames";
import { useEffect, useRef } from "react";
export function SectionTitle(props: {
children: React.ReactNode;
children?: React.ReactNode;
className?: string;
}) {
return (
<h3
className={classNames(
"uppercase font-bold text-video-context-type-secondary text-xs pt-8 pl-1 pb-2.5 border-b border-video-context-border",
"uppercase font-bold text-type-secondary text-xs pl-1 pb-2.5 border-b border-type-secondary/40",
props.children ? "pt-8" : "pt-4",
props.className,
)}
>
@ -20,9 +21,15 @@ export function SectionTitle(props: {
export function Section(props: {
children: React.ReactNode;
className?: string;
grid?: boolean;
}) {
return (
<div className={classNames("pt-4 space-y-1", props.className)}>
<div
className={classNames(
props.grid ? "grid grid-cols-2 gap-3 pt-6" : "pt-4 space-y-1",
props.className,
)}
>
{props.children}
</div>
);

View file

@ -8,6 +8,8 @@ export interface FlareProps {
flareSize?: number;
cssColorVar?: string;
enabled?: boolean;
gradientOpacity?: number;
gradientSpread?: number;
}
const SIZE_DEFAULT = 200;
@ -38,6 +40,8 @@ function Light(props: FlareProps) {
const outerRef = useRef<HTMLDivElement>(null);
const size = props.flareSize ?? SIZE_DEFAULT;
const cssVar = props.cssColorVar ?? CSS_VAR_DEFAULT;
const opacity = props.gradientOpacity ?? 1;
const spread = props.gradientSpread ?? 70;
useEffect(() => {
function mouseMove(e: MouseEvent) {
@ -69,7 +73,7 @@ function Light(props: FlareProps) {
},
)}
style={{
backgroundImage: `radial-gradient(circle at center, rgba(var(${cssVar}) / 1), rgba(var(${cssVar}) / 0) 70%)`,
backgroundImage: `radial-gradient(circle at center, rgba(var(${cssVar}) / ${opacity}), rgba(var(${cssVar}) / 0) ${spread}%)`,
backgroundPosition: `var(--bg-x) var(--bg-y)`,
backgroundRepeat: "no-repeat",
backgroundSize: `${size.toFixed(0)}px ${size.toFixed(0)}px`,
@ -85,7 +89,7 @@ function Light(props: FlareProps) {
<div
className="absolute inset-0 opacity-10"
style={{
background: `radial-gradient(circle at center, rgba(var(${cssVar}) / 1), rgba(var(${cssVar}) / 0) 70%)`,
backgroundImage: `radial-gradient(circle at center, rgba(var(${cssVar}) / ${opacity}), rgba(var(${cssVar}) / 0) ${spread}%)`,
backgroundPosition: `var(--bg-x) var(--bg-y)`,
backgroundRepeat: "no-repeat",
backgroundSize: `${size.toFixed(0)}px ${size.toFixed(0)}px`,