diff --git a/app/(auth)/(tabs)/(home)/intro/page.tsx b/app/(auth)/(tabs)/(home)/intro/page.tsx
index cef9db31..59a315b0 100644
--- a/app/(auth)/(tabs)/(home)/intro/page.tsx
+++ b/app/(auth)/(tabs)/(home)/intro/page.tsx
@@ -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() {
- Welcome to Streamyfin
+ {t("home.intro.welcome_to_streamyfin")}
- A free and open source client for Jellyfin.
+ {t("home.intro.a_free_and_open_source_client_for_jellyfin")}
- Features
+ {t("home.intro.features_title")}
- 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")}
Jellyseerr
- Connect to your Jellyseerr instance and request movies directly in
- the app.
+ {t("home.intro.jellyseerr_feature_description")}
@@ -60,11 +60,9 @@ export default function page() {
- Downloads
+ {t("home.intro.downloads_feature_title")}
- 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")}
@@ -81,7 +79,7 @@ export default function page() {
Chromecast
- Cast movies and tv-shows to your Chromecast devices.
+ {t("home.intro.chromecast_feature_description")}
@@ -93,7 +91,7 @@ export default function page() {
}}
className="mt-4"
>
- Done
+ {t("home.intro.done_button")}
{
@@ -102,7 +100,7 @@ export default function page() {
}}
className="mt-4"
>
- Go to settings
+ {t("home.intro.go_to_settings_button")}
);
diff --git a/app/(auth)/(tabs)/(home)/settings/marlin-search/page.tsx b/app/(auth)/(tabs)/(home)/settings/marlin-search/page.tsx
index b263d857..4a907dd3 100644
--- a/app/(auth)/(tabs)/(home)/settings/marlin-search/page.tsx
+++ b/app/(auth)/(tabs)/(home)/settings/marlin-search/page.tsx
@@ -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() {
- Change server
+ {t("login.change_server")}
) : 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);
diff --git a/components/SubtitleTrackSelector.tsx b/components/SubtitleTrackSelector.tsx
index 887a26c8..f389e453 100644
--- a/components/SubtitleTrackSelector.tsx
+++ b/components/SubtitleTrackSelector.tsx
@@ -56,7 +56,7 @@ export const SubtitleTrackSelector: React.FC = ({
{selectedSubtitleSteam
? tc(selectedSubtitleSteam?.DisplayTitle, 7)
- : "None"}
+ : t("item_card.none")}
diff --git a/components/jellyseerr/discover/Slide.tsx b/components/jellyseerr/discover/Slide.tsx
index 5a593b41..f110eb15 100644
--- a/components/jellyseerr/discover/Slide.tsx
+++ b/components/jellyseerr/discover/Slide.tsx
@@ -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 = ({
return (
- {DiscoverSliderType[slide.type].toString().toTitle()}
+ {t("search." + DiscoverSliderType[slide.type].toString().toLowerCase())}
= ({ ...props }) => {
});
}}
>
- t("home.settings.audio.none")
+ {t("home.settings.audio.none")}
{cultures?.map((l) => (
= ({ ...props }) => {
- {settings?.defaultSubtitleLanguage?.DisplayName || "None"}
+ {settings?.defaultSubtitleLanguage?.DisplayName || t("home.settings.subtitles.none")}
= ({
const [jellyfin, setJellyfin] = useState(undefined);
const [deviceId, setDeviceId] = useState(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")
);
}
}
diff --git a/translations/en.json b/translations/en.json
index 74a13001..df44273d 100644
--- a/translations/en.json
+++ b/translations/en.json
@@ -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",
diff --git a/translations/fr.json b/translations/fr.json
index 02182ec2..a7b72412 100644
--- a/translations/fr.json
+++ b/translations/fr.json
@@ -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",