diff --git a/composeApp/src/androidMain/kotlin/com/nuvio/app/features/p2p/P2pStreamingEngine.android.kt b/composeApp/src/androidMain/kotlin/com/nuvio/app/features/p2p/P2pStreamingEngine.android.kt
index 7497c0607..93aecad7c 100644
--- a/composeApp/src/androidMain/kotlin/com/nuvio/app/features/p2p/P2pStreamingEngine.android.kt
+++ b/composeApp/src/androidMain/kotlin/com/nuvio/app/features/p2p/P2pStreamingEngine.android.kt
@@ -2,6 +2,7 @@ package com.nuvio.app.features.p2p
import android.content.Context
import android.util.Log
+import com.nuvio.app.core.i18n.localizedP2pUnknownTorrentError
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -93,7 +94,7 @@ actual object P2pStreamingEngine {
throw e
} catch (e: Exception) {
if (isCurrentGeneration(generation)) {
- _state.value = P2pStreamingState.Error(e.message ?: "Unknown torrent error")
+ _state.value = P2pStreamingState.Error(e.message ?: localizedP2pUnknownTorrentError())
}
throw e
}
diff --git a/composeApp/src/commonMain/composeResources/values-fr/strings.xml b/composeApp/src/commonMain/composeResources/values-fr/strings.xml
index a09f31754..f4a6a3dd6 100644
--- a/composeApp/src/commonMain/composeResources/values-fr/strings.xml
+++ b/composeApp/src/commonMain/composeResources/values-fr/strings.xml
@@ -320,8 +320,11 @@
Rechercher
Pistes audio
Audio
+ Synchro auto
+ Gras
Intégré
Décalage inférieur
+ Capturer
Fermer le lecteur
Couleur
En cours de lecture
@@ -332,11 +335,15 @@
Taille de police
%1$dsp
Verrouiller les contrôles du lecteur
+ Chargement des lignes de sous-titres…
+ Aucune ligne de sous-titres trouvée
+ Impossible de charger les lignes de sous-titres
Aucune piste audio disponible
Aucun épisode disponible
Aucun stream trouvé
Aucun
Contour
+ Couleur du contour
Épisodes
Sources
Streams
@@ -344,6 +351,8 @@
Lecture en cours
Appuie pour chercher des sous-titres
Retour
+ Recharger
+ Réinitialiser
Rétablir les valeurs par défaut
Remplir
Ajuster
@@ -356,8 +365,11 @@
Avancer de 10 secondes
Sources
Style
+ Sélectionne d’abord un sous-titre d’addon
Sous-titres
+ Délai des sous-titres
Sous-titres
+ Opacité du texte
Luminosité %1$s
Volume %1$s
Muet
@@ -386,6 +398,7 @@
Général
Compte
Addons
+ Avancé
Apparence
Contenu et découverte
Continuer à regarder
@@ -400,12 +413,15 @@
Plugins
Personnalisation des affiches
Paramètres
+ Streams
Supporters et contributeurs
Enrichissement TMDB
Trakt
À PROPOS
Gère ton compte, déconnecte-toi ou supprime-le.
COMPTE
+ Comportement au démarrage et des profils.
+ AVANCÉ
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
@@ -415,12 +431,20 @@
GÉNÉRAL
Connecte les services TMDB et MDBList.
Gère les alertes de sortie d’épisodes et envoie une notification de test.
+ Affichage des résultats de streams et règles d’URL de badges.
Basculer vers un profil différent.
Changer de profil
Connecte Trakt, synchronise des listes et enregistre des titres directement dans Trakt.
Aucun paramètre trouvé.
Rechercher dans les paramètres…
RÉSULTATS
+ DÉMARRAGE
+ CACHE
+ Mémoriser le dernier profil
+ Mémorise le dernier profil sélectionné au démarrage
+ Vider le cache de Continuer à regarder
+ Supprime les miniatures, titres et données d’enrichissement en cache pour Continuer à regarder
+ Cache vidé
LICENCE DE L’APP
DONNÉES ET SERVICES
LICENCE DE LECTURE
@@ -584,6 +608,8 @@
VISIBILITÉ
Afficher le bandeau Continuer à regarder sur l’écran d’accueil.
Afficher Continuer à regarder
+ Carte
+ Carte paysage façon TV
Affiche
Carte d’affiche centrée sur la couverture
Large
@@ -646,6 +672,38 @@
Contrôle les métadonnées affichées sous chaque résultat.
Réinitialiser la mise en forme
Restaurer la mise en forme par défaut des résultats.
+ Style Fusion
+ Badges de taille
+ Affiche les badges de taille de fichier dans les résultats de flux et les panneaux de source du lecteur.
+ Logo de l’addon
+ Affiche le logo et le nom de l’addon à côté des sources de streams.
+ Affichage
+ Position des badges
+ Choisis si les badges Fusion et de taille apparaissent au-dessus ou en dessous des cartes de flux.
+ Position des badges
+ Choisis où les badges de flux apparaissent sur les cartes de flux.
+ En haut
+ En bas
+ URL de badges Fusion
+ Importe jusqu’à %1$d URL JSON de badges de flux de style Fusion. Chaque URL peut être mise à jour ou supprimée séparément.
+ Gère les URL JSON de badges de flux de style Fusion importées.
+ Échec de l’import du badge.
+ Saisis une URL JSON de badge.
+ L’URL du badge doit commencer par http:// ou https://.
+ Tu peux importer jusqu’à %1$d URL de badges.
+ %1$d/%2$d URL, %3$d badges Fusion actifs
+ Aucune URL de badge Fusion importée.
+ URL JSON du badge Fusion
+ %1$d/%2$d URL Fusion importées
+ Active
+ Inactive
+ %1$s · %2$d badges activés · %3$d groupes
+ Aperçu
+ Aperçu du badge Fusion
+ %1$d badges de style Fusion depuis cette URL
+ Aucune image de badge de style Fusion dans cette URL.
+ Groupe %1$d
+ Autres badges Fusion
Clé API validée.
Impossible de valider cette clé API.
Ajoute ta clé API MDBList ci-dessous avant d’activer les notes.
@@ -669,6 +727,8 @@
Section de commentaires Trakt.
Détails
Durée, statut, date de sortie, langue et informations associées.
+ Lecture des bandes-annonces dans le Hero
+ Lit un aperçu de la bande-annonce dans le Hero des métadonnées quand une bande-annonce est disponible.
Cartes d’épisodes
Choisis comment les épisodes sont affichés sur l’écran de métadonnées.
Horizontal
@@ -768,10 +828,18 @@
App de lecteur externe
Ouvre les nouvelles lectures avec l’app vidéo par défaut d’Android ou le sélecteur système.
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 ta langue préférée et les transmet au lecteur externe.
Aucun lecteur externe compatible n’est installé
+ Lecteur
+ Interne
+ Externe
+ Choisis quel lecteur gère les nouvelles lectures.
Vitesse au maintien
Maintenir pour accélérer
Garde le doigt appuyé n’importe où sur le lecteur pour accélérer temporairement.
+ Gestes tactiles
+ Autorise les balayages et les doubles appuis sur le lecteur pour avancer ou reculer, ajuster la luminosité ou le volume.
Modèle regex invalide
Durée du cache du dernier lien
Mapper DV7 vers HEVC
@@ -785,6 +853,13 @@
Langue de l’appareil
Forcé
Aucun
+ Tous les sous-titres
+ Récupère et affiche tous les sous-titres d’addons pour la vidéo.
+ Démarrage rapide
+ Ignore la récupération automatique des sous-titres d’addons jusqu’à ce que tu la demandes dans le lecteur.
+ Sous-titres d’addons au démarrage
+ Préférés uniquement
+ Récupère les sous-titres d’addons, mais n’affiche que ceux dans tes langues préférées.
Préférer le groupe binge
Lors de la lecture automatique, préférer un stream du même groupe binge que le stream actuel.
Réutiliser le groupe de binge
@@ -829,6 +904,20 @@
%1$d sélectionné(s)
Afficher la superposition de chargement
Afficher la superposition de chargement initiale pendant le démarrage d’un stream.
+ Couleur d’arrière-plan
+ Gras
+ Utilise une graisse de police plus épaisse pour les sous-titres.
+ Transparent
+ Contour
+ Couleur du contour
+ Dessine une bordure autour du texte des sous-titres.
+ Afficher uniquement les langues préférées
+ N’affiche que les sous-titres correspondant à tes langues de sous-titres préférées.
+ Taille des sous-titres
+ Couleur du texte
+ Utiliser les sous-titres forcés
+ Privilégie les sous-titres forcés selon tes préférences de langue de sous-titres.
+ Décalage vertical
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
@@ -928,6 +1017,12 @@
Nuvio Sync
Source de progression réglée sur Trakt
Source de progression réglée sur Nuvio Sync
+ Source de la section Similaires
+ Choisis la provenance des recommandations sur les pages de détails
+ Source de la section Similaires
+ Sélectionne la source des recommandations affichées sur les pages de détails.
+ Trakt
+ TMDB
Fenêtre de Continuer à regarder
Historique Trakt pris en compte pour Continuer à regarder
Fenêtre de Continuer à regarder
@@ -1049,10 +1144,13 @@
Quitter l’application
Ce catalogue n’a renvoyé aucun élément.
Aucun titre trouvé
+ Plus d’actions
Vérifie ta connexion Wi‑Fi ou données mobiles et réessaie.
Réalisateur
Échec du chargement
À voir aussi
+ Données fournies par TMDB
+ Données fournies par Trakt
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.
@@ -1084,6 +1182,8 @@
Marquer comme vu
À suivre
%1$s vu
+ %1$d h %2$d min restantes
+ %1$d min restantes
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
@@ -1179,6 +1279,7 @@
S%1$dE%2$d - %3$s
Récupération…
Recherche de la source…
+ Chargement des sous-titres depuis les addons…
Recherche des streams…
Lien du stream copié
Aucun lien direct du stream disponible
@@ -1283,6 +1384,16 @@
Impossible de terminer la connexion Trakt
Utilisateur Trakt
Liste de suivi
+
+ Autorisation Trakt expirée
+ Liste Trakt introuvable
+ Limite de listes Trakt atteinte
+ Limite de requêtes Trakt atteinte
+ Échec de la requête Trakt
+ Échec de l’ajout à ta liste de suivi Trakt
+ Échec de l’ajout à la liste Trakt
+ Identifiants Trakt compatibles manquants
+ Réponse vide du serveur
Ajoute une clé API TMDB dans les paramètres pour utiliser les sources TMDB.
Collection TMDB %1$d
Collection TMDB introuvable
@@ -1483,6 +1594,11 @@
Permettre à mpv de cibler par défaut l’espace colorimétrique de l’écran actif.
Primaires cibles
Transfert cible
+ Sortie audio iOS
+ Sortie audio
+ Essaie d’abord AVFoundation, puis bascule sur AudioUnit.
+ Prise en charge expérimentale de l’audio spatial et de la sortie multicanal.
+ Utilise l’ancienne sortie AudioUnit.
Gestion des résultats
Nombre max de résultats
@@ -1498,6 +1614,7 @@
En savoir plus
Format par défaut
+ Format d’origine
Saisis un groupe par ligne.
Ordre original
@@ -1582,6 +1699,7 @@
Capturer
Décodeur matériel
+ Sortie audio
Primaires cibles
Transfert cible
@@ -1760,4 +1878,21 @@
Liste Trakt %1$s
Lecteur système Android
+ Streaming P2P
+ Ce flux utilise la technologie pair-à-pair (P2P). En activant le P2P, tu reconnais et acceptes que :\n\n• Ton adresse IP sera visible par les autres pairs du réseau\n• Tu es seul responsable du contenu auquel tu accèdes\n• Tu confirmes avoir le droit légal de visionner ce contenu dans ta juridiction\n• Nuvio n’héberge, ne distribue ni ne contrôle aucun contenu P2P\n• Nuvio ne peut être tenu responsable des conséquences légales liées à ton utilisation du streaming P2P\n\nTu utilises cette fonctionnalité entièrement à tes propres risques. Le P2P peut être désactivé à tout moment dans les paramètres.
+ Activer le P2P
+ Annuler
+ Erreur torrent inconnue
+ Streaming P2P
+ Autoriser les flux pair-à-pair (torrent)
+ Masquer les statistiques torrent
+ Masquer la mémoire tampon, les seeders, les pairs et la vitesse de téléchargement pendant le chargement et la lecture
+ %1$d sources · %2$d pairs
+ %1$s en mémoire tampon · %2$s · %3$s
+ %1$s · %2$s
+ %1$d pairs · %2$d sources · %3$d %%
+ Connexion aux pairs…
+ Démarrage du moteur P2P…
+ Impossible de démarrer le torrent : %1$s
+ Erreur de torrent : %1$s
diff --git a/composeApp/src/commonMain/composeResources/values/strings.xml b/composeApp/src/commonMain/composeResources/values/strings.xml
index b05145984..313d53338 100644
--- a/composeApp/src/commonMain/composeResources/values/strings.xml
+++ b/composeApp/src/commonMain/composeResources/values/strings.xml
@@ -344,6 +344,8 @@
%1$dsp
Lock player controls
Loading subtitle lines...
+ No subtitle lines found
+ Unable to load subtitle lines
No audio tracks available
No episodes available
No streams found
@@ -693,6 +695,10 @@
Fusion badge URLs
Import up to %1$d Fusion-style stream badge JSON URLs. Each URL can be updated or deleted separately.
Manage imported Fusion-style stream badge JSON URLs.
+ Badge import failed.
+ Enter a badge JSON URL.
+ Badge URL must start with http:// or https://.
+ You can import up to %1$d badge URLs.
%1$d/%2$d URLs, %3$d active Fusion badges
No Fusion badge URLs imported.
Fusion badge JSON URL
@@ -1146,6 +1152,7 @@
Exit app
This catalog did not return any items.
No titles found
+ More actions
Check your Wi-Fi or mobile data connection and try again.
Director
Failed to load
@@ -1389,6 +1396,16 @@
Failed to complete Trakt sign in
Trakt user
Watchlist
+
+ Trakt authorization expired
+ Trakt list not found
+ Trakt list limit reached
+ Trakt rate limit reached
+ Trakt request failed
+ Failed to add to Trakt watchlist
+ Failed to add to Trakt list
+ Missing compatible Trakt IDs
+ Empty response body
Add a TMDB API key in Settings to use TMDB sources.
TMDB Collection %1$d
TMDB collection not found
@@ -1862,6 +1879,7 @@
This stream uses peer-to-peer (P2P) technology. By enabling P2P, you acknowledge and agree that:\n\n• Your IP address will be visible to other peers in the network\n• You are solely responsible for the content you access\n• You confirm you have the legal right to stream this content in your jurisdiction\n• Nuvio does not host, distribute, or control any P2P content\n• Nuvio bears no liability for any legal consequences arising from your use of P2P streaming\n\nYou use this feature entirely at your own risk. P2P can be disabled anytime in Settings.
Enable P2P
Cancel
+ Unknown torrent error
P2P Streaming
Allow peer-to-peer (torrent) streams
Hide torrent stats
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/core/i18n/LocalizedUiText.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/core/i18n/LocalizedUiText.kt
index ca955abb2..3c96e28c7 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/core/i18n/LocalizedUiText.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/core/i18n/LocalizedUiText.kt
@@ -8,6 +8,8 @@ import nuvio.composeapp.generated.resources.action_resume
import nuvio.composeapp.generated.resources.action_resume_episode
import nuvio.composeapp.generated.resources.compose_player_episode_code_episode_only
import nuvio.composeapp.generated.resources.compose_player_episode_code_full
+import nuvio.composeapp.generated.resources.compose_player_no_subtitle_lines_found
+import nuvio.composeapp.generated.resources.compose_player_subtitle_lines_load_error
import nuvio.composeapp.generated.resources.continue_watching_up_next
import nuvio.composeapp.generated.resources.continue_watching_up_next_episode
import nuvio.composeapp.generated.resources.date_month_april
@@ -40,6 +42,11 @@ import nuvio.composeapp.generated.resources.media_movie
import nuvio.composeapp.generated.resources.media_movies
import nuvio.composeapp.generated.resources.media_series
import nuvio.composeapp.generated.resources.media_tv
+import nuvio.composeapp.generated.resources.p2p_error_unknown
+import nuvio.composeapp.generated.resources.settings_stream_badge_enter_url
+import nuvio.composeapp.generated.resources.settings_stream_badge_import_failed
+import nuvio.composeapp.generated.resources.settings_stream_badge_import_limit
+import nuvio.composeapp.generated.resources.settings_stream_badge_url_scheme_invalid
import nuvio.composeapp.generated.resources.unit_bytes_b
import nuvio.composeapp.generated.resources.unit_bytes_gb
import nuvio.composeapp.generated.resources.unit_bytes_kb
@@ -134,6 +141,27 @@ fun localizedShortMonthName(month: Int): String =
else -> month.toString()
}
+fun localizedNoSubtitleLinesFound(): String =
+ resourceString("No subtitle lines found") { getString(Res.string.compose_player_no_subtitle_lines_found) }
+
+fun localizedSubtitleLinesLoadError(): String =
+ resourceString("Unable to load subtitle lines") { getString(Res.string.compose_player_subtitle_lines_load_error) }
+
+fun localizedBadgeImportFailed(): String =
+ resourceString("Badge import failed.") { getString(Res.string.settings_stream_badge_import_failed) }
+
+fun localizedBadgeEnterUrl(): String =
+ resourceString("Enter a badge JSON URL.") { getString(Res.string.settings_stream_badge_enter_url) }
+
+fun localizedBadgeUrlSchemeInvalid(): String =
+ resourceString("Badge URL must start with http:// or https://.") { getString(Res.string.settings_stream_badge_url_scheme_invalid) }
+
+fun localizedBadgeImportLimit(limit: Int): String =
+ resourceString("You can import up to $limit badge URLs.") { getString(Res.string.settings_stream_badge_import_limit, limit) }
+
+fun localizedP2pUnknownTorrentError(): String =
+ resourceString("Unknown torrent error") { getString(Res.string.p2p_error_unknown) }
+
fun localizedByteUnit(unit: String): String =
when (unit) {
"GB" -> resourceString("GB") { getString(Res.string.unit_bytes_gb) }
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/components/DetailActionButtons.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/components/DetailActionButtons.kt
index 7c3324ba8..ae11644dc 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/components/DetailActionButtons.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/details/components/DetailActionButtons.kt
@@ -58,7 +58,7 @@ fun DetailActionButtons(
modifier: Modifier = Modifier,
playLabel: String = stringResource(Res.string.action_play),
secondaryActions: List = emptyList(),
- actionsMenuLabel: String = "More actions",
+ actionsMenuLabel: String = stringResource(Res.string.details_actions_menu_label),
isTablet: Boolean = false,
onPlayClick: () -> Unit = {},
onPlayLongClick: (() -> Unit)? = null,
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreenRuntimeSubtitleActions.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreenRuntimeSubtitleActions.kt
index fa9c8afcb..0823f8207 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreenRuntimeSubtitleActions.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/player/PlayerScreenRuntimeSubtitleActions.kt
@@ -1,5 +1,7 @@
package com.nuvio.app.features.player
+import com.nuvio.app.core.i18n.localizedNoSubtitleLinesFound
+import com.nuvio.app.core.i18n.localizedSubtitleLinesLoadError
import com.nuvio.app.features.addons.httpGetTextWithHeaders
import kotlinx.coroutines.launch
@@ -33,13 +35,13 @@ internal fun PlayerScreenRuntime.loadSubtitleAutoSyncCues(force: Boolean = false
subtitleAutoSyncState = subtitleAutoSyncState.copy(
cues = cues,
isLoading = false,
- errorMessage = if (cues.isEmpty()) "No subtitle lines found" else null,
+ errorMessage = if (cues.isEmpty()) localizedNoSubtitleLinesFound() else null,
)
},
onFailure = { error ->
subtitleAutoSyncState = subtitleAutoSyncState.copy(
isLoading = false,
- errorMessage = error.message ?: "Unable to load subtitle lines",
+ errorMessage = error.message ?: localizedSubtitleLinesLoadError(),
)
},
)
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamBadgeSettingsRepository.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamBadgeSettingsRepository.kt
index 397d26adf..febd2b9b5 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamBadgeSettingsRepository.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/streams/StreamBadgeSettingsRepository.kt
@@ -1,5 +1,9 @@
package com.nuvio.app.features.streams
+import com.nuvio.app.core.i18n.localizedBadgeEnterUrl
+import com.nuvio.app.core.i18n.localizedBadgeImportFailed
+import com.nuvio.app.core.i18n.localizedBadgeImportLimit
+import com.nuvio.app.core.i18n.localizedBadgeUrlSchemeInvalid
import com.nuvio.app.features.addons.httpGetText
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.flow.MutableStateFlow
@@ -77,12 +81,12 @@ object StreamBadgeSettingsRepository {
ensureLoaded()
val normalizedUrl = url.trim()
if (normalizedUrl.isBlank()) {
- return StreamBadgeImportResult.Error("Enter a badge JSON URL.")
+ return StreamBadgeImportResult.Error(localizedBadgeEnterUrl())
}
if (!normalizedUrl.startsWith("https://", ignoreCase = true) &&
!normalizedUrl.startsWith("http://", ignoreCase = true)
) {
- return StreamBadgeImportResult.Error("Badge URL must start with http:// or https://.")
+ return StreamBadgeImportResult.Error(localizedBadgeUrlSchemeInvalid())
}
return try {
@@ -91,7 +95,7 @@ object StreamBadgeSettingsRepository {
import.sourceUrl.equals(normalizedUrl, ignoreCase = true)
}
if (!isExistingImport && currentRules.imports.size >= STREAM_BADGE_IMPORT_LIMIT) {
- return StreamBadgeImportResult.Error("You can import up to $STREAM_BADGE_IMPORT_LIMIT badge URLs.")
+ return StreamBadgeImportResult.Error(localizedBadgeImportLimit(STREAM_BADGE_IMPORT_LIMIT))
}
val payload = httpGetText(normalizedUrl)
val parsedImport = StreamBadgeRulesParser.parse(
@@ -104,7 +108,7 @@ object StreamBadgeSettingsRepository {
StreamBadgeImportResult.Success(streamBadgeRules)
} catch (error: Exception) {
if (error is CancellationException) throw error
- StreamBadgeImportResult.Error(error.message ?: "Badge import failed.")
+ StreamBadgeImportResult.Error(error.message ?: localizedBadgeImportFailed())
}
}
diff --git a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/trakt/TraktLibraryRepository.kt b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/trakt/TraktLibraryRepository.kt
index c8d365abf..39f82e9c2 100644
--- a/composeApp/src/commonMain/kotlin/com/nuvio/app/features/trakt/TraktLibraryRepository.kt
+++ b/composeApp/src/commonMain/kotlin/com/nuvio/app/features/trakt/TraktLibraryRepository.kt
@@ -14,10 +14,12 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
+import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withLock
import nuvio.composeapp.generated.resources.*
+import org.jetbrains.compose.resources.StringResource
import org.jetbrains.compose.resources.getString
import kotlinx.coroutines.sync.withPermit
import kotlinx.coroutines.selects.select
@@ -612,10 +614,10 @@ object TraktLibraryRepository {
followRedirects = true,
)
if (response.status !in 200..299) {
- throw IllegalStateException(errorMessageForStatus(response.status, "Trakt request failed"))
+ throw IllegalStateException(errorMessageForStatus(response.status, localizedString(Res.string.trakt_error_request_failed)))
}
if (response.body.isBlank()) {
- throw IllegalStateException("Empty response body")
+ throw IllegalStateException(localizedString(Res.string.trakt_error_empty_response))
}
return response
}
@@ -636,7 +638,7 @@ object TraktLibraryRepository {
followRedirects = true,
)
if (response.status !in 200..299) {
- throw IllegalStateException(errorMessageForStatus(response.status, "Trakt request failed"))
+ throw IllegalStateException(errorMessageForStatus(response.status, localizedString(Res.string.trakt_error_request_failed)))
}
return response
}
@@ -661,7 +663,7 @@ object TraktLibraryRepository {
headers = headers,
)
if (!isSuccessfulAddResponse(response.body)) {
- throw IllegalStateException(errorMessageForStatus(response.status, "Failed to add to Trakt watchlist"))
+ throw IllegalStateException(errorMessageForStatus(response.status, localizedString(Res.string.trakt_error_add_watchlist_failed)))
}
}
@@ -682,7 +684,7 @@ object TraktLibraryRepository {
headers = headers,
)
if (!isSuccessfulAddResponse(response.body)) {
- throw IllegalStateException(errorMessageForStatus(response.status, "Failed to add to Trakt list"))
+ throw IllegalStateException(errorMessageForStatus(response.status, localizedString(Res.string.trakt_error_add_list_failed)))
}
}
@@ -699,7 +701,7 @@ object TraktLibraryRepository {
val type = normalizeType(item.type)
val ids = resolveIds(item)
if (!ids.hasAnyId()) {
- throw IllegalStateException("Missing compatible Trakt IDs")
+ throw IllegalStateException(localizedString(Res.string.trakt_error_missing_ids))
}
val request = if (type == "movie") {
@@ -819,12 +821,14 @@ object TraktLibraryRepository {
return addCount > 0 || existingCount > 0
}
+ private fun localizedString(resource: StringResource): String = runBlocking { getString(resource) }
+
private fun errorMessageForStatus(status: Int, defaultMessage: String): String =
when (status) {
- 401, 403 -> "Trakt authorization expired"
- 404 -> "Trakt list not found"
- 420 -> "Trakt list limit reached"
- 429 -> "Trakt rate limit reached"
+ 401, 403 -> localizedString(Res.string.trakt_error_authorization_expired)
+ 404 -> localizedString(Res.string.trakt_error_list_not_found)
+ 420 -> localizedString(Res.string.trakt_error_list_limit_reached)
+ 429 -> localizedString(Res.string.trakt_error_rate_limit_reached)
else -> "$defaultMessage ($status)"
}