mirror of
https://github.com/streamyfin/streamyfin.git
synced 2025-08-20 18:37:18 +02:00
Settings Fields V
This commit is contained in:
@@ -14,6 +14,7 @@ import { Alert, ScrollView, View } from "react-native";
|
||||
import * as Progress from "react-native-progress";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
import { toast } from "sonner-native";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export default function settings() {
|
||||
const { logout } = useJellyfin();
|
||||
@@ -25,6 +26,8 @@ export default function settings() {
|
||||
|
||||
const insets = useSafeAreaInsets();
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { data: size, isLoading: appSizeLoading } = useQuery({
|
||||
queryKey: ["appSize", appSizeUsage],
|
||||
queryFn: async () => {
|
||||
@@ -98,31 +101,31 @@ export default function settings() {
|
||||
registerBackgroundFetchAsync
|
||||
</Button> */}
|
||||
<View>
|
||||
<Text className="font-bold text-lg mb-2">User Info</Text>
|
||||
<Text className="font-bold text-lg mb-2">{t("home.settings.user_info.user_info_title")}</Text>
|
||||
|
||||
<View className="flex flex-col rounded-xl overflow-hidden border-neutral-800 divide-y-2 divide-solid divide-neutral-800 ">
|
||||
<ListItem title="User" subTitle={user?.Name} />
|
||||
<ListItem title="Server" subTitle={api?.basePath} />
|
||||
<ListItem title="Token" subTitle={api?.accessToken} />
|
||||
<ListItem title={t("home.settings.user_info.user")} subTitle={user?.Name} />
|
||||
<ListItem title={t("home.settings.user_info.server")} subTitle={api?.basePath} />
|
||||
<ListItem title={t("home.settings.user_info.token")} subTitle={api?.accessToken} />
|
||||
</View>
|
||||
<Button className="my-2.5" color="black" onPress={logout}>
|
||||
Log out
|
||||
{t("home.settings.user_info.log_out_button")}
|
||||
</Button>
|
||||
</View>
|
||||
|
||||
<View>
|
||||
<Text className="font-bold text-lg mb-2">Quick connect</Text>
|
||||
<Text className="font-bold text-lg mb-2">{t("home.settings.quick_connect.quick_connect_title")}</Text>
|
||||
<Button onPress={openQuickConnectAuthCodeInput} color="black">
|
||||
Authorize
|
||||
{t("home.settings.quick_connect.authorize_button")}
|
||||
</Button>
|
||||
</View>
|
||||
|
||||
<SettingToggles />
|
||||
|
||||
<View className="flex flex-col space-y-2">
|
||||
<Text className="font-bold text-lg mb-2">Storage</Text>
|
||||
<Text className="font-bold text-lg mb-2">{t("home.settings.storage.storage_title")}</Text>
|
||||
<View className="mb-4 space-y-2">
|
||||
{size && <Text>App usage: {size.app.bytesToReadable()}</Text>}
|
||||
{size && <Text>{t("home.settings.storage.app_usage", {usedSpace: size.app.bytesToReadable()})}</Text>}
|
||||
<Progress.Bar
|
||||
className="bg-gray-100/10"
|
||||
indeterminate={appSizeLoading}
|
||||
@@ -135,20 +138,20 @@ export default function settings() {
|
||||
/>
|
||||
{size && (
|
||||
<Text>
|
||||
Available: {size.remaining?.bytesToReadable()}, Total:{" "}
|
||||
{size.total?.bytesToReadable()}
|
||||
{t("home.settings.storage.available_total", {availableSpace: size.remaining?.bytesToReadable(), totalSpace: size.total?.bytesToReadable()})}
|
||||
{}
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
<Button color="red" onPress={onDeleteClicked}>
|
||||
Delete all downloaded files
|
||||
{t("home.settings.storage.delete_all_downloaded_files")}
|
||||
</Button>
|
||||
<Button color="red" onPress={onClearLogsClicked}>
|
||||
Delete all logs
|
||||
{t("home.settings.storage.delete_all_logs")}
|
||||
</Button>
|
||||
</View>
|
||||
<View>
|
||||
<Text className="font-bold text-lg mb-2">Logs</Text>
|
||||
<Text className="font-bold text-lg mb-2">{t("home.settings.logs.logs_title")}</Text>
|
||||
<View className="flex flex-col space-y-2">
|
||||
{logs?.map((log, index) => (
|
||||
<View key={index} className="bg-neutral-900 rounded-xl p-3">
|
||||
@@ -167,7 +170,7 @@ export default function settings() {
|
||||
</View>
|
||||
))}
|
||||
{logs?.length === 0 && (
|
||||
<Text className="opacity-50">No logs available</Text>
|
||||
<Text className="opacity-50">{t("home.settings.logs.no_logs_available")}</Text>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -3,6 +3,7 @@ import * as DropdownMenu from "zeego/dropdown-menu";
|
||||
import { Text } from "../common/Text";
|
||||
import { useMedia } from "./MediaContext";
|
||||
import { Switch } from "react-native-gesture-handler";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
interface Props extends ViewProps {}
|
||||
|
||||
@@ -10,12 +11,13 @@ export const AudioToggles: React.FC<Props> = ({ ...props }) => {
|
||||
const media = useMedia();
|
||||
const { settings, updateSettings } = media;
|
||||
const cultures = media.cultures;
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (!settings) return null;
|
||||
|
||||
return (
|
||||
<View>
|
||||
<Text className="text-lg font-bold mb-2">Audio</Text>
|
||||
<Text className="text-lg font-bold mb-2">{t("home.settings.audio.audio_title")}</Text>
|
||||
<View className="flex flex-col rounded-xl mb-4 overflow-hidden divide-y-2 divide-solid divide-neutral-800">
|
||||
<View
|
||||
className={`
|
||||
@@ -23,9 +25,9 @@ export const AudioToggles: React.FC<Props> = ({ ...props }) => {
|
||||
`}
|
||||
>
|
||||
<View className="flex flex-col shrink">
|
||||
<Text className="font-semibold">Audio language</Text>
|
||||
<Text className="font-semibold">{t("home.settings.audio.audio_language")}</Text>
|
||||
<Text className="text-xs opacity-50">
|
||||
Choose a default audio language.
|
||||
{t("home.settings.audio.audio_language_hint")}
|
||||
</Text>
|
||||
</View>
|
||||
<DropdownMenu.Root>
|
||||
@@ -76,9 +78,9 @@ export const AudioToggles: React.FC<Props> = ({ ...props }) => {
|
||||
<View className="flex flex-col">
|
||||
<View className="flex flex-row items-center justify-between bg-neutral-900 p-4">
|
||||
<View className="flex flex-col">
|
||||
<Text className="font-semibold">Use Default Audio</Text>
|
||||
<Text className="font-semibold">{t("home.settings.audio.use_default_audio")}</Text>
|
||||
<Text className="text-xs opacity-50">
|
||||
Play default audio track regardless of language.
|
||||
{t("home.settings.audio.use_default_audio_hint")}
|
||||
</Text>
|
||||
</View>
|
||||
<Switch
|
||||
@@ -93,11 +95,10 @@ export const AudioToggles: React.FC<Props> = ({ ...props }) => {
|
||||
<View className="flex flex-row items-center justify-between bg-neutral-900 p-4">
|
||||
<View className="flex flex-col">
|
||||
<Text className="font-semibold">
|
||||
Set Audio Track From Previous Item
|
||||
{t("home.settings.audio.set_audio_track")}
|
||||
</Text>
|
||||
<Text className="text-xs opacity-50 min max-w-[85%]">
|
||||
Try to set the audio track to the closest match to the last
|
||||
video.
|
||||
{t("home.settings.audio.set_audio_track_hint")}
|
||||
</Text>
|
||||
</View>
|
||||
<Switch
|
||||
|
||||
@@ -11,6 +11,7 @@ import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||
import { useAtom } from "jotai";
|
||||
import { toast } from "sonner-native";
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export const JellyseerrSettings = () => {
|
||||
const {
|
||||
@@ -20,6 +21,8 @@ export const JellyseerrSettings = () => {
|
||||
clearAllJellyseerData,
|
||||
} = useJellyseerr();
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [user] = useAtom(userAtom);
|
||||
const [settings, updateSettings] = useSettings();
|
||||
|
||||
@@ -121,19 +124,16 @@ export const JellyseerrSettings = () => {
|
||||
) : (
|
||||
<View className="flex flex-col rounded-xl overflow-hidden p-4 bg-neutral-900">
|
||||
<Text className="text-xs text-red-600 mb-2">
|
||||
This integration is in its early stages. Expect things to change.
|
||||
{t("home.settings.jellyseer.jellyseer_warning")}
|
||||
</Text>
|
||||
<Text className="font-bold mb-1">Server URL</Text>
|
||||
<Text className="font-bold mb-1">{t("home.settings.jellyseer.server_url")}</Text>
|
||||
<View className="flex flex-col shrink mb-2">
|
||||
<Text className="text-xs text-gray-600">
|
||||
Example: http(s)://your-host.url
|
||||
</Text>
|
||||
<Text className="text-xs text-gray-600">
|
||||
(add port if required)
|
||||
{t("home.settings.jellyseer.server_url_hint")}
|
||||
</Text>
|
||||
</View>
|
||||
<Input
|
||||
placeholder="Jellyseerr URL..."
|
||||
placeholder={t("home.settings.jellyseer.server_url_placeholder")}
|
||||
value={settings?.jellyseerrServerUrl ?? jellyseerrServerUrl}
|
||||
defaultValue={
|
||||
settings?.jellyseerrServerUrl ?? jellyseerrServerUrl
|
||||
@@ -163,7 +163,7 @@ export const JellyseerrSettings = () => {
|
||||
marginBottom: 8,
|
||||
}}
|
||||
>
|
||||
{promptForJellyseerrPass ? "Clear" : "Save"}
|
||||
{promptForJellyseerrPass ? t("home.settings.jellyseer.clear_button") : t("home.settings.jellyseer.save_button")}
|
||||
</Button>
|
||||
|
||||
<View
|
||||
@@ -172,11 +172,11 @@ export const JellyseerrSettings = () => {
|
||||
opacity: promptForJellyseerrPass ? 1 : 0.5,
|
||||
}}
|
||||
>
|
||||
<Text className="font-bold mb-2">Password</Text>
|
||||
<Text className="font-bold mb-2">{t("home.settings.jellyseer.password")}</Text>
|
||||
<Input
|
||||
autoFocus={true}
|
||||
focusable={true}
|
||||
placeholder={`Enter password for Jellyfin user ${user?.Name}`}
|
||||
placeholder={t("home.settings.jellyseer.password_placeholder", {username: user?.Name})}
|
||||
value={jellyseerrPassword}
|
||||
keyboardType="default"
|
||||
secureTextEntry={true}
|
||||
@@ -196,7 +196,7 @@ export const JellyseerrSettings = () => {
|
||||
className="h-12 mt-2"
|
||||
onPress={() => loginToJellyseerrMutation.mutate()}
|
||||
>
|
||||
Login
|
||||
{t("home.settings.jellyseer.login_button")}
|
||||
</Button>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
import { useSettings } from "@/utils/atoms/settings";
|
||||
import { TouchableOpacity, View, ViewProps } from "react-native";
|
||||
import { Text } from "../common/Text";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
interface Props extends ViewProps {}
|
||||
|
||||
export const MediaToggles: React.FC<Props> = ({ ...props }) => {
|
||||
const [settings, updateSettings] = useSettings();
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (!settings) return null;
|
||||
|
||||
return (
|
||||
<View>
|
||||
<Text className="text-lg font-bold mb-2">Media</Text>
|
||||
<Text className="text-lg font-bold mb-2">{t("home.settings.media.media_title")}</Text>
|
||||
<View className="flex flex-col rounded-xl mb-4 overflow-hidden divide-y-2 divide-solid divide-neutral-800">
|
||||
<View
|
||||
className={`
|
||||
@@ -19,9 +21,9 @@ export const MediaToggles: React.FC<Props> = ({ ...props }) => {
|
||||
`}
|
||||
>
|
||||
<View className="flex flex-col shrink">
|
||||
<Text className="font-semibold">Forward skip length</Text>
|
||||
<Text className="font-semibold">{t("home.settings.media.forward_skip_length")}</Text>
|
||||
<Text className="text-xs opacity-50">
|
||||
Choose length in seconds when skipping in video playback.
|
||||
{t("home.settings.media.forward_skip_length_hint")}
|
||||
</Text>
|
||||
</View>
|
||||
<View className="flex flex-row items-center">
|
||||
@@ -57,9 +59,9 @@ export const MediaToggles: React.FC<Props> = ({ ...props }) => {
|
||||
`}
|
||||
>
|
||||
<View className="flex flex-col shrink">
|
||||
<Text className="font-semibold">Rewind length</Text>
|
||||
<Text className="font-semibold">{t("home.settings.media.rewind_length")}</Text>
|
||||
<Text className="text-xs opacity-50">
|
||||
Choose length in seconds when skipping in video playback.
|
||||
{t("home.settings.media.rewind_length_hint")}
|
||||
</Text>
|
||||
</View>
|
||||
<View className="flex flex-row items-center">
|
||||
|
||||
@@ -43,6 +43,7 @@ import { AudioToggles } from "./AudioToggles";
|
||||
import { JellyseerrApi, useJellyseerr } from "@/hooks/useJellyseerr";
|
||||
import { ListItem } from "@/components/ListItem";
|
||||
import { JellyseerrSettings } from "./Jellyseerr";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
interface Props extends ViewProps {}
|
||||
|
||||
@@ -59,6 +60,8 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
/********************
|
||||
* Background task
|
||||
*******************/
|
||||
@@ -137,15 +140,14 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
|
||||
</MediaProvider>
|
||||
|
||||
<View>
|
||||
<Text className="text-lg font-bold mb-2">Other</Text>
|
||||
<Text className="text-lg font-bold mb-2">{t("home.settings.other.other_title")}</Text>
|
||||
|
||||
<View className="flex flex-col rounded-xl overflow-hidden divide-y-2 divide-solid divide-neutral-800">
|
||||
<View className="flex flex-row items-center justify-between bg-neutral-900 p-4">
|
||||
<View className="shrink">
|
||||
<Text className="font-semibold">Auto rotate</Text>
|
||||
<Text className="font-semibold">{t("home.settings.other.auto_rotate")}</Text>
|
||||
<Text className="text-xs opacity-50">
|
||||
Important on android since the video player orientation is
|
||||
locked to the app orientation.
|
||||
{t("home.settings.other.auto_rotate_hint")}
|
||||
</Text>
|
||||
</View>
|
||||
<Switch
|
||||
@@ -166,9 +168,9 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
|
||||
`}
|
||||
>
|
||||
<View className="flex flex-col shrink">
|
||||
<Text className="font-semibold">Video orientation</Text>
|
||||
<Text className="font-semibold">{t("home.settings.other.video_orientation")}</Text>
|
||||
<Text className="text-xs opacity-50">
|
||||
Set the full screen video player orientation.
|
||||
{t("home.settings.other.video_orientation_hint")}
|
||||
</Text>
|
||||
</View>
|
||||
<DropdownMenu.Root>
|
||||
@@ -263,9 +265,9 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
|
||||
|
||||
<View className="flex flex-row items-center justify-between bg-neutral-900 p-4">
|
||||
<View className="shrink">
|
||||
<Text className="font-semibold">Safe area in controls</Text>
|
||||
<Text className="font-semibold">{t("home.settings.other.safe_area_in_controls")}</Text>
|
||||
<Text className="text-xs opacity-50">
|
||||
Enable safe area in video player controls
|
||||
{t("home.settings.other.safe_area_in_controls_hint")}
|
||||
</Text>
|
||||
</View>
|
||||
<Switch
|
||||
@@ -279,8 +281,8 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
|
||||
<View className="flex flex-col">
|
||||
<View className="flex flex-row items-center justify-between bg-neutral-900 p-4">
|
||||
<View className="flex flex-col">
|
||||
<Text className="font-semibold">Use popular lists plugin</Text>
|
||||
<Text className="text-xs opacity-50">Made by: lostb1t</Text>
|
||||
<Text className="font-semibold">{t("home.settings.other.use_popular_lists_plugin")}</Text>
|
||||
<Text className="text-xs opacity-50">{t("home.settings.other.use_popular_lists_plugin_hint")}</Text>
|
||||
<TouchableOpacity
|
||||
onPress={() => {
|
||||
Linking.openURL(
|
||||
@@ -288,7 +290,7 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
|
||||
);
|
||||
}}
|
||||
>
|
||||
<Text className="text-xs text-purple-600">More info</Text>
|
||||
<Text className="text-xs text-purple-600">{t("home.settings.other.more_info")}</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<Switch
|
||||
@@ -353,9 +355,9 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
|
||||
`}
|
||||
>
|
||||
<View className="flex flex-col shrink">
|
||||
<Text className="font-semibold">Search engine</Text>
|
||||
<Text className="font-semibold">{t("home.settings.other.search_engine")}</Text>
|
||||
<Text className="text-xs opacity-50">
|
||||
Choose the search engine you want to use.
|
||||
{t("home.settings.other.search_engine_hint")}
|
||||
</Text>
|
||||
</View>
|
||||
<DropdownMenu.Root>
|
||||
@@ -421,7 +423,7 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
|
||||
});
|
||||
}}
|
||||
>
|
||||
Save
|
||||
{t("home.settings.other.save_button")}
|
||||
</Button>
|
||||
</View>
|
||||
|
||||
@@ -436,10 +438,9 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
|
||||
|
||||
<View className="flex flex-row items-center justify-between bg-neutral-900 p-4">
|
||||
<View className="shrink">
|
||||
<Text className="font-semibold">Show Custom Menu Links</Text>
|
||||
<Text className="font-semibold">{t("home.settings.other.show_custom_menu_links")}</Text>
|
||||
<Text className="text-xs opacity-50">
|
||||
Show custom menu links defined inside your Jellyfin web
|
||||
config.json file
|
||||
{t("home.settings.other.show_custom_menu_links_hint")}
|
||||
</Text>
|
||||
<TouchableOpacity
|
||||
onPress={() =>
|
||||
@@ -448,7 +449,7 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
|
||||
)
|
||||
}
|
||||
>
|
||||
<Text className="text-xs text-purple-600">More info</Text>
|
||||
<Text className="text-xs text-purple-600">{t("home.settings.other.more_info")}</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<Switch
|
||||
@@ -462,7 +463,7 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
|
||||
</View>
|
||||
|
||||
<View className="mt-4">
|
||||
<Text className="text-lg font-bold mb-2">Downloads</Text>
|
||||
<Text className="text-lg font-bold mb-2">{t("home.settings.downloads.downloads_title")}</Text>
|
||||
<View className="flex flex-col rounded-xl overflow-hidden divide-y-2 divide-solid divide-neutral-800">
|
||||
<View
|
||||
className={`
|
||||
@@ -470,10 +471,9 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
|
||||
`}
|
||||
>
|
||||
<View className="flex flex-col shrink">
|
||||
<Text className="font-semibold">Download method</Text>
|
||||
<Text className="font-semibold">{t("home.settings.downloads.download_method")}</Text>
|
||||
<Text className="text-xs opacity-50">
|
||||
Choose the download method to use. Optimized requires the
|
||||
optimized server.
|
||||
{t("home.settings.downloads.download_method_hint")}
|
||||
</Text>
|
||||
</View>
|
||||
<DropdownMenu.Root>
|
||||
@@ -531,10 +531,9 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
|
||||
}`}
|
||||
>
|
||||
<View className="flex flex-col shrink">
|
||||
<Text className="font-semibold">Remux max download</Text>
|
||||
<Text className="font-semibold">{t("home.settings.downloads.remux_max_download")}</Text>
|
||||
<Text className="text-xs opacity-50 shrink">
|
||||
This is the total media you want to be able to download at the
|
||||
same time.
|
||||
{t("home.settings.downloads.remux_max_download_hint")}
|
||||
</Text>
|
||||
</View>
|
||||
<Stepper
|
||||
@@ -563,10 +562,9 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
|
||||
}`}
|
||||
>
|
||||
<View className="flex flex-col shrink">
|
||||
<Text className="font-semibold">Auto download</Text>
|
||||
<Text className="font-semibold">{t("home.settings.downloads.auto_download")}</Text>
|
||||
<Text className="text-xs opacity-50 shrink">
|
||||
This will automatically download the media file when it's
|
||||
finished optimizing on the server.
|
||||
{t("home.settings.downloads.auto_download_hint")}
|
||||
</Text>
|
||||
</View>
|
||||
<Switch
|
||||
@@ -589,11 +587,11 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
|
||||
<View className="flex flex-col shrink mb-2">
|
||||
<View className="flex flex-row justify-between items-center">
|
||||
<Text className="font-semibold">
|
||||
Optimized versions server
|
||||
{t("home.settings.downloads.optimized_versions_server")}
|
||||
</Text>
|
||||
</View>
|
||||
<Text className="text-xs opacity-50">
|
||||
Set the URL for the optimized versions server for downloads.
|
||||
{t("home.settings.downloads.optimized_versions_server_hint")}
|
||||
</Text>
|
||||
</View>
|
||||
<View></View>
|
||||
@@ -629,7 +627,7 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
|
||||
} else toast.error("Could not connect");
|
||||
}}
|
||||
>
|
||||
Save
|
||||
{t("home.settings.downloads.save_button")}
|
||||
</Button>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Text } from "../common/Text";
|
||||
import { useMedia } from "./MediaContext";
|
||||
import { Switch } from "react-native-gesture-handler";
|
||||
import { SubtitlePlaybackMode } from "@jellyfin/sdk/lib/generated-client";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
interface Props extends ViewProps {}
|
||||
|
||||
@@ -11,6 +12,8 @@ export const SubtitleToggles: React.FC<Props> = ({ ...props }) => {
|
||||
const media = useMedia();
|
||||
const { settings, updateSettings } = media;
|
||||
const cultures = media.cultures;
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (!settings) return null;
|
||||
|
||||
const subtitleModes = [
|
||||
@@ -23,7 +26,7 @@ export const SubtitleToggles: React.FC<Props> = ({ ...props }) => {
|
||||
|
||||
return (
|
||||
<View>
|
||||
<Text className="text-lg font-bold mb-2">Subtitle</Text>
|
||||
<Text className="text-lg font-bold mb-2">{t("home.settings.subtitles.subtitle_title")}</Text>
|
||||
<View className="flex flex-col rounded-xl mb-4 overflow-hidden divide-y-2 divide-solid divide-neutral-800">
|
||||
<View
|
||||
className={`
|
||||
@@ -31,9 +34,9 @@ export const SubtitleToggles: React.FC<Props> = ({ ...props }) => {
|
||||
`}
|
||||
>
|
||||
<View className="flex flex-col shrink">
|
||||
<Text className="font-semibold">Subtitle language</Text>
|
||||
<Text className="font-semibold">{t("home.settings.subtitles.subtitle_language")}</Text>
|
||||
<Text className="text-xs opacity-50">
|
||||
Choose a default subtitle language.
|
||||
{t("home.settings.subtitles.subtitle_language_hint")}
|
||||
</Text>
|
||||
</View>
|
||||
<DropdownMenu.Root>
|
||||
@@ -88,11 +91,9 @@ export const SubtitleToggles: React.FC<Props> = ({ ...props }) => {
|
||||
`}
|
||||
>
|
||||
<View className="flex flex-col shrink">
|
||||
<Text className="font-semibold">Subtitle Mode</Text>
|
||||
<Text className="font-semibold">{t("home.settings.subtitles.subtitle_mode")}</Text>
|
||||
<Text className="text-xs opacity-50 mr-2">
|
||||
Subtitles are loaded based on the default and forced flags in the
|
||||
embedded metadata. Language preferences are considered when
|
||||
multiple options are available.
|
||||
{t("home.settings.subtitles.subtitle_mode_hint")}
|
||||
</Text>
|
||||
</View>
|
||||
<DropdownMenu.Root>
|
||||
@@ -131,11 +132,10 @@ export const SubtitleToggles: React.FC<Props> = ({ ...props }) => {
|
||||
<View className="flex flex-row items-center justify-between bg-neutral-900 p-4">
|
||||
<View className="flex flex-col">
|
||||
<Text className="font-semibold">
|
||||
Set Subtitle Track From Previous Item
|
||||
{t("home.settings.subtitles.set_subtitle_track")}
|
||||
</Text>
|
||||
<Text className="text-xs opacity-50 min max-w-[85%]">
|
||||
Try to set the subtitle track to the closest match to the last
|
||||
video.
|
||||
{t("home.settings.subtitles.set_subtitle_track_hint")}
|
||||
</Text>
|
||||
</View>
|
||||
<Switch
|
||||
@@ -153,10 +153,9 @@ export const SubtitleToggles: React.FC<Props> = ({ ...props }) => {
|
||||
`}
|
||||
>
|
||||
<View className="flex flex-col shrink">
|
||||
<Text className="font-semibold">Subtitle Size</Text>
|
||||
<Text className="font-semibold">{t("home.settings.subtitles.subtitle_size")}</Text>
|
||||
<Text className="text-xs opacity-50">
|
||||
Choose a default subtitle size for direct play (only works for
|
||||
some subtitle formats).
|
||||
{t("home.settings.subtitles.subtitle_size_hint")}
|
||||
</Text>
|
||||
</View>
|
||||
<View className="flex flex-row items-center">
|
||||
|
||||
@@ -29,13 +29,16 @@
|
||||
"suggested_episodes": "Suggested Episodes",
|
||||
"settings": {
|
||||
"settings_title": "Settings",
|
||||
"user_info": "User Info",
|
||||
"user": "User",
|
||||
"server": "Server",
|
||||
"token": "Token",
|
||||
"log_out": "Log out",
|
||||
"quick_connect": "Quick connect",
|
||||
"authorize": "Authorize",
|
||||
"user_info": {
|
||||
"user_info_title": "User Info",
|
||||
"user": "User",
|
||||
"server": "Server",
|
||||
"log_out_button": "Log out"
|
||||
},
|
||||
"quick_connect": {
|
||||
"quick_connect_title": "Quick connect",
|
||||
"authorize_button": "Authorize"
|
||||
},
|
||||
"media":{
|
||||
"media_title": "Media",
|
||||
"forward_skip_length": "Forward skip length",
|
||||
@@ -58,14 +61,15 @@
|
||||
"subtitle_language_hint": "Choose a default subtitle language.",
|
||||
"subtitle_mode": "Subtitle Mode",
|
||||
"subtitle_mode_hint": "Subtitles are loaded based on the default and forced flags in the\nembedded metadata. Language preferences are considered when\nmultiple options are available.",
|
||||
"set_subtitle_track": "Try to set the subtitle track to the closest match to the last\nvideo.",
|
||||
"set_subtitle_track": "Set Subtitle Track From Previous Item",
|
||||
"set_subtitle_track_hint" :"Try to set the subtitle track to the closest match to the last\nvideo.",
|
||||
"subtitle_size": "Subtitle Size",
|
||||
"subtitle_size_hint": "Choose a default subtitle size for direct play (only works for\nsome subtitle formats)."
|
||||
},
|
||||
"other": {
|
||||
"other_title": "Other",
|
||||
"auto_rotate": "Auto rotate",
|
||||
"auto_rotate_hint": "Important on android since the video player orientation is\nlocked to the app orientation.",
|
||||
"auto_rotate_hint": "Important on android since the video player orientation is locked to the app orientation.",
|
||||
"video_orientation": "Video orientation",
|
||||
"video_orientation_hint": "Set the full screen video player orientation",
|
||||
"safe_area_in_controls": "Safe area in controls",
|
||||
@@ -76,18 +80,20 @@
|
||||
"search_engine": "Search engine",
|
||||
"search_engine_hint": "Choose the search engine you want to use.",
|
||||
"show_custom_menu_links": "Show Custom Menu Links",
|
||||
"show_custom_menu_links_hint": "Show custom menu links defined inside your Jellyfin web\nconfig.json file"
|
||||
"show_custom_menu_links_hint": "Show custom menu links defined inside your Jellyfin web config.json file",
|
||||
"save_button": "Save"
|
||||
},
|
||||
"downloads": {
|
||||
"downloads_title": "Downloads",
|
||||
"download_method": "Download method",
|
||||
"download_method_hint": "Choose the download method to use. Optimized requires the\noptimized server.",
|
||||
"download_method_hint": "Choose the download method to use. Optimized requires the optimized server.",
|
||||
"remux_max_download": "Remux max download",
|
||||
"remux_max_download_hint": "This is the total media you want to be able to download at the\nsame time.",
|
||||
"remux_max_download_hint": "This is the total media you want to be able to download at the same time.",
|
||||
"auto_download": "Auto download",
|
||||
"auto_download_hint": "This will automatically download the media file when it's\nfinished optimizing on the server.",
|
||||
"auto_download_hint": "This will automatically download the media file when it's finished optimizing on the server.",
|
||||
"optimized_versions_server": "Optimized versions server",
|
||||
"optimized_versions_server_hint": "TSet the URL for the optimized versions server for downloads."
|
||||
"optimized_versions_server_hint": "Set the URL for the optimized versions server for downloads.",
|
||||
"save_button": "Save"
|
||||
},
|
||||
"jellyseer": {
|
||||
"jellyseer_warning": "This integration is in its early stages. Expect things to change.",
|
||||
@@ -95,7 +101,10 @@
|
||||
"server_url_hint": "Example: http(s)://your-host.url\n(add port if required)",
|
||||
"server_url_placeholder": "Jellyseerr URL...",
|
||||
"password": "Password",
|
||||
"password_placeholder": "Enter password for Jellyfin user {{username}}"
|
||||
"password_placeholder": "Enter password for Jellyfin user {{username}}",
|
||||
"save_button": "Save",
|
||||
"clear_button": "Clear",
|
||||
"login_button": "Login"
|
||||
},
|
||||
"storage": {
|
||||
"storage_title": "Storage",
|
||||
@@ -107,9 +116,7 @@
|
||||
"logs": {
|
||||
"logs_title": "Logs",
|
||||
"no_logs_available": "No logs available"
|
||||
},
|
||||
"save_button": "Save",
|
||||
"login_button": "Login"
|
||||
}
|
||||
},
|
||||
"downloads": {
|
||||
"downloads_title": "Downloads",
|
||||
|
||||
Reference in New Issue
Block a user