mirror of
https://github.com/p-stream/p-stream.git
synced 2026-04-21 05:52:25 +00:00
update atoms settings style
This commit is contained in:
parent
5eb15d8fb6
commit
c0b97d848c
8 changed files with 94 additions and 43 deletions
|
|
@ -498,8 +498,8 @@
|
||||||
"playbackItem": "Playback settings",
|
"playbackItem": "Playback settings",
|
||||||
"audioItem": "Audio",
|
"audioItem": "Audio",
|
||||||
"qualityItem": "Quality",
|
"qualityItem": "Quality",
|
||||||
"sourceItem": "Video sources",
|
"sourceItem": "Source",
|
||||||
"subtitleItem": "Subtitle settings",
|
"subtitleItem": "Subtitles",
|
||||||
"videoSection": "Video settings"
|
"videoSection": "Video settings"
|
||||||
},
|
},
|
||||||
"sources": {
|
"sources": {
|
||||||
|
|
@ -544,6 +544,9 @@
|
||||||
"watchpartyItem": "Watch Party",
|
"watchpartyItem": "Watch Party",
|
||||||
"notice": "Legacy Watch Party might not be available for some sources",
|
"notice": "Legacy Watch Party might not be available for some sources",
|
||||||
"legacyWatchparty": "Use legacy Watch Party"
|
"legacyWatchparty": "Use legacy Watch Party"
|
||||||
|
},
|
||||||
|
"audio": {
|
||||||
|
"default": "Default"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"metadata": {
|
"metadata": {
|
||||||
|
|
|
||||||
|
|
@ -77,12 +77,14 @@ function RouterBase(props: { id: string; children: ReactNode }) {
|
||||||
style={dimensions}
|
style={dimensions}
|
||||||
className="overflow-hidden relative z-10 max-h-full"
|
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
|
<Flare.Light
|
||||||
flareSize={400}
|
flareSize={400}
|
||||||
cssColorVar="--colors-video-context-light"
|
cssColorVar="--colors-video-context-light"
|
||||||
backgroundClass="bg-video-context-background duration-100"
|
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">
|
<Flare.Child className="pointer-events-auto relative transition-transform duration-100 h-full">
|
||||||
{props.children}
|
{props.children}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ function ButtonList(props: {
|
||||||
onClick: (v: any) => void;
|
onClick: (v: any) => void;
|
||||||
}) {
|
}) {
|
||||||
return (
|
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) => {
|
{props.options.map((option) => {
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
|
@ -20,7 +20,7 @@ function ButtonList(props: {
|
||||||
className={classNames(
|
className={classNames(
|
||||||
"w-full px-2 py-1 rounded-md tabbable",
|
"w-full px-2 py-1 rounded-md tabbable",
|
||||||
props.selected === option
|
props.selected === option
|
||||||
? "bg-video-context-buttons-active text-white"
|
? "bg-video-context-light/20 text-white"
|
||||||
: null,
|
: null,
|
||||||
)}
|
)}
|
||||||
onClick={() => props.onClick(option)}
|
onClick={() => props.onClick(option)}
|
||||||
|
|
|
||||||
|
|
@ -48,31 +48,57 @@ export function SettingsMenu({ id }: { id: string }) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu.Card>
|
<Menu.Card>
|
||||||
<Menu.SectionTitle>
|
<Menu.Section grid>
|
||||||
{t("player.menus.settings.videoSection")}
|
|
||||||
</Menu.SectionTitle>
|
|
||||||
<Menu.Section>
|
|
||||||
<Menu.ChevronLink
|
<Menu.ChevronLink
|
||||||
|
box
|
||||||
onClick={() => router.navigate("/quality")}
|
onClick={() => router.navigate("/quality")}
|
||||||
rightText={currentQuality ? qualityToString(currentQuality) : ""}
|
rightText={currentQuality ? qualityToString(currentQuality) : ""}
|
||||||
>
|
>
|
||||||
{t("player.menus.settings.qualityItem")}
|
{t("player.menus.settings.qualityItem")}
|
||||||
|
<span className="text-type-secondary">
|
||||||
|
{currentQuality ? qualityToString(currentQuality) : ""}
|
||||||
|
</span>
|
||||||
</Menu.ChevronLink>
|
</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
|
<Menu.ChevronLink
|
||||||
|
box
|
||||||
onClick={() => router.navigate("/audio")}
|
onClick={() => router.navigate("/audio")}
|
||||||
rightText={selectedAudioLanguagePretty ?? undefined}
|
rightText={selectedAudioLanguagePretty ?? undefined}
|
||||||
>
|
>
|
||||||
{t("player.menus.settings.audioItem")}
|
{t("player.menus.settings.audioItem")}
|
||||||
</Menu.ChevronLink>
|
</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.Section>
|
||||||
<Menu.ChevronLink
|
<Menu.Section>
|
||||||
onClick={() => router.navigate("/source")}
|
|
||||||
rightText={sourceName}
|
|
||||||
>
|
|
||||||
{t("player.menus.settings.sourceItem")}
|
|
||||||
</Menu.ChevronLink>
|
|
||||||
<Menu.Link
|
<Menu.Link
|
||||||
clickable
|
clickable
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
|
|
@ -94,10 +120,7 @@ export function SettingsMenu({ id }: { id: string }) {
|
||||||
{t("player.menus.watchparty.watchpartyItem")} (Beta)
|
{t("player.menus.watchparty.watchpartyItem")} (Beta)
|
||||||
</Menu.Link>
|
</Menu.Link>
|
||||||
</Menu.Section>
|
</Menu.Section>
|
||||||
|
<Menu.SectionTitle />
|
||||||
<Menu.SectionTitle>
|
|
||||||
{t("player.menus.settings.experienceSection")}
|
|
||||||
</Menu.SectionTitle>
|
|
||||||
<Menu.Section>
|
<Menu.Section>
|
||||||
<Menu.Link
|
<Menu.Link
|
||||||
rightSide={
|
rightSide={
|
||||||
|
|
@ -109,12 +132,6 @@ export function SettingsMenu({ id }: { id: string }) {
|
||||||
>
|
>
|
||||||
{t("player.menus.settings.enableSubtitles")}
|
{t("player.menus.settings.enableSubtitles")}
|
||||||
</Menu.Link>
|
</Menu.Link>
|
||||||
<Menu.ChevronLink
|
|
||||||
onClick={() => router.navigate("/captions")}
|
|
||||||
rightText={selectedLanguagePretty ?? undefined}
|
|
||||||
>
|
|
||||||
{t("player.menus.settings.subtitleItem")}
|
|
||||||
</Menu.ChevronLink>
|
|
||||||
<Menu.ChevronLink onClick={() => router.navigate("/playback")}>
|
<Menu.ChevronLink onClick={() => router.navigate("/playback")}>
|
||||||
{t("player.menus.settings.playbackItem")}
|
{t("player.menus.settings.playbackItem")}
|
||||||
</Menu.ChevronLink>
|
</Menu.ChevronLink>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
export function Card(props: { children: React.ReactNode }) {
|
export function Card(props: { children: React.ReactNode }) {
|
||||||
return (
|
return (
|
||||||
<div className="h-full grid grid-rows-[1fr]">
|
<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}
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,13 @@ export function Chevron(props: { children?: React.ReactNode }) {
|
||||||
export function LinkTitle(props: {
|
export function LinkTitle(props: {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
textClass?: string;
|
textClass?: string;
|
||||||
|
box?: boolean;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
className={classNames([
|
className={classNames([
|
||||||
"font-medium text-left",
|
"font-medium text-left",
|
||||||
|
props.box ? "flex flex-col items-center justify-center h-full" : "",
|
||||||
props.textClass || "text-video-context-type-main",
|
props.textClass || "text-video-context-type-main",
|
||||||
])}
|
])}
|
||||||
>
|
>
|
||||||
|
|
@ -78,13 +80,21 @@ export function Link(props: {
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
box?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
}) {
|
}) {
|
||||||
const classes = classNames("flex py-2 px-3 rounded-lg w-full -ml-3", {
|
const classes = classNames(
|
||||||
"cursor-default": !props.clickable,
|
"flex py-2 transition-colors duration-100 rounded-lg",
|
||||||
"hover:bg-video-context-hoverColor hover:bg-opacity-50 cursor-pointer tabbable":
|
props.box ? "bg-video-context-light/10 h-20" : "",
|
||||||
props.clickable,
|
{
|
||||||
"bg-video-context-hoverColor bg-opacity-50": props.active,
|
"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 styles = { width: "calc(100% + 1.5rem)" };
|
||||||
|
|
||||||
const content = (
|
const content = (
|
||||||
|
|
@ -110,9 +120,10 @@ export function Link(props: {
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={classes}
|
className={classes}
|
||||||
style={styles}
|
style={props.box ? {} : styles}
|
||||||
onClick={props.onClick}
|
onClick={props.onClick}
|
||||||
data-active-link={props.active ? true : undefined}
|
data-active-link={props.active ? true : undefined}
|
||||||
|
disabled={props.disabled}
|
||||||
>
|
>
|
||||||
{content}
|
{content}
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -124,6 +135,8 @@ export function ChevronLink(props: {
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
active?: boolean;
|
active?: boolean;
|
||||||
|
box?: boolean;
|
||||||
|
disabled?: boolean;
|
||||||
}) {
|
}) {
|
||||||
const rightContent = <Chevron>{props.rightText}</Chevron>;
|
const rightContent = <Chevron>{props.rightText}</Chevron>;
|
||||||
return (
|
return (
|
||||||
|
|
@ -131,9 +144,12 @@ export function ChevronLink(props: {
|
||||||
onClick={props.onClick}
|
onClick={props.onClick}
|
||||||
active={props.active}
|
active={props.active}
|
||||||
clickable
|
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>
|
</Link>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -145,6 +161,7 @@ export function SelectableLink(props: {
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
error?: ReactNode;
|
error?: ReactNode;
|
||||||
|
box?: boolean;
|
||||||
}) {
|
}) {
|
||||||
let rightContent;
|
let rightContent;
|
||||||
if (props.selected) {
|
if (props.selected) {
|
||||||
|
|
@ -168,6 +185,7 @@ export function SelectableLink(props: {
|
||||||
onClick={props.onClick}
|
onClick={props.onClick}
|
||||||
clickable={!props.disabled}
|
clickable={!props.disabled}
|
||||||
rightSide={rightContent}
|
rightSide={rightContent}
|
||||||
|
box={props.box}
|
||||||
>
|
>
|
||||||
<LinkTitle
|
<LinkTitle
|
||||||
textClass={classNames({
|
textClass={classNames({
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,14 @@ import classNames from "classnames";
|
||||||
import { useEffect, useRef } from "react";
|
import { useEffect, useRef } from "react";
|
||||||
|
|
||||||
export function SectionTitle(props: {
|
export function SectionTitle(props: {
|
||||||
children: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
className?: string;
|
className?: string;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<h3
|
<h3
|
||||||
className={classNames(
|
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,
|
props.className,
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|
@ -20,9 +21,15 @@ export function SectionTitle(props: {
|
||||||
export function Section(props: {
|
export function Section(props: {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
grid?: boolean;
|
||||||
}) {
|
}) {
|
||||||
return (
|
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}
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ export interface FlareProps {
|
||||||
flareSize?: number;
|
flareSize?: number;
|
||||||
cssColorVar?: string;
|
cssColorVar?: string;
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
|
gradientOpacity?: number;
|
||||||
|
gradientSpread?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SIZE_DEFAULT = 200;
|
const SIZE_DEFAULT = 200;
|
||||||
|
|
@ -38,6 +40,8 @@ function Light(props: FlareProps) {
|
||||||
const outerRef = useRef<HTMLDivElement>(null);
|
const outerRef = useRef<HTMLDivElement>(null);
|
||||||
const size = props.flareSize ?? SIZE_DEFAULT;
|
const size = props.flareSize ?? SIZE_DEFAULT;
|
||||||
const cssVar = props.cssColorVar ?? CSS_VAR_DEFAULT;
|
const cssVar = props.cssColorVar ?? CSS_VAR_DEFAULT;
|
||||||
|
const opacity = props.gradientOpacity ?? 1;
|
||||||
|
const spread = props.gradientSpread ?? 70;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
function mouseMove(e: MouseEvent) {
|
function mouseMove(e: MouseEvent) {
|
||||||
|
|
@ -69,7 +73,7 @@ function Light(props: FlareProps) {
|
||||||
},
|
},
|
||||||
)}
|
)}
|
||||||
style={{
|
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)`,
|
backgroundPosition: `var(--bg-x) var(--bg-y)`,
|
||||||
backgroundRepeat: "no-repeat",
|
backgroundRepeat: "no-repeat",
|
||||||
backgroundSize: `${size.toFixed(0)}px ${size.toFixed(0)}px`,
|
backgroundSize: `${size.toFixed(0)}px ${size.toFixed(0)}px`,
|
||||||
|
|
@ -85,7 +89,7 @@ function Light(props: FlareProps) {
|
||||||
<div
|
<div
|
||||||
className="absolute inset-0 opacity-10"
|
className="absolute inset-0 opacity-10"
|
||||||
style={{
|
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)`,
|
backgroundPosition: `var(--bg-x) var(--bg-y)`,
|
||||||
backgroundRepeat: "no-repeat",
|
backgroundRepeat: "no-repeat",
|
||||||
backgroundSize: `${size.toFixed(0)}px ${size.toFixed(0)}px`,
|
backgroundSize: `${size.toFixed(0)}px ${size.toFixed(0)}px`,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue