Fix some missing fields

This commit is contained in:
Simon Caron
2025-01-07 22:26:09 -05:00
parent 2da774272d
commit 14c8c1aaed
10 changed files with 129 additions and 37 deletions

View File

@@ -6,9 +6,11 @@ import { Image } from "expo-image";
import { useFocusEffect, useRouter } from "expo-router";
import { useCallback } from "react";
import { TouchableOpacity, View } from "react-native";
import {useTranslation } from "react-i18next";
export default function page() {
const router = useRouter();
const { t } = useTranslation();
useFocusEffect(
useCallback(() => {
@@ -20,18 +22,17 @@ export default function page() {
<View className="bg-neutral-900 h-full py-32 px-4 space-y-4">
<View>
<Text className="text-3xl font-bold text-center mb-2">
Welcome to Streamyfin
{t("home.intro.welcome_to_streamyfin")}
</Text>
<Text className="text-center">
A free and open source client for Jellyfin.
{t("home.intro.a_free_and_open_source_client_for_jellyfin")}
</Text>
</View>
<View>
<Text className="text-lg font-bold">Features</Text>
<Text className="text-lg font-bold">{t("home.intro.features_title")}</Text>
<Text className="text-xs">
Streamyfin has a bunch of features and integrates with a wide array of
software which you can find in the settings menu, these include:
{t("home.intro.features_description")}
</Text>
<View className="flex flex-row items-center mt-4">
<Image
@@ -44,8 +45,7 @@ export default function page() {
<View className="shrink ml-2">
<Text className="font-bold mb-1">Jellyseerr</Text>
<Text className="shrink text-xs">
Connect to your Jellyseerr instance and request movies directly in
the app.
{t("home.intro.jellyseerr_feature_description")}
</Text>
</View>
</View>
@@ -60,11 +60,9 @@ export default function page() {
<Ionicons name="cloud-download-outline" size={32} color="white" />
</View>
<View className="shrink ml-2">
<Text className="font-bold mb-1">Downloads</Text>
<Text className="font-bold mb-1">{t("home.intro.downloads_feature_title")}</Text>
<Text className="shrink text-xs">
Download movies and tv-shows to view offline. Use either the
default method or install the optimize server to download files in
the background.
{t("home.intro.downloads_feature_description")}
</Text>
</View>
</View>
@@ -81,7 +79,7 @@ export default function page() {
<View className="shrink ml-2">
<Text className="font-bold mb-1">Chromecast</Text>
<Text className="shrink text-xs">
Cast movies and tv-shows to your Chromecast devices.
{t("home.intro.chromecast_feature_description")}
</Text>
</View>
</View>
@@ -93,7 +91,7 @@ export default function page() {
}}
className="mt-4"
>
Done
{t("home.intro.done_button")}
</Button>
<TouchableOpacity
onPress={() => {
@@ -102,7 +100,7 @@ export default function page() {
}}
className="mt-4"
>
<Text className="text-purple-600 text-center">Go to settings</Text>
<Text className="text-purple-600 text-center">{t("home.intro.go_to_settings_button")}</Text>
</TouchableOpacity>
</View>
);

View File

@@ -30,7 +30,7 @@ export default function page() {
updateSettings({
marlinServerUrl: !val.endsWith("/") ? val : val.slice(0, -1),
});
toast.success("Saved");
toast.success(t("home.settings.plugins.marlin_search.toasts.saved"));
};
const handleOpenLink = () => {
@@ -82,7 +82,7 @@ export default function page() {
<TextInput
editable={settings.searchEngine === "Marlin"}
className="text-white"
placeholder={t("home.settings.plugins.marlin_search.url")}
placeholder={t("home.settings.plugins.marlin_search.server_url_placeholder")}
value={value}
keyboardType="url"
returnKeyType="done"

View File

@@ -83,7 +83,7 @@ const CredentialsSchema = z.object({
className="flex flex-row items-center"
>
<Ionicons name="chevron-back" size={18} color={Colors.primary} />
<Text className="ml-2 text-purple-600">Change server</Text>
<Text className="ml-2 text-purple-600">{t("login.change_server")}</Text>
</TouchableOpacity>
) : null,
});
@@ -100,9 +100,9 @@ const CredentialsSchema = z.object({
}
} catch (error) {
if (error instanceof Error) {
Alert.alert("Connection failed", error.message);
Alert.alert(t("login.connection_failed"), error.message);
} else {
Alert.alert("Connection failed", "An unexpected error occurred");
Alert.alert(t("login.connection_failed"), t("login.an_unexpeted_error_occured"));
}
} finally {
setLoading(false);

View File

@@ -56,7 +56,7 @@ export const SubtitleTrackSelector: React.FC<Props> = ({
<Text className=" ">
{selectedSubtitleSteam
? tc(selectedSubtitleSteam?.DisplayTitle, 7)
: "None"}
: t("item_card.none")}
</Text>
</TouchableOpacity>
</View>

View File

@@ -4,6 +4,7 @@ import { DiscoverSliderType } from "@/utils/jellyseerr/server/constants/discover
import { Text } from "@/components/common/Text";
import { FlashList } from "@shopify/flash-list";
import {View, ViewProps} from "react-native";
import { t } from "i18next";
export interface SlideProps {
slide: DiscoverSlider;
@@ -32,7 +33,7 @@ const Slide = <T extends unknown>({
return (
<View {...props}>
<Text className="font-bold text-lg mb-2 px-4">
{DiscoverSliderType[slide.type].toString().toTitle()}
{t("search." + DiscoverSliderType[slide.type].toString().toLowerCase())}
</Text>
<FlashList
horizontal

View File

@@ -68,7 +68,7 @@ export const AudioToggles: React.FC<Props> = ({ ...props }) => {
});
}}
>
<DropdownMenu.ItemTitle>t("home.settings.audio.none")</DropdownMenu.ItemTitle>
<DropdownMenu.ItemTitle>{t("home.settings.audio.none")}</DropdownMenu.ItemTitle>
</DropdownMenu.Item>
{cultures?.map((l) => (
<DropdownMenu.Item

View File

@@ -42,7 +42,7 @@ export const SubtitleToggles: React.FC<Props> = ({ ...props }) => {
<DropdownMenu.Trigger>
<TouchableOpacity className="flex flex-row items-center justify-between py-3 pl-3">
<Text className="mr-1 text-[#8E8D91]">
{settings?.defaultSubtitleLanguage?.DisplayName || "None"}
{settings?.defaultSubtitleLanguage?.DisplayName || t("home.settings.subtitles.none")}
</Text>
<Ionicons
name="chevron-expand-sharp"

View File

@@ -20,6 +20,7 @@ import { Platform } from "react-native";
import uuid from "react-native-uuid";
import { getDeviceName } from "react-native-device-info";
import { toast } from "sonner-native";
import { useTranslation } from "react-i18next";
interface Server {
address: string;
@@ -48,6 +49,8 @@ export const JellyfinProvider: React.FC<{ children: ReactNode }> = ({
const [jellyfin, setJellyfin] = useState<Jellyfin | undefined>(undefined);
const [deviceId, setDeviceId] = useState<string | undefined>(undefined);
const { t } = useTranslation();
useEffect(() => {
(async () => {
const id = getOrSetDeviceId();
@@ -231,22 +234,22 @@ export const JellyfinProvider: React.FC<{ children: ReactNode }> = ({
if (axios.isAxiosError(error)) {
switch (error.response?.status) {
case 401:
throw new Error("Invalid username or password");
throw new Error(t("login.invalid_username_or_password"));
case 403:
throw new Error("User does not have permission to log in");
throw new Error(t("login.user_does_not_have_permission_to_log_in"));
case 408:
throw new Error(
"Server is taking too long to respond, try again later"
t("login.server_is_taking_too_long_to_respond_try_again_later")
);
case 429:
throw new Error(
"Server received too many requests, try again later"
t("login.server_received_too_many_requests_try_again_later")
);
case 500:
throw new Error("There is a server error");
throw new Error(t("login.there_is_a_server_error"));
default:
throw new Error(
"An unexpected error occurred. Did you enter the server URL correctly?"
t("login.an_unexpected_error_occured_did_you_enter_the_correct_url")
);
}
}

View File

@@ -12,7 +12,15 @@
"failed_to_initiate_quick_connect": "Failed to initiate Quick Connect",
"got_it": "Got it",
"connection_failed": "Connection failed",
"could_not_connect_to_server": "Could not connect to the server. Please check the URL and your network connection."
"could_not_connect_to_server": "Could not connect to the server. Please check the URL and your network connection.",
"an_unexpected_error_occured": "An unexpected error occurred",
"change_server": "Change server",
"invalid_username_or_password": "Invalid username or password",
"user_does_not_have_permission_to_log_in": "User does not have permission to log in",
"server_is_taking_too_long_to_respond_try_again_later": "Server is taking too long to respond, try again later",
"server_received_too_many_requests_try_again_later": "Server received too many requests, try again late.",
"there_is_a_server_error": "There is a server error",
"an_unexpected_error_occured_did_you_enter_the_correct_url": "An unexpected error occurred. Did you enter the server URL correctly?"
},
"server": {
"enter_url_to_jellyfin_server": "Enter the URL to your Jellyfin server",
@@ -33,6 +41,18 @@
"recently_added_in": "Recently Added in {{libraryName}}",
"suggested_movies": "Suggested Movies",
"suggested_episodes": "Suggested Episodes",
"intro": {
"welcome_to_streamyfin": "Welcome to Streamyfin",
"a_free_and_open_source_client_for_jellyfin": "A free and open-source client for Jellyfin.",
"features_title": "Features",
"features_description": "Streamyfin has a bunch of features and integrates with a wide array of software which you can find in the settings menu, these include:",
"jellyseerr_feature_description": "Connect to your Jellyseerr instance and request movies directly in the app.",
"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.",
"chromecast_feature_description": "Cast movies and tv-shows to your Chromecast devices.",
"done_button": "Done",
"go_to_settings_button": "Go to settings"
},
"settings": {
"settings_title": "Settings",
"log_out_button": "Log out",
@@ -121,7 +141,10 @@
"server_url_placeholder": "http(s)://domain.org:port",
"marlin_search_hint": "Enter the URL for the Marlin server. The URL should include http or https and optionally the port.",
"read_more_about_marlin": "Read more about Marlin.",
"save_button": "Save"
"save_button": "Save",
"toasts": {
"saved": "Saved"
}
},
"popular_lists": {
"enable_plugin": "Enable plugin",
@@ -223,7 +246,28 @@
"albums": "Albums",
"songs": "Songs",
"request_movies": "Request Movies",
"request_series": "Request Series"
"request_series": "Request Series",
"recently_added": "Recently Added",
"recent_requests": "Recent Requests",
"plex_watchlist": "Plex Watchlist",
"trending": "Trending",
"popular_movies": "Popular Movies",
"movie_genres": "Movie Genres",
"upcoming_movies": "Upcoming Movies",
"studios": "Studios",
"popular_tv": "Popular TV",
"tv_genres": "TV Genres",
"upcoming_tv": "Upcoming TV",
"networks": "Networks",
"tmdb_movie_keyword": "TMDB Movie Keyword",
"tmdb_movie_genre": "TMDB Movie Genre",
"tmdb_tv_keyword": "TMDB TV Keyword",
"tmdb_tv_genre": "TMDB TV Genre",
"tmdb_search": "TMDB Search",
"tmdb_studio": "TMDB Studio",
"tmdb_network": "TMDB Network",
"tmdb_movie_streaming_services": "TMDB Movie Streaming Services",
"tmdb_tv_streaming_services": "TMDB TV Streaming Services"
},
"library": {
"no_items_found": "No items found",
@@ -301,6 +345,7 @@
"x_albums": "{{count}} albums",
"artists": "Artists",
"could_not_load_item": "Could not load item",
"none": "None",
"download": {
"download_season": "Download Season",
"download_x_item": "Download {{item_count}} items",

View File

@@ -12,7 +12,15 @@
"failed_to_initiate_quick_connect": "Échec de l'initialisation de Connexion Rapide",
"got_it": "D'accord",
"connection_failed": "La connection a échouée",
"could_not_connect_to_server": "Impossible de se connecter au serveur. Veuillez vérifier l'URL et votre connection réseau."
"could_not_connect_to_server": "Impossible de se connecter au serveur. Veuillez vérifier l'URL et votre connection réseau.",
"an_unexpected_error_occured": "Une erreur inattendue s'est produite",
"change_server": "Changer de serveur",
"invalid_username_or_password": "Nom d'utilisateur ou mot de passe invalide",
"user_does_not_have_permission_to_log_in": "L'utilisateur n'a pas la permission de se connecter",
"server_is_taking_too_long_to_respond_try_again_later": "Le serveur met trop de temps à répondre, réessayez plus tard",
"server_received_too_many_requests_try_again_later": "Le serveur a reçu trop de demandes, réessayez plus tard",
"there_is_a_server_error": "Il y a une erreur de serveur",
"an_unexpected_error_occured_did_you_enter_the_correct_url": "Une erreur inattendue s'est produite. Avez-vous entré la bonne URL?"
},
"server": {
"enter_url_to_jellyfin_server": "Entrez l'URL de votre serveur Jellyfin",
@@ -33,6 +41,18 @@
"recently_added_in": "Ajoutés récemment dans {{libraryName}}",
"suggested_movies": "Films suggérés",
"suggested_episodes": "Épisodes suggérés",
"intro": {
"welcome_to_streamyfin": "Bienvenue sur Streamyfin",
"a_free_and_open_source_client_for_jellyfin": "Un client gratuit et open source pour Jellyfin",
"features_title": "Fonctionnalités",
"features_description": "Streamyfin possède de nombreuses fonctionnalités et s'intègre à un large éventail de logiciels que vous pouvez trouver dans le menu des paramètres, notamment:",
"jellyseerr_feature_description": "Connectez-vous à votre instance Jellyseerr et demandez des films directement dans l'application.",
"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.",
"chromecast_feature_description": "Diffusez des films et des émissions de télévision sur vos appareils Chromecast.",
"done_button": "Fait",
"go_to_settings_button": "Allez dans les paramètres"
},
"settings": {
"settings_title": "Paramètres",
"log_out_button": "Déconnexion",
@@ -62,7 +82,7 @@
"set_audio_track": "Configurer la piste audio à partir de l'élément précédent",
"audio_language": "Langue audio",
"audio_hint": "Chosissez une langue audio par défaut.",
"none": "Aucun"
"none": "Aucune"
},
"subtitles": {
"subtitle_title": "Sous-titres",
@@ -71,7 +91,7 @@
"set_subtitle_track": "Configurer la piste de sous-titres à partir de l'élément précédent",
"subtitle_size": "Taille des sous-titres",
"subtitle_hint": "Configurez les préférences des sous-titres.",
"none": "Aucun"
"none": "Aucune"
},
"other": {
"other_title": "Autres",
@@ -121,7 +141,10 @@
"server_url_placeholder": "http(s)://domaine.org:port",
"marlin_search_hint": "Entrez l'URL du serveur Marlin. L'URL devrait inclure http ou https et optionnellement le port.",
"read_more_about_marlin": "Lisez-en plus sur Marlin.",
"save_button": "Enregistrer"
"save_button": "Enregistrer",
"toasts": {
"saved": "Enregistré"
}
},
"popular_lists": {
"enable_plugin": "Activer le plugiciel",
@@ -223,7 +246,28 @@
"albums": "Albums",
"songs": "Chansons",
"request_movies": "Demander un film",
"request_series": "Demander une série"
"request_series": "Demander une série",
"recently_added": "Ajoutés récemment",
"recent_requests": "Demandes récentes",
"plex_watchlist": "Liste de lecture Plex",
"trending": "Tendance",
"popular_movies": "Films populaires",
"movie_genres": "Genres de films",
"upcoming_movies": "Films à venir",
"studios": "Studios",
"popular_tv": "TV populaire",
"tv_genres": "Genres TV",
"upcoming_tv": "TV à venir",
"networks": "Réseaux",
"tmdb_movie_keyword": "Mot-clé Films TMDB",
"tmdb_movie_genre": "Genre de film TMDB",
"tmdb_tv_keyword": "Mot-clé TV TMDB",
"tmdb_tv_genre": "Genre TV TMDB",
"tmdb_search": "Recherche TMDB",
"tmdb_studio": "Studio TMDB",
"tmdb_network": "Réseau TMDB",
"tmdb_movie_streaming_services": "Services de streaming de films TMDB",
"tmdb_tv_streaming_services": "Services de streaming TV TMDB"
},
"library": {
"no_items_found": "Aucun item trouvé",
@@ -301,6 +345,7 @@
"x_albums": "{{count}} albums",
"artists": "Artistes",
"could_not_load_item": "Impossible de charger l'item",
"none": "Aucun",
"download": {
"download_season": "Télécharger la saison",
"download_x_item": "Télécharger {{item_count}} items",