diff --git a/composeApp/src/commonMain/composeResources/values-fr/strings.xml b/composeApp/src/commonMain/composeResources/values-fr/strings.xml
index 287403fae..42a36ae84 100644
--- a/composeApp/src/commonMain/composeResources/values-fr/strings.xml
+++ b/composeApp/src/commonMain/composeResources/values-fr/strings.xml
@@ -20,6 +20,7 @@
Réessayer
Enregistrer
Enregistrement…
+ Changer
Valider
Installation en cours
Addons
@@ -32,6 +33,11 @@
Indisponible
Configurer l’addon
Supprimer l’addon
+ Connectez votre propre serveur multimédia pour parcourir et lire depuis votre bibliothèque personnelle.
+ Ajoutez une URL de serveur ci-dessus pour que Nuvio affiche votre bibliothèque privée.
+ Aucune bibliothèque personnelle connectée.
+ URL du serveur
+ Ajouter
Ajoutez une URL de manifeste pour commencer à charger des catalogues, métadonnées, streams ou sous-titres dans Nuvio.
Aucun addon installé.
Saisissez une URL d’addon.
@@ -311,6 +317,8 @@
S’inscrire
Vos données seront uniquement stockées localement
Regardez tout, partout
+ En m’inscrivant, j’accepte les
+ Conditions d’utilisation
Bon retour
Bibliothèque
Bibliothèque Trakt
@@ -524,9 +532,13 @@
Statut
Anonyme
Connecté
+ Backend de synchronisation
+ Changer de backend ?
+ Basculer vers %1$s et se déconnecter ? Vous pourrez vous reconnecter sur le backend sélectionné.
Noir AMOLED
Utilise des fonds noirs purs pour les écrans OLED.
Langue de l’application
+ Langue de l’appareil
Choisir la langue
Afficher, masquer et ajuster le bandeau Continuer à regarder.
Liquid Glass
@@ -621,6 +633,7 @@
ACCUEIL
SOURCES
Installez, supprimez, mettez à jour et ordonnez vos sources de contenu.
+ Connectez des sources multimédias personnelles et gérez l’accès à votre propre bibliothèque.
Installez des dépôts de scrapers JavaScript et testez des fournisseurs en interne.
Contrôle quels catalogues apparaissent à l’accueil et dans quel ordre.
Désactivez des sections de détails et réorganisez tout sous le Hero.
@@ -768,6 +781,10 @@
Notification de test
Communauté
Découvrez les personnes qui construisent et soutiennent Nuvio sur Mobile, TV et Web.
+ Serveur et maintenance de ce mois-ci
+ Couvert. Le soutien supplémentaire va désormais au développement.
+ Au-delà de 100 %%, le soutien supplémentaire va au développement.
+ Chargement de la progression du financement…
L’API des supporters n’est pas configurée. Ajoutez DONATIONS_BASE_URL dans local.properties.
Contributeurs
Supporters
@@ -830,6 +847,8 @@
Ouvre les nouvelles lectures avec le lecteur installé sélectionné.
Transmettre les sous-titres au lecteur externe
Récupère les sous-titres d’addons dans votre langue préférée et les transmet au lecteur externe.
+ Envoyer les horodatages d’intro et d’outro
+ Transmet les horodatages de saut d’intro et d’outro résolus au lecteur externe pour le saut automatique. Ne fonctionne que dans les lecteurs compatibles ; les autres l’ignorent.
Aucun lecteur externe compatible n’est installé
Lecteur
Interne
@@ -851,6 +870,8 @@
Non défini
Par défaut
Langue de l’appareil
+ Langue originale
+ Nécessite l’activation de l’enrichissement TMDB
Forcé
Aucun
Tous les sous-titres
@@ -894,6 +915,16 @@
Langue audio secondaire
Langue des sous-titres secondaire
DÉCODEUR
+ Moteur de lecture
+ Utiliser d’abord ExoPlayer et basculer sur libmpv si la lecture échoue.
+ Utiliser ExoPlayer et les décodeurs Android Media3.
+ Utiliser libmpv pour la lecture Android.
+ Moteur de rendu libmpv
+ Moteur de rendu libmpv
+ Décodage matériel libmpv
+ Utiliser le décodage matériel mpv quand il est disponible.
+ Compatibilité YUV420P libmpv
+ Forcer la sortie YUV420P pour les appareils ayant des problèmes de rendu ou de couleur.
ÉPISODE SUIVANT
LECTEUR
PASSER LES SEGMENTS
@@ -1280,6 +1311,7 @@
Récupération…
Recherche de la source…
Chargement des sous-titres depuis les addons…
+ Chargement des segments à passer…
Recherche des streams…
Lien du stream copié
Aucun lien direct du stream disponible
@@ -1349,7 +1381,7 @@
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.
+ Moteur de lecture MPV indisponible. Reconstruisez 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. Réessayez.
@@ -1422,8 +1454,10 @@
Reprendre %1$s
Le JSON est vide.
La collection %1$d a un ID vide.
+ L’identifiant de collection « %1$s » est utilisé plusieurs fois.
La collection « %1$s » a un titre vide.
Le dossier %1$d dans « %2$s » a un ID vide.
+ L’identifiant de dossier « %1$s » est utilisé plusieurs fois dans « %2$s ».
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.
@@ -1784,7 +1818,7 @@
Vérifiez votre connexion et réessayez.
Échec de la requête (HTTP %1$d)
%1$s (%2$s)
- Moteur de lecture MPV indisponible. Reconstruis l’app.
+ Moteur de lecture MPV indisponible. Reconstruisez l’app.
Impossible de lire ce stream.
Plugins désactivés
Plugins activés
@@ -1895,4 +1929,19 @@
Démarrage du moteur P2P…
Impossible de démarrer le torrent : %1$s
Erreur de torrent : %1$s
+
+ Naissance
+ Lieu de naissance
+ Crédits
+ Biographie
+ Pays
+ Type
+ Catalogue
+ À propos
+ Chargement des sous-titres depuis les addons…
+ Téléchargement des sous-titres…
+
+ - %d titre
+ - %d titres
+
diff --git a/composeApp/src/commonMain/composeResources/values/strings.xml b/composeApp/src/commonMain/composeResources/values/strings.xml
index 68ef9347f..6c7761556 100644
--- a/composeApp/src/commonMain/composeResources/values/strings.xml
+++ b/composeApp/src/commonMain/composeResources/values/strings.xml
@@ -1926,4 +1926,19 @@
Starting P2P engine…
Failed to start torrent: %1$s
Torrent error: %1$s
+
+ Born
+ Place of birth
+ Credits
+ Biography
+ Country
+ Type
+ Catalogue
+ About
+ Loading subtitles from addons...
+ Downloading subtitles...
+
+ - %d title
+ - %d titles
+
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/PersonDetailScreen.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/PersonDetailScreen.kt
index 5da68dc8d..179f94b04 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/PersonDetailScreen.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/PersonDetailScreen.kt
@@ -523,15 +523,15 @@ private fun PersonIdentitySidebar(
Column(verticalArrangement = Arrangement.spacedBy(15.dp)) {
person.birthday?.let { birthday ->
PersonSidebarFact(
- label = "Born",
+ label = stringResource(Res.string.person_detail_born),
value = personBirthLine(birthday = birthday, deathday = person.deathday),
)
}
person.placeOfBirth?.takeIf { it.isNotBlank() }?.let { place ->
- PersonSidebarFact(label = "Place of birth", value = place)
+ PersonSidebarFact(label = stringResource(Res.string.person_detail_place_of_birth), value = place)
}
if (creditSummary.isNotBlank()) {
- PersonSidebarFact(label = "Credits", value = creditSummary)
+ PersonSidebarFact(label = stringResource(Res.string.person_detail_credits), value = creditSummary)
}
}
@@ -543,7 +543,7 @@ private fun PersonIdentitySidebar(
.background(MaterialTheme.colorScheme.outline.copy(alpha = 0.30f)),
)
Column(verticalArrangement = Arrangement.spacedBy(9.dp)) {
- SidebarLabel(text = "Biography")
+ SidebarLabel(text = stringResource(Res.string.person_detail_biography))
Text(
text = biography,
style = MaterialTheme.typography.bodyMedium.copy(lineHeight = 22.sp),
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/TmdbEntityBrowseScreen.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/TmdbEntityBrowseScreen.kt
index 38d10fe34..5d6316fa9 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/TmdbEntityBrowseScreen.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/TmdbEntityBrowseScreen.kt
@@ -49,6 +49,7 @@ import androidx.compose.ui.unit.sp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import coil3.compose.AsyncImage
import nuvio.composeapp.generated.resources.*
+import org.jetbrains.compose.resources.pluralStringResource
import org.jetbrains.compose.resources.stringResource
import com.nuvio.app.core.ui.landscapePosterHeightForWidth
import com.nuvio.app.core.ui.landscapePosterWidth
@@ -404,15 +405,15 @@ private fun EntityIdentitySidebar(
Column(verticalArrangement = Arrangement.spacedBy(15.dp)) {
header.originCountry?.takeIf { it.isNotBlank() }?.let { country ->
- EntitySidebarFact(label = "Country", value = country)
+ EntitySidebarFact(label = stringResource(Res.string.entity_browse_country), value = country)
}
header.secondaryLabel?.takeIf { it.isNotBlank() }?.let { label ->
- EntitySidebarFact(label = "Type", value = label)
+ EntitySidebarFact(label = stringResource(Res.string.entity_browse_type), value = label)
}
if (catalogueCount > 0) {
EntitySidebarFact(
- label = "Catalogue",
- value = "$catalogueCount ${if (catalogueCount == 1) "title" else "titles"}",
+ label = stringResource(Res.string.entity_browse_catalogue),
+ value = pluralStringResource(Res.plurals.entity_browse_title_count, catalogueCount, catalogueCount),
)
}
}
@@ -425,7 +426,7 @@ private fun EntityIdentitySidebar(
.background(MaterialTheme.colorScheme.outline.copy(alpha = 0.30f)),
)
Column(verticalArrangement = Arrangement.spacedBy(9.dp)) {
- EntitySidebarLabel(text = "About")
+ EntitySidebarLabel(text = stringResource(Res.string.entity_browse_about))
Text(
text = description,
style = MaterialTheme.typography.bodyMedium.copy(lineHeight = 22.sp),
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/ExternalPlayerLaunchCoordinator.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/ExternalPlayerLaunchCoordinator.kt
index 4fe5ff08a..5024ef945 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/ExternalPlayerLaunchCoordinator.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/ExternalPlayerLaunchCoordinator.kt
@@ -11,6 +11,10 @@ import kotlinx.coroutines.withTimeoutOrNull
import kotlinx.serialization.json.addJsonObject
import kotlinx.serialization.json.buildJsonArray
import kotlinx.serialization.json.put
+import nuvio.composeapp.generated.resources.Res
+import nuvio.composeapp.generated.resources.player_external_downloading_subtitles
+import nuvio.composeapp.generated.resources.player_external_loading_subtitles
+import org.jetbrains.compose.resources.getString
private const val SkipSegmentResolveTimeoutMs = 4_000L
@@ -39,7 +43,7 @@ suspend fun prepareExternalPlayerLaunch(
val subtitlesDeferred = if (forwardSubtitles && !preferredLanguage.equals(SubtitleLanguageOption.NONE, ignoreCase = true)) {
async {
- onOverlayMessage("Loading subtitles from addons...")
+ onOverlayMessage(getString(Res.string.player_external_loading_subtitles))
val subtitles = SubtitleForwarder.fetchForExternalPlayer(
type = type,
@@ -49,7 +53,7 @@ suspend fun prepareExternalPlayerLaunch(
)
if (subtitles != null) {
- onOverlayMessage("Downloading subtitles...")
+ onOverlayMessage(getString(Res.string.player_external_downloading_subtitles))
val cachedSubtitles = SubtitleCacheProvider.cacheForExternalPlayer(subtitles)
// Fallback: use original URLs if caching fails
cachedSubtitles ?: subtitles