diff --git a/translations/fr-FR.README.md b/translations/fr-FR.README.md new file mode 100644 index 0000000..dd53390 --- /dev/null +++ b/translations/fr-FR.README.md @@ -0,0 +1,13 @@ +# Traduction française de Moonfin + +Ce dossier conserve la traduction française des pages d’administration du plugin. + +Le fichier `fr-FR.patch` est la sauvegarde des modifications de traduction appliquées aux pages Jellyfin et Emby. Après une mise à jour du plugin, réappliquer ce patch depuis la racine du dépôt avec : + +```bash +git apply translations/fr-FR.patch +``` + +Si le dépôt a évolué entre-temps, Git peut signaler des conflits. Dans ce cas, il faut conserver les nouvelles fonctionnalités du plugin et réappliquer uniquement les lignes de traduction concernées. + +Ne pas compiler automatiquement après une mise à jour : vérifier d’abord le patch, puis compiler seulement après validation. diff --git a/translations/fr-FR.patch b/translations/fr-FR.patch new file mode 100644 index 0000000..56dec9f --- /dev/null +++ b/translations/fr-FR.patch @@ -0,0 +1,4467 @@ +diff --git a/Emby/Emby.Plugins.Moonfin/Pages/configPage.html b/Emby/Emby.Plugins.Moonfin/Pages/configPage.html +index c1c04a5..d26a672 100644 +--- a/Emby/Emby.Plugins.Moonfin/Pages/configPage.html ++++ b/Emby/Emby.Plugins.Moonfin/Pages/configPage.html +@@ -582,7 +582,7 @@ +
+
+
+-

Moonfin Settings

++

Réglages Moonfin

+
+ +
+@@ -593,84 +593,84 @@ +
+ + + + + + + + + +
+
+ +- ++ +
+
+
+-

General

++

Général

+
+ +
+- Allow Moonfin clients to sync their settings across devices via this server. ++ Autoriser les clients Moonfin à synchroniser leurs réglages entre les appareils via ce serveur. +
+
+
+ +
+-

Moonfin Web Client

++

Client Web Moonfin

+
+- ++ + +
+- Pre-fills the Add Server dialog in Moonfin web. ++ Préremplit la boîte de dialogue « Ajouter un serveur » dans Moonfin Web. + Leave empty to auto-fill from the current Emby origin. + Use the Emby base URL (for example, http://192.168.1.10:8096), not /web. +
+
+
+- ++ + +
+- Forces Moonfin web to auto-connect to this URL on load. +- Leave empty to use plugin-mode auto-connect behavior. ++ Force Moonfin Web à se connecter automatiquement à cette URL au chargement. ++ Laisser vide pour utiliser la connexion automatique du mode plugin. + Use the Emby base URL and do not include a /web suffix. +
+
+
+ +
+- Allows Moonfin web to scan private LAN ranges via WebRTC hints. +- Disable if your browser environment blocks or restricts WebRTC. ++ Autorise Moonfin Web à analyser les plages privées du réseau local grâce aux indications WebRTC. ++ Désactivez cette option si votre navigateur bloque ou restreint WebRTC. +
+
+
+@@ -678,130 +678,130 @@ +
+
+
+-

Seerr Integration

++

Intégration Seerr

+
+ +
+- Enable Seerr integration for all users. Moonfin handles authentication through a server-side proxy so users can sign in once and stay authenticated across clients. ++ Activer l’intégration Seerr pour tous les utilisateurs. Moonfin gère l’authentification via un proxy côté serveur afin que les utilisateurs se connectent une seule fois et restent authentifiés sur tous les clients. +
+
+
+ + +
+- Where Emby can reach your Seerr server. +- Start the address with http:// or https://. Examples: ++ Adresse à laquelle Emby peut joindre votre serveur Seerr. ++ Commencez l’adresse par http:// ou https://. Exemples : +
    +-
  • http://192.168.1.10:5055 (another machine on your network)
  • ++
  • http://192.168.1.10:5055 (une autre machine de votre réseau)
  • +
  • http://seerr:5055 (Docker, on the same network as Emby)
  • +-
  • https://requests.example.com (a public address)
  • ++
  • https://requests.example.com (une adresse publique)
  • +
+- This is the address the Emby server connects to behind the scenes, not the one you +- open in a web browser, so a local network or Docker address works fine. You do not enter a +- username, password, or API key here; people sign in later from the app. ++ Il s’agit de l’adresse à laquelle le serveur Emby se connecte en arrière-plan, et non de celle que vous ++ ouvrez dans un navigateur. Une adresse du réseau local ou de Docker convient. N’indiquez pas de ++ nom d’utilisateur, de mot de passe ou de clé API ici ; la connexion se fera ensuite dans l’application. +

+- Advanced: If a reverse proxy in front of Seerr shows its own login page, ++ Avancé : Si un proxy inverse placé devant Seerr affiche sa propre page de connexion, + let the Emby server through it. If Emby itself sits behind a reverse proxy, make sure + that proxy forwards /Moonfin/ requests to Emby. +
+
+
+- +- ++ ++ +
+- Optional override. The name shown in the UI (e.g., "Requests", "Media Requests"). +- Leave blank to auto-detect from the configured URL. +- The icon is always auto-detected regardless of this setting. ++ Remplacement facultatif. Nom affiché dans l’interface (par exemple « Demandes » ou « Demandes de médias »). ++ Laissez vide pour détecter automatiquement le nom depuis l’URL configurée. ++ L’icône est toujours détectée automatiquement, quel que soit ce réglage. +
+
+
+- SSO Proxy: When Seerr is enabled, Moonfin provides single sign-on. ++ Proxy SSO : Lorsque Seerr est activé, Moonfin fournit une authentification unique. + Users authenticate once with their Emby credentials, and the session is stored server-side. +- All Moonfin clients access Seerr API through /Moonfin/Seerr/Api/ +- without re-authenticating. ++ Tous les clients Moonfin accèdent à l’API Seerr via /Moonfin/Seerr/Api/ ++ sans nouvelle authentification. +
+
+ +
+-

MDBList Integration

++

Intégration MDBList

+
+- +- ++ ++ +
+- Provide a server-wide MDBList API key +- that all users can use for ratings (IMDb, Rotten Tomatoes, Metacritic, etc.). +- Users who set their own key in their Moonfin client settings will use that instead. +- This key also powers the MDBList official list home rows (IMDb Top 250, Most Popular, and similar charts), +- which the "Moonfin MDBList Official Lists Sync" scheduled task fetches and caches on the server. ++ Fournissez une MDBList clé API ++ que tous les utilisateurs peuvent utiliser pour les notes (IMDb, Rotten Tomatoes, Metacritic, etc.). ++ Les utilisateurs qui définissent leur propre clé dans les réglages de leur client Moonfin utiliseront celle-ci. ++ Cette clé alimente également les rangées d’accueil des listes officielles MDBList (IMDb Top 250, plus populaires et classements similaires), ++ que la tâche planifiée « Synchronisation des listes officielles MDBList de Moonfin » récupère et met en cache sur le serveur. +
+
+
+ + +
+
+- Drops every cached rating so they refetch from MDBList. Use this if ratings look +- wrong or are missing after changing the key or updating the plugin. ++ Supprime toutes les notes mises en cache afin de les récupérer à nouveau depuis MDBList. Utilisez cette action si les notes semblent ++ incorrectes ou manquantes après un changement de clé ou une mise à jour du plugin. +
+
+
+ +
+- Fetches IMDb charts (Top 250 movies/TV, Most Popular, and similar) on a schedule so clients +- can show them as home rows and custom rows can resolve the IMDb source. No API key required. ++ Récupère périodiquement les classements IMDb (Top 250 films/séries, plus populaires et similaires) afin que les clients ++ puissent les afficher dans les rangées d’accueil et que les rangées personnalisées puissent utiliser la source IMDb. Aucune clé API n’est nécessaire. +
+
+
+ +
+-

TMDB Integration

++

Intégration TMDB

+
+- +- ++ ++ +
+- Provide a server-wide TMDB API key +- that all users can use for episode ratings. +- Users who set their own key in their Moonfin client settings will use that instead. +- Supports both v3 API keys and v4 Bearer tokens. +- This key is also used to fetch posters for the MDBList official list home rows. Without it, +- those rows still work but show titles without artwork. ++ Fournissez une TMDB clé API ++ que tous les utilisateurs peuvent utiliser pour les notes des épisodes. ++ Les utilisateurs qui définissent leur propre clé dans les réglages de leur client Moonfin utiliseront celle-ci. ++ Prend en charge les clés API v3 et les jetons Bearer v4. ++ Cette clé sert également à récupérer les affiches des rangées officielles MDBList. Sans elle, ++ ces rangées restent fonctionnelles, mais affichent les titres sans illustration. +
+
+
+ +
+- Pre-warms the studio (production company) logo cache from TMDB on a schedule so clients can +- show studio logos on the details screen. Uses the server-wide TMDB key above. ++ Préchauffe périodiquement le cache des logos de studios (sociétés de production) depuis TMDB afin que les clients puissent ++ afficher les logos des studios sur la page de détails. Utilise la clé TMDB globale du serveur ci-dessus. +
+
+
+ +
+-

Push Notifications (Optional)

++

Notifications push (facultatif)

+
+- +- ++ ++ +
+- Optional. Paste a Firebase service-account JSON to send Seerr push notifications directly +- through FCM from this server. Leave empty to use the hosted Moonfin push relay instead. +- Secret: never logged. ++ Facultatif. Collez un JSON de compte de service Firebase pour envoyer directement les notifications push Seerr ++ via FCM depuis ce serveur. Laissez vide pour utiliser le relais push hébergé de Moonfin. ++ Secret : il n’est jamais écrit dans les journaux. +
+
+
+- ++ + +
+ Optional path to a service-account JSON file on the server. When both this and the JSON above +@@ -809,19 +809,19 @@ +
+
+
+- ++ + +
+- Where push notifications are forwarded when no service account is set. Leave blank to use the +- hosted Moonfin relay. ++ Destination des notifications push lorsqu’aucun compte de service n’est défini. Laissez vide pour utiliser le ++ relais hébergé de Moonfin. +
+
+
+- +- ++ ++ +
+- Overrides the key this build ships with, for anyone running their own relay. +- Secret: never logged. ++ Remplace la clé fournie avec cette version, pour les personnes qui utilisent leur propre relais. ++ Secret : il n’est jamais écrit dans les journaux. +
+
+
+@@ -829,323 +829,323 @@ +
+
+
+-

Retro Games (EmulatorJS)

++

Jeux rétro (EmulatorJS)

+
+ +
+- Lets Moonfin clients browse and play ROMs from a "Mixed Content" library using ++ Permet aux clients Moonfin de parcourir et de lancer des ROM d’une bibliothèque « Contenu mixte » avec + EmulatorJS. +- Organize ROMs as System/<game>/rom.ext with any BIOS files at the +- top of each system folder. No setup is needed for the emulator itself: cores stream +- from the EmulatorJS CDN by default. ++ Organisez les ROM comme System/<game>/rom.ext avec les fichiers BIOS à la ++ à la racine de chaque dossier système. Aucun réglage n’est nécessaire pour l’émulateur : les cœurs sont diffusés ++ par défaut depuis le CDN EmulatorJS. +
+
+
+- ++ +
+- Online (default): cores stream from the EmulatorJS CDN. Zero setup, +- but each client needs internet access when a game launches.
+- Offline (self-host): install the cores on this server once so clients +- play with no internet and lower latency. Use either option below; clients switch to +- the local copy automatically once it is installed. ++ En ligne (par défaut) : les cœurs sont diffusés depuis le CDN EmulatorJS. Aucune configuration, ++ mais chaque client doit avoir accès à Internet au lancement d’un jeu.
++ Hors ligne (auto-hébergé) : installez une fois les cœurs sur ce serveur afin que les clients ++ puissent jouer sans Internet et avec une latence réduite. Utilisez l’une des options ci-dessous ; les clients basculeront vers ++ la copie locale automatiquement une fois installée. +
+
+- Checking... ++ Vérification… +
+
+
+- ++ +
+ +- ++ +
+
+- Upload an EmulatorJS data folder zipped up (the zip must contain +- loader.js somewhere inside). Get it from +- EmulatorJS releases +- (extract the archive and zip its data folder). ~290 MB. ++ Importez un dossier data EmulatorJS compressé (l’archive doit contenir ++ loader.js quelque part). Téléchargez-le depuis ++ Versions d’EmulatorJS ++ (décompressez l’archive, puis compressez son dossier data). Environ 290 Mo. +
+
+
+- ++ +
+
+- Select the libraries that hold your game ROMs, then click Save below. If none are +- selected, libraries whose name contains "game", "rom", or "emulat" are auto-detected. ++ Sélectionnez les bibliothèques contenant vos ROM de jeux, puis cliquez sur Enregistrer ci-dessous. Si aucune n’est ++ selected, libraries whose name contains "game", "rom", or "emulat" are détectées automatiquement. +
+
+
+- Box art is fetched automatically from the keyless +- libretro thumbnail server +- (matched by game name); no API keys or accounts are needed. ++ Les jaquettes sont récupérées automatiquement depuis le ++ serveur de miniatures libretro ++ (par correspondance avec le nom du jeu) ; aucune clé API ni aucun compte n’est nécessaire. +
+
+ +
+
+
+-

Default User Settings

++

Réglages utilisateur par défaut

+
+- Configure default Moonfin settings for all users. New users and users who haven't customized +- a setting will see these values. Users can always override defaults in their own Moonfin settings panel. ++ Configurez les réglages Moonfin par défaut pour tous les utilisateurs. Les nouveaux utilisateurs et ceux qui n’ont pas personnalisé ++ un réglage verront ces valeurs. Ils peuvent toujours remplacer ces valeurs dans leur propre panneau de réglages Moonfin. +
+ +
+- How it works: These are the lowest-priority fallback. Resolution order: +- User's device profile → User's global settings → These admin defaults → Built-in defaults. ++ Fonctionnement : Il s’agit de la solution de dernier recours. Ordre de résolution : ++ Profil de l’appareil de l’utilisateur → Réglages globaux de l’utilisateur → Ces valeurs administrateur par défaut → Valeurs intégrées. +
+ +
+- Important: New nullable settings use Not set / Yes / No style inputs. +- Not set means "do not force this value" so users keep their own choice. ++ Important : Les nouveaux réglages facultatifs utilisent des champs de type Non défini / Oui / Non. ++ Non défini signifie « ne pas imposer cette valeur » : les utilisateurs conservent leur propre choix. +
+ +
+- +- ++ ++ + +- +- +- +- ++ ++ ++ ++ + +- ++ +
+ +- ++ +
+-

Theme

++

Thème

+
+- ++ + +-
Automatic adapts to your device. Choose Apple or Material to lock the look.
++
Automatique s’adapte à votre appareil. Choisissez Apple ou Material pour figer l’apparence.
+
+
+- ++ + +-
Default overall app style. Keep Not set to let users choose.
++
Style général par défaut de l’application. Laissez « Non défini » pour permettre aux utilisateurs de choisir.
+
+
+- ++ + +-
Color used for focused cards and controls.
++
Couleur utilisée pour les cartes et contrôles sélectionnés.
+
+ +-

Clock

++

Horloge

+
+- ++ + +
+
+- ++ + +
+ +-

Display

++

Affichage

+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+- ++ +
+ + + -- +
+
+
+- ++ + +
+
+- ++ + +
+
+ +- ++ +
+-

Details Screen

++

Écran de détails

+
+- ++ + +-
Default layout for item detail pages. Keep Not set to let users choose.
++
Disposition par défaut des pages de détails. Laissez « Non défini » pour permettre aux utilisateurs de choisir.
+
+
+- ++ +
+ + + -- +
+
+
+- ++ + +-
When on, detail screen tabs start expanded and moving focus between them reveals content without pressing select.
++
Lorsqu’il est activé, les onglets de la page de détails sont développés et le déplacement du focus affiche le contenu sans appuyer sur Sélectionner.
+
+
+- ++ + +
+
+- ++ + +-
Source used for recommended and similar media on detail pages.
++
Source utilisée pour les médias recommandés et similaires sur les pages de détails.
+
+
+- ++ + +-
Filter recommendations to not exceed the current item's age rating.
++
Limiter les recommandations à la classification d’âge de l’élément actuel.
+
+

Action Buttons

+
+- +-
Check which action buttons to show on detail pages and use the arrows to set their order.
++ ++
Choisissez les boutons d’action à afficher sur les pages de détails et utilisez les flèches pour définir leur ordre.
+
+
+
+ + +
+-

Appearance

++

Apparence

+
+- ++ + +
+
+- ++ + +
+
+- ++ +
+ + + -- +@@ -1154,126 +1154,126 @@ + +

Nav Buttons

+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+ + +
+-

Home Row Display

++

Affichage des rangées d’accueil

+
+- ++ + +
+
+- ++ + +-
Combine Continue Watching and Next Up into a single home row by default.
++
Regrouper par défaut « Continuer à regarder » et « À suivre » dans une seule rangée d’accueil.
+
+
+- ++ + +-
How long a show stays in Next Up after it was last watched.
++
Durée pendant laquelle une série reste dans « À suivre » après son dernier visionnage.
+
+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+ +
+ + + -- +@@ -1283,48 +1283,48 @@ + +
+ + + -- +
+
+
+- ++ + +
+
+- ++ + +
+
+ + +
+-

Default Home Layout

+-
Choose active default home sections and their order. This builder configures layout and custom dynamic rows.
++

Disposition d’accueil par défaut

++
Choisissez les sections d’accueil actives par défaut et leur ordre. Cet outil configure la disposition et les rangées dynamiques personnalisées.
+
+
+-
Current Layout
++
Disposition actuelle
+
+
+
+-
Available Rows
++
Rangées disponibles
+
+- ++ +
+
+
+@@ -1332,192 +1332,192 @@ + + +
+-

General

++

Général

+
+- ++ + +
+
+- ++ + +-
Combines recently added media from different libraries of the same type into unified rows.
++
Combine les médias récemment ajoutés de bibliothèques différentes du même type dans des rangées communes.
+
+ +-

Library View

++

Vue des bibliothèques

+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+ + +
+-

Video Playback

++

Lecture vidéo

+
+- ++ + +-
Automatically rewinds slightly when resuming an in-progress video.
++
Rembobiner légèrement automatiquement lors de la reprise d’une vidéo en cours.
+
+
+- ++ + +-
Rewinds slightly when unpausing playback.
++
Rembobine légèrement lors de la reprise de la lecture.
+
+
+- ++ + +
+
+- ++ + +
+ +-

Audio Playback

++

Lecture audio

+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+ +-

Subtitle Preferences

++

Préférences des sous-titres

+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+ +

Automation & Queue

+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+@@ -1526,30 +1526,30 @@ +
+

Media Bar

+
+- ++ + +
+
+- ++ + +
+
+ + +
+
+- ++ + +
+
+ + +
+
+ + +
+ + +@@ -1600,139 +1600,139 @@ + +

Local Previews

+
+- ++ + +
+
+- ++ + +
+
+- ++ + +-
Show closed captions on YouTube trailers when available.
++
Afficher les sous-titres des bandes-annonces YouTube lorsqu’ils sont disponibles.
+
+
+ + +
+
+- ++ + +
+
+ +
+-
Titles in these genres never appear in the media bar.
++
Les titres de ces genres n’apparaissent jamais dans la barre multimédia.
+
+ +

Seasonal Effects

+
+ + +
+ +-

Theme Music

++

Musique du thème

+
+- ++ + +
+
+- ++ +
+ + + -- +
+
+
+- ++ + +
+
+- ++ + +
+
+ +- ++ +
+-

Metadata & Ratings

++

Métadonnées et notes

+
+ +-
Enable MDBList ratings by default (requires server-wide or user API key).
++
Activer par défaut les notes MDBList (nécessite une clé API globale au serveur ou une clé API utilisateur).
+
+
+ +-
Enable TMDB episode ratings by default (requires server-wide or user API key).
++
Activer par défaut les notes des épisodes TMDB (nécessite une clé API globale au serveur ou une clé API utilisateur).
+
+
+- ++ + +
+
+- ++ + +
+
+- +-
Check which ratings to display and drag or use the arrows to set their order.
++ ++
Choisissez les notes à afficher et utilisez les flèches pour définir leur ordre.
+
+
+ +@@ -1740,14 +1740,14 @@ +
+ + +
+
+- +-
Enable rows to see on Seerr mainpage and use the arrows to set their order.
++ ++
Activez les rangées à afficher sur la page principale de Seerr et utilisez les flèches pour définir leur ordre.
+
+
+
+@@ -1756,28 +1756,28 @@ +
+
+
+-

Uploaded Themes

++

Thèmes importés

+
+- Upload theme editor JSON exports so Moonfin clients can download and apply them. +- Uploaded themes are synced to Mobile-Desktop, tvOS, and Smart-TV through plugin sync. ++ Importez les exports JSON de l’éditeur de thèmes afin que les clients Moonfin puissent les télécharger et les appliquer. ++ Les thèmes importés sont synchronisés vers Mobile-Desktop, tvOS et Smart-TV grâce à la synchronisation du plugin. +
+
+- Validation: The server validates theme schema and field ranges on upload. +- Fix any listed field-path errors in the theme editor, then upload again. ++ Validation : Le serveur valide le schéma du thème et les plages de valeurs lors de l’importation. ++ Corrigez les erreurs de chemin de champ indiquées dans l’éditeur de thèmes, puis importez à nouveau. +
+ +
+ +- No file selected ++ Aucun fichier sélectionné + +
+ +
+- ++ +
+
+
+@@ -1785,34 +1785,34 @@ +
+
+
+-

Push Defaults To Existing Users

++

Appliquer les valeurs par défaut aux utilisateurs existants

+
+- Apply the configured defaults above to every existing user now. ++ Appliquez maintenant les valeurs par défaut configurées ci-dessus à tous les utilisateurs existants. + Only fields that are set (not "Not set") will be merged into user global settings. +- Save your default settings first if you made changes. ++ Enregistrez d’abord vos réglages par défaut si vous les avez modifiés. +
+
+- Warning: This action updates existing user profiles immediately for all set fields. ++ Avertissement : This action updates existing user profiles immediately for all set fields. + Device-specific profile overrides are not touched. +
+ + +
+ +
+-

Broadcast Message

++

Message diffusé

+
+- Send a live message to all currently connected Moonfin clients. +- This message is not saved and only appears for users with an active connection. ++ Envoyer un message en direct à tous les clients Moonfin actuellement connectés. ++ Ce message n’est pas enregistré et n’apparaît qu’aux utilisateurs disposant d’une connexion active. +
+
+ +- ++ +
+ + +
+@@ -1820,7 +1820,7 @@ +
+
+
+-

Opening Moonfin

++

Ouvrir Moonfin

+
+

+ Open Moonfin directly at /Moonfin/Web/ on your Emby server. +@@ -1838,19 +1838,19 @@ +

+
+
+-

Active Downloads

++

Téléchargements actifs

+
+ Transcoded downloads Moonfin clients have in progress. Regular playback transcodes + are hidden here since they already show on the Emby dashboard. +
+
+-
Loading...
++
Chargement…
+
+
+
+
+ +
+
+diff --git a/Jellyfin/backend/Pages/configPage.html b/Jellyfin/backend/Pages/configPage.html +index 3dd9a77..8f87e1c 100644 +--- a/Jellyfin/backend/Pages/configPage.html ++++ b/Jellyfin/backend/Pages/configPage.html +@@ -345,7 +345,7 @@ +
+ +
+-

Moonfin Settings

++

Réglages Moonfin

+
+ +
+@@ -356,84 +356,84 @@ +
+ + + + + + + + + +
+
+ +- ++ +
+
+
+-

General

++

Général

+
+ +
+- Allow Moonfin clients to sync their settings across devices via this server. ++ Autoriser les clients Moonfin à synchroniser leurs réglages entre les appareils via ce serveur. +
+
+
+ +
+-

Moonfin Web Client

++

Client Web Moonfin

+
+- ++ + +
+- Pre-fills the Add Server dialog in Moonfin web. +- Leave empty to auto-fill from the current Jellyfin origin. +- Use the Jellyfin base URL (for example, http://192.168.1.10:8096), not /web. ++ Préremplit la boîte de dialogue « Ajouter un serveur » dans Moonfin Web. ++ Laissez vide pour remplir automatiquement depuis l’adresse Jellyfin actuelle. ++ Utilisez l’URL de base de Jellyfin (par exemple, http://192.168.1.10:8096), not /web. +
+
+
+- ++ + +
+- Forces Moonfin web to auto-connect to this URL on load. +- Leave empty to use plugin-mode auto-connect behavior. +- Use the Jellyfin base URL and do not include a /web suffix. ++ Force Moonfin Web à se connecter automatiquement à cette URL au chargement. ++ Laisser vide pour utiliser la connexion automatique du mode plugin. ++ Utilisez l’URL de base de Jellyfin sans ajouter le suffixe /web. +
+
+
+ +
+- Allows Moonfin web to scan private LAN ranges via WebRTC hints. +- Disable if your browser environment blocks or restricts WebRTC. ++ Autorise Moonfin Web à analyser les plages privées du réseau local grâce aux indications WebRTC. ++ Désactivez cette option si votre navigateur bloque ou restreint WebRTC. +
+
+
+@@ -441,143 +441,143 @@ +
+
+
+-

Seerr Integration

++

Intégration Seerr

+
+ +
+- Enable Seerr integration for all users. Moonfin handles authentication through a server-side proxy so users can sign in once and stay authenticated across clients. ++ Activer l’intégration Seerr pour tous les utilisateurs. Moonfin gère l’authentification via un proxy côté serveur afin que les utilisateurs se connectent une seule fois et restent authentifiés sur tous les clients. +
+
+
+ + +
+- Where Jellyfin can reach your Seerr server. +- Start the address with http:// or https://. Examples: ++ Adresse à laquelle Jellyfin peut joindre votre serveur Seerr. ++ Commencez l’adresse par http:// ou https://. Exemples : +
    +-
  • http://192.168.1.10:5055 (another machine on your network)
  • +-
  • http://seerr:5055 (Docker, on the same network as Jellyfin)
  • +-
  • https://requests.example.com (a public address)
  • ++
  • http://192.168.1.10:5055 (une autre machine de votre réseau)
  • ++
  • http://seerr:5055 (Docker, sur le même réseau que Jellyfin)
  • ++
  • https://requests.example.com (une adresse publique)
  • +
+- This is the address the Jellyfin server connects to behind the scenes, not the one you +- open in a web browser, so a local network or Docker address works fine. You do not enter a +- username, password, or API key here; people sign in later from the app. ++ Il s’agit de l’adresse à laquelle le serveur Jellyfin se connecte en arrière-plan, et non de celle que vous ++ ouvrez dans un navigateur. Une adresse du réseau local ou de Docker convient. N’indiquez pas de ++ nom d’utilisateur, de mot de passe ou de clé API ici ; la connexion se fera ensuite dans l’application. +

+- Advanced: If a reverse proxy in front of Seerr shows its own login page, +- let the Jellyfin server through it. If Jellyfin itself sits behind a reverse proxy, make sure +- that proxy forwards /Moonfin/ requests to Jellyfin. ++ Avancé : Si un proxy inverse placé devant Seerr affiche sa propre page de connexion, ++ autorisez le serveur Jellyfin à le traverser. Si Jellyfin se trouve lui-même derrière un proxy inverse, vérifiez ++ que ce proxy transmet les requêtes /Moonfin/ à Jellyfin. +
+
+
+- +- ++ ++ +
+- Optional override. The name shown in the UI (e.g., "Requests", "Media Requests"). +- Leave blank to auto-detect from the configured URL. +- The icon is always auto-detected regardless of this setting. ++ Remplacement facultatif. Nom affiché dans l’interface (par exemple « Demandes » ou « Demandes de médias »). ++ Laissez vide pour détecter automatiquement le nom depuis l’URL configurée. ++ L’icône est toujours détectée automatiquement, quel que soit ce réglage. +
+
+
+- ++ + +
+- The address Seerr uses to reach this Jellyfin server for request +- notifications (the webhook Seerr calls back). Set this when Seerr and Jellyfin run in +- separate containers or hosts, since the server otherwise can only guess a local address +- that Seerr may not be able to reach. Use the base URL, for example +- http://192.168.1.10:8096 or https://jellyfin.example.com. ++ L’adresse utilisée par Seerr pour joindre ce serveur Jellyfin pour les demandes ++ notifications (le webhook rappelé par Seerr). Renseignez-la lorsque Seerr et Jellyfin fonctionnent dans ++ des conteneurs ou hôtes distincts, car le serveur ne peut sinon que deviner une adresse locale ++ que Seerr ne pourra peut-être pas atteindre. Utilisez l’URL de base, par exemple ++ http://192.168.1.10:8096 ou https://jellyfin.example.com. +

+ +
+ +
+
+
+- ++ + +
+- Hosted relay that forwards push to backgrounded clients. Leave the default unless you run +- your own relay. Used only when no service account below is configured. ++ Relais hébergé qui transmet les notifications push aux clients en arrière-plan. Conservez la valeur par défaut, sauf si vous utilisez ++ votre propre relais. Utilisé uniquement si aucun compte de service ci-dessous n’est configuré. +
+
+
+- +- ++ ++ +
+- Override the built-in relay key. Most self-hosters leave this blank. This is a secret and is +- never logged. ++ Remplace la clé intégrée du relais. La plupart des hébergeurs laissent ce champ vide. Il s’agit d’un secret qui est ++ n’est jamais écrit dans les journaux. +
+
+
+- +- ++ ++ +
+- Paste the Firebase service-account JSON to enable push notifications so backgrounded or +- closed mobile clients still receive request updates. Generate it in the Firebase console under +- Project Settings → Service accounts. This is a secret and is stored in the plugin config. +- Leave blank to disable push. ++ Collez le JSON du compte de service Firebase pour activer les notifications push afin que les clients ++ mobiles en arrière-plan ou fermés reçoivent toujours les mises à jour des demandes. Générez-le dans la console Firebase, sous ++ Project Settings → Service accounts. Il s’agit d’un secret stocké dans la configuration du plugin. ++ Laissez vide pour désactiver les notifications push. +
+
+
+- ++ + +
+- Optional path to the service-account JSON file on the server. When set, it takes priority +- over the pasted JSON above. ++ Chemin facultatif vers le fichier JSON du compte de service sur le serveur. Lorsqu’il est renseigné, il est prioritaire ++ sur le JSON collé ci-dessus. +
+
+
+- SSO Proxy: When Seerr is enabled, Moonfin provides single sign-on. +- Users authenticate once with their Jellyfin credentials, and the session is stored server-side. +- All Moonfin clients access Seerr API through /Moonfin/Seerr/Api/ +- without re-authenticating. ++ Proxy SSO : Lorsque Seerr est activé, Moonfin fournit une authentification unique. ++ Les utilisateurs s’authentifient une fois avec leurs identifiants Jellyfin, puis la session est stockée côté serveur. ++ Tous les clients Moonfin accèdent à l’API Seerr via /Moonfin/Seerr/Api/ ++ sans nouvelle authentification. +
+
+ +
+-

MDBList Integration

++

Intégration MDBList

+
+- +- ++ ++ +
+- Provide a server-wide MDBList API key +- that all users can use for ratings (IMDb, Rotten Tomatoes, Metacritic, etc.). +- Users who set their own key in their Moonfin client settings will use that instead. ++ Fournissez une MDBList clé API ++ que tous les utilisateurs peuvent utiliser pour les notes (IMDb, Rotten Tomatoes, Metacritic, etc.). ++ Les utilisateurs qui définissent leur propre clé dans les réglages de leur client Moonfin utiliseront celle-ci. +
+
+
+ + +
+
+- Drops every cached rating so they refetch from MDBList. Use this if ratings look +- wrong or are missing after changing the key or updating the plugin. ++ Supprime toutes les notes mises en cache afin de les récupérer à nouveau depuis MDBList. Utilisez cette action si les notes semblent ++ incorrectes ou manquantes après un changement de clé ou une mise à jour du plugin. +
+
+
+ +
+- Nightly task that caches MDBList's official charts (e.g. IMDb Top 250) so clients can +- show them as home rows without their own key. ++ Tâche nocturne qui met en cache les classements officiels de MDBList (par exemple IMDb Top 250) afin que les clients puissent ++ les afficher dans les rangées d’accueil sans leur propre clé. +
+
+
+- ++ + +
+- Cap on items cached per official list (default 250). ++ Limite du nombre d’éléments mis en cache par liste officielle (250 par défaut). +
+
+
+@@ -590,42 +590,42 @@ + Sync IMDb charts + +
+- Nightly task that caches IMDb charts (Top 250, Popular, etc.) for IMDb custom rows. ++ Tâche nocturne qui met en cache les classements IMDb (Top 250, Populaires, etc.) pour les rangées IMDb personnalisées. +
+
+
+ +
+-

Studio Logos

++

Logos des studios

+
+ +
+- Nightly task that caches production-company logos for the studio row on detail pages. +- Requires the server-wide TMDB key below. ++ Tâche nocturne qui met en cache les logos des sociétés de production pour la rangée des studios sur les pages de détails. ++ Nécessite la clé TMDB globale au serveur ci-dessous. +
+
+
+- ++ + +
+- Logos older than this are re-fetched (default 30). ++ Les logos plus anciens que cette durée sont récupérés à nouveau (30 jours par défaut). +
+
+
+ +
+-

TMDB Integration

++

Intégration TMDB

+
+- +- ++ ++ +
+- Provide a server-wide TMDB API key +- that all users can use for episode ratings. +- Users who set their own key in their Moonfin client settings will use that instead. +- Supports both v3 API keys and v4 Bearer tokens. ++ Fournissez une TMDB clé API ++ que tous les utilisateurs peuvent utiliser pour les notes des épisodes. ++ Les utilisateurs qui définissent leur propre clé dans les réglages de leur client Moonfin utiliseront celle-ci. ++ Prend en charge les clés API v3 et les jetons Bearer v4. +
+
+
+@@ -633,326 +633,326 @@ + +
+
+-

Retro Games (EmulatorJS)

++

Jeux rétro (EmulatorJS)

+
+ +
+- Lets Moonfin clients browse and play ROMs from a "Mixed Content" library using ++ Permet aux clients Moonfin de parcourir et de lancer des ROM d’une bibliothèque « Contenu mixte » avec + EmulatorJS. +- Organize ROMs as System/<game>/rom.ext with any BIOS files at the +- top of each system folder. No setup is needed for the emulator itself: cores stream +- from the EmulatorJS CDN by default. For offline use, drop the EmulatorJS +- data/ folder into <plugin data>/emulatorjs/data/ and it +- is used automatically. ++ Organisez les ROM comme System/<game>/rom.ext avec les fichiers BIOS à la ++ à la racine de chaque dossier système. Aucun réglage n’est nécessaire pour l’émulateur : les cœurs sont diffusés ++ par défaut depuis le CDN EmulatorJS. Pour une utilisation hors ligne, placez le dossier EmulatorJS ++ data/ dans <plugin data>/emulatorjs/data/ ; il ++ il sera utilisé automatiquement. +
+
+
+- ++ +
+- Online (default): cores stream from the EmulatorJS CDN. Zero setup, +- but each client needs internet access when a game launches.
+- Offline (self-host): install the cores on this server once so clients +- play with no internet and lower latency. Use either option below; clients switch to +- the local copy automatically once it is installed. ++ En ligne (par défaut) : les cœurs sont diffusés depuis le CDN EmulatorJS. Aucune configuration, ++ mais chaque client doit avoir accès à Internet au lancement d’un jeu.
++ Hors ligne (auto-hébergé) : installez une fois les cœurs sur ce serveur afin que les clients ++ puissent jouer sans Internet et avec une latence réduite. Utilisez l’une des options ci-dessous ; les clients basculeront vers ++ la copie locale automatiquement une fois installée. +
+
+- Checking... ++ Vérification… +
+
+
+- ++ +
+ +- ++ +
+
+- Upload an EmulatorJS data folder zipped up (the zip must contain +- loader.js somewhere inside). Get it from +- EmulatorJS releases +- (extract the archive and zip its data folder). ~290 MB. ++ Importez un dossier data EmulatorJS compressé (l’archive doit contenir ++ loader.js quelque part). Téléchargez-le depuis ++ Versions d’EmulatorJS ++ (décompressez l’archive, puis compressez son dossier data). Environ 290 Mo. +
+
+
+- ++ +
+
+- Select the libraries that hold your game ROMs, then click Save below. If none +- are selected, libraries whose name contains "game", "rom", or "emulat" are +- auto-detected. ++ Sélectionnez les bibliothèques contenant vos ROM de jeux, puis cliquez sur Enregistrer ci-dessous. Si aucune ++ n’est sélectionnée, les bibliothèques dont le nom contient « game », « rom » ou « emulat » sont ++ détectées automatiquement. +
+
+
+- Box art is fetched automatically from the keyless +- libretro thumbnail server +- (matched by game name); no API keys or accounts are needed. ++ Les jaquettes sont récupérées automatiquement depuis le ++ serveur de miniatures libretro ++ (par correspondance avec le nom du jeu) ; aucune clé API ni aucun compte n’est nécessaire. +
+
+ +
+
+
+-

Default User Settings

++

Réglages utilisateur par défaut

+
+- Configure default Moonfin settings for all users. New users and users who haven't customized +- a setting will see these values. Users can always override defaults in their own Moonfin settings panel. ++ Configurez les réglages Moonfin par défaut pour tous les utilisateurs. Les nouveaux utilisateurs et ceux qui n’ont pas personnalisé ++ un réglage verront ces valeurs. Ils peuvent toujours remplacer ces valeurs dans leur propre panneau de réglages Moonfin. +
+ +
+- How it works: These are the lowest-priority fallback. Resolution order: +- User's device profile → User's global settings → These admin defaults → Built-in defaults. ++ Fonctionnement : Il s’agit de la solution de dernier recours. Ordre de résolution : ++ Profil de l’appareil de l’utilisateur → Réglages globaux de l’utilisateur → Ces valeurs administrateur par défaut → Valeurs intégrées. +
+ +
+- Important: New nullable settings use Not set / Yes / No style inputs. +- Not set means "do not force this value" so users keep their own choice. ++ Important : Les nouveaux réglages facultatifs utilisent des champs de type Non défini / Oui / Non. ++ Non défini signifie « ne pas imposer cette valeur » : les utilisateurs conservent leur propre choix. +
+ +
+- +- ++ ++ + +- +- +- +- ++ ++ ++ ++ + +- ++ +
+ +- ++ +
+-

Theme

++

Thème

+
+- ++ + +-
Automatic adapts to your device. Choose Apple or Material to lock the look.
++
Automatique s’adapte à votre appareil. Choisissez Apple ou Material pour figer l’apparence.
+
+
+- ++ + +-
Default overall app style. Keep Not set to let users choose.
++
Style général par défaut de l’application. Laissez « Non défini » pour permettre aux utilisateurs de choisir.
+
+
+- ++ + +-
Color used for focused cards and controls.
++
Couleur utilisée pour les cartes et contrôles sélectionnés.
+
+ +-

Clock

++

Horloge

+
+- ++ + +
+
+- ++ + +
+ +-

Display

++

Affichage

+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+- ++ +
+ + + -- +
+
+
+- ++ + +
+
+- ++ + +
+
+ +- ++ +
+-

Details Screen

++

Écran de détails

+
+- ++ + +-
Default layout for item detail pages. Keep Not set to let users choose.
++
Disposition par défaut des pages de détails. Laissez « Non défini » pour permettre aux utilisateurs de choisir.
+
+
+- ++ +
+ + + -- +
+
+
+- ++ + +-
When on, detail screen tabs start expanded and moving focus between them reveals content without pressing select.
++
Lorsqu’il est activé, les onglets de la page de détails sont développés et le déplacement du focus affiche le contenu sans appuyer sur Sélectionner.
+
+
+- ++ + +
+
+- ++ + +-
Source used for recommended and similar media on detail pages.
++
Source utilisée pour les médias recommandés et similaires sur les pages de détails.
+
+
+- ++ + +-
Filter recommendations to not exceed the current item's age rating.
++
Limiter les recommandations à la classification d’âge de l’élément actuel.
+
+

Action Buttons

+
+- +-
Check which action buttons to show on detail pages and use the arrows to set their order.
++ ++
Choisissez les boutons d’action à afficher sur les pages de détails et utilisez les flèches pour définir leur ordre.
+
+
+
+ + +
+-

Appearance

++

Apparence

+
+- ++ + +
+
+- ++ + +
+
+- ++ +
+ + + -- +@@ -961,155 +961,155 @@ + +

Nav Buttons

+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+ + +
+-

Home Row Display

++

Affichage des rangées d’accueil

+
+- ++ + +
+
+- ++ + +-
Combine Continue Watching and Next Up into a single home row by default.
++
Regrouper par défaut « Continuer à regarder » et « À suivre » dans une seule rangée d’accueil.
+
+
+- ++ + +-
How long a show stays in Next Up after it was last watched.
++
Durée pendant laquelle une série reste dans « À suivre » après son dernier visionnage.
+
+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+ + +
+-

Default Home Layout

+-
Choose active default home sections and their order. This builder configures layout and custom dynamic rows.
++

Disposition d’accueil par défaut

++
Choisissez les sections d’accueil actives par défaut et leur ordre. Cet outil configure la disposition et les rangées dynamiques personnalisées.
+
+
+-
Current Layout
++
Disposition actuelle
+
+
+
+-
Available Rows
++
Rangées disponibles
+
+- ++ +
+
+
+@@ -1117,192 +1117,192 @@ + + +
+-

General

++

Général

+
+- ++ + +
+
+- ++ + +-
Combines recently added media from different libraries of the same type into unified rows.
++
Combine les médias récemment ajoutés de bibliothèques différentes du même type dans des rangées communes.
+
+ +-

Library View

++

Vue des bibliothèques

+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+ + +
+-

Video Playback

++

Lecture vidéo

+
+- ++ + +-
Automatically rewinds slightly when resuming an in-progress video.
++
Rembobiner légèrement automatiquement lors de la reprise d’une vidéo en cours.
+
+
+- ++ + +-
Rewinds slightly when unpausing playback.
++
Rembobine légèrement lors de la reprise de la lecture.
+
+
+- ++ + +
+
+- ++ + +
+ +-

Audio Playback

++

Lecture audio

+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+ +-

Subtitle Preferences

++

Préférences des sous-titres

+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+ +

Automation & Queue

+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+- ++ + +
+
+@@ -1311,30 +1311,30 @@ +
+

Media Bar

+
+- ++ + +
+
+- ++ + +
+
+ + +
+
+- ++ + +
+
+ + +
+
+ + +
+ + +@@ -1385,139 +1385,139 @@ + +

Local Previews

+
+- ++ + +
+
+- ++ + +
+
+- ++ + +-
Show closed captions on YouTube trailers when available.
++
Afficher les sous-titres des bandes-annonces YouTube lorsqu’ils sont disponibles.
+
+
+ + +
+
+- ++ + +
+
+ +
+-
Titles in these genres never appear in the media bar.
++
Les titres de ces genres n’apparaissent jamais dans la barre multimédia.
+
+ +

Seasonal Effects

+
+ + +
+ +-

Theme Music

++

Musique du thème

+
+- ++ + +
+
+- ++ +
+ + + -- +
+
+
+- ++ + +
+
+- ++ + +
+
+ +- ++ +
+-

Metadata & Ratings

++

Métadonnées et notes

+
+ +-
Enable MDBList ratings by default (requires server-wide or user API key).
++
Activer par défaut les notes MDBList (nécessite une clé API globale au serveur ou une clé API utilisateur).
+
+
+ +-
Enable TMDB episode ratings by default (requires server-wide or user API key).
++
Activer par défaut les notes des épisodes TMDB (nécessite une clé API globale au serveur ou une clé API utilisateur).
+
+
+- ++ + +
+
+- ++ + +
+
+- +-
Check which ratings to display and drag or use the arrows to set their order.
++ ++
Choisissez les notes à afficher et utilisez les flèches pour définir leur ordre.
+
+
+ +@@ -1525,14 +1525,14 @@ +
+ + +
+
+- +-
Enable rows to see on Seerr mainpage and use the arrows to set their order.
++ ++
Activez les rangées à afficher sur la page principale de Seerr et utilisez les flèches pour définir leur ordre.
+
+
+
+@@ -1540,28 +1540,28 @@ +
+
+
+-

Uploaded Themes

++

Thèmes importés

+
+- Upload theme editor JSON exports so Moonfin clients can download and apply them. +- Uploaded themes are synced to Mobile-Desktop, tvOS, and Smart-TV through plugin sync. ++ Importez les exports JSON de l’éditeur de thèmes afin que les clients Moonfin puissent les télécharger et les appliquer. ++ Les thèmes importés sont synchronisés vers Mobile-Desktop, tvOS et Smart-TV grâce à la synchronisation du plugin. +
+
+- Validation: The server validates theme schema and field ranges on upload. +- Fix any listed field-path errors in the theme editor, then upload again. ++ Validation : Le serveur valide le schéma du thème et les plages de valeurs lors de l’importation. ++ Corrigez les erreurs de chemin de champ indiquées dans l’éditeur de thèmes, puis importez à nouveau. +
+ +
+ +- No file selected ++ Aucun fichier sélectionné + +
+ +
+- ++ +
+
+
+@@ -1569,31 +1569,31 @@ +
+
+
+-

Apply Defaults To Users

++

Appliquer les valeurs par défaut aux utilisateurs

+
+- New users and any setting a user hasn't customized already use the defaults above automatically once you Save. +- Use these actions to also push the defaults onto users' existing settings. Save your changes first. ++ Les nouveaux utilisateurs et tout réglage non personnalisé utilisent automatiquement les valeurs par défaut ci-dessus après l’enregistrement. ++ Utilisez ces actions pour appliquer également les valeurs par défaut aux réglages existants des utilisateurs. Enregistrez d’abord vos modifications. +
+ +
+ +
+- Destructive. Erases every user's current settings (global and any desktop/mobile/TV overrides) +- and replaces them with a single global profile equal to the defaults. Also creates profiles for +- users who never customized and removes settings files for users that no longer exist on the server. +- When unchecked, the defaults are merged in without removing users' personal customizations. ++ Destructif. Efface les réglages actuels de chaque utilisateur (réglages globaux et remplacements ordinateur/mobile/TV) ++ puis les remplace par un profil global correspondant aux valeurs par défaut. Crée également des profils pour ++ les utilisateurs n’ayant jamais personnalisé leurs réglages et supprime les fichiers des utilisateurs qui n’existent plus sur le serveur. ++ Si cette option est désactivée, les valeurs par défaut sont fusionnées sans supprimer les personnalisations personnelles des utilisateurs. +
+
+ + + +
+- Or apply the defaults to a single user: ++ Ou appliquez les valeurs par défaut à un seul utilisateur : +
+
+ +@@ -1602,27 +1602,27 @@ +
+ +
+ + +
+ +
+-

Broadcast Message

++

Message diffusé

+
+- Send a live message to all currently connected Moonfin clients. +- This message is not saved and only appears for users with an active connection. ++ Envoyer un message en direct à tous les clients Moonfin actuellement connectés. ++ Ce message n’est pas enregistré et n’apparaît qu’aux utilisateurs disposant d’une connexion active. +
+
+ +- ++ +
+ + +
+@@ -1630,26 +1630,26 @@ +
+
+
+-

Web Plugin Status

++

État du plugin Web

+
+-

Moonfin uses the ++

Moonfin utilise le + File Transformation +- plugin to inject a header button in Jellyfin Web. ++ plugin pour ajouter un bouton dans l’en-tête de Jellyfin Web. +

+

+- What it does: the injected button opens the Flutter app at /Moonfin/Web/. ++ Fonctionnement : le bouton ajouté ouvre l’application Flutter à /Moonfin/Web/. +

+

+ Setup: +

+
    +-
  1. Install the File Transformation plugin (add https://www.iamparadox.dev/jellyfin/plugins/manifest.json to your plugin repositories)
  2. ++
  3. Installez le plugin File Transformations)
  4. +
  5. Restart Jellyfin
  6. +-
  7. Force refresh your browser (Ctrl+Shift+R)
  8. ++
  9. Forcez l’actualisation de votre navigateur (Ctrl+Shift+R)
  10. +
+

+- UI not loading? Go to Dashboard > Scheduled Tasks and run the +- Moonfin Startup task once, then refresh your browser. ++ L’interface ne se charge pas ? Allez dans Dashboard > Tâches planifiées et exécutez la tâche ++ Moonfin Startup tâche une fois, puis actualisez votre navigateur. +

+
+
+@@ -1657,15 +1657,15 @@ +
+
+
+-

Active Downloads

++

Téléchargements actifs

+
+-
Loading...
++
Chargement…
+
+
+
+
+ +
+
+@@ -2189,72 +2189,72 @@ + ]; + + var HOME_SECTION_DEFINITIONS = [ +- { type: 'smalllibrarytiles', label: 'My Media' }, +- { type: 'resume', label: 'Continue Watching' }, +- { type: 'nextup', label: 'Next Up' }, +- { type: 'latestmedia', label: 'Recently Added Media' }, +- { type: 'recentlyreleased', label: 'Recently Released' }, +- { type: 'livetv', label: 'Live TV' }, +- { type: 'librarybuttons', label: 'Library Buttons' }, +- { type: 'resumeaudio', label: 'Resume Audio' }, +- { type: 'resumebook', label: 'Resume Books' }, +- { type: 'activerecordings', label: 'Active Recordings' }, ++ { type: 'smalllibrarytiles', label: 'Mes médias' }, ++ { type: 'resume', label: 'Continuer à regarder' }, ++ { type: 'nextup', label: 'À suivre' }, ++ { type: 'latestmedia', label: 'Médias récemment ajoutés' }, ++ { type: 'recentlyreleased', label: 'Sorties récentes' }, ++ { type: 'livetv', label: 'TV en direct' }, ++ { type: 'librarybuttons', label: 'Boutons des bibliothèques' }, ++ { type: 'resumeaudio', label: 'Reprendre l’audio' }, ++ { type: 'resumebook', label: 'Reprendre les livres' }, ++ { type: 'activerecordings', label: 'Enregistrements actifs' }, + { type: 'collections', label: 'Collections' }, +- { type: 'favoritemovies', label: 'Favorite Movies' }, +- { type: 'favoriteseries', label: 'Favorite Series' }, +- { type: 'favoriteepisodes', label: 'Favorite Episodes' }, +- { type: 'favoritepeople', label: 'Favorite People' }, +- { type: 'favoriteartists', label: 'Favorite Artists' }, +- { type: 'favoritemusicvideos', label: 'Favorite Music Videos' }, +- { type: 'favoritealbums', label: 'Favorite Albums' }, +- { type: 'favoritesongs', label: 'Favorite Songs' }, ++ { type: 'favoritemovies', label: 'Films favoris' }, ++ { type: 'favoriteseries', label: 'Séries favorites' }, ++ { type: 'favoriteepisodes', label: 'Épisodes favoris' }, ++ { type: 'favoritepeople', label: 'Personnes favorites' }, ++ { type: 'favoriteartists', label: 'Artistes favoris' }, ++ { type: 'favoritemusicvideos', label: 'Vidéos musicales favorites' }, ++ { type: 'favoritealbums', label: 'Albums favoris' }, ++ { type: 'favoritesongs', label: 'Chansons favorites' }, + { type: 'genres', label: 'Genres' }, +- { type: 'playlists', label: 'Playlists' }, +- { type: 'sinceyouwatched1', label: "Since You Watched 1" }, +- { type: 'sinceyouwatched2', label: "Since You Watched 2" }, +- { type: 'sinceyouwatched3', label: "Since You Watched 3" }, +- { type: 'sinceyouwatched4', label: "Since You Watched 4" }, +- { type: 'sinceyouwatched5', label: "Since You Watched 5" }, +- { type: 'rewatch', label: "Rewatch" }, +- { type: 'seerr_shortcuts', label: 'Seerr Browse' }, +- { type: 'seerr_recent_requests', label: 'Seerr Recent Requests' }, +- { type: 'seerr_recently_added', label: 'Seerr Recently Added' }, +- { type: 'seerr_popular_movies', label: 'Seerr Popular Movies' }, +- { type: 'seerr_upcoming_movies', label: 'Seerr Upcoming Movies' }, +- { type: 'seerr_popular_series', label: 'Seerr Popular Series' }, +- { type: 'seerr_upcoming_series', label: 'Seerr Upcoming Series' }, +- { type: 'seerr_trending', label: 'Seerr Trending' }, +- { type: 'seerr_movie_genres', label: 'Seerr Movie Genres' }, +- { type: 'seerr_studios', label: 'Seerr Studios' }, +- { type: 'seerr_series_genres', label: 'Seerr Series Genres' }, +- { type: 'seerr_networks', label: 'Seerr Networks' }, +- { type: 'imdb_top_250_movies', label: 'IMDB Top 250 Movies' }, +- { type: 'imdb_top_250_tv_shows', label: 'IMDB Top 250 Shows' }, +- { type: 'imdb_most_popular_movies', label: 'IMDB Most Popular Movies' }, +- { type: 'imdb_most_popular_tv_shows', label: 'IMDB Most Popular Shows' }, +- { type: 'imdb_lowest_rated_movies', label: 'IMDB Lowest Rated Movies' }, +- { type: 'imdb_top_english_movies', label: 'IMDB Top English Movies' }, +- { type: 'tmdb_popular_movies', label: 'TMDB Popular Movies' }, +- { type: 'tmdb_top_rated_movies', label: 'TMDB Top Rated Movies' }, +- { type: 'tmdb_now_playing_movies', label: 'TMDB Now Playing Movies' }, +- { type: 'tmdb_upcoming_movies', label: 'TMDB Upcoming Movies' }, +- { type: 'tmdb_popular_tv', label: 'TMDB Popular TV' }, +- { type: 'tmdb_top_rated_tv', label: 'TMDB Top Rated TV' }, +- { type: 'tmdb_airing_today_tv', label: 'TMDB Airing Today TV' }, +- { type: 'tmdb_on_the_air_tv', label: 'TMDB On The Air TV' }, +- { type: 'tmdb_trending_movie_daily', label: 'TMDB Trending Movies (Daily)' }, +- { type: 'tmdb_trending_movie_weekly', label: 'TMDB Trending Movies (Weekly)' }, +- { type: 'tmdb_trending_tv_daily', label: 'TMDB Trending TV (Daily)' }, +- { type: 'tmdb_trending_tv_weekly', label: 'TMDB Trending TV (Weekly)' }, +- { type: 'tmdb_trending_all_weekly', label: 'TMDB Trending All (Weekly)' }, +- { type: 'radarr_calendar', label: 'Radarr Upcoming' }, +- { type: 'sonarr_calendar', label: 'Sonarr Upcoming' } ++ { type: 'playlists', label: 'Liste de lectures' }, ++ { type: 'sinceyouwatched1', label: "Depuis votre dernier visionnage 1" }, ++ { type: 'sinceyouwatched2', label: "Depuis votre dernier visionnage 2" }, ++ { type: 'sinceyouwatched3', label: "Depuis votre dernier visionnage 3" }, ++ { type: 'sinceyouwatched4', label: "Depuis votre dernier visionnage 4" }, ++ { type: 'sinceyouwatched5', label: "Depuis votre dernier visionnage 5" }, ++ { type: 'rewatch', label: "À revoir" }, ++ { type: 'seerr_shortcuts', label: 'Parcourir Seerr' }, ++ { type: 'seerr_recent_requests', label: 'Demandes récentes Seerr' }, ++ { type: 'seerr_recently_added', label: 'Seerr : ajouts récents' }, ++ { type: 'seerr_popular_movies', label: 'Seerr : films populaires' }, ++ { type: 'seerr_upcoming_movies', label: 'Seerr : films à venir' }, ++ { type: 'seerr_popular_series', label: 'Seerr : séries populaires' }, ++ { type: 'seerr_upcoming_series', label: 'Seerr : séries à venir' }, ++ { type: 'seerr_trending', label: 'Seerr : tendances' }, ++ { type: 'seerr_movie_genres', label: 'Seerr : genres de films' }, ++ { type: 'seerr_studios', label: 'Seerr : studios' }, ++ { type: 'seerr_series_genres', label: 'Seerr : genres de séries' }, ++ { type: 'seerr_networks', label: 'Seerr : réseaux' }, ++ { type: 'imdb_top_250_movies', label: 'Films IMDb Top 250' }, ++ { type: 'imdb_top_250_tv_shows', label: 'Séries IMDb Top 250' }, ++ { type: 'imdb_most_popular_movies', label: 'IMDB Films les plus populaires' }, ++ { type: 'imdb_most_popular_tv_shows', label: 'Séries IMDb les plus populaires' }, ++ { type: 'imdb_lowest_rated_movies', label: 'IMDB Films les moins bien notés' }, ++ { type: 'imdb_top_english_movies', label: 'Meilleurs films anglophones IMDb' }, ++ { type: 'tmdb_popular_movies', label: 'Films TMDB populaires' }, ++ { type: 'tmdb_top_rated_movies', label: 'Films TMDB les mieux notés' }, ++ { type: 'tmdb_now_playing_movies', label: 'Films TMDB actuellement à l’affiche' }, ++ { type: 'tmdb_upcoming_movies', label: 'Films TMDB à venir' }, ++ { type: 'tmdb_popular_tv', label: 'Séries TV TMDB populaires' }, ++ { type: 'tmdb_top_rated_tv', label: 'Séries TV TMDB les mieux notées' }, ++ { type: 'tmdb_airing_today_tv', label: 'Séries TMDB diffusées aujourd’hui' }, ++ { type: 'tmdb_on_the_air_tv', label: 'Séries TMDB en cours de diffusion' }, ++ { type: 'tmdb_trending_movie_daily', label: 'Films TMDB tendance (Daily)' }, ++ { type: 'tmdb_trending_movie_weekly', label: 'Films TMDB tendance (Weekly)' }, ++ { type: 'tmdb_trending_tv_daily', label: 'Séries TV TMDB tendance (Daily)' }, ++ { type: 'tmdb_trending_tv_weekly', label: 'Séries TV TMDB tendance (Weekly)' }, ++ { type: 'tmdb_trending_all_weekly', label: 'TMDB : tendances générales (Weekly)' }, ++ { type: 'radarr_calendar', label: 'Radarr : à venir' }, ++ { type: 'sonarr_calendar', label: 'Sonarr : à venir' } + ]; + + function loadAdminGenrePicker(selectedIds) { + var picker = document.querySelector('#DefaultGenrePicker'); + if (!picker) return; +- picker.innerHTML = '
Loading...
'; ++ picker.innerHTML = '
Chargement…
'; + + var serverUrl = ApiClient.serverAddress ? ApiClient.serverAddress() : ''; + var token = ApiClient.accessToken ? ApiClient.accessToken() : ''; +@@ -2265,7 +2265,7 @@ + .then(function(data) { + var genres = data.Items || data.items || []; + if (genres.length === 0) { +- picker.innerHTML = '
No genres found.
'; ++ picker.innerHTML = '
Aucun genre trouvé.
'; + return; + } + var html = ''; +@@ -2281,7 +2281,7 @@ + picker.innerHTML = html; + }) + .catch(function() { +- picker.innerHTML = '
Failed to load genres.
'; ++ picker.innerHTML = '
Impossible de charger les genres.
'; + }); + } + +@@ -2342,7 +2342,7 @@ + // ISO 639-2 codes, matching the table Core resolves track languages against. + // The audio and subtitle pickers share the list so the two stay in sync. + var LANGUAGE_OPTIONS = [ +- ['auto', 'Server Default'], ['eng', 'English'], ['spa', 'Spanish'], ++ ['auto', 'Serveur par défaut'], ['eng', 'Anglais'], ['spa', 'Espagnol'], + ['fra', 'French'], ['deu', 'German'], ['ita', 'Italian'], + ['jpn', 'Japanese'], ['kor', 'Korean'], ['zho', 'Chinese'], + ['rus', 'Russian'], ['por', 'Portuguese'], ['ara', 'Arabic'], +@@ -2358,7 +2358,7 @@ + var select = document.querySelector(selector); + if (!select || select.dataset.filled) return; + select.dataset.filled = 'true'; +- var html = ''; ++ var html = ''; + for (var i = 0; i < LANGUAGE_OPTIONS.length; i++) { + var code = LANGUAGE_OPTIONS[i][0]; + var label = LANGUAGE_OPTIONS[i][1]; +@@ -2371,8 +2371,8 @@ + // Same ids and declaration order as DetailButton in Core, so an untouched + // arrangement here matches what a fresh client shows. + var DETAIL_BUTTONS = [ +- { id: 'seerrRequest', label: 'Request' }, +- { id: 'seerrRequest4k', label: 'Request 4K' }, ++ { id: 'seerrDemande', label: 'Demande' }, ++ { id: 'seerrDemande4k', label: 'Demande 4K' }, + { id: 'shuffle', label: 'Shuffle' }, + { id: 'restart', label: 'Restart', canHide: false }, + { id: 'playOffline', label: 'Play Offline', canHide: false }, +@@ -2381,16 +2381,16 @@ + { id: 'version', label: 'Version' }, + { id: 'cast', label: 'Cast' }, + { id: 'trailer', label: 'Trailer' }, +- { id: 'watchWithGroup', label: 'Watch with group' }, ++ { id: 'watchWithGroup', label: 'Regarder en groupe' }, + { id: 'watched', label: 'Watched' }, + { id: 'favorite', label: 'Favorite' }, + { id: 'playlist', label: 'Playlist' }, +- { id: 'download', label: 'Download' }, +- { id: 'deleteFiles', label: 'Delete files' }, +- { id: 'goToSeries', label: 'Go to series' }, ++ { id: 'download', label: 'Téléchargement' }, ++ { id: 'deleteFiles', label: 'Supprimer les fichiers' }, ++ { id: 'goToSeries', label: 'Allez dans series' }, + { id: 'seerrWatchlist', label: 'Watchlist' }, +- { id: 'seerrReportIssue', label: 'Report Issue' }, +- { id: 'seerrManage', label: 'Manage Requests' }, ++ { id: 'seerrReportIssue', label: 'Signaler un problème' }, ++ { id: 'seerrManage', label: 'Gérer les demandes' }, + { id: 'admin', label: 'Admin' } + ]; + +@@ -2440,7 +2440,7 @@ + row.innerHTML = + (item.hideable + ? '' +- : '') ++ : '') + + '' + esc(item.label) + '' + + '' + + ''; +@@ -2482,18 +2482,18 @@ + } + + var SEERR_DISCOVERY_ROWS = [ +- { id: 'shortcuts', label: 'Seerr Browse' }, +- { id: 'recent_requests', label: 'Recent Requests' }, ++ { id: 'shortcuts', label: 'Parcourir Seerr' }, ++ { id: 'recent_requests', label: 'Demandes récentes' }, + { id: 'watchlist', label: 'Your Watchlist' }, +- { id: 'recently_added', label: 'Recently Added' }, ++ { id: 'recently_added', label: 'Ajouts récents' }, + { id: 'trending', label: 'Trending' }, + { id: 'popular_movies', label: 'Popular Movies' }, +- { id: 'movie_genres', label: 'Movie Genres' }, ++ { id: 'movie_genres', label: 'Genres de films' }, + { id: 'upcoming_movies', label: 'Upcoming Movies' }, + { id: 'studios', label: 'Studios' }, +- { id: 'popular_series', label: 'Popular Series' }, +- { id: 'series_genres', label: 'Series Genres' }, +- { id: 'upcoming_series', label: 'Upcoming Series' }, ++ { id: 'popular_series', label: 'Séries populaires' }, ++ { id: 'series_genres', label: 'Genres de séries' }, ++ { id: 'upcoming_series', label: 'Séries à venir' }, + { id: 'networks', label: 'Networks' } + ]; + +@@ -2581,12 +2581,12 @@ + } + + var HOME_LAYOUT_TABS = [ +- { id: 'builtin', label: 'Basics' }, ++ { id: 'builtin', label: 'Éléments de base' }, + { id: 'collections', label: 'Collections' }, +- { id: 'playlists', label: 'Playlists' }, ++ { id: 'playlists', label: 'Liste de lectures' }, + { id: 'genres', label: 'Genres' }, + { id: 'seerr', label: 'Seerr' }, +- { id: 'external', label: 'External Lists' } ++ { id: 'external', label: 'Listes externes' } + ]; + + var HOME_LAYOUT_SEERR_TYPES = { +@@ -2656,21 +2656,21 @@ + } + + function homeSectionLabel(section) { +- if (!section) return 'Unknown row'; ++ if (!section) return 'Rangée inconnue'; + if (section.kind === 'pluginDynamic') { +- return section.pluginDisplayText || section.pluginSection || 'Dynamic row'; ++ return section.pluginDisplayText || section.pluginSection || 'Rangée dynamique'; + } + var definition = homeSectionDefinition(section.type); +- return definition ? definition.label : (section.type || 'Unknown row'); ++ return definition ? definition.label : (section.type || 'Rangée inconnue'); + } + + function homeSectionMeta(section) { +- if (!section) return 'Basics'; ++ if (!section) return 'Éléments de base'; + if (section.kind !== 'pluginDynamic') { +- return isSeerrHomeSectionType(section.type) ? 'Seerr' : (isExternalHomeSectionType(section.type) ? 'External Lists' : 'Basics'); ++ return isSeerrHomeSectionType(section.type) ? 'Seerr' : (isExternalHomeSectionType(section.type) ? 'Listes externes' : 'Éléments de base'); + } + if (section.pluginSource === 'collections') return 'Collection'; +- if (section.pluginSource === 'playlists') return 'Playlist'; ++ if (section.pluginSource === 'playlists') return 'Liste de lecture'; + if (section.pluginSource === 'genres') return 'Genre'; + return 'Dynamic'; + } +@@ -2760,7 +2760,7 @@ + pluginSource: section.pluginSource, + pluginSection: section.pluginSection || '', + pluginAdditionalData: section.pluginAdditionalData || '', +- pluginDisplayText: section.pluginDisplayText || section.pluginSection || 'Dynamic row' ++ pluginDisplayText: section.pluginDisplayText || section.pluginSection || 'Rangée dynamique' + }; + } else { + if (section.enabled === false) return; +@@ -2788,7 +2788,7 @@ + key: 'builtin:' + definition.type, + tab: 'builtin', + label: definition.label, +- meta: isSeerrHomeSectionType(definition.type) ? 'Seerr' : (isExternalHomeSectionType(definition.type) ? 'External Lists' : 'Basics'), ++ meta: isSeerrHomeSectionType(definition.type) ? 'Seerr' : (isExternalHomeSectionType(definition.type) ? 'Listes externes' : 'Éléments de base'), + badgeClass: isSeerrHomeSectionType(definition.type) ? 'homeLayoutBadge-seerr' : (isExternalHomeSectionType(definition.type) ? 'homeLayoutBadge-external' : 'homeLayoutBadge-builtin'), + section: { + kind: 'builtin', +@@ -2803,7 +2803,7 @@ + return { + key: ['pluginDynamic', source, sectionName, id || ''].join(':'), + tab: tab, +- label: label || 'Untitled', ++ label: label || 'Sans titre', + meta: meta, + badgeClass: 'homeLayoutBadge-' + (source || 'dynamic'), + section: { +@@ -2815,7 +2815,7 @@ + pluginSource: source, + pluginSection: sectionName, + pluginAdditionalData: id || '', +- pluginDisplayText: label || 'Untitled' ++ pluginDisplayText: label || 'Sans titre' + } + }; + } +@@ -2897,7 +2897,7 @@ + container.innerHTML = ''; + + if (HOME_LAYOUT_STATE.sections.length === 0) { +- container.innerHTML = '
No default rows configured. Add rows from the catalog.
'; ++ container.innerHTML = '
Aucune rangée par défaut configurée. Ajoutez des rangées depuis le catalogue.
'; + return; + } + +@@ -2931,7 +2931,7 @@ + + container.innerHTML = ''; + if (candidates.length === 0) { +- container.innerHTML = '
No rows found.
'; ++ container.innerHTML = '
Aucune rangée trouvée.
'; + return; + } + +@@ -2944,7 +2944,7 @@ + '
' + + '
' + esc(candidate.label) + '
' + + '
' +- + ''; ++ + ''; + container.appendChild(row); + }); + } +@@ -3068,7 +3068,7 @@ + }).then(function(result) { + var items = result.Items || []; + setHomeLayoutAvailable('collections', items.map(function(item) { +- return createDynamicCandidate('collections', 'collections', 'collection', item.Id, item.Name || 'Untitled', 'Collection row', serverId); ++ return createDynamicCandidate('collections', 'collections', 'collection', item.Id, item.Name || 'Sans titre', 'Rangée de collections', serverId); + })); + }).catch(function() { + setHomeLayoutAvailable('collections', []); +@@ -3090,7 +3090,7 @@ + }).then(function(result) { + var items = result.Items || []; + setHomeLayoutAvailable('playlists', items.map(function(item) { +- return createDynamicCandidate('playlists', 'playlists', 'playlist', item.Id, item.Name || 'Untitled', 'Playlist row', serverId); ++ return createDynamicCandidate('playlists', 'playlists', 'playlist', item.Id, item.Name || 'Sans titre', 'Rangée de playlists', serverId); + })); + }).catch(function() { + setHomeLayoutAvailable('playlists', []); +@@ -3100,8 +3100,8 @@ + function mapGenreCandidates(items, serverId) { + return (items || []).map(function(item) { + var id = item.id || item.Id; +- var name = item.name || item.Name || 'Untitled'; +- return createDynamicCandidate('genres', 'genres', 'genre', id, name, 'Genre row', serverId); ++ var name = item.name || item.Name || 'Sans titre'; ++ return createDynamicCandidate('genres', 'genres', 'genre', id, name, 'Rangée de genres', serverId); + }).filter(function(candidate) { return !!candidate.section.pluginAdditionalData; }); + } + +@@ -3146,7 +3146,7 @@ + var isDynamic = section.kind === 'pluginDynamic'; + var result = { + type: isDynamic ? 'none' : section.type, +- // Dynamic rows stay in the editor when disabled, unlike builtins, so ++ // Rangée dynamiques stay in the editor when disabled, unlike builtins, so + // writing them all back as enabled would switch every custom row on. + enabled: isDynamic ? section.enabled !== false : true, + order: section.order +@@ -3250,14 +3250,14 @@ + result.textContent = message; + } + +- function setSelectedThemeFileLabel(file) { ++ function setSelectedThèmeFileLabel(file) { + var label = document.querySelector('#AdminThemeChosenFile'); + if (!label) { + return; + } + + if (!file) { +- label.textContent = 'No file selected'; ++ label.textContent = 'Aucun fichier sélectionné'; + return; + } + +@@ -3287,7 +3287,7 @@ + } + + if (!items || items.length === 0) { +- container.innerHTML = '
No uploaded themes yet.
'; ++ container.innerHTML = '
Aucun thème importé pour le moment.
'; + return; + } + +@@ -3306,12 +3306,12 @@ + + '' + + '
ID: ' + esc(id) + '
' + + '
' +- + 'Uploaded: ' + esc(formatThemeUploadedAt(uploadedAt)) +- + ' • Size: ' + esc(formatThemeSize(sizeBytes)) ++ + 'Importé : ' + esc(formatThemeUploadedAt(uploadedAt)) ++ + ' • Taille : ' + esc(formatThemeSize(sizeBytes)) + + (checksum ? ' • SHA256: ' + esc(checksum.slice(0, 12)) + '…' : '') + + '
' + + '' +- + '' ++ + '' + + ''; + }); + +@@ -3325,7 +3325,7 @@ + } + + var serverUrl = ApiClient.serverAddress ? ApiClient.serverAddress() : ''; +- container.innerHTML = '
Loading uploaded themes...
'; ++ container.innerHTML = '
Chargement des thèmes importés…
'; + + fetch(serverUrl + '/Moonfin/Admin/Themes', { + method: 'GET', +@@ -3337,11 +3337,11 @@ + }) + .catch(function(error) { + container.innerHTML = '
' +- + esc((error && error.message) ? error.message : 'Failed to load uploaded themes.') + '
'; ++ + esc((error && error.message) ? error.message : 'Impossible de charger les thèmes importés.') + ''; + }); + } + +- function clearSelectedThemeFile() { ++ function clearSelectedThèmeFile() { + var fileInput = document.querySelector('#AdminThemeFileInput'); + var uploadButton = document.querySelector('#AdminThemeUploadBtn'); + if (fileInput) { +@@ -3350,16 +3350,16 @@ + if (uploadButton) { + uploadButton.disabled = true; + } +- setSelectedThemeFileLabel(null); ++ setSelectedThèmeFileLabel(null); + } + +- function uploadSelectedThemeFile() { ++ function uploadSelectedThèmeFile() { + var fileInput = document.querySelector('#AdminThemeFileInput'); + var uploadButton = document.querySelector('#AdminThemeUploadBtn'); + var file = fileInput && fileInput.files ? fileInput.files[0] : null; + + if (!file) { +- setThemeUploadResult('Select a JSON file first.', '#d9534f'); ++ setThemeUploadResult('Sélectionnez d’abord un fichier JSON.', '#d9534f'); + return; + } + +@@ -3372,11 +3372,11 @@ + try { + payload = JSON.parse(raw); + } catch (error) { +- throw new Error('Invalid JSON file.'); ++ throw new Error('Fichier JSON invalide.'); + } + + if (!payload || typeof payload !== 'object' || Array.isArray(payload)) { +- throw new Error('Theme file must contain a JSON object.'); ++ throw new Error('Thème file must contain a JSON object.'); + } + + var serverUrl = ApiClient.serverAddress ? ApiClient.serverAddress() : ''; +@@ -3389,13 +3389,13 @@ + .then(parseJsonResponse) + .then(function(payload) { + var item = payload.item || payload.Item || {}; +- var displayName = item.displayName || item.DisplayName || 'Theme'; ++ var displayName = item.displayName || item.DisplayName || 'Thème'; + setThemeUploadResult('Uploaded "' + displayName + '" successfully.', '#52b54b'); +- clearSelectedThemeFile(); ++ clearSelectedThèmeFile(); + loadAdminThemesList(); + }) + .catch(function(error) { +- var message = (error && error.message) ? error.message : 'Upload failed.'; ++ var message = (error && error.message) ? error.message : 'Échec de l’importation.'; + if (error && error.payload && Array.isArray(error.payload.errors) && error.payload.errors.length > 0) { + message = error.payload.errors.join(' | '); + } +@@ -3413,7 +3413,7 @@ + return; + } + +- if (!window.confirm('Delete uploaded theme "' + themeId + '" from the plugin?')) { ++ if (!window.confirm('Supprimer uploaded theme "' + themeId + '" from the plugin?')) { + return; + } + +@@ -3426,11 +3426,11 @@ + }) + .then(parseJsonResponse) + .then(function() { +- setThemeUploadResult('Deleted "' + themeId + '".', '#52b54b'); ++ setThemeUploadResult('Supprimerd "' + themeId + '".', '#52b54b'); + loadAdminThemesList(); + }) + .catch(function(error) { +- setThemeUploadResult((error && error.message) ? error.message : 'Delete failed.', '#d9534f'); ++ setThemeUploadResult((error && error.message) ? error.message : 'Supprimer failed.', '#d9534f'); + }); + } + +@@ -3501,7 +3501,7 @@ + themeFileInput.dataset.bound = 'true'; + themeFileInput.addEventListener('change', function() { + var file = themeFileInput.files && themeFileInput.files.length ? themeFileInput.files[0] : null; +- setSelectedThemeFileLabel(file); ++ setSelectedThèmeFileLabel(file); + if (themeUploadButton) { + themeUploadButton.disabled = !file; + } +@@ -3511,7 +3511,7 @@ + if (themeUploadButton && !themeUploadButton.dataset.bound) { + themeUploadButton.dataset.bound = 'true'; + themeUploadButton.addEventListener('click', function() { +- uploadSelectedThemeFile(); ++ uploadSelectedThèmeFile(); + }); + } + +@@ -3579,7 +3579,7 @@ + }); + } + +- clearSelectedThemeFile(); ++ clearSelectedThèmeFile(); + setThemeUploadResult('', ''); + loadAdminThemesList(); + +@@ -3643,7 +3643,7 @@ + setSelectValue('#DefaultNavbarColor', defaults.navbarColor, 'Configured color'); + bindNullableRangeInput('#DefaultNavbarOpacity', '%'); + setNullableRangeInput('#DefaultNavbarOpacity', defaults.navbarOpacity, '%'); +- setNullableBoolSelect('#DefaultNavbarAlwaysExpanded', defaults.navbarAlwaysExpanded); ++ setNullableBoolSelect('#DefaultNavbarAlwaysExpanded', defaults.navbarToujoursExpanded); + setNullableBoolSelect('#DefaultEnableFolderView', defaults.enableFolderView); + setNullableBoolSelect('#DefaultShowSeerrButton', defaults.showSeerrButton); + +@@ -3750,7 +3750,7 @@ + function loadAdminCollectionPicker(selectedIds) { + var picker = document.querySelector('#DefaultCollectionPicker'); + if (!picker) return; +- picker.innerHTML = '
Loading...
'; ++ picker.innerHTML = '
Chargement…
'; + + var userId = ApiClient.getCurrentUserId(); + ApiClient.getItems(userId, { +@@ -3765,7 +3765,7 @@ + }).then(function(result) { + var items = result.Items || []; + if (items.length === 0) { +- picker.innerHTML = '
No collections or playlists found.
'; ++ picker.innerHTML = '
Aucune collection ou playlist trouvée.
'; + return; + } + var html = ''; +@@ -3781,7 +3781,7 @@ + html += '