mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Add playback settings
This commit is contained in:
parent
5f89c6e498
commit
27ae6b512b
@ -34,6 +34,30 @@ export const UserP = ResourceP("user").extend({
|
||||
* The list of permissions of the user. The format of this is implementation dependent.
|
||||
*/
|
||||
permissions: z.array(z.string()),
|
||||
/**
|
||||
* User settings
|
||||
*/
|
||||
settings: z
|
||||
.object({
|
||||
downloadQuality: z
|
||||
.union([
|
||||
z.literal("original"),
|
||||
z.literal("8k"),
|
||||
z.literal("4k"),
|
||||
z.literal("1440p"),
|
||||
z.literal("1080p"),
|
||||
z.literal("720p"),
|
||||
z.literal("480p"),
|
||||
z.literal("360p"),
|
||||
z.literal("240p"),
|
||||
])
|
||||
.default("original")
|
||||
.catch("original"),
|
||||
audioLanguage: z.string().default("default").catch("default"),
|
||||
subtitleLanguage: z.string().nullable().default(null).catch(null),
|
||||
})
|
||||
// keep a default for older versions of the api
|
||||
.default({}),
|
||||
});
|
||||
|
||||
export type User = z.infer<typeof UserP>;
|
||||
|
@ -360,6 +360,7 @@ const ProgressBar = ({ url, chapters }: { url: string; chapters?: Chapter[] }) =
|
||||
<Tooltip
|
||||
id={"progress-scrubber"}
|
||||
isOpen={hoverProgress !== null}
|
||||
place="top"
|
||||
position={{ x: layout.x + (layout.width * hoverProgress!) / (duration ?? 1), y: layout.y }}
|
||||
render={() =>
|
||||
hoverProgress ? (
|
||||
|
@ -24,12 +24,14 @@ import { ScrollView } from "react-native";
|
||||
import { DefaultLayout } from "../layout";
|
||||
import { AccountSettings } from "./account";
|
||||
import { About, GeneralSettings } from "./general";
|
||||
import { PlaybackSettings } from "./playback";
|
||||
|
||||
export const SettingsPage: QueryPage = () => {
|
||||
const account = useAccount();
|
||||
return (
|
||||
<ScrollView contentContainerStyle={{ gap: ts(4), paddingBottom: ts(4) }}>
|
||||
<GeneralSettings />
|
||||
{account && <PlaybackSettings />}
|
||||
{account && <AccountSettings />}
|
||||
<About />
|
||||
</ScrollView>
|
||||
|
81
front/packages/ui/src/settings/playback.tsx
Normal file
81
front/packages/ui/src/settings/playback.tsx
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Kyoo - A portable and vast media library solution.
|
||||
* Copyright (c) Kyoo.
|
||||
*
|
||||
* See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
*
|
||||
* Kyoo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Kyoo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { setUserTheme, useAccount } from "@kyoo/models";
|
||||
import { Select } from "@kyoo/primitives";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Preference, SettingsContainer, useSetting } from "./base";
|
||||
|
||||
import SubtitleLanguage from "@material-symbols/svg-400/rounded/closed_caption-fill.svg";
|
||||
import AudioLanguage from "@material-symbols/svg-400/rounded/music_note-fill.svg";
|
||||
|
||||
// I gave up on finding a way to retrive this using the Intl api (probably does not exist)
|
||||
// Simply copy pasted the list of languages from https://www.localeplanet.com/api/codelist.json
|
||||
// prettier-ignore
|
||||
const allLanguages = ["af", "agq", "ak", "am", "ar", "as", "asa", "ast", "az", "bas", "be", "bem", "bez", "bg", "bm", "bn", "bo", "br", "brx", "bs", "ca", "ccp", "ce", "cgg", "chr", "ckb", "cs", "cy", "da", "dav", "de", "dje", "dsb", "dua", "dyo", "dz", "ebu", "ee", "el", "en", "eo", "es", "et", "eu", "ewo", "fa", "ff", "fi", "fil", "fo", "fr", "fur", "fy", "ga", "gd", "gl", "gsw", "gu", "guz", "gv", "ha", "haw", "he", "hi", "hr", "hsb", "hu", "hy", "id", "ig", "ii", "is", "it", "ja", "jgo", "jmc", "ka", "kab", "kam", "kde", "kea", "khq", "ki", "kk", "kkj", "kl", "kln", "km", "kn", "ko", "kok", "ks", "ksb", "ksf", "ksh", "kw", "ky", "lag", "lb", "lg", "lkt", "ln", "lo", "lrc", "lt", "lu", "luo", "luy", "lv", "mas", "mer", "mfe", "mg", "mgh", "mgo", "mk", "ml", "mn", "mr", "ms", "mt", "mua", "my", "mzn", "naq", "nb", "nd", "nds", "ne", "nl", "nmg", "nn", "nnh", "nus", "nyn", "om", "or", "os", "pa", "pl", "ps", "pt", "qu", "rm", "rn", "ro", "rof", "ru", "rw", "rwk", "sah", "saq", "sbp", "se", "seh", "ses", "sg", "shi", "si", "sk", "sl", "smn", "sn", "so", "sq", "sr", "sv", "sw", "ta", "te", "teo", "tg", "th", "ti", "to", "tr", "tt", "twq", "tzm", "ug", "uk", "ur", "uz", "vai", "vi", "vun", "wae", "wo", "xog", "yav", "yi", "yo", "yue", "zgh", "zh", "zu",];
|
||||
|
||||
export const PlaybackSettings = () => {
|
||||
const { t, i18n } = useTranslation();
|
||||
const [audio, setAudio] = useSetting("audioLanguage")!;
|
||||
const [subtitle, setSubtitle] = useSetting("subtitleLanguage")!;
|
||||
const languages = new Intl.DisplayNames([i18n.language ?? "en"], {
|
||||
type: "language",
|
||||
languageDisplay: "standard",
|
||||
});
|
||||
|
||||
return (
|
||||
<SettingsContainer title={t("settings.playback.label")}>
|
||||
<Preference
|
||||
icon={AudioLanguage}
|
||||
label={t("settings.playback.audioLanguage.label")}
|
||||
description={t("settings.playback.audioLanguage.description")}
|
||||
>
|
||||
<Select
|
||||
label={t("settings.playback.audioLanguage.label")}
|
||||
value={audio}
|
||||
onValueChange={(value) => setAudio(value)}
|
||||
values={["default", ...allLanguages]}
|
||||
getLabel={(key) =>
|
||||
key === "default" ? t("mediainfo.default") : languages.of(key) ?? key
|
||||
}
|
||||
/>
|
||||
</Preference>
|
||||
<Preference
|
||||
icon={SubtitleLanguage}
|
||||
label={t("settings.playback.subtitleLanguage.label")}
|
||||
description={t("settings.playback.subtitleLanguage.description")}
|
||||
>
|
||||
<Select
|
||||
label={t("settings.playback.subtitleLanguage.label")}
|
||||
value={subtitle ?? "none"}
|
||||
onValueChange={(value) => setSubtitle(value === "none" ? null : value)}
|
||||
values={["none", "default", ...allLanguages]}
|
||||
getLabel={(key) =>
|
||||
key === "none"
|
||||
? t("settings.playback.subtitleLanguage.none")
|
||||
: key === "default"
|
||||
? t("mediainfo.default")
|
||||
: languages.of(key) ?? key
|
||||
}
|
||||
/>
|
||||
</Preference>
|
||||
</SettingsContainer>
|
||||
);
|
||||
};
|
@ -92,6 +92,18 @@
|
||||
"system": "System"
|
||||
}
|
||||
},
|
||||
"playback": {
|
||||
"label": "Playback",
|
||||
"audioLanguage": {
|
||||
"label": "Audio language",
|
||||
"description": "The default audio language used when playing multi-audio videos"
|
||||
},
|
||||
"subtitleLanguage": {
|
||||
"label": "Subtitle language",
|
||||
"description": "The default subtitle language used",
|
||||
"none": "None"
|
||||
}
|
||||
},
|
||||
"account": {
|
||||
"label": "Account",
|
||||
"username": {
|
||||
|
@ -92,6 +92,18 @@
|
||||
"system": "Système"
|
||||
}
|
||||
},
|
||||
"playback": {
|
||||
"label": "Lecteur",
|
||||
"audioLanguage": {
|
||||
"label": "Langue audio",
|
||||
"description": "Langue audio par défaut utilisée lors de la lecture de vidéos multi-audio"
|
||||
},
|
||||
"subtitleLanguage": {
|
||||
"label": "Langue des sous-titres",
|
||||
"description": "Langue des sous-titres utilisée par défaut",
|
||||
"none": "Aucun"
|
||||
}
|
||||
},
|
||||
"account": {
|
||||
"label": "Compte",
|
||||
"username": {
|
||||
|
Loading…
x
Reference in New Issue
Block a user