diff --git a/composeApp/src/commonMain/composeResources/values-fr/strings.xml b/composeApp/src/commonMain/composeResources/values-fr/strings.xml
index 15b373b8..a8917f8a 100644
--- a/composeApp/src/commonMain/composeResources/values-fr/strings.xml
+++ b/composeApp/src/commonMain/composeResources/values-fr/strings.xml
@@ -1,3 +1,4 @@
+
Reconnaissance et crédits du projet
Retour
@@ -25,60 +26,60 @@
Actualisation
%1$d ressources
Indisponible
- Configurer l'addon
- Supprimer l'addon
- Ajoutez une URL de manifeste pour commencer à charger des catalogues, métadonnées, streams ou sous-titres dans Nuvio.
+ Configurer l’addon
+ Supprimer l’addon
+ Ajoute une URL de manifeste pour commencer à charger des catalogues, métadonnées, streams ou sous-titres dans Nuvio.
Aucun addon installé.
- Veuillez saisir une URL d'addon.
- URL de l'addon
- Installer l'addon
+ Saisis une URL d’addon.
+ URL de l’addon
+ Installer l’addon
Chargement des détails du manifeste…
- Validation de l'URL du manifeste et chargement des détails de l'addon avant installation.
- Vérification de l'addon
- Échec de l'installation
+ Validation de l’URL du manifeste et chargement des détails de l’addon avant installation.
+ Vérification de l’addon
+ Échec de l’installation
%1$s a été validé et ajouté avec succès.
Addon installé
- Déplacer l'addon vers le bas
- Déplacer l'addon vers le haut
+ Déplacer l’addon vers le bas
+ Déplacer l’addon vers le haut
Actif
Addons
Catalogues
- Actualiser l'addon
+ Actualiser l’addon
Ajouter un addon
Addons installés
Aperçu
- %1$d règles d'ID
+ %1$d règles d’ID
Version %1$s
Sélectionné
Copier le JSON
%1$d collection(s), %2$d dossier(s)
- Supprimer "%1$s" ? Cette action est irréversible.
+ Supprimer « %1$s » ? Cette action est irréversible.
Supprimer la collection
Ajouter un catalogue
Ajouter un dossier
Tous les genres
- Ajoutez des catalogues depuis vos addons installés pour définir ce qu'affiche ce dossier.
+ Ajoute des catalogues depuis tes addons installés pour définir ce qu’affiche ce dossier.
Aucune source de catalogue
Choisir
Emoji
- URL de l'image
+ URL de l’image
Aucune
Couverture
Créer une collection
Terminé
Modifier la collection
Modifier le dossier
- Configurez l'identité, la présentation et les sources de catalogue du dossier avec la même structure que l'éditeur principal de collections.
- Ajoutez-en un pour commencer.
+ Configure l’identité, la présentation et les sources de catalogue du dossier avec la même structure que l’éditeur principal de collections.
+ Ajoute-en un pour commencer.
Aucun dossier
Dossiers
Filtre de genre
- Afficher uniquement l'image de couverture
+ Afficher uniquement l’image de couverture
Masquer le titre
Nouveau dossier
- Affiche cette collection au-dessus de tous les catalogues normaux de l'accueil. Plusieurs collections épinglées suivent l'ordre de création.
+ Affiche cette collection au-dessus de tous les catalogues normaux de l’accueil. Plusieurs collections épinglées suivent l’ordre de création.
Épingler au-dessus des catalogues
- URL de l'image de fond (facultatif)
+ URL de l’image de fond (facultatif)
Nom du dossier
URL du GIF animé (se lit uniquement au focus)
Nom de la collection
@@ -87,7 +88,7 @@
Apparence
Informations de base
Sources de catalogue
- Choisissez les catalogues d'addon que ce dossier doit regrouper.
+ Choisis les catalogues d’addon que ce dossier doit regrouper.
Sélectionner des catalogues
Sélectionner un genre
%1$d sélectionné(s)
@@ -97,14 +98,14 @@
Carré
Large
Combiner tous les catalogues en un seul onglet
- Afficher l'onglet « Tout »
- Lire le GIF configuré à la place de la couverture statique lorsqu'il est disponible.
+ Afficher l’onglet « Tout »
+ Lire le GIF configuré à la place de la couverture statique lorsqu’il est disponible.
Afficher le GIF si configuré
%1$d source(s) · %2$s
Forme de la tuile
Lignes
Onglets
- Mode d'affichage
+ Mode d’affichage
Sources TMDB
Liste publique
Production
@@ -113,14 +114,14 @@
Personne
Réalisateur
Personnalisé
- Choisissez une source prédéfinie. Vous pouvez la modifier ou la supprimer après l'avoir ajoutée.
- Collez une URL de liste publique TMDB ou uniquement le numéro de l'URL.
- Recherchez par nom de studio, ou collez un ID/URL de société TMDB et ajoutez-le directement.
- Saisissez un ID de chaîne. Les chaînes courantes sont disponibles dans les préréglages et les filtres rapides.
- Recherchez le nom d'une collection de films ou collez l'ID de collection TMDB.
- Saisissez un ID ou une URL de personne TMDB pour créer une ligne à partir des crédits de casting.
- Saisissez un ID ou une URL de personne TMDB pour créer une ligne à partir des crédits de réalisation.
- Créez une ligne TMDB dynamique avec des filtres optionnels. Laissez les champs vides si vous n'avez pas besoin de ce filtre.
+ Choisis une source prédéfinie. Tu peux la modifier ou la supprimer après l’avoir ajoutée.
+ Colle une URL de liste publique TMDB ou uniquement le numéro de l’URL.
+ Recherche par nom de studio, ou colle un ID/URL de société TMDB et ajoute-le directement.
+ Saisis un ID de chaîne. Les chaînes courantes sont disponibles dans les préréglages et les filtres rapides.
+ Recherche le nom d’une collection de films ou colle l’ID de collection TMDB.
+ Saisis un ID ou une URL de personne TMDB pour créer une ligne à partir de ses crédits d’acteur.
+ Saisis un ID ou une URL de personne TMDB pour créer une ligne à partir de ses crédits de réalisation.
+ Crée une ligne TMDB dynamique avec des filtres optionnels. Laisse les champs vides si tu n’as pas besoin de ce filtre.
Liste publique TMDB
ID de chaîne
ID de collection
@@ -130,19 +131,19 @@
https://www.themoviedb.org/list/8504994 ou 8504994
213 pour Netflix, 49 pour HBO, 2739 pour Disney+
10 pour Star Wars Collection
+ 31 pour Tom Hanks, ou URL de la personne
Marvel Studios, 420 ou URL de société
- 31 pour Tom Hanks, ou URL de personne
- Exemples : Marvel Studios, 420 ou https://www.themoviedb.org/company/420.
- Exemple : Star Wars Collection, Harry Potter Collection ou une URL de collection.
- Exemples d'ID : Netflix 213, HBO 49, Disney+ 2739.
- Exemple : https://www.themoviedb.org/list/8504994 ou 8504994.
- Exemple : https://www.themoviedb.org/person/31-tom-hanks ou 31.
+ Exemples : Marvel Studios, 420 ou https://www.themoviedb.org/company/420.
+ Exemple : Star Wars Collection, Harry Potter Collection ou une URL de collection.
+ Exemples d’ID : Netflix 213, HBO 49, Disney+ 2739.
+ Exemple : https://www.themoviedb.org/list/8504994 ou 8504994.
+ Exemple : https://www.themoviedb.org/person/31-tom-hanks ou 31.
Titre affiché
Affiché comme nom de ligne/onglet. Si vide, Nuvio en génère un depuis la source.
Films Marvel, Originaux Netflix, Pixar
- Films avec Tom Hanks, Acteurs favoris
+ Films de Tom Hanks, Acteurs favoris
Films de Christopher Nolan, Réalisateurs favoris
- Meilleurs films d'action, drames coréens, animation 2024
+ Meilleurs films d’action, drames coréens, animation 2024
Résultats de recherche
Collection TMDB
Société TMDB %1$d
@@ -153,7 +154,7 @@
Les deux
Tri
Filtres
- Laissez les champs vides si vous n'avez pas besoin de ce filtre.
+ Laisse les champs vides si tu n’as pas besoin de ce filtre.
Genres rapides
Langues rapides
Pays rapides
@@ -161,30 +162,40 @@
Studios rapides
Chaînes rapides
ID de genre
- Utilisez des numéros de genre TMDB. Séparez plusieurs valeurs par des virgules pour ET, ou des barres verticales pour OU.
+ Utilise des numéros de genre TMDB. Sépare plusieurs valeurs par des virgules pour ET, ou des barres verticales pour OU.
+ 28,12
+ 18,35
Date de sortie ou de diffusion depuis
- Date de sortie ou de diffusion jusqu'au
- Utilisez le format AAAA-MM-JJ, ex. 2024-01-01.
+ Date de sortie ou de diffusion jusqu’au
+ Utilise le format AAAA-MM-JJ, ex. 2024-01-01.
+ 2020-01-01
+ 2024-12-31
Note minimale
Note maximale
- Note TMDB de 0 à 10. Exemple : 7.0.
+ Note TMDB de 0 à 10. Exemple : 7.0.
+ 7.0
+ 10
Votes minimum
- Utilisez ceci pour éviter les titres peu connus avec peu de votes. Exemple : 100.
+ Utilise ceci pour éviter les titres peu connus avec peu de votes. Exemple : 100.
+ 100
Langue originale
- Utilisez des codes de langue à deux lettres, ex. en, ko, ja, hi.
- Pays d'origine
- Utilisez des codes de pays à deux lettres, ex. US, KR, JP, IN.
+ Utilise des codes de langue à deux lettres, ex. en, ko, ja, hi.
+ en, ko, ja, hi
+ Pays d’origine
+ Utilise des codes de pays à deux lettres, ex. US, KR, JP, IN.
+ US, KR, JP, IN
ID de mots-clés
- Utilisez des numéros de mots-clés TMDB. Les puces rapides remplissent des exemples courants.
+ Utilise des numéros de mots-clés TMDB. Les puces rapides remplissent des exemples courants.
9715 pour super-héros
ID de société
- Utilisez des ID de studio/société. Les puces rapides remplissent des exemples courants.
+ Utilise des ID de studio/société. Les puces rapides remplissent des exemples courants.
420 pour Marvel Studios
ID de chaîne
- Pour les séries uniquement. Utilisez des ID de chaîne comme Netflix 213 ou HBO 49.
+ Pour les séries uniquement. Utilise des ID de chaîne comme Netflix 213 ou HBO 49.
213 pour Netflix
Année
- Utilisez une année à quatre chiffres, ex. 2024.
+ Utilise une année à quatre chiffres, ex. 2024.
+ 2024
Préréglages
Rechercher
Ajouter une source
@@ -192,13 +203,13 @@
Modifier la liste Trakt
Listes Trakt
Liste Trakt
- Rechercher un titre, URL Trakt ou ID de liste
- Utilisez une URL publique de liste Trakt ou un ID numérique de liste, ou recherchez par nom.
- Programme du week-end, Lauréats
+ Titre, URL Trakt ou ID de liste
+ Utilise une URL de liste Trakt publique, un ID numérique de liste, ou recherche par nom.
+ Films du week-end, Films primés
Résultats de recherche
- Listes tendances
+ Listes en vogue
Listes populaires
- Ordre
+ Sens
Croissant
Décroissant
Ordre de la liste
@@ -209,6 +220,12 @@
Populaire
Pourcentage
Votes
+ Saisis un nom, une URL ou un ID de liste Trakt
+ Saisis un ID ou une URL de liste Trakt
+ Impossible de charger la liste Trakt
+ Aucune liste Trakt trouvée
+ Liste Trakt résolue
+ Liste Trakt %1$d
Action
Aventure
Animation
@@ -229,7 +246,7 @@
Inde
Royaume-Uni
Super-héros
- Adapté d'un roman
+ Adapté d’un roman
Voyage dans le temps
Espace
Marvel
@@ -242,10 +259,10 @@
Disney+
Prime Video
Hulu
- Original
Populaire
Mieux notés
Récent
+ Original
Liste TMDB
Collection de films TMDB
Production
@@ -253,7 +270,7 @@
Personne
Réalisateur
Découverte TMDB
- Créez-en une pour organiser vos catalogues.
+ Crée-en une pour organiser tes catalogues.
Aucune collection
%1$d dossier(s)
Aucun élément trouvé
@@ -261,31 +278,31 @@
Collections
Importer des collections
JSON
- Collez le JSON de vos collections ci-dessous.
+ Colle le JSON de tes collections ci-dessous.
Importer
Nouvelle collection
Épinglé
Tout
- Vos collections
+ Tes collections
Fait avec ❤️ par Tapframe et ses amis
Version %1$s (%2$s)
Désactivé
Activé
Pause
Recharger
- Vous avez déjà un compte ?
+ Tu as déjà un compte ?
Continuer sans compte
Créer un compte
- Pas encore de compte ?
+ Pas encore de compte ?
Adresse e-mail
ou
Mot de passe
- Connectez-vous pour accéder à votre bibliothèque et votre progression
+ Connecte-toi pour accéder à ta bibliothèque et ta progression
Se connecter
- Inscrivez-vous pour synchroniser vos données entre appareils
- S'inscrire
- Vos données seront uniquement stockées localement
- Regardez tout, partout
+ Inscris-toi pour synchroniser tes données entre appareils
+ S’inscrire
+ Tes données seront uniquement stockées localement
+ Regarde tout, partout
Bon retour
Bibliothèque
Bibliothèque Trakt
@@ -317,7 +334,7 @@
Streams
Erreur de lecture
Lecture en cours
- Appuyez pour chercher des sous-titres
+ Appuie pour chercher des sous-titres
Retour
Rétablir les valeurs par défaut
Remplir
@@ -339,20 +356,20 @@
Téléchargé
Diffusé
À confirmer
- Appuyez pour déverrouiller
+ Appuie pour déverrouiller
Piste %1$d
Déverrouiller les contrôles du lecteur
- Vous regardez
+ Tu regardes
Ajouter un profil
Effacer la recherche
Découvrir
- Les addons installés n'ont renvoyé aucun résultat de recherche valide.
+ Les addons installés n’ont retourné aucun résultat de recherche valide.
La recherche a échoué
- Installez et validez au moins un addon avant de rechercher.
+ Installe et valide au moins un addon avant de rechercher.
Aucun addon actif
- Les catalogues installés n'ont renvoyé aucun résultat pour cette requête.
+ Les catalogues installés n’ont retourné aucun résultat pour cette requête.
Aucun résultat trouvé
- Vos addons installés n'exposent pas de catalogue de recherche.
+ Tes addons installés n’exposent pas de catalogue de recherche.
Aucun catalogue de recherche
Rechercher des films, séries…
Recherches récentes
@@ -364,7 +381,7 @@
Apparence
Contenu et découverte
Continuer à regarder
- Écran d'accueil
+ Écran d’accueil
Intégrations
Notes MDBList
Écran méta
@@ -377,22 +394,22 @@
Enrichissement TMDB
Trakt
À PROPOS
- Gérez votre compte, déconnectez-vous ou supprimez-le.
+ Gère ton compte, déconnecte-toi ou supprime-le.
COMPTE
- Ajustez la présentation de l'accueil et les préférences visuelles.
- Rechercher de nouvelles versions de l'application.
+ Ajuste la présentation de l’accueil et les préférences visuelles.
+ Rechercher de nouvelles versions de l’application.
Vérifier les mises à jour
- Gérez les addons et sources de découverte.
- Gérez vos films et épisodes téléchargés.
+ Gère les addons et sources de découverte.
+ Gère tes films et épisodes téléchargés.
Téléchargements
GÉNÉRAL
- Connectez les services TMDB et MDBList.
- Gérez les alertes de sortie d'épisodes et envoyez une notification de test.
+ Connecte les services TMDB et MDBList.
+ Gère les alertes de sortie d’épisodes et envoie une notification de test.
Basculer vers un profil différent.
Changer de profil
- Connectez Trakt, synchronisez des listes et enregistrez des titres directement dans Trakt.
- Chargement de vos listes Trakt…
- Choisissez où enregistrer ce titre dans Trakt
+ Connecte Trakt, synchronise des listes et enregistre des titres directement dans Trakt.
+ Chargement de tes listes Trakt…
+ Choisis où enregistrer ce titre dans Trakt
Faire un don
Voir les détails
Supprimer
@@ -401,8 +418,8 @@
%1$d/10
Avis
Spoiler
- Aucun avis Trakt pour l'instant.
- %1$d j'aime
+ Aucun avis Trakt pour l’instant.
+ %1$d j’aime
Ce commentaire contient des spoilers.
Ce commentaire contient des spoilers et a été masqué.
Commentaires
@@ -423,7 +440,7 @@
Vu
Saison %1$d
Spéciaux
- Reprendre où vous en étiez
+ Reprendre où tu en étais
Ajouter à la bibliothèque
Marquer comme non vu
Marquer comme vu
@@ -433,37 +450,37 @@
Logo de %1$s
Compte
Supprimer le compte
- Cela supprimera définitivement votre compte et toutes les données associées.
- Cette action est irréversible. Toutes vos données, profils et historique de synchronisation seront définitivement supprimés.
- Supprimer le compte ?
+ Cela supprimera définitivement ton compte et toutes les données associées.
+ Cette action est irréversible. Toutes tes données, profils et historique de synchronisation seront définitivement supprimés.
+ Supprimer le compte ?
Adresse e-mail
Non connecté
Se déconnecter
- Vous serez redirigé vers l'écran de connexion.
- Se déconnecter ?
+ Tu seras redirigé vers l’écran de connexion.
+ Se déconnecter ?
Statut
Anonyme
Connecté
Noir AMOLED
Utilise des fonds noirs purs pour les écrans OLED.
- Langue de l'application
+ Langue de l’application
Choisir la langue
Afficher, masquer et ajuster le bandeau Continuer à regarder.
- Ajustez la largeur partagée des cartes d'affiches et les rayons des coins.
+ Ajuste la largeur partagée des cartes d’affiches et les rayons des coins.
AFFICHAGE
ACCUEIL
THÈME
Collection • %1$s
Nom affiché
- Installez un addon avec des catalogues compatibles avec les tableaux pour configurer les lignes de l'écran d'accueil.
- Aucun catalogue d'accueil
+ Installe un addon avec des catalogues compatibles avec les tableaux pour configurer les lignes de l’écran d’accueil.
+ Aucun catalogue d’accueil
Source Hero
Masqué
- Garder l'accueil en focus
+ Garder l’accueil en focus
%1$s • Limite atteinte (max. %2$d)
Aucune source Hero sélectionnée
Absent du Hero
- Retirez l'épingle de la collection pour la déplacer
+ Retire l’épingle de la collection pour la déplacer
Épinglé
Épinglé en haut
Réorganiser
@@ -474,23 +491,23 @@
SOURCES HERO
%1$d sur %2$d sélectionnés
Afficher le Hero
- Afficher un carrousel Hero en vedette en haut de l'accueil. Choisissez jusqu'à 2 catalogues sources ci-dessous.
+ Afficher un carrousel Hero en vedette en haut de l’accueil. Choisis jusqu’à 2 catalogues sources ci-dessous.
%1$d sur %2$d catalogues visibles • %3$d sources Hero sélectionnées
- Ouvrez un catalogue uniquement si vous avez besoin de le renommer ou de le réorganiser.
+ Ouvre un catalogue uniquement si tu as besoin de le renommer ou de le réorganiser.
Visible
Lecteur, sous-titres et lecture automatique
Rayon de carte
- STYLE DE CARTE D'AFFICHE
+ STYLE DE CARTE D’AFFICHE
Largeur de carte
Personnalisé
- Personnalisez la largeur de carte et le rayon des coins pour les cartes d'affiches partagées dans toute l'application.
+ Personnalise la largeur de carte et le rayon des coins pour les cartes d’affiches partagées dans toute l’application.
Masquer les étiquettes
Mode paysage pour les affiches dans les rayons
Aperçu en direct
%1$s (%2$s)
- Rayon de coin : %1$ddp
- Hauteur : %1$ddp
- Largeur : %1$ddp
+ Rayon de coin : %1$ddp
+ Hauteur : %1$ddp
+ Largeur : %1$ddp
Classique
Pilule
Arrondi
@@ -502,36 +519,36 @@
Dense
Grand
Standard
- Afficher une invite pour reprendre là où vous en étiez à l'ouverture de l'application après avoir quitté le lecteur.
+ Afficher une invite pour reprendre là où tu en étais à l’ouverture de l’application après avoir quitté le lecteur.
Invite de reprise au démarrage
STYLE DE CARTE
AU DÉMARRAGE
COMPORTEMENT DE LA SUITE
VISIBILITÉ
- Afficher le bandeau Continuer à regarder sur l'écran d'accueil.
+ Afficher le bandeau Continuer à regarder sur l’écran d’accueil.
Afficher Continuer à regarder
Affiche
- Carte d'affiche centrée sur la couverture
+ Carte d’affiche centrée sur la couverture
Large
Carte horizontale riche en informations
- Quand activé, La suite reprend toujours depuis l'épisode le plus avancé vu. Quand désactivé, suit l'épisode le plus récemment visionné. Utile si vous revoyez des épisodes précédents.
- La suite depuis l'épisode le plus avancé
+ Activé : « La suite » reprend toujours depuis l’épisode le plus avancé vu. Désactivé : suit l’épisode le plus récemment visionné. Utile si tu revois des épisodes précédents.
+ La suite depuis l’épisode le plus avancé
ACCUEIL
SOURCES
- Installez, supprimez, mettez à jour et ordonnez vos sources de contenu.
- Installez des dépôts de scrapers JavaScript et testez des fournisseurs en interne.
- Contrôlez quels catalogues apparaissent à l'accueil et dans quel ordre.
- Désactivez des sections de détails et réorganisez tout sous le Hero.
- Créez des regroupements de catalogues personnalisés avec des dossiers affichés à l'accueil.
+ Installe, supprime, mets à jour et ordonne tes sources de contenu.
+ Installe des dépôts de scrapers JavaScript et teste des fournisseurs en interne.
+ Contrôle quels catalogues apparaissent à l’accueil et dans quel ordre.
+ Désactive des sections de détails et réorganise tout sous le Hero.
+ Crée des regroupements de catalogues personnalisés avec des dossiers affichés à l’accueil.
INTÉGRATIONS
- Enrichissez les pages de détails avec de l'art, des crédits, des métadonnées d'épisodes et plus depuis TMDB.
- Ajoutez des notes externes d'IMDb, Rotten Tomatoes, Metacritic et d'autres aux pages de détails.
- Ajoutez votre clé API MDBList ci-dessous avant d'activer les notes.
- Obtenez une clé sur https://mdblist.com/preferences et collez-la ici.
+ Enrichis les pages de détails avec de l’art, des crédits, des métadonnées d’épisodes et plus depuis TMDB.
+ Ajoute des notes externes d’IMDb, Rotten Tomatoes, Metacritic et d’autres aux pages de détails.
+ Ajoute ta clé API MDBList ci-dessous avant d’activer les notes.
+ Obtiens une clé sur https://mdblist.com/preferences et colle-la ici.
Clé API
Clé API MDBList
Activer les notes MDBList
- Afficher les notes externes de MDBList sur les pages de métadonnées lorsqu'un ID IMDb est disponible.
+ Afficher les notes externes de MDBList sur les pages de métadonnées lorsqu’un ID IMDb est disponible.
CLÉ API
FOURNISSEURS DE NOTES
MDBLIST
@@ -540,23 +557,23 @@
Casting
Liste principale du casting.
Fond cinématographique
- Fond flou derrière le contenu, similaire à l'écran de streams.
+ Fond flou derrière le contenu, similaire à l’écran de streams.
Collection
Rayon de collection ou de franchise associée.
Commentaires
Section de commentaires Trakt.
Détails
Durée, statut, sortie, langue et informations associées.
- Cartes d'épisodes
- Choisissez comment les épisodes sont affichés sur l'écran de métadonnées.
+ Cartes d’épisodes
+ Choisis comment les épisodes sont affichés sur l’écran de métadonnées.
Horizontal
Cartes en ligne style fond
Liste
Cartes empilées centrées sur les détails
Épisodes
- Saisons et liste d'épisodes pour les séries.
+ Saisons et liste d’épisodes pour les séries.
Groupe %1$d
- Plus comme ceci
+ À voir aussi
Rayon de recommandations.
Aucun
Résumé
@@ -565,26 +582,26 @@
Studios et chaînes.
APPARENCE
SECTIONS
- Groupe d'onglets %1$d
+ Groupe d’onglets %1$d
Disposition des onglets
- Regroupez les sections en onglets comme dans l'application TV. Assignez jusqu'à 3 sections par groupe d'onglets.
+ Regroupe les sections en onglets comme dans l’application TV. Assigne jusqu’à 3 sections par groupe d’onglets.
Bandes-annonces
Rayon de bandes-annonces et raccourcis de lecture.
Les notifications sont actuellement désactivées dans Nuvio.
- Alertes de sortie d'épisodes
- Programmez des notifications locales lorsqu'un nouvel épisode d'une série sauvegardée est disponible.
- Les notifications système sont désactivées pour Nuvio. Activez-les pour recevoir des alertes et des notifications de test.
+ Alertes de sortie d’épisodes
+ Programme des notifications locales lorsqu’un nouvel épisode d’une série enregistrée est disponible.
+ Les notifications système sont désactivées pour Nuvio. Active-les pour recevoir des alertes et des notifications de test.
Il y a actuellement %1$d alertes de sortie programmées sur cet appareil.
ALERTES
TEST
Envoyer une notification de test
Envoi de la notification de test…
Envoyer une notification locale de test pour %1$s.
- Sauvegardez d'abord une série dans votre bibliothèque pour tester les notifications.
+ Sauvegarde d’abord une série dans ta bibliothèque pour tester les notifications.
Notification de test
Communauté
- Découvrez les personnes qui construisent et soutiennent Nuvio sur Mobile, TV et Web.
- L'API des supporters n'est pas configurée. Ajoutez DONATIONS_BASE_URL dans local.properties.
+ Découvre les personnes qui construisent et soutiennent Nuvio sur Mobile, TV et Web.
+ L’API des supporters n’est pas configurée. Ajoute DONATIONS_BASE_URL dans local.properties.
Contributeurs
Supporters
Ouvrir GitHub
@@ -620,16 +637,20 @@
Plugins autorisés
Anime Skip
ID client AnimeSkip
- Saisissez votre ID client API AnimeSkip. Obtenez-en un sur anime-skip.com.
+ Saisis ton ID client API AnimeSkip. Obtiens-en un sur anime-skip.com.
+ Activer la soumission d’intro
+ Affiche un bouton pour soumettre les marqueurs d’intro/outro à la base communautaire.
+ Clé API IntroDB
+ Saisis ta clé API IntroDB pour soumettre des marqueurs. Requis pour la soumission.
Rechercher également des marqueurs de saut sur AnimeSkip (nécessite un ID client).
- Lecture automatique de l'épisode suivant
- Rechercher et lire automatiquement l'épisode suivant lorsque le seuil est atteint.
+ Lecture automatique de l’épisode suivant
+ Rechercher et lire automatiquement l’épisode suivant lorsque le seuil est atteint.
Appareil uniquement
- Préférer l'application (FFmpeg)
- Préférer l'appareil
+ Préférer l’application (FFmpeg)
+ Préférer l’appareil
Priorité du décodeur
- Appuyez en dehors pour fermer
- Appuyez en dehors pour enregistrer et fermer
+ Appuie en dehors pour fermer
+ Appuie en dehors pour enregistrer et fermer
%1$d jour
%1$d jours
%1$d heure
@@ -638,18 +659,18 @@
Utiliser libass pour afficher les sous-titres ASS/SSA à la place du moteur par défaut.
Vitesse au maintien
Maintenir pour accélérer
- Maintenez appuyé n'importe où sur la surface du lecteur pour augmenter temporairement la vitesse.
+ Garde le doigt appuyé n’importe où sur le lecteur pour accélérer temporairement.
Modèle regex invalide
Durée du cache du dernier lien
Mapper DV7 vers HEVC
Utiliser Dolby Vision Profil 7 vers HEVC comme alternative pour les appareils non compatibles.
Minutes avant la fin
- Afficher la carte de l'épisode suivant ce nombre de minutes avant la fin.
- %1$s min
+ Afficher la carte de l’épisode suivant ce nombre de minutes avant la fin.
+ %1$d min
Aucun élément disponible
Non défini
Par défaut
- Langue de l'appareil
+ Langue de l’appareil
Forcé
Aucun
Préférer le groupe binge
@@ -657,10 +678,10 @@
Langue audio préférée
Langue des sous-titres préférée
Préréglages
- Correspond au nom du stream, à l'étiquette, à la description, à l'addon et à l'URL.
+ Correspond au nom du stream, à l’étiquette, à la description, à l’addon et à l’URL.
Modèle regex
4K|2160p|Remux
- N'importe quel 1080p+
+ N’importe quel 1080p+
AVC / x264
Qualité BluRay
Dolby Atmos / DTS
@@ -680,7 +701,7 @@
Canvas superposé
OpenGL superposé
Réutiliser le dernier lien
- Lire automatiquement votre dernier stream fonctionnel pour ce même film/épisode lorsque le cache est encore valide.
+ Lire automatiquement ton dernier stream fonctionnel pour ce même film/épisode lorsque le cache est encore valide.
Langue audio secondaire
Langue des sous-titres secondaire
DÉCODEUR
@@ -693,9 +714,9 @@
RENDU DES SOUS-TITRES
%1$d sélectionné(s)
Afficher la superposition de chargement
- Afficher la superposition de chargement initiale pendant le démarrage d'un stream.
- Passer l'intro/outro/récap
- Afficher un bouton de saut lors des segments d'intro, d'outro et de récapitulatif détectés.
+ Afficher la superposition de chargement initiale pendant le démarrage d’un stream.
+ Passer l’intro/outro/récap
+ Afficher un bouton de saut lors des segments d’intro, d’outro et de récapitulatif détectés.
Périmètre des sources
Tous les addons
Considérer les streams de tous les addons installés.
@@ -712,28 +733,28 @@
Sélectionner les streams manuellement à chaque fois.
Correspondance regex
Sélectionner automatiquement un stream correspondant à un modèle regex.
- Délai d'expiration du stream
+ Délai d’expiration du stream
Combien de temps attendre les streams avant la sélection automatique.
Minutes avant la fin
Mode de seuil
Minutes avant la fin
Pourcentage
Pourcentage de seuil
- Afficher la carte de l'épisode suivant lorsque la lecture atteint ce pourcentage.
- %1$s %
+ Afficher la carte de l’épisode suivant lorsque la lecture atteint ce pourcentage.
+ %1$d%
Instantané
- %1$ss
+ %1$ds
Illimité
Lecture tunnelisée
Active la lecture tunnelisée pour une latence réduite dans la synchronisation audio/vidéo.
- Ajoutez votre propre clé API TMDB ci-dessous avant d'activer l'enrichissement.
+ Ajoute ta propre clé API TMDB ci-dessous avant d’activer l’enrichissement.
Clé API TMDB
- Activer l'enrichissement TMDB
- Utiliser votre clé API TMDB pour enrichir les métadonnées de l'addon sur l'écran de détails lorsqu'un ID TMDB ou IMDb est disponible.
- Saisissez votre clé API v3 TMDB.
+ Activer l’enrichissement TMDB
+ Utiliser ta clé API TMDB pour enrichir les métadonnées de l’addon sur l’écran de détails lorsqu’un ID TMDB ou IMDb est disponible.
+ Saisis ta clé API v3 TMDB.
Code de langue
Visuels
- Remplacer le fond, l'affiche et le logo par les visuels TMDB.
+ Remplacer le fond, l’affiche et le logo par les visuels TMDB.
Informations de base
Utiliser le titre, le synopsis, les genres et la note de TMDB.
Collections
@@ -744,24 +765,24 @@
Utiliser les informations de sortie, durée, classification, statut, pays et langue de TMDB.
Épisodes
Utiliser les titres, miniatures, descriptions et durées des épisodes de TMDB pour les séries.
- Plus comme ceci
+ À voir aussi
Afficher les recommandations TMDB en bas des pages de détails.
Chaînes
Utiliser les métadonnées des chaînes TMDB pour les titres TV.
Sociétés de production
- Utiliser les métadonnées des sociétés de production TMDB sur l'écran de détails.
+ Utiliser les métadonnées des sociétés de production TMDB sur l’écran de détails.
Affiches de saison
- Utiliser les affiches de saison TMDB dans le sélecteur de saisons de l'écran de métadonnées pour les séries.
+ Utiliser les affiches de saison TMDB dans le sélecteur de saisons de l’écran de métadonnées pour les séries.
Bandes-annonces
Récupérer et afficher la section des bandes-annonces TMDB sur les pages de détails.
Clé API personnelle
Langue préférée
- Configurez le code de langue TMDB utilisé pour les métadonnées localisées, ex. `en`, `en-US` ou `pt-BR`.
+ Configure le code de langue TMDB utilisé pour les métadonnées localisées, ex. `en`, `en-US` ou `pt-BR`.
IDENTIFIANTS
LOCALISATION
MODULES
TMDB
- Après approbation, vous serez redirigé automatiquement.
+ Après approbation, tu seras redirigé automatiquement.
AUTHENTIFICATION
Commentaires
Afficher les commentaires Trakt dans les détails des films et séries
@@ -769,14 +790,14 @@
Connecté en tant que %1$s
Utilisateur Trakt
Déconnecter
- Impossible d'ouvrir le navigateur
+ Impossible d’ouvrir le navigateur
FONCTIONNALITÉS
- Terminez la connexion Trakt dans votre navigateur
- Suivez ce que vous regardez, enregistrez dans votre liste ou vos listes personnalisées et gardez votre bibliothèque synchronisée avec Trakt.
+ Termine la connexion Trakt dans ton navigateur
+ Suis ce que tu regardes, enregistre dans ta liste ou tes listes personnalisées et garde ta bibliothèque synchronisée avec Trakt.
Identifiants Trakt manquants dans local.properties (TRAKT_CLIENT_ID / TRAKT_CLIENT_SECRET).
Ouvrir la connexion Trakt
- Vos actions d'enregistrement peuvent maintenant cibler la watchlist Trakt et vos listes personnelles.
- Connectez-vous avec Trakt pour activer la sauvegarde basée sur les listes et le mode bibliothèque Trakt.
+ Tu peux maintenant enregistrer dans ta liste de suivi Trakt et tes listes personnelles.
+ Connecte-toi avec Trakt pour activer la sauvegarde basée sur les listes et le mode bibliothèque Trakt.
Score du public
IMDb
Letterboxd
@@ -795,11 +816,11 @@
Épisode suivant
Recherche de la source…
Lecture via %1$s dans %2$d…
- Miniature de l'épisode suivant
+ Miniature de l’épisode suivant
Non diffusé
Passer
- Passer l'intro
- Passer l'outro
+ Passer l’intro
+ Passer l’outro
Passer le récap
Aucun sous-titre trouvé
Afrikaans
@@ -888,32 +909,32 @@
Non
Mettre à jour
Oui
- Voulez-vous quitter l'application ?
- Quitter l'application
- Ce catalogue n'a renvoyé aucun élément.
+ Veux-tu quitter l’application ?
+ Quitter l’application
+ Ce catalogue n’a retourné aucun élément.
Aucun titre trouvé
- Vérifiez votre connexion Wi‑Fi ou données mobiles et réessayez.
+ Vérifie ta connexion Wi‑Fi ou données mobiles et réessaie.
Réalisateur
Échec du chargement
- Plus comme ceci
+ À voir aussi
Saisons
- Cet addon a renvoyé des vidéos pour la série, mais aucune n'incluait de numéros de saison ou d'épisode.
- Cet addon n'a fourni aucune métadonnée d'épisode pour cette série.
- Cet addon n'a pas encore publié d'épisodes.
- Votre appareil est en ligne, mais Nuvio n'a pas pu se connecter aux serveurs nécessaires.
+ Cet addon a retourné des vidéos pour la série, mais aucune n’incluait de numéros de saison ou d’épisode.
+ Cet addon n’a fourni aucune métadonnée d’épisode pour cette série.
+ Cet addon n’a pas encore publié d’épisodes.
+ Ton appareil est en ligne, mais Nuvio n’a pas pu se connecter aux serveurs nécessaires.
Afficher moins
Afficher plus ▾
Scénariste
Tous les genres
Catalogue
%1$s • %2$s
- Le catalogue sélectionné n'a renvoyé aucun élément de découverte.
+ Le catalogue sélectionné n’a retourné aucun élément de découverte.
Impossible de charger Découvrir
- Les addons installés n'exposent pas de catalogues compatibles avec le tableau pour Découvrir.
+ Les addons installés n’exposent pas de catalogues compatibles avec le tableau pour Découvrir.
Aucun catalogue de découverte
- Le catalogue et les filtres sélectionnés n'ont renvoyé aucun élément.
+ Le catalogue et les filtres sélectionnés n’ont retourné aucun élément.
Aucun titre trouvé
- Installez et validez au moins un addon avant d'explorer les catalogues dans Découvrir.
+ Installe et valide au moins un addon avant d’explorer les catalogues dans Découvrir.
Sélectionner un catalogue
Sélectionner un genre
Sélectionner un type
@@ -926,9 +947,9 @@
Marquer comme vu
Suivant
%1$s vu
- Installez et validez au moins un addon avant de charger des lignes de catalogue à l'accueil.
- Les addons installés n'exposent actuellement aucun catalogue compatible avec le tableau sans extras requis.
- Aucune ligne d'accueil disponible
+ Installe et valide au moins un addon avant de charger des lignes de catalogue à l’accueil.
+ Les addons installés n’exposent actuellement aucun catalogue compatible avec le tableau sans extras requis.
+ Aucune ligne d’accueil disponible
Voir les détails
Contrôles pour lire et enregistrer.
Actions
@@ -938,21 +959,23 @@
Section de commentaires Trakt.
Durée, statut, date de sortie, langue et informations associées.
Détails
- Saisons et liste d'épisodes pour les séries.
+ Saisons et liste d’épisodes pour les séries.
Rayon de recommandations.
- Plus comme ceci
+ À voir aussi
Synopsis, notes, genres et crédits principaux.
Résumé
Studios et chaînes.
Production
Rayon de bandes-annonces et raccourcis de lecture.
De nouveau en ligne
- Impossible d'atteindre les serveurs
+ Impossible d’atteindre les serveurs
+ Corps de réponse vide
+ La requête a échoué avec HTTP %1$d
Pas de connexion Internet
(âge %1$d)
Né(e) le %1$s%2$s
Décédé(e) le %1$s
- Connu(e) pour : %1$s
+ Connu(e) pour : %1$s
Récent
Impossible de charger les détails de %1$s
Populaire
@@ -962,15 +985,15 @@
Annuler
Saisir le code PIN
Saisir le code PIN pour %1$s
- Code PIN oublié ?
+ Code PIN oublié ?
Code PIN incorrect
- Bloqué. Réessayez dans %1$ds
- Les options d'avatar apparaîtront ici une fois le catalogue chargé.
- Avatar : %1$s
+ Bloqué. Réessaie dans %1$ds
+ Les options d’avatar apparaîtront ici une fois le catalogue chargé.
+ Avatar : %1$s
Choisir un avatar
- Choisissez un avatar ci-dessous.
+ Choisis un avatar ci-dessous.
Créer un profil
- Toutes les données de "%1$s" seront définitivement supprimées.
+ Toutes les données de « %1$s » seront définitivement supprimées.
Supprimer le profil
Ajouter un profil
Modifier le profil
@@ -987,26 +1010,26 @@
Supprimer le verrouillage PIN
Enregistrement…
Sécurité
- Ajoutez un code PIN si vous souhaitez que ce profil soit verrouillé avant d'y accéder.
+ Ajoute un code PIN si tu souhaites que ce profil soit verrouillé avant d’y accéder.
Ce profil est protégé par un code PIN.
- Sélectionnez un avatar pour ce profil.
+ Sélectionne un avatar pour ce profil.
Configurer le verrouillage PIN
Profil sans nom
Utiliser les addons principaux
Partager la configuration des addons du profil principal plutôt que de gérer une liste séparée.
- Qui regarde ?
+ Qui regarde ?
Téléchargé
Reprendre
Scrapers actifs
- Vérification d'autres addons…
+ Vérification d’autres addons…
Copier le lien du stream
Télécharger le fichier
- Les addons de streams installés n'ont pas renvoyé de réponse valide.
+ Les addons de streams installés n’ont pas retourné de réponse valide.
Impossible de charger les streams
- Installez d'abord un addon pour charger les streams de ce titre.
- Vos addons installés ne fournissent pas de streams pour ce type de titre.
+ Installe d’abord un addon pour charger les streams de ce titre.
+ Tes addons installés ne fournissent pas de streams pour ce type de titre.
Aucun addon de streams disponible
- Aucun de vos addons installés n'a renvoyé de stream pour ce titre.
+ Aucun de tes addons installés n’a retourné de streams pour ce titre.
S%1$d E%2$d
Épisode
S%1$dE%2$d - %3$s
@@ -1017,7 +1040,7 @@
Aucun lien direct du stream disponible
Aucune métadonnée disponible
Actualiser les streams
- Reprendre depuis %1$d %
+ Reprendre depuis %1$d%
Reprendre depuis %1$s
TAILLE %1$s
Fermer la bande-annonce
@@ -1027,10 +1050,12 @@
%1$s • %2$s
Échec de la vérification des mises à jour
Échec du téléchargement
- Téléchargement %1$d %
- Impossible de démarrer l'installation
- Vous utilisez la version la plus récente.
- Activez l'installation d'applications pour Nuvio puis revenez pour continuer.
+ Corps du téléchargement vide
+ Le fichier de mise à jour téléchargé est introuvable.
+ Téléchargement %1$d%%
+ Impossible de démarrer l’installation
+ Tu utilises la version la plus récente.
+ Active l’installation d’applications pour Nuvio puis reviens pour continuer.
Téléchargement de la mise à jour…
Aucune mise à jour trouvée.
Une nouvelle version est prête à être installée.
@@ -1041,20 +1066,20 @@
Mise à jour disponible
Statut de la mise à jour
Cet addon est déjà installé.
- Veuillez saisir une URL d'addon valide
+ Saisis une URL d’addon valide
Impossible de charger le manifeste
Nuvio
Impossible de supprimer le compte
Échec de la connexion
Échec de la déconnexion
- Échec de l'inscription
+ Échec de l’inscription
Impossible de charger les éléments du catalogue.
À suivre
À suivre • S%1$dE%2$d
- logo de %1$s
+ Logo de %1$s
Impossible de charger les commentaires
- Impossible de charger les détails depuis aucun addon.
- Réseaux
+ Aucun addon n’a pu fournir les détails.
+ Chaînes
Aucun addon ne fournit de métadonnées pour ce contenu.
Téléchargement échoué
Affiche la progression en direct et les contrôles de téléchargement.
@@ -1064,38 +1089,71 @@
Téléchargement de %1$s • %2$s / %3$s
Téléchargement échoué
En pause %1$s
- Supprimer
- Supprimer %1$s de votre bibliothèque ?
- Retirer de la bibliothèque ?
+ Retirer
+ Supprimer %1$s de ta bibliothèque ?
+ Retirer de la bibliothèque ?
Film
- Alertes lorsqu'un nouvel épisode d'une série sauvegardée est disponible.
- Aperçu de l'alerte de sortie d'épisode.
- Impossible d'envoyer une notification de test.
+ Alertes lorsqu’un nouvel épisode d’une série enregistrée est disponible.
+ Aperçu de l’alerte de sortie d’épisode.
+ Impossible d’envoyer une notification de test.
Notification de test envoyée pour %1$s.
+ Moteur de lecture MPV indisponible. Reconstruis l’app.
Impossible de lire ce stream.
- Le code PIN de ce profil a changé. Connectez-vous une fois pour mettre à jour le verrouillage sur cet appareil.
- Impossible de supprimer le verrouillage PIN. Veuillez réessayer.
- Connectez-vous à Internet pour supprimer le verrouillage PIN.
- Ce code PIN ne peut pas encore être vérifié hors ligne sur cet appareil. Connectez-vous une fois et déverrouillez-le en ligne d'abord.
- Impossible de définir le code PIN. Veuillez réessayer.
- Connectez-vous à Internet pour définir un code PIN.
+ Le code PIN de ce profil a changé. Connecte-toi une fois pour mettre à jour le verrouillage sur cet appareil.
+ Impossible de supprimer le verrouillage PIN. Réessaie.
+ Connecte-toi à Internet pour supprimer le verrouillage PIN.
+ Ce code PIN ne peut pas encore être vérifié hors ligne sur cet appareil. Connecte-toi une fois et déverrouille-le en ligne d’abord.
+ Impossible de définir le code PIN. Réessaie.
+ Connecte-toi à Internet pour définir un code PIN.
Ce profil utilise les addons principaux.
Impossible de charger %1$s
Source
Intégré
Autorisation refusée
- Terminez la connexion Trakt dans votre navigateur
+ Termine la connexion Trakt dans ton navigateur
+ Connecté à Trakt
+ Déconnecté de Trakt
Callback Trakt invalide
État du callback Trakt invalide
Réponse de jeton Trakt invalide
Impossible de charger la bibliothèque Trakt
Liste %1$d
- Trakt n'a pas renvoyé de code d'autorisation
+ Trakt n’a pas retourné de code d’autorisation
Identifiants Trakt manquants
Impossible de charger la progression Trakt
+ Liste publique Trakt
+ Saisis un ID ou une URL de liste Trakt valide
+ %1$d éléments
+ %1$d j’aime
+ Identifiants Trakt manquants dans local.properties (TRAKT_CLIENT_ID).
+ ID de liste Trakt manquant
+ La liste Trakt n’inclut pas d’ID numérique
+ Liste Trakt introuvable ou non publique
+ Limite de débit Trakt atteinte
+ Échec de la requête Trakt
Impossible de terminer la connexion Trakt
Utilisateur Trakt
Liste de suivi
+ Ajoute une clé API TMDB dans les paramètres pour utiliser les sources TMDB.
+ Collection TMDB %1$d
+ Collection TMDB introuvable
+ Production TMDB %1$d
+ Société TMDB introuvable
+ Réalisateur TMDB %1$d
+ La découverte TMDB n’a retourné aucune donnée
+ Découverte TMDB
+ Saisis un ID ou une URL TMDB valide.
+ Liste TMDB %1$d
+ Liste TMDB introuvable
+ Impossible de charger la source TMDB
+ ID de collection TMDB manquant
+ ID de liste TMDB manquant
+ ID de personne TMDB manquant
+ Chaîne TMDB %1$d
+ Chaîne TMDB introuvable
+ Crédits de personne TMDB introuvables
+ Personne TMDB %1$d
+ Personne TMDB introuvable
Bande-annonce
Inconnu
Addon
@@ -1103,14 +1161,16 @@
Lire %1$s
Reprendre %1$s
Le JSON est vide.
- La collection '%1$d' a un ID vide.
- La collection '%1$s' a un titre vide.
- Le dossier '%1$d' dans '%2$s' a un ID vide.
- Le dossier '%1$s' dans '%2$s' a un titre vide.
- La source '%1$d' dans le dossier '%2$s' a des champs vides.
- La source '%1$d' dans le dossier '%2$s' n'a pas d'ID de liste Trakt.
- JSON invalide : %1$s
- Addon introuvable : %1$s
+ La collection %1$d a un ID vide.
+ La collection « %1$s » a un titre vide.
+ Le dossier %1$d dans « %2$s » a un ID vide.
+ Le dossier « %1$s » dans « %2$s » a un titre vide.
+ La source %1$d dans le dossier « %2$s » a des champs vides.
+ La source %1$d dans le dossier « %2$s » n’a pas d’ID de liste Trakt.
+ JSON invalide : %1$s
+ Addon introuvable : %1$s
+ Liste de films Trakt
+ Liste de séries Trakt
Janvier
Février
Mars
@@ -1145,7 +1205,7 @@
Classification
Détails du film
Langue originale
- Pays d'origine
+ Pays d’origine
Informations de sortie
Durée
Affiches
@@ -1159,17 +1219,21 @@
Téléchargement démarré
Format de stream non pris en charge pour les téléchargements
Corps de réponse vide
+ Impossible de finaliser le fichier téléchargé
La requête a échoué avec HTTP %1$d
- Le système de téléchargement n'est pas initialisé
+ Le système de téléchargement n’est pas initialisé
+ Impossible d’ouvrir le fichier de téléchargement partiel
+ Le fichier de téléchargement partiel n’est pas ouvert
La requête de téléchargement a échoué
+ Impossible d’écrire dans le fichier de téléchargement partiel
%1$s - %2$s
- Les titres enregistrés apparaîtront ici après avoir appuyé sur Enregistrer dans un écran de détails.
- Votre bibliothèque est vide
+ Appuie sur Enregistrer depuis un écran de détails pour ajouter des titres ici.
+ Ta bibliothèque est vide
Impossible de charger la bibliothèque
Autre
Bibliothèque
- Connectez Trakt et enregistrez des titres dans votre liste de suivi ou vos listes personnelles.
- Votre bibliothèque Trakt est vide
+ Connecte Trakt et enregistre des titres dans ta liste de suivi ou tes listes personnelles.
+ Ta bibliothèque Trakt est vide
Impossible de charger la bibliothèque Trakt
Bibliothèque Trakt
Anime
@@ -1181,7 +1245,7 @@
%1$s • %2$s est maintenant disponible
Un nouvel épisode est maintenant disponible
%1$s est maintenant disponible
- Sorties d'épisodes
+ Sorties d’épisodes
Créateur
Réalisateur
Scénariste
@@ -1192,4 +1256,152 @@
Ko
Mo
Go
+ APERÇU
+ %1$d dépôts
+ %1$d fournisseurs
+ Plugins activés
+ Plugins désactivés
+ Clé API TMDB renseignée
+ Clé API TMDB manquante
+ Les fournisseurs de plugins nécessitent une clé API TMDB. Configure-la dans l’écran TMDB, sinon les fournisseurs ne fonctionneront pas correctement.
+ Activer les fournisseurs de plugins
+ Utilise les fournisseurs de plugins pendant la recherche de streams.
+ Regrouper les fournisseurs par dépôt
+ Dans Streams, affiche un fournisseur par dépôt au lieu d’un par source.
+ AJOUTER UN DÉPÔT
+ URL du manifeste du plugin
+ Installation…
+ Installer le dépôt de plugin
+ Saisis une URL de dépôt de plugin.
+ Saisis une URL de plugin valide.
+ Ce dépôt de plugin est déjà installé.
+ Impossible d’installer le dépôt de plugin
+ Impossible d’actualiser le dépôt
+ Fournisseur introuvable
+ Les plugins ne sont pas disponibles dans cette version.
+ Nom du manifeste manquant.
+ Version du manifeste manquante.
+ Le manifeste ne contient aucun fournisseur.
+ %1$s installé.
+ DÉPÔTS INSTALLÉS
+ Aucun dépôt de plugin installé pour l’instant.
+ Ajoute une URL de dépôt pour installer des plugins fournisseurs.
+ Version %1$s
+ Actualiser le dépôt de plugin
+ Supprimer le dépôt de plugin
+ Actualisation
+ FOURNISSEURS
+ Aucun fournisseur disponible pour l’instant.
+ Aucune description
+ v%1$s
+ Désactivé par le dépôt
+ Test en cours…
+ Tester le fournisseur
+ Erreur
+ Échec du test du fournisseur
+ Résultats du test (%1$d)
+ Dépôt de plugin
+ Soumettre l’intro
+ Soumettre les horodatages
+ TYPE DE SEGMENT
+ Intro
+ Récap
+ Outro
+ DÉBUT (MM:SS)
+ FIN (MM:SS)
+ Soumettre
+ Capturer
+ Clé API invalide ou échec de connexion
+ Masquer les contenus non sortis
+ Masque les films et séries qui ne sont pas encore sortis.
+ Liquid Glass
+ Utilise la barre d’onglets native d’iPhone sur iOS 26 et plus. Le changement de profil instantané depuis la barre d’onglets est indisponible quand cette option est active.
+ Floute les miniatures du prochain épisode dans « Continuer à regarder » pour éviter les spoilers.
+ Flouter les épisodes non vus dans « Continuer à regarder »
+ Inclure les épisodes à venir dans « Continuer à regarder » avant leur diffusion.
+ Afficher les prochains épisodes non diffusés
+ Préférer les miniatures d’épisodes lorsqu’elles sont disponibles.
+ Préférer les miniatures d’épisodes dans « Continuer à regarder »
+ Masquer la valeur
+ Flouter les épisodes non vus
+ Flouter les miniatures d’épisodes jusqu’à ce qu’ils soient vus pour éviter les spoilers.
+ Afficher la valeur
+ Les streams torrent ne sont pas pris en charge
+ Tout l’historique
+ Historique Trakt pris en compte pour « Continuer à regarder »
+ Fenêtre de reprise
+ Choisis quelle quantité d’activité Trakt doit apparaître dans « Continuer à regarder ».
+ Fenêtre de reprise
+ %1$d jours
+ Choisis où enregistrer et gérer les éléments de ta bibliothèque
+ Source de la bibliothèque
+ Bibliothèque Nuvio
+ Bibliothèque Nuvio sélectionnée
+ Choisis la bibliothèque à utiliser pour enregistrer et consulter ta collection
+ Source de la bibliothèque
+ Trakt
+ Bibliothèque Trakt sélectionnée
+ Choisis si la reprise et « Continuer à regarder » doivent utiliser Trakt ou Nuvio Sync, sans interrompre le scrobbling Trakt.
+ Progression de visionnage
+ Source de progression définie sur Nuvio Sync
+ Nuvio Sync
+ Trakt
+ Choisis quelle source de progression alimente la reprise et « Continuer à regarder »
+ Progression de visionnage
+ Source de progression définie sur Trakt
+ Saisis une URL d’image valide commençant par http:// ou https://.
+ URL d’avatar personnalisée sélectionnée.
+ URL d’avatar personnalisée
+ Colle un lien d’image, ou laisse vide pour utiliser le catalogue d’avatars intégré.
+ https://exemple.com/avatar.png
+ Sources de données, remerciements et licences de la plateforme
+ Licences et attributions
+ Impossible d’ouvrir le lecteur externe
+ Choisis d’abord un lecteur externe dans les paramètres
+ Aucun lecteur externe disponible
+ Retirer %1$s de %2$s ?
+ ORDRE DE TRI
+ Par défaut
+ Trie tous les éléments par récence
+ Style streaming
+ Éléments sortis d’abord, à venir à la fin
+ Ordre de tri
+ Masquer le soulignement des catalogues
+ Retire le trait d’accent sous les titres de catalogues et de collections dans toute l’application.
+ Utilisé pour la lecture sur les builds Android.
+ Sous licence Apache License, version 2.0.
+ AndroidX Media3 ExoPlayer 1.8.0
+ Nuvio utilise les IMDb Non-Commercial Datasets, dont title.ratings.tsv.gz, pour les notes et le nombre de votes IMDb. Informations fournies par IMDb (https://www.imdb.com). Utilisé avec autorisation. Les données IMDb sont destinées à un usage personnel et non commercial selon les conditions d’IMDb.
+ IMDb Non-Commercial Datasets
+ Nuvio utilise l’API IntroDB pour les horodatages d’intro, de récap, de générique et d’aperçu fournis par la communauté, utilisés par les contrôles de saut. Nuvio n’est ni affilié ni approuvé par IntroDB.
+ IntroDB
+ Nuvio utilise MDBList pour les notes et les données de fournisseurs de scores externes. Nuvio n’est ni affilié ni approuvé par MDBList.
+ MDBList
+ Utilisé pour la lecture sur les builds iOS.
+ Le code source de MPVKit seul est sous licence LGPL v3.0. Les bundles MPVKit, dont libmpv et les bibliothèques FFmpeg, sont également sous licence LGPL v3.0.
+ MPVKit
+ Le code source et les termes de licence sont disponibles dans le dépôt du projet.
+ Sous licence GNU General Public License v3.0.
+ Nuvio Mobile
+ LICENCE DE L’APPLICATION
+ DONNÉES ET SERVICES
+ LICENCE DE LECTURE
+ Nuvio utilise l’API TMDB pour les métadonnées de films et de séries, les artworks, les bandes-annonces, le casting, les détails de production, les collections et les recommandations. Ce produit utilise l’API TMDB mais n’est ni approuvé ni certifié par TMDB.
+ The Movie Database (TMDB)
+ Nuvio se connecte à Trakt pour l’authentification de compte, l’historique de visionnage, la synchronisation de progression, les données de bibliothèque, les notes, les listes et les commentaires. Nuvio n’est ni affilié ni approuvé par Trakt.
+ Trakt
+ Lecteur externe
+ Application de lecteur externe
+ Ouvre la nouvelle lecture avec l’application vidéo par défaut d’Android ou le sélecteur système.
+ Ouvre la nouvelle lecture avec le lecteur installé sélectionné.
+ Aucun lecteur externe pris en charge n’est installé
+ Aucun paramètre trouvé.
+ Rechercher dans les paramètres…
+ RÉSULTATS
+ Ouvrir dans un lecteur externe
+ Ouvrir dans le lecteur interne
+ Problème de connexion
+ Vérifie ta connexion et réessaie.
+ Bibliothèque Nuvio
+ Dépôt de plugin
diff --git a/composeApp/src/commonMain/composeResources/values/strings.xml b/composeApp/src/commonMain/composeResources/values/strings.xml
index c32e32d0..c8ac4ae5 100644
--- a/composeApp/src/commonMain/composeResources/values/strings.xml
+++ b/composeApp/src/commonMain/composeResources/values/strings.xml
@@ -163,18 +163,27 @@
Quick networks
Genre IDs
Use TMDB genre numbers. Separate multiple with commas for AND, or pipes for OR.
+ 28,12
+ 18,35
Release or air date from
Release or air date to
Use YYYY-MM-DD, for example 2024-01-01.
+ 2020-01-01
+ 2024-12-31
Minimum rating
Maximum rating
TMDB rating from 0 to 10. Example: 7.0.
+ 7.0
+ 10
Minimum votes
Use this to avoid obscure low-vote titles. Example: 100.
+ 100
Original language
Use two-letter language codes, for example en, ko, ja, hi.
+ en, ko, ja, hi
Origin country
Use two-letter country codes, for example US, KR, JP, IN.
+ US, KR, JP, IN
Keyword IDs
Use TMDB keyword numbers. Quick chips fill common examples.
9715 for superhero
@@ -186,6 +195,7 @@
213 for Netflix
Year
Use a four-digit year, for example 2024.
+ 2024
Presets
Search
Add Source
@@ -210,6 +220,12 @@
Popular
Percentage
Votes
+ Enter a Trakt list name, URL, or ID
+ Enter a Trakt list ID or URL
+ Could not load Trakt list
+ No Trakt lists found
+ Resolved Trakt list
+ Trakt List %1$d
Action
Adventure
Animation
@@ -1028,6 +1044,8 @@
Trailer rail and playback shortcuts.
Back online
Cannot reach servers
+ Empty response body
+ Request failed with HTTP %1$d
No internet connection
(age %1$d)
Born %1$s%2$s
@@ -1118,6 +1136,8 @@
%1$s • %2$s
Update check failed
Download failed
+ Empty download body
+ Downloaded update file is missing.
Downloading %1$d%
Unable to start installation
You're using the latest version.
@@ -1165,6 +1185,7 @@
Failed to send a test notification.
Test notification sent for %1$s.
Unable to play this stream.
+ MPV player engine not available. Please rebuild the app.
This profile PIN changed. Connect once to refresh the lock on this device.
Couldn't remove PIN lock. Try again.
Connect to the internet to remove the PIN lock.
@@ -1177,6 +1198,8 @@
Embedded
Authorization denied
Complete Trakt sign in in your browser
+ Connected to Trakt
+ Disconnected from Trakt
Invalid Trakt callback
Invalid Trakt callback state
Invalid Trakt token response
@@ -1185,9 +1208,39 @@
Trakt did not return an authorization code
Missing Trakt credentials
Failed to load Trakt progress
+ Trakt public list
+ Enter a valid Trakt list ID or URL
+ %1$d items
+ %1$d likes
+ Missing Trakt credentials in local.properties (TRAKT_CLIENT_ID).
+ Missing Trakt list ID
+ Trakt list did not include a numeric ID
+ Trakt list not found or not public
+ Trakt rate limit reached
+ Trakt request failed
Failed to complete Trakt sign in
Trakt user
Watchlist
+ Add a TMDB API key in Settings to use TMDB sources.
+ TMDB Collection %1$d
+ TMDB collection not found
+ TMDB Production %1$d
+ TMDB company not found
+ TMDB Director %1$d
+ TMDB discover returned no data
+ TMDB Discover
+ Enter a valid TMDB ID or URL.
+ TMDB List %1$d
+ TMDB list not found
+ Could not load TMDB source
+ Missing TMDB collection ID
+ Missing TMDB list ID
+ Missing TMDB person ID
+ TMDB Network %1$d
+ TMDB network not found
+ TMDB person credits not found
+ TMDB Person %1$d
+ TMDB person not found
Trailer
Unknown
Addon
@@ -1203,6 +1256,8 @@
Source %1$d in folder '%2$s' is missing a Trakt list ID.
Invalid JSON: %1$s
Addon not found: %1$s
+ Trakt Movie List
+ Trakt Series List
January
February
March
@@ -1251,9 +1306,13 @@
Download started
Unsupported stream format for downloads
Empty response body
+ Failed to finalize download file
Request failed with HTTP %1$d
Download system is not initialized
+ Failed to open partial download file
+ Partial download file is not open
Download request failed
+ Failed to write partial download file
%1$s - %2$s
Saved titles will appear here after you tap Save on a details screen.
Your library is empty
@@ -1284,4 +1343,64 @@
KB
MB
GB
+ OVERVIEW
+ %1$d repos
+ %1$d providers
+ Plugins enabled
+ Plugins disabled
+ TMDB API key set
+ TMDB API key missing
+ Plugin providers require a TMDB API key. Set it on the TMDB screen or plugin providers will not work correctly.
+ Enable plugin providers globally
+ Use plugin providers during stream discovery.
+ Group plugin providers by repository
+ In Streams, show one provider per repository instead of one per source.
+ ADD REPOSITORY
+ Plugin manifest URL
+ Installing…
+ Install Plugin Repository
+ Enter a plugin repository URL.
+ Enter a valid plugin URL.
+ That plugin repository is already installed.
+ Unable to install plugin repository
+ Unable to refresh repository
+ Provider not found
+ Plugins are not available in this build.
+ Manifest name is missing.
+ Manifest version is missing.
+ Manifest has no providers.
+ Installed %1$s.
+ INSTALLED REPOSITORIES
+ No plugin repositories installed yet.
+ Add a repository URL to install provider plugins for stream discovery.
+ Version %1$s
+ Refresh plugin repository
+ Delete plugin repository
+ Refreshing
+ PROVIDERS
+ No providers available yet.
+ No description
+ v%1$s
+ Disabled by repo
+ Testing…
+ Test Provider
+ Error
+ Provider test failed
+ Test results (%1$d)
+ Plugin repository
+ Submit Intro
+ Submit Timestamps
+ SEGMENT TYPE
+ Intro
+ Recap
+ Outro
+ START TIME (MM:SS)
+ END TIME (MM:SS)
+ Submit
+ Capture
+ Invalid API Key or connection failed
+ Connection issue
+ Please check your connection and try again.
+ Nuvio Library
+ Plugin repository
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/core/network/NetworkStatusRepository.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/core/network/NetworkStatusRepository.kt
index e9976f75..606389c4 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/core/network/NetworkStatusRepository.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/core/network/NetworkStatusRepository.kt
@@ -1,5 +1,6 @@
package com.nuvio.app.core.network
+import androidx.compose.runtime.Composable
import com.nuvio.app.features.addons.httpRequestRaw
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -9,6 +10,14 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withTimeoutOrNull
+import nuvio.composeapp.generated.resources.Res
+import nuvio.composeapp.generated.resources.details_check_connection
+import nuvio.composeapp.generated.resources.details_servers_unreachable
+import nuvio.composeapp.generated.resources.network_cannot_reach_servers
+import nuvio.composeapp.generated.resources.network_connection_issue
+import nuvio.composeapp.generated.resources.network_no_internet_connection
+import nuvio.composeapp.generated.resources.network_please_check_connection
+import org.jetbrains.compose.resources.stringResource
enum class NetworkCondition {
Unknown,
@@ -28,18 +37,20 @@ data class NetworkStatusUiState(
get() = condition == NetworkCondition.NoInternet || condition == NetworkCondition.ServersUnreachable
}
+@Composable
fun NetworkCondition.titleForEmptyState(): String =
when (this) {
- NetworkCondition.ServersUnreachable -> "Cannot reach servers"
- NetworkCondition.NoInternet -> "No internet connection"
- else -> "Connection issue"
+ NetworkCondition.ServersUnreachable -> stringResource(Res.string.network_cannot_reach_servers)
+ NetworkCondition.NoInternet -> stringResource(Res.string.network_no_internet_connection)
+ else -> stringResource(Res.string.network_connection_issue)
}
+@Composable
fun NetworkCondition.messageForEmptyState(): String =
when (this) {
- NetworkCondition.ServersUnreachable -> "Your device is online, but Nuvio could not reach required servers."
- NetworkCondition.NoInternet -> "Check your Wi-Fi or mobile data connection and try again."
- else -> "Please check your connection and try again."
+ NetworkCondition.ServersUnreachable -> stringResource(Res.string.details_servers_unreachable)
+ NetworkCondition.NoInternet -> stringResource(Res.string.details_check_connection)
+ else -> stringResource(Res.string.network_please_check_connection)
}
object NetworkStatusRepository {
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/library/LibraryRepository.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/library/LibraryRepository.kt
index 46c2acdc..68099d3e 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/library/LibraryRepository.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/library/LibraryRepository.kt
@@ -13,6 +13,11 @@ import com.nuvio.app.features.trakt.effectiveLibrarySourceMode as resolveEffecti
import com.nuvio.app.features.trakt.shouldUseTraktLibrary
import io.github.jan.supabase.postgrest.postgrest
import io.github.jan.supabase.postgrest.rpc
+import kotlinx.coroutines.runBlocking
+import nuvio.composeapp.generated.resources.Res
+import nuvio.composeapp.generated.resources.library_local_tab_title
+import nuvio.composeapp.generated.resources.library_other
+import org.jetbrains.compose.resources.getString
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
@@ -405,12 +410,11 @@ object LibraryRepository {
}
internal const val LOCAL_LIBRARY_LIST_KEY = "local"
-internal const val LOCAL_LIBRARY_LIST_TITLE = "Nuvio Library"
internal fun localLibraryListTab(): TraktListTab =
TraktListTab(
key = LOCAL_LIBRARY_LIST_KEY,
- title = LOCAL_LIBRARY_LIST_TITLE,
+ title = runBlocking { getString(Res.string.library_local_tab_title) },
type = TraktListType.WATCHLIST,
)
@@ -461,7 +465,7 @@ private fun LibraryItem.toSyncItem(): LibrarySyncItem = LibrarySyncItem(
internal fun String.toLibraryDisplayTitle(): String {
val normalized = trim()
- if (normalized.isBlank()) return "Other"
+ if (normalized.isBlank()) return runBlocking { getString(Res.string.library_other) }
return normalized
.split('-', '_', ' ')
@@ -469,5 +473,5 @@ internal fun String.toLibraryDisplayTitle(): String {
.joinToString(" ") { token ->
token.lowercase().replaceFirstChar { char -> char.uppercase() }
}
- .ifBlank { "Other" }
+ .ifBlank { runBlocking { getString(Res.string.library_other) } }
}
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/notifications/EpisodeReleaseNotificationsRepository.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/notifications/EpisodeReleaseNotificationsRepository.kt
index c2ab3eac..b7bb198f 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/notifications/EpisodeReleaseNotificationsRepository.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/notifications/EpisodeReleaseNotificationsRepository.kt
@@ -21,6 +21,7 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
+import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.sync.withPermit
@@ -294,7 +295,7 @@ object EpisodeReleaseNotificationsRepository {
permissionGranted = granted,
testTargetTitle = currentTestTarget()?.name,
errorMessage = when {
- _uiState.value.isEnabled && !granted -> "System notifications are currently disabled for Nuvio."
+ _uiState.value.isEnabled && !granted -> runBlocking { getString(Res.string.settings_notifications_permission_disabled) }
else -> _uiState.value.errorMessage
},
)
@@ -362,7 +363,7 @@ object EpisodeReleaseNotificationsRepository {
scheduledCount = 0,
testTargetTitle = currentTestTarget()?.name,
errorMessage = if (_uiState.value.isEnabled && !permissionGranted) {
- "System notifications are currently disabled for Nuvio."
+ runBlocking { getString(Res.string.settings_notifications_permission_disabled) }
} else {
null
},
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerControls.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerControls.kt
index 13f975ed..8268cc0c 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerControls.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerControls.kt
@@ -268,7 +268,7 @@ private fun PlayerHeader(
if (onSubmitIntroClick != null) {
PlayerHeaderIconButton(
icon = Icons.Rounded.Flag,
- contentDescription = "Submit Intro",
+ contentDescription = stringResource(Res.string.submit_intro_action),
buttonSize = metrics.headerIconSize + 16.dp,
iconSize = metrics.headerIconSize,
onClick = onSubmitIntroClick,
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/skip/SubmitIntroDialog.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/skip/SubmitIntroDialog.kt
index 7d3df719..6f3e8069 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/skip/SubmitIntroDialog.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/skip/SubmitIntroDialog.kt
@@ -49,6 +49,19 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch
+import nuvio.composeapp.generated.resources.Res
+import nuvio.composeapp.generated.resources.action_cancel
+import nuvio.composeapp.generated.resources.action_close
+import nuvio.composeapp.generated.resources.submit_intro_button_submit
+import nuvio.composeapp.generated.resources.submit_intro_capture_button
+import nuvio.composeapp.generated.resources.submit_intro_end_time_label
+import nuvio.composeapp.generated.resources.submit_intro_segment_intro
+import nuvio.composeapp.generated.resources.submit_intro_segment_outro
+import nuvio.composeapp.generated.resources.submit_intro_segment_recap
+import nuvio.composeapp.generated.resources.submit_intro_segment_type_label
+import nuvio.composeapp.generated.resources.submit_intro_start_time_label
+import nuvio.composeapp.generated.resources.submit_intro_title
+import org.jetbrains.compose.resources.stringResource
import kotlin.math.floor
@OptIn(ExperimentalMaterial3Api::class)
@@ -91,20 +104,24 @@ fun SubmitIntroDialog(
verticalAlignment = Alignment.CenterVertically,
) {
Text(
- text = "Submit Timestamps",
+ text = stringResource(Res.string.submit_intro_title),
style = MaterialTheme.typography.titleLarge,
color = MaterialTheme.colorScheme.onSurface,
fontWeight = FontWeight.Bold,
)
IconButton(onClick = onDismiss) {
- Icon(Icons.Rounded.Close, contentDescription = "Close", tint = MaterialTheme.colorScheme.onSurfaceVariant)
+ Icon(
+ Icons.Rounded.Close,
+ contentDescription = stringResource(Res.string.action_close),
+ tint = MaterialTheme.colorScheme.onSurfaceVariant,
+ )
}
}
// Segment Type
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
Text(
- text = "SEGMENT TYPE",
+ text = stringResource(Res.string.submit_intro_segment_type_label),
style = MaterialTheme.typography.labelSmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
fontWeight = FontWeight.SemiBold,
@@ -114,21 +131,21 @@ fun SubmitIntroDialog(
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
SegmentTypeButton(
- label = "Intro",
+ label = stringResource(Res.string.submit_intro_segment_intro),
icon = Icons.Rounded.PlayCircleOutline,
selected = segmentType == "intro",
onClick = { onSegmentTypeChange("intro") },
modifier = Modifier.weight(1f)
)
SegmentTypeButton(
- label = "Recap",
+ label = stringResource(Res.string.submit_intro_segment_recap),
icon = Icons.Rounded.Replay,
selected = segmentType == "recap",
onClick = { onSegmentTypeChange("recap") },
modifier = Modifier.weight(1f)
)
SegmentTypeButton(
- label = "Outro",
+ label = stringResource(Res.string.submit_intro_segment_outro),
icon = Icons.Rounded.StopCircle,
selected = segmentType == "outro",
onClick = { onSegmentTypeChange("outro") },
@@ -139,7 +156,7 @@ fun SubmitIntroDialog(
// Start Time
TimeInputRow(
- label = "START TIME (MM:SS)",
+ label = stringResource(Res.string.submit_intro_start_time_label),
value = startTimeStr,
onValueChange = onStartTimeChange,
onCapture = { onStartTimeChange(formatSecondsToMMSS(currentTimeSec)) }
@@ -147,7 +164,7 @@ fun SubmitIntroDialog(
// End Time
TimeInputRow(
- label = "END TIME (MM:SS)",
+ label = stringResource(Res.string.submit_intro_end_time_label),
value = endTimeStr,
onValueChange = onEndTimeChange,
onCapture = { onEndTimeChange(formatSecondsToMMSS(currentTimeSec)) }
@@ -170,7 +187,7 @@ fun SubmitIntroDialog(
contentAlignment = Alignment.Center
) {
Text(
- text = "Cancel",
+ text = stringResource(Res.string.action_cancel),
color = MaterialTheme.colorScheme.onSurfaceVariant,
fontWeight = FontWeight.SemiBold
)
@@ -217,7 +234,7 @@ fun SubmitIntroDialog(
) {
Icon(Icons.Rounded.Send, contentDescription = null, tint = MaterialTheme.colorScheme.onPrimary, modifier = Modifier.size(18.dp))
Text(
- text = "Submit",
+ text = stringResource(Res.string.submit_intro_button_submit),
color = MaterialTheme.colorScheme.onPrimary,
fontWeight = FontWeight.Bold
)
@@ -328,7 +345,7 @@ private fun TimeInputRow(
modifier = Modifier.size(18.dp)
)
Text(
- text = "Capture",
+ text = stringResource(Res.string.submit_intro_capture_button),
color = MaterialTheme.colorScheme.onSurfaceVariant,
style = MaterialTheme.typography.bodySmall,
fontWeight = FontWeight.SemiBold
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/PlaybackSettingsPage.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/PlaybackSettingsPage.kt
index 042d592d..aa0e3226 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/PlaybackSettingsPage.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/settings/PlaybackSettingsPage.kt
@@ -2111,6 +2111,7 @@ private fun IntroDbApiKeyDialog(
var value by remember { mutableStateOf(initialValue) }
var isVerifying by remember { mutableStateOf(false) }
var errorMessage by remember { mutableStateOf(null) }
+ val invalidKeyMessage = stringResource(Res.string.settings_playback_introdb_invalid_key)
BasicAlertDialog(onDismissRequest = { if (!isVerifying) onDismiss() }) {
Surface(
@@ -2179,7 +2180,7 @@ private fun IntroDbApiKeyDialog(
if (isValid) {
onSave(trimmed)
} else {
- errorMessage = "Invalid API Key or connection failed"
+ errorMessage = invalidKeyMessage
}
}
},
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamsRepository.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamsRepository.kt
index daa96a7b..4b603dbd 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamsRepository.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamsRepository.kt
@@ -23,6 +23,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
+import kotlinx.coroutines.runBlocking
import nuvio.composeapp.generated.resources.*
import org.jetbrains.compose.resources.getString
import kotlinx.coroutines.launch
@@ -596,6 +597,8 @@ private fun String.fallbackRepositoryLabel(): String {
val withoutManifest = withoutQuery.removeSuffix("/manifest.json")
val host = withoutManifest.substringAfter("://", withoutManifest).substringBefore('/')
return host.ifBlank {
- withoutManifest.substringAfterLast('/').ifBlank { "Plugin repository" }
+ withoutManifest.substringAfterLast('/').ifBlank {
+ runBlocking { getString(Res.string.streams_plugin_repository_fallback) }
+ }
}
}
diff --git a/composeApp/src/fullCommonMain/kotlin/com/nuvio/app/features/plugins/PluginRuntime.kt b/composeApp/src/fullCommonMain/kotlin/com/nuvio/app/features/plugins/PluginRuntime.kt
index 8d792b5e..3a003d8e 100644
--- a/composeApp/src/fullCommonMain/kotlin/com/nuvio/app/features/plugins/PluginRuntime.kt
+++ b/composeApp/src/fullCommonMain/kotlin/com/nuvio/app/features/plugins/PluginRuntime.kt
@@ -22,6 +22,10 @@ import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.contentOrNull
import kotlinx.serialization.json.intOrNull
import kotlinx.serialization.json.jsonPrimitive
+import kotlinx.coroutines.runBlocking
+import nuvio.composeapp.generated.resources.Res
+import nuvio.composeapp.generated.resources.generic_unknown
+import org.jetbrains.compose.resources.getString
import kotlin.random.Random
private const val PLUGIN_TIMEOUT_MS = 60_000L
@@ -438,7 +442,7 @@ internal object PluginRuntime {
?.takeIf { it.isNotEmpty() }
PluginRuntimeResult(
- title = item.stringOrNull("title") ?: item.stringOrNull("name") ?: "Unknown",
+ title = item.stringOrNull("title") ?: item.stringOrNull("name") ?: runBlocking { getString(Res.string.generic_unknown) },
name = item.stringOrNull("name"),
url = url,
quality = item.stringOrNull("quality"),
diff --git a/composeApp/src/fullCommonMain/kotlin/com/nuvio/app/features/plugins/PluginsSettingsScreen.kt b/composeApp/src/fullCommonMain/kotlin/com/nuvio/app/features/plugins/PluginsSettingsScreen.kt
index 71b7e4e3..7243ae70 100644
--- a/composeApp/src/fullCommonMain/kotlin/com/nuvio/app/features/plugins/PluginsSettingsScreen.kt
+++ b/composeApp/src/fullCommonMain/kotlin/com/nuvio/app/features/plugins/PluginsSettingsScreen.kt
@@ -40,6 +40,44 @@ import com.nuvio.app.core.ui.NuvioSectionLabel
import com.nuvio.app.core.ui.NuvioSurfaceCard
import com.nuvio.app.features.tmdb.TmdbSettingsRepository
import kotlinx.coroutines.launch
+import nuvio.composeapp.generated.resources.Res
+import nuvio.composeapp.generated.resources.plugins_badge_disabled
+import nuvio.composeapp.generated.resources.plugins_badge_enabled
+import nuvio.composeapp.generated.resources.plugins_badge_providers
+import nuvio.composeapp.generated.resources.plugins_badge_refreshing
+import nuvio.composeapp.generated.resources.plugins_badge_repos
+import nuvio.composeapp.generated.resources.plugins_badge_tmdb_key_missing
+import nuvio.composeapp.generated.resources.plugins_badge_tmdb_key_set
+import nuvio.composeapp.generated.resources.plugins_button_install_repo
+import nuvio.composeapp.generated.resources.plugins_button_installing
+import nuvio.composeapp.generated.resources.plugins_button_test_provider
+import nuvio.composeapp.generated.resources.plugins_button_testing
+import nuvio.composeapp.generated.resources.plugins_cd_delete_repo
+import nuvio.composeapp.generated.resources.plugins_cd_refresh_repo
+import nuvio.composeapp.generated.resources.plugins_empty_providers
+import nuvio.composeapp.generated.resources.plugins_empty_repos_subtitle
+import nuvio.composeapp.generated.resources.plugins_empty_repos_title
+import nuvio.composeapp.generated.resources.plugins_enable_globally_desc
+import nuvio.composeapp.generated.resources.plugins_enable_globally_title
+import nuvio.composeapp.generated.resources.plugins_error_enter_repo_url
+import nuvio.composeapp.generated.resources.plugins_group_by_repo_desc
+import nuvio.composeapp.generated.resources.plugins_group_by_repo_title
+import nuvio.composeapp.generated.resources.plugins_input_manifest_placeholder
+import nuvio.composeapp.generated.resources.plugins_message_installed
+import nuvio.composeapp.generated.resources.plugins_provider_disabled_by_repo
+import nuvio.composeapp.generated.resources.plugins_provider_no_description
+import nuvio.composeapp.generated.resources.plugins_provider_version
+import nuvio.composeapp.generated.resources.plugins_repo_fallback_label
+import nuvio.composeapp.generated.resources.plugins_repo_version
+import nuvio.composeapp.generated.resources.plugins_section_add_repo
+import nuvio.composeapp.generated.resources.plugins_section_installed_repos
+import nuvio.composeapp.generated.resources.plugins_section_overview
+import nuvio.composeapp.generated.resources.plugins_section_providers
+import nuvio.composeapp.generated.resources.plugins_test_error_title
+import nuvio.composeapp.generated.resources.plugins_test_failed
+import nuvio.composeapp.generated.resources.plugins_test_results_count
+import nuvio.composeapp.generated.resources.plugins_tmdb_required_message
+import org.jetbrains.compose.resources.stringResource
@Composable
fun PluginsSettingsPageContent(
@@ -79,29 +117,43 @@ fun PluginsSettingsPageContent(
)
}
+ val repoFallbackLabel = stringResource(Res.string.plugins_repo_fallback_label)
+ val testFailedDefault = stringResource(Res.string.plugins_test_failed)
+ val testErrorTitle = stringResource(Res.string.plugins_test_error_title)
+ val installedTemplate = stringResource(Res.string.plugins_message_installed)
+ val enterRepoUrlError = stringResource(Res.string.plugins_error_enter_repo_url)
+
Column(
modifier = modifier,
verticalArrangement = Arrangement.spacedBy(12.dp),
) {
- NuvioSectionLabel("OVERVIEW")
+ NuvioSectionLabel(stringResource(Res.string.plugins_section_overview))
NuvioSurfaceCard {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(10.dp),
) {
- NuvioInfoBadge(text = "${sortedRepos.size} repos")
- NuvioInfoBadge(text = "${sortedScrapers.size} providers")
+ NuvioInfoBadge(text = stringResource(Res.string.plugins_badge_repos, sortedRepos.size))
+ NuvioInfoBadge(text = stringResource(Res.string.plugins_badge_providers, sortedScrapers.size))
NuvioInfoBadge(
- text = if (uiState.pluginsEnabled) "Plugins enabled" else "Plugins disabled",
+ text = if (uiState.pluginsEnabled) {
+ stringResource(Res.string.plugins_badge_enabled)
+ } else {
+ stringResource(Res.string.plugins_badge_disabled)
+ },
)
NuvioInfoBadge(
- text = if (hasTmdbApiKey) "TMDB API key set" else "TMDB API key missing",
+ text = if (hasTmdbApiKey) {
+ stringResource(Res.string.plugins_badge_tmdb_key_set)
+ } else {
+ stringResource(Res.string.plugins_badge_tmdb_key_missing)
+ },
)
}
if (!hasTmdbApiKey) {
Spacer(modifier = Modifier.height(12.dp))
Text(
- text = "Plugin providers require a TMDB API key. Set it on the TMDB screen or plugin providers will not work correctly.",
+ text = stringResource(Res.string.plugins_tmdb_required_message),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.error,
)
@@ -114,13 +166,13 @@ fun PluginsSettingsPageContent(
) {
Column(modifier = Modifier.weight(1f)) {
Text(
- text = "Enable plugin providers globally",
+ text = stringResource(Res.string.plugins_enable_globally_title),
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onSurface,
)
Spacer(modifier = Modifier.height(2.dp))
Text(
- text = "Use plugin providers during stream discovery.",
+ text = stringResource(Res.string.plugins_enable_globally_desc),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
@@ -143,13 +195,13 @@ fun PluginsSettingsPageContent(
) {
Column(modifier = Modifier.weight(1f)) {
Text(
- text = "Group plugin providers by repository",
+ text = stringResource(Res.string.plugins_group_by_repo_title),
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onSurface,
)
Spacer(modifier = Modifier.height(2.dp))
Text(
- text = "In Streams, show one provider per repository instead of one per source.",
+ text = stringResource(Res.string.plugins_group_by_repo_desc),
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
@@ -162,7 +214,7 @@ fun PluginsSettingsPageContent(
}
}
- NuvioSectionLabel("ADD REPOSITORY")
+ NuvioSectionLabel(stringResource(Res.string.plugins_section_add_repo))
NuvioSurfaceCard {
NuvioInputField(
value = repositoryUrl,
@@ -170,16 +222,20 @@ fun PluginsSettingsPageContent(
repositoryUrl = it
message = null
},
- placeholder = "Plugin manifest URL",
+ placeholder = stringResource(Res.string.plugins_input_manifest_placeholder),
)
Spacer(modifier = Modifier.height(16.dp))
NuvioPrimaryButton(
- text = if (isAdding) "Installing..." else "Install Plugin Repository",
+ text = if (isAdding) {
+ stringResource(Res.string.plugins_button_installing)
+ } else {
+ stringResource(Res.string.plugins_button_install_repo)
+ },
enabled = repositoryUrl.isNotBlank() && !isAdding,
onClick = {
val requested = repositoryUrl.trim()
if (requested.isBlank()) {
- message = "Enter a plugin repository URL."
+ message = enterRepoUrlError
return@NuvioPrimaryButton
}
isAdding = true
@@ -188,7 +244,7 @@ fun PluginsSettingsPageContent(
when (val result = PluginRepository.addRepository(requested)) {
is AddPluginRepositoryResult.Success -> {
repositoryUrl = ""
- message = "Installed ${result.repository.name}."
+ message = installedTemplate.format(result.repository.name)
}
is AddPluginRepositoryResult.Error -> {
message = result.message
@@ -208,17 +264,17 @@ fun PluginsSettingsPageContent(
}
}
- NuvioSectionLabel("INSTALLED REPOSITORIES")
+ NuvioSectionLabel(stringResource(Res.string.plugins_section_installed_repos))
if (sortedRepos.isEmpty()) {
NuvioSurfaceCard {
Text(
- text = "No plugin repositories installed yet.",
+ text = stringResource(Res.string.plugins_empty_repos_title),
style = MaterialTheme.typography.titleLarge,
color = MaterialTheme.colorScheme.onSurface,
)
Spacer(modifier = Modifier.height(8.dp))
Text(
- text = "Add a repository URL to install provider plugins for stream discovery.",
+ text = stringResource(Res.string.plugins_empty_repos_subtitle),
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
@@ -242,7 +298,7 @@ fun PluginsSettingsPageContent(
repo.version?.let { version ->
Spacer(modifier = Modifier.height(6.dp))
Text(
- text = "Version $version",
+ text = stringResource(Res.string.plugins_repo_version, version),
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
@@ -259,13 +315,13 @@ fun PluginsSettingsPageContent(
Row(verticalAlignment = Alignment.CenterVertically) {
NuvioIconActionButton(
icon = Icons.Rounded.Refresh,
- contentDescription = "Refresh plugin repository",
+ contentDescription = stringResource(Res.string.plugins_cd_refresh_repo),
tint = MaterialTheme.colorScheme.primary,
onClick = { PluginRepository.refreshRepository(repo.manifestUrl, pushAfterRefresh = true) },
)
NuvioIconActionButton(
icon = Icons.Rounded.Delete,
- contentDescription = "Delete plugin repository",
+ contentDescription = stringResource(Res.string.plugins_cd_delete_repo),
tint = MaterialTheme.colorScheme.error,
onClick = { PluginRepository.removeRepository(repo.manifestUrl) },
)
@@ -276,9 +332,9 @@ fun PluginsSettingsPageContent(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(10.dp),
) {
- NuvioInfoBadge(text = "${repo.scraperCount} providers")
+ NuvioInfoBadge(text = stringResource(Res.string.plugins_badge_providers, repo.scraperCount))
if (repo.isRefreshing) {
- NuvioInfoBadge(text = "Refreshing")
+ NuvioInfoBadge(text = stringResource(Res.string.plugins_badge_refreshing))
}
}
repo.errorMessage?.let { errorMessage ->
@@ -293,11 +349,11 @@ fun PluginsSettingsPageContent(
}
}
- NuvioSectionLabel("PROVIDERS")
+ NuvioSectionLabel(stringResource(Res.string.plugins_section_providers))
if (sortedScrapers.isEmpty()) {
NuvioSurfaceCard {
Text(
- text = "No providers available yet.",
+ text = stringResource(Res.string.plugins_empty_providers),
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
@@ -307,7 +363,7 @@ fun PluginsSettingsPageContent(
val scraperResults = testResults[scraper.id]
val isTestingThisScraper = testingScraperId == scraper.id
val repositoryName = repositoryNameByUrl[scraper.repositoryUrl]
- ?: scraper.repositoryUrl.fallbackRepositoryLabel()
+ ?: scraper.repositoryUrl.fallbackRepositoryLabel(repoFallbackLabel)
NuvioSurfaceCard {
Row(
@@ -342,7 +398,9 @@ fun PluginsSettingsPageContent(
overflow = TextOverflow.Ellipsis,
)
Text(
- text = scraper.description.ifBlank { "No description" },
+ text = scraper.description.ifBlank {
+ stringResource(Res.string.plugins_provider_no_description)
+ },
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
maxLines = 2,
@@ -363,15 +421,19 @@ fun PluginsSettingsPageContent(
horizontalArrangement = Arrangement.spacedBy(10.dp),
) {
NuvioInfoBadge(text = scraper.supportedTypes.joinToString(" | "))
- NuvioInfoBadge(text = "v${scraper.version}")
+ NuvioInfoBadge(text = stringResource(Res.string.plugins_provider_version, scraper.version))
if (!scraper.manifestEnabled) {
- NuvioInfoBadge(text = "Disabled by repo")
+ NuvioInfoBadge(text = stringResource(Res.string.plugins_provider_disabled_by_repo))
}
}
Spacer(modifier = Modifier.height(12.dp))
NuvioPrimaryButton(
- text = if (isTestingThisScraper) "Testing..." else "Test Provider",
+ text = if (isTestingThisScraper) {
+ stringResource(Res.string.plugins_button_testing)
+ } else {
+ stringResource(Res.string.plugins_button_test_provider)
+ },
enabled = hasTmdbApiKey && !isTestingThisScraper,
onClick = {
testingScraperId = scraper.id
@@ -383,8 +445,8 @@ fun PluginsSettingsPageContent(
.onFailure { error ->
testResults[scraper.id] = listOf(
PluginRuntimeResult(
- title = "Error",
- name = error.message ?: "Provider test failed",
+ title = testErrorTitle,
+ name = error.message ?: testFailedDefault,
url = "about:error",
),
)
@@ -399,7 +461,7 @@ fun PluginsSettingsPageContent(
HorizontalDivider(color = MaterialTheme.colorScheme.outline)
Spacer(modifier = Modifier.height(12.dp))
Text(
- text = "Test results (${scraperResults.size})",
+ text = stringResource(Res.string.plugins_test_results_count, scraperResults.size),
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onSurface,
)
@@ -441,11 +503,11 @@ fun PluginsSettingsPageContent(
}
}
-private fun String.fallbackRepositoryLabel(): String {
+private fun String.fallbackRepositoryLabel(fallback: String): String {
val withoutQuery = substringBefore("?")
val withoutManifest = withoutQuery.removeSuffix("/manifest.json")
val host = withoutManifest.substringAfter("://", withoutManifest).substringBefore('/')
return host.ifBlank {
- withoutManifest.substringAfterLast('/').ifBlank { "Plugin repository" }
+ withoutManifest.substringAfterLast('/').ifBlank { fallback }
}
}