More settings + language component spacing

This commit is contained in:
Simon Caron
2025-01-12 21:30:57 -05:00
parent 7e62c9bc9a
commit ea1f45bbaf
15 changed files with 110 additions and 55 deletions

View File

@@ -1,10 +1,9 @@
import { nestedTabPageScreenOptions } from "@/components/stacks/NestedTabPageStack"; import { nestedTabPageScreenOptions } from "@/components/stacks/NestedTabPageStack";
import { Stack } from "expo-router"; import { Stack } from "expo-router";
import { Platform } from "react-native"; import { Platform } from "react-native";
import { useTranslation } from "react-i18next"; import { t } from "i18next";
export default function SearchLayout() { export default function SearchLayout() {
const { t } = useTranslation();
return ( return (
<Stack> <Stack>
<Stack.Screen <Stack.Screen

View File

@@ -94,11 +94,9 @@ export default function page() {
<Feather name="settings" size={28} color={"white"} /> <Feather name="settings" size={28} color={"white"} />
</View> </View>
<View className="shrink ml-2"> <View className="shrink ml-2">
<Text className="font-bold mb-1">Centralised Settings Plugin</Text> <Text className="font-bold mb-1">{t("home.intro.centralised_settings_plugin_title")}</Text>
<Text className="shrink text-xs"> <Text className="shrink text-xs">
Configure settings from a centralised location on your Jellyfin {t("home.intro.centralised_settings_plugin_description")}{" "}
server. All client settings for all users will be synced
automatically.{" "}
<Text <Text
className="text-purple-600" className="text-purple-600"
onPress={() => { onPress={() => {
@@ -107,7 +105,7 @@ export default function page() {
); );
}} }}
> >
Read more {t("home.intro.read_more")}
</Text> </Text>
</Text> </Text>
</View> </View>

View File

@@ -66,24 +66,25 @@ export default function settings() {
</MediaProvider> </MediaProvider>
<OtherSettings /> <OtherSettings />
<AppLanguageSelector/>
<DownloadSettings /> <DownloadSettings />
<PluginSettings /> <PluginSettings />
<AppLanguageSelector/>
<ListGroup title={"Intro"}> <ListGroup title={"Intro"}>
<ListItem <ListItem
onPress={() => { onPress={() => {
router.push("/intro/page"); router.push("/intro/page");
}} }}
title={"Show intro"} title={t("home.settings.intro.show_intro")}
/> />
<ListItem <ListItem
textColor="red" textColor="red"
onPress={() => { onPress={() => {
storage.set("hasShownIntro", false); storage.set("hasShownIntro", false);
}} }}
title={"Reset intro"} title={t("home.settings.intro.reset_intro")}
/> />
</ListGroup> </ListGroup>

View File

@@ -8,6 +8,7 @@ import { getUserViewsApi } from "@jellyfin/sdk/lib/utils/api";
import { useQuery } from "@tanstack/react-query"; import { useQuery } from "@tanstack/react-query";
import { useAtomValue } from "jotai"; import { useAtomValue } from "jotai";
import { Switch, View } from "react-native"; import { Switch, View } from "react-native";
import { useTranslation } from "react-i18next";
import DisabledSetting from "@/components/settings/DisabledSetting"; import DisabledSetting from "@/components/settings/DisabledSetting";
export default function page() { export default function page() {
@@ -15,6 +16,8 @@ export default function page() {
const user = useAtomValue(userAtom); const user = useAtomValue(userAtom);
const api = useAtomValue(apiAtom); const api = useAtomValue(apiAtom);
const { t } = useTranslation();
const { data, isLoading: isLoading } = useQuery({ const { data, isLoading: isLoading } = useQuery({
queryKey: ["user-views", user?.Id], queryKey: ["user-views", user?.Id],
queryFn: async () => { queryFn: async () => {
@@ -57,8 +60,7 @@ export default function page() {
))} ))}
</ListGroup> </ListGroup>
<Text className="px-4 text-xs text-neutral-500 mt-1"> <Text className="px-4 text-xs text-neutral-500 mt-1">
Select the libraries you want to hide from the Library tab and home page {t("home.settings.other.select_liraries_you_want_to_hide")}
sections.
</Text> </Text>
</DisabledSetting> </DisabledSetting>
); );

View File

@@ -4,6 +4,7 @@ import { useJellyfinDiscovery } from "@/hooks/useJellyfinDiscovery";
import { Button } from "./Button"; import { Button } from "./Button";
import { ListGroup } from "./list/ListGroup"; import { ListGroup } from "./list/ListGroup";
import { ListItem } from "./list/ListItem"; import { ListItem } from "./list/ListItem";
import { useTranslation } from "react-i18next";
interface Props { interface Props {
onServerSelect?: (server: { address: string; serverName?: string }) => void; onServerSelect?: (server: { address: string; serverName?: string }) => void;
@@ -11,17 +12,18 @@ interface Props {
const JellyfinServerDiscovery: React.FC<Props> = ({ onServerSelect }) => { const JellyfinServerDiscovery: React.FC<Props> = ({ onServerSelect }) => {
const { servers, isSearching, startDiscovery } = useJellyfinDiscovery(); const { servers, isSearching, startDiscovery } = useJellyfinDiscovery();
const { t } = useTranslation();
return ( return (
<View className="mt-2"> <View className="mt-2">
<Button onPress={startDiscovery} color="black"> <Button onPress={startDiscovery} color="black">
<Text className="text-white text-center"> <Text className="text-white text-center">
{isSearching ? "Searching..." : "Search for local servers"} {isSearching ? t("server.searching") : t("server.search_for_local_servers")}
</Text> </Text>
</Button> </Button>
{servers.length ? ( {servers.length ? (
<ListGroup title="Servers" className="mt-4"> <ListGroup title={t("server.servers")} className="mt-4">
{servers.map((server) => ( {servers.map((server) => (
<ListItem <ListItem
key={server.address} key={server.address}

View File

@@ -15,6 +15,7 @@ import { useAtom } from "jotai";
import { useMemo } from "react"; import { useMemo } from "react";
import { TouchableOpacityProps, View } from "react-native"; import { TouchableOpacityProps, View } from "react-native";
import { TouchableItemRouter } from "../common/TouchableItemRouter"; import { TouchableItemRouter } from "../common/TouchableItemRouter";
import { useTranslation } from "react-i18next";
interface Props extends TouchableOpacityProps { interface Props extends TouchableOpacityProps {
library: BaseItemDto; library: BaseItemDto;
@@ -42,6 +43,8 @@ export const LibraryItemCard: React.FC<Props> = ({ library, ...props }) => {
const [user] = useAtom(userAtom); const [user] = useAtom(userAtom);
const [settings] = useSettings(); const [settings] = useSettings();
const { t } = useTranslation();
const url = useMemo( const url = useMemo(
() => () =>
getPrimaryImageUrl({ getPrimaryImageUrl({
@@ -69,13 +72,13 @@ export const LibraryItemCard: React.FC<Props> = ({ library, ...props }) => {
let nameStr: string; let nameStr: string;
if (library.CollectionType === "movies") { if (library.CollectionType === "movies") {
nameStr = "movies"; nameStr = t("library.item_types.movies");
} else if (library.CollectionType === "tvshows") { } else if (library.CollectionType === "tvshows") {
nameStr = "series"; nameStr = t("library.item_types.series");
} else if (library.CollectionType === "boxsets") { } else if (library.CollectionType === "boxsets") {
nameStr = "box sets"; nameStr = t("library.item_types.boxsets");
} else { } else {
nameStr = "items"; nameStr = t("library.item_types.items");
} }
return nameStr; return nameStr;

View File

@@ -47,7 +47,7 @@ export const AudioToggles: React.FC<Props> = ({ ...props }) => {
<DropdownMenu.Trigger> <DropdownMenu.Trigger>
<TouchableOpacity className="flex flex-row items-center justify-between py-3 pl-3 "> <TouchableOpacity className="flex flex-row items-center justify-between py-3 pl-3 ">
<Text className="mr-1 text-[#8E8D91]"> <Text className="mr-1 text-[#8E8D91]">
{settings?.defaultAudioLanguage?.DisplayName || "None"} {settings?.defaultAudioLanguage?.DisplayName || t("home.settings.audio.none")}
</Text> </Text>
<Ionicons <Ionicons
name="chevron-expand-sharp" name="chevron-expand-sharp"
@@ -65,7 +65,7 @@ export const AudioToggles: React.FC<Props> = ({ ...props }) => {
collisionPadding={8} collisionPadding={8}
sideOffset={8} sideOffset={8}
> >
<DropdownMenu.Label>Languages</DropdownMenu.Label> <DropdownMenu.Label>{t("home.settings.audio.language")}</DropdownMenu.Label>
<DropdownMenu.Item <DropdownMenu.Item
key={"none-audio"} key={"none-audio"}
onSelect={() => { onSelect={() => {

View File

@@ -61,7 +61,7 @@ export const DownloadSettings: React.FC = ({ ...props }) => {
collisionPadding={8} collisionPadding={8}
sideOffset={8} sideOffset={8}
> >
<DropdownMenu.Label>Methods</DropdownMenu.Label> <DropdownMenu.Label>{t("home.settings.downloads.methods")}</DropdownMenu.Label>
<DropdownMenu.Item <DropdownMenu.Item
key="1" key="1"
onSelect={() => { onSelect={() => {
@@ -69,7 +69,7 @@ export const DownloadSettings: React.FC = ({ ...props }) => {
setProcesses([]); setProcesses([]);
}} }}
> >
<DropdownMenu.ItemTitle>Default</DropdownMenu.ItemTitle> <DropdownMenu.ItemTitle>{t("home.settings.downloads.default")}</DropdownMenu.ItemTitle>
</DropdownMenu.Item> </DropdownMenu.Item>
<DropdownMenu.Item <DropdownMenu.Item
key="2" key="2"
@@ -79,7 +79,7 @@ export const DownloadSettings: React.FC = ({ ...props }) => {
queryClient.invalidateQueries({ queryKey: ["search"] }); queryClient.invalidateQueries({ queryKey: ["search"] });
}} }}
> >
<DropdownMenu.ItemTitle>Optimized</DropdownMenu.ItemTitle> <DropdownMenu.ItemTitle>{t("home.settings.downloads.optimized")}</DropdownMenu.ItemTitle>
</DropdownMenu.Item> </DropdownMenu.Item>
</DropdownMenu.Content> </DropdownMenu.Content>
</DropdownMenu.Root> </DropdownMenu.Root>

View File

@@ -37,7 +37,7 @@ export const MediaToggles: React.FC<Props> = ({ ...props }) => {
value={settings.forwardSkipTime} value={settings.forwardSkipTime}
disabled={pluginSettings?.forwardSkipTime?.locked} disabled={pluginSettings?.forwardSkipTime?.locked}
step={5} step={5}
appendValue="s" appendValue={t("home.settings.media_controls.seconds_unit")}
min={0} min={0}
max={60} max={60}
onUpdate={(forwardSkipTime) => updateSettings({forwardSkipTime})} onUpdate={(forwardSkipTime) => updateSettings({forwardSkipTime})}
@@ -52,7 +52,7 @@ export const MediaToggles: React.FC<Props> = ({ ...props }) => {
value={settings.rewindSkipTime} value={settings.rewindSkipTime}
disabled={pluginSettings?.rewindSkipTime?.locked} disabled={pluginSettings?.rewindSkipTime?.locked}
step={5} step={5}
appendValue="s" appendValue={t("home.settings.media_controls.seconds_unit")}
min={0} min={0}
max={60} max={60}
onUpdate={(rewindSkipTime) => updateSettings({rewindSkipTime})} onUpdate={(rewindSkipTime) => updateSettings({rewindSkipTime})}

View File

@@ -147,11 +147,11 @@ export const OtherSettings: React.FC = () => {
</ListItem> </ListItem>
<ListItem <ListItem
onPress={() => router.push("/settings/hide-libraries/page")} onPress={() => router.push("/settings/hide-libraries/page")}
title="Hide Libraries" title={t("home.settings.other.hide_libraries")}
showArrow showArrow
/> />
<ListItem <ListItem
title="Disable Haptic Feedback" title={t("home.settings.other.disable_haptic_feedback")}
disabled={pluginSettings?.disableHapticFeedback?.locked} disabled={pluginSettings?.disableHapticFeedback?.locked}
> >
<Switch <Switch

View File

@@ -16,7 +16,7 @@ export const PluginSettings = () => {
if (!settings) return null; if (!settings) return null;
return ( return (
<View> <View>
<ListGroup title={t("home.settings.plugins.plugins_title")}> <ListGroup title={t("home.settings.plugins.plugins_title")} className="mb-4">
<ListItem <ListItem
onPress={() => router.push("/settings/jellyseerr/page")} onPress={() => router.push("/settings/jellyseerr/page")}
title={"Jellyseerr"} title={"Jellyseerr"}

View File

@@ -65,7 +65,7 @@ export const QuickConnect: React.FC<Props> = ({ ...props }) => {
return ( return (
<View {...props}> <View {...props}>
<ListGroup title={"Quick Connect"}> <ListGroup title={t("home.settings.quick_connect.quick_connect_title")}>
<ListItem <ListItem
onPress={() => bottomSheetModalRef?.current?.present()} onPress={() => bottomSheetModalRef?.current?.present()}
title={t("home.settings.quick_connect.authorize_button")} title={t("home.settings.quick_connect.authorize_button")}
@@ -96,7 +96,7 @@ export const QuickConnect: React.FC<Props> = ({ ...props }) => {
<BottomSheetTextInput <BottomSheetTextInput
style={{ color: "white" }} style={{ color: "white" }}
clearButtonMode="always" clearButtonMode="always"
placeholder="Enter the quick connect code..." placeholder={t("home.settings.quick_connect.enter_the_quick_connect_code")}
placeholderTextColor="#9CA3AF" placeholderTextColor="#9CA3AF"
value={quickConnectCode} value={quickConnectCode}
onChangeText={setQuickConnectCode} onChangeText={setQuickConnectCode}
@@ -108,7 +108,7 @@ export const QuickConnect: React.FC<Props> = ({ ...props }) => {
onPress={authorizeQuickConnect} onPress={authorizeQuickConnect}
color="purple" color="purple"
> >
Authorize {t("home.settings.quick_connect.authorize")}
</Button> </Button>
</View> </View>
</BottomSheetView> </BottomSheetView>

View File

@@ -43,7 +43,7 @@ export const SubtitleToggles: React.FC<Props> = ({ ...props }) => {
> >
<ListItem title={t("home.settings.subtitles.subtitle_language")}> <ListItem title={t("home.settings.subtitles.subtitle_language")}>
<Dropdown <Dropdown
data={[{DisplayName: "None", ThreeLetterISOLanguageName: "none-subs" },...(cultures ?? [])]} data={[{DisplayName: t("home.settings.subtitles.none"), ThreeLetterISOLanguageName: "none-subs" },...(cultures ?? [])]}
keyExtractor={(item) => item?.ThreeLetterISOLanguageName ?? "unknown"} keyExtractor={(item) => item?.ThreeLetterISOLanguageName ?? "unknown"}
titleExtractor={(item) => item?.DisplayName} titleExtractor={(item) => item?.DisplayName}
title={ title={
@@ -58,7 +58,7 @@ export const SubtitleToggles: React.FC<Props> = ({ ...props }) => {
/> />
</TouchableOpacity> </TouchableOpacity>
} }
label="Languages" label={t("home.settings.subtitles.language")}
onSelected={(defaultSubtitleLanguage) => onSelected={(defaultSubtitleLanguage) =>
updateSettings({ updateSettings({
defaultSubtitleLanguage: defaultSubtitleLanguage.DisplayName === t("home.settings.subtitles.none") defaultSubtitleLanguage: defaultSubtitleLanguage.DisplayName === t("home.settings.subtitles.none")
@@ -81,7 +81,7 @@ export const SubtitleToggles: React.FC<Props> = ({ ...props }) => {
title={ title={
<TouchableOpacity className="flex flex-row items-center justify-between py-3 pl-3"> <TouchableOpacity className="flex flex-row items-center justify-between py-3 pl-3">
<Text className="mr-1 text-[#8E8D91]"> <Text className="mr-1 text-[#8E8D91]">
{settings?.subtitleMode || "Loading"} {settings?.subtitleMode || t("home.settings.subtitles.loading")}
</Text> </Text>
<Ionicons <Ionicons
name="chevron-expand-sharp" name="chevron-expand-sharp"
@@ -90,7 +90,7 @@ export const SubtitleToggles: React.FC<Props> = ({ ...props }) => {
/> />
</TouchableOpacity> </TouchableOpacity>
} }
label="Subtitle Mode" label={t("home.settings.subtitles.subtitle_mode")}
onSelected={(subtitleMode) => onSelected={(subtitleMode) =>
updateSettings({subtitleMode}) updateSettings({subtitleMode})
} }

View File

@@ -27,7 +27,10 @@
"server_url_placeholder": "http(s)://your-server.com", "server_url_placeholder": "http(s)://your-server.com",
"connect_button": "Connect", "connect_button": "Connect",
"previous_servers": "previous servers", "previous_servers": "previous servers",
"clear_button": "Clear" "clear_button": "Clear",
"search_for_local_servers": "Search for local servers",
"searching": "Searching...",
"servers": "Servers"
}, },
"home": { "home": {
"no_internet": "No Internet", "no_internet": "No Internet",
@@ -50,8 +53,11 @@
"downloads_feature_title": "Downloads", "downloads_feature_title": "Downloads",
"downloads_feature_description": "Download movies and tv-shows to view offline. Use either the default method or install the optimize server to download files in the background.", "downloads_feature_description": "Download movies and tv-shows to view offline. Use either the default method or install the optimize server to download files in the background.",
"chromecast_feature_description": "Cast movies and tv-shows to your Chromecast devices.", "chromecast_feature_description": "Cast movies and tv-shows to your Chromecast devices.",
"centralised_settings_plugin_title": "Centralised Settings Plugin",
"centralised_settings_plugin_description": "Configure settings from a centralised location on your Jellyfin server. All client settings for all users will be synced automatically.",
"done_button": "Done", "done_button": "Done",
"go_to_settings_button": "Go to settings" "go_to_settings_button": "Go to settings",
"read_more": "Read more"
}, },
"settings": { "settings": {
"settings_title": "Settings", "settings_title": "Settings",
@@ -66,23 +72,26 @@
"quick_connect": { "quick_connect": {
"quick_connect_title": "Quick Connect", "quick_connect_title": "Quick Connect",
"authorize_button": "Authorize Quick Connect", "authorize_button": "Authorize Quick Connect",
"enter_the_quick_connect_code": "Enter the Quick Connect code", "enter_the_quick_connect_code": "Enter the quick connect code...",
"success": "Success", "success": "Success",
"quick_connect_autorized": "Quick Connect authorized", "quick_connect_autorized": "Quick Connect authorized",
"error": "Error", "error": "Error",
"invalid_code": "Invalid code" "invalid_code": "Invalid code",
"authorize": "Authorize"
}, },
"media_controls": { "media_controls": {
"media_controls_title": "Media Controls", "media_controls_title": "Media Controls",
"forward_skip_length": "Forward skip length", "forward_skip_length": "Forward skip length",
"rewind_length": "Rewind length" "rewind_length": "Rewind length",
"seconds_unit": "s"
}, },
"audio": { "audio": {
"audio_title": "Audio", "audio_title": "Audio",
"set_audio_track": "Set Audio Track From Previous Item", "set_audio_track": "Set Audio Track From Previous Item",
"audio_language": "Audio language", "audio_language": "Audio language",
"audio_hint": "Choose a default audio language.", "audio_hint": "Choose a default audio language.",
"none": "None" "none": "None",
"language": "Language"
}, },
"subtitles": { "subtitles": {
"subtitle_title": "Subtitles", "subtitle_title": "Subtitles",
@@ -91,14 +100,19 @@
"set_subtitle_track": "Set Subtitle Track From Previous Item", "set_subtitle_track": "Set Subtitle Track From Previous Item",
"subtitle_size": "Subtitle Size", "subtitle_size": "Subtitle Size",
"subtitle_hint": "Configure subtitle preference.", "subtitle_hint": "Configure subtitle preference.",
"none": "None" "none": "None",
"language": "Language",
"loading": "Loading"
}, },
"other": { "other": {
"other_title": "Other", "other_title": "Other",
"auto_rotate": "Auto rotate", "auto_rotate": "Auto rotate",
"video_orientation": "Video orientation", "video_orientation": "Video orientation",
"safe_area_in_controls": "Safe area in controls", "safe_area_in_controls": "Safe area in controls",
"show_custom_menu_links": "Show Custom Menu Links" "show_custom_menu_links": "Show Custom Menu Links",
"hide_libraries": "Hide Libraries",
"select_liraries_you_want_to_hide": "Select the libraries you want to hide from the Library tab and home page sections.",
"disable_haptic_feedback": "Disable Haptic Feedback"
}, },
"downloads": { "downloads": {
"downloads_title": "Downloads", "downloads_title": "Downloads",
@@ -162,6 +176,10 @@
"size_used": "{{used}} of {{total}} used", "size_used": "{{used}} of {{total}} used",
"delete_all_downloaded_files": "Delete All Downloaded Files" "delete_all_downloaded_files": "Delete All Downloaded Files"
}, },
"intro": {
"show_intro": "Show intro",
"reset_intro": "Reset intro"
},
"logs": { "logs": {
"logs_title": "Logs", "logs_title": "Logs",
"no_logs_available": "No logs available", "no_logs_available": "No logs available",
@@ -203,6 +221,7 @@
"something_went_wrong": "Something went wrong", "something_went_wrong": "Something went wrong",
"could_not_get_stream_url_from_jellyfin": "Could not get stream URL from Jellyfin", "could_not_get_stream_url_from_jellyfin": "Could not get stream URL from Jellyfin",
"eta": "ETA {{eta}}", "eta": "ETA {{eta}}",
"methods": "Methods",
"toasts": { "toasts": {
"you_are_not_allowed_to_download_files": "You are not allowed to download files.", "you_are_not_allowed_to_download_files": "You are not allowed to download files.",
"deleted_all_movies_successfully": "Deleted all movies successfully!", "deleted_all_movies_successfully": "Deleted all movies successfully!",
@@ -270,6 +289,12 @@
"no_items_found": "No items found", "no_items_found": "No items found",
"no_results": "No results", "no_results": "No results",
"no_libraries_found": "No libraries found", "no_libraries_found": "No libraries found",
"item_types": {
"movies": "movies",
"series": "series",
"boxsets": "box sets",
"items": "items"
},
"options": { "options": {
"display": "Display", "display": "Display",
"row": "Row", "row": "Row",

View File

@@ -27,7 +27,10 @@
"server_url_placeholder": "http(s)://votre-serveur.com", "server_url_placeholder": "http(s)://votre-serveur.com",
"connect_button": "Connexion", "connect_button": "Connexion",
"previous_servers": "Serveurs précédents", "previous_servers": "Serveurs précédents",
"clear_button": "Effacer" "clear_button": "Effacer",
"search_for_local_servers": "Rechercher des serveurs locaux",
"searching": "Recherche...",
"servers": "Serveurs"
}, },
"home": { "home": {
"no_internet": "Pas d'Internet", "no_internet": "Pas d'Internet",
@@ -50,8 +53,11 @@
"downloads_feature_title": "Téléchargements", "downloads_feature_title": "Téléchargements",
"downloads_feature_description": "Téléchargez des films et des émissions de télévision pour les regarder hors ligne. Utilisez la méthode par défaut ou installez le serveur d'optimisation pour télécharger les fichiers en arrière-plan.", "downloads_feature_description": "Téléchargez des films et des émissions de télévision pour les regarder hors ligne. Utilisez la méthode par défaut ou installez le serveur d'optimisation pour télécharger les fichiers en arrière-plan.",
"chromecast_feature_description": "Diffusez des films et des émissions de télévision sur vos appareils Chromecast.", "chromecast_feature_description": "Diffusez des films et des émissions de télévision sur vos appareils Chromecast.",
"centralised_settings_plugin_title": "Plugin de paramètres centralisés",
"centralised_settings_plugin_description": "Configuration des paramètres d'un emplacement centralisé sur votre serveur Jellyfin. Tous les paramètres clients pour tous les utilisateurs seront synchronisés automatiquement.",
"done_button": "Fait", "done_button": "Fait",
"go_to_settings_button": "Allez dans les paramètres" "go_to_settings_button": "Allez dans les paramètres",
"read_more": "Lisez-en plus"
}, },
"settings": { "settings": {
"settings_title": "Paramètres", "settings_title": "Paramètres",
@@ -66,23 +72,26 @@
"quick_connect": { "quick_connect": {
"quick_connect_title": "Connexion Rapide", "quick_connect_title": "Connexion Rapide",
"authorize_button": "Autoriser Connexion Rapide", "authorize_button": "Autoriser Connexion Rapide",
"enter_the_quick_connect_code": "Entrez le code Connexion Rapide", "enter_the_quick_connect_code": "Entrez le code Connexion Rapide...",
"success": "Succès", "success": "Succès",
"quick_connect_autorized": "Connexion Rapide autorisé", "quick_connect_autorized": "Connexion Rapide autorisé",
"error": "Errur", "error": "Erreur",
"invalid_code": "Code invalide" "invalid_code": "Code invalide",
"authorize": "Autoriser"
}, },
"media_controls": { "media_controls": {
"media_controls_title": "Contrôles Média", "media_controls_title": "Contrôles Média",
"forward_skip_length": "Durée de saut en avant", "forward_skip_length": "Durée de saut en avant",
"rewind_length": "Durée de retour arrière" "rewind_length": "Durée de retour arrière",
"seconds_unit": "s"
}, },
"audio": { "audio": {
"audio_title": "Audio", "audio_title": "Audio",
"set_audio_track": "Configurer la piste audio à partir de l'élément précédent", "set_audio_track": "Configurer la piste audio à partir de l'élément précédent",
"audio_language": "Langue audio", "audio_language": "Langue audio",
"audio_hint": "Chosissez une langue audio par défaut.", "audio_hint": "Chosissez une langue audio par défaut.",
"none": "Aucune" "none": "Aucune",
"language": "Langage"
}, },
"subtitles": { "subtitles": {
"subtitle_title": "Sous-titres", "subtitle_title": "Sous-titres",
@@ -91,14 +100,19 @@
"set_subtitle_track": "Configurer la piste de sous-titres à partir de l'élément précédent", "set_subtitle_track": "Configurer la piste de sous-titres à partir de l'élément précédent",
"subtitle_size": "Taille des sous-titres", "subtitle_size": "Taille des sous-titres",
"subtitle_hint": "Configurez les préférences des sous-titres.", "subtitle_hint": "Configurez les préférences des sous-titres.",
"none": "Aucune" "none": "Aucune",
"language": "Langage",
"loading": "Chargement"
}, },
"other": { "other": {
"other_title": "Autres", "other_title": "Autres",
"auto_rotate": "Rotation automatique", "auto_rotate": "Rotation automatique",
"video_orientation": "Orientation vidéo", "video_orientation": "Orientation vidéo",
"safe_area_in_controls": "Zone de sécurité dans les contrôles", "safe_area_in_controls": "Zone de sécurité dans les contrôles",
"show_custom_menu_links": "Afficher les liens personnalisés" "show_custom_menu_links": "Afficher les liens personnalisés",
"hide_libraries": "Cacher des bibliothèques",
"select_liraries_you_want_to_hide": "Sélectionnez les bibliothèques que vous souhaitez obtenir de la table de bibliothèque et de la page d'accueil des sections.",
"disable_haptic_feedback": "Désactiver le retour haptique"
}, },
"downloads": { "downloads": {
"downloads_title": "Téléchargements", "downloads_title": "Téléchargements",
@@ -109,7 +123,7 @@
"save_button": "Enregistrer", "save_button": "Enregistrer",
"optimized_server": "Serveur optimisé", "optimized_server": "Serveur optimisé",
"optimized": "Optimisé", "optimized": "Optimisé",
"default": "Défaut", "default": "Par défaut",
"optimized_version_hint": "Entrez l'URL du serveur de versions optimisées. L'URL devrait inclure http ou https et optionnellement le port.", "optimized_version_hint": "Entrez l'URL du serveur de versions optimisées. L'URL devrait inclure http ou https et optionnellement le port.",
"read_more_about_optimized_server": "Lisez-en plus sur le serveur de versions optimisées.", "read_more_about_optimized_server": "Lisez-en plus sur le serveur de versions optimisées.",
"url": "URL", "url": "URL",
@@ -121,7 +135,7 @@
"jellyseerr_warning": "Cette intégration est dans ses débuts. Attendez-vous à ce que des choses changent.", "jellyseerr_warning": "Cette intégration est dans ses débuts. Attendez-vous à ce que des choses changent.",
"server_url": "URL du serveur", "server_url": "URL du serveur",
"server_url_hint": "Exemple: http(s)://votre-domaine.url\n(ajouter le port si nécessaire)", "server_url_hint": "Exemple: http(s)://votre-domaine.url\n(ajouter le port si nécessaire)",
"server_url_placeholder": "URL Jellyseerr...", "server_url_placeholder": "URL de Jellyseerr...",
"password": "Mot de passe", "password": "Mot de passe",
"password_placeholder": "Entrez le mot de passe pour l'utilisateur Jellyfin {{username}}", "password_placeholder": "Entrez le mot de passe pour l'utilisateur Jellyfin {{username}}",
"save_button": "Enregistrer", "save_button": "Enregistrer",
@@ -159,9 +173,13 @@
"storage_title": "Stockage", "storage_title": "Stockage",
"app_usage": "App {{usedSpace}}%", "app_usage": "App {{usedSpace}}%",
"phone_usage": "Téléphone {{availableSpace}}%", "phone_usage": "Téléphone {{availableSpace}}%",
"size_used": "{{used}} de {{total}} utilisé", "size_used": "{{used}} de {{total}} utilisés",
"delete_all_downloaded_files": "Supprimer tous les fichiers téléchargés" "delete_all_downloaded_files": "Supprimer tous les fichiers téléchargés"
}, },
"intro": {
"show_intro": "Afficher l'intro",
"reset_intro": "Réinitialiser l'intro"
},
"logs": { "logs": {
"logs_title": "Journaux", "logs_title": "Journaux",
"no_logs_available": "Aucun journal disponible", "no_logs_available": "Aucun journal disponible",
@@ -203,6 +221,7 @@
"something_went_wrong": "Quelque chose s'est mal passé", "something_went_wrong": "Quelque chose s'est mal passé",
"could_not_get_stream_url_from_jellyfin": "Impossible d'obtenir l'URL du flux depuis Jellyfin", "could_not_get_stream_url_from_jellyfin": "Impossible d'obtenir l'URL du flux depuis Jellyfin",
"eta": "ETA {{eta}}", "eta": "ETA {{eta}}",
"methods": "Méthodes",
"toasts": { "toasts": {
"you_are_not_allowed_to_download_files": "Vous n'êtes pas autorisé à télécharger des fichiers", "you_are_not_allowed_to_download_files": "Vous n'êtes pas autorisé à télécharger des fichiers",
"deleted_all_movies_successfully": "Tous les films ont été supprimés avec succès!", "deleted_all_movies_successfully": "Tous les films ont été supprimés avec succès!",
@@ -270,6 +289,12 @@
"no_items_found": "Aucun item trouvé", "no_items_found": "Aucun item trouvé",
"no_results": "Aucun résultat", "no_results": "Aucun résultat",
"no_libraries_found": "Aucune bibliothèque trouvée", "no_libraries_found": "Aucune bibliothèque trouvée",
"item_types": {
"movies": "films",
"series": "séries",
"boxsets": "coffrets",
"items": "items"
},
"options": { "options": {
"display": "Affichage", "display": "Affichage",
"row": "Rangée", "row": "Rangée",