+62
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"app": {
|
||||
"title": "Plezy"
|
||||
},
|
||||
},
|
||||
"auth": {
|
||||
"signInWithPlex": "Mit Plex anmelden",
|
||||
"showQRCode": "QR-Code anzeigen",
|
||||
@@ -831,5 +831,66 @@
|
||||
"launchFailed": "Externer Player konnte nicht geöffnet werden",
|
||||
"appNotInstalled": "${name} ist nicht installiert",
|
||||
"playInExternalPlayer": "In externem Player abspielen"
|
||||
},
|
||||
"metadataEdit": {
|
||||
"editMetadata": "Bearbeiten...",
|
||||
"screenTitle": "Metadaten bearbeiten",
|
||||
"basicInfo": "Grundlegende Infos",
|
||||
"artwork": "Artwork",
|
||||
"advancedSettings": "Erweiterte Einstellungen",
|
||||
"title": "Titel",
|
||||
"sortTitle": "Sortiertitel",
|
||||
"originalTitle": "Originaltitel",
|
||||
"releaseDate": "Erscheinungsdatum",
|
||||
"contentRating": "Altersfreigabe",
|
||||
"studio": "Studio",
|
||||
"tagline": "Tagline",
|
||||
"summary": "Zusammenfassung",
|
||||
"poster": "Poster",
|
||||
"background": "Hintergrund",
|
||||
"selectPoster": "Poster auswählen",
|
||||
"selectBackground": "Hintergrund auswählen",
|
||||
"fromUrl": "Von URL",
|
||||
"uploadFile": "Datei hochladen",
|
||||
"enterImageUrl": "Bild-URL eingeben",
|
||||
"imageUrl": "Bild-URL",
|
||||
"metadataUpdated": "Metadaten aktualisiert",
|
||||
"metadataUpdateFailed": "Metadaten konnten nicht aktualisiert werden",
|
||||
"artworkUpdated": "Artwork aktualisiert",
|
||||
"artworkUpdateFailed": "Artwork konnte nicht aktualisiert werden",
|
||||
"noArtworkAvailable": "Kein Artwork verfügbar",
|
||||
"notSet": "Nicht festgelegt",
|
||||
"libraryDefault": "Bibliotheksstandard",
|
||||
"accountDefault": "Kontostandard",
|
||||
"seriesDefault": "Serienstandard",
|
||||
"episodeSorting": "Episodensortierung",
|
||||
"oldestFirst": "Älteste zuerst",
|
||||
"newestFirst": "Neueste zuerst",
|
||||
"keep": "Behalten",
|
||||
"allEpisodes": "Alle Episoden",
|
||||
"latestEpisodes": "${count} neueste Episoden",
|
||||
"latestEpisode": "Neueste Episode",
|
||||
"episodesAddedPastDays": "Episoden der letzten ${count} Tage",
|
||||
"deleteAfterPlaying": "Episoden nach Wiedergabe löschen",
|
||||
"never": "Nie",
|
||||
"afterADay": "Nach einem Tag",
|
||||
"afterAWeek": "Nach einer Woche",
|
||||
"afterAMonth": "Nach einem Monat",
|
||||
"onNextRefresh": "Bei nächster Aktualisierung",
|
||||
"seasons": "Staffeln",
|
||||
"show": "Anzeigen",
|
||||
"hide": "Ausblenden",
|
||||
"episodeOrdering": "Episodenreihenfolge",
|
||||
"tmdbAiring": "The Movie Database (Ausgestrahlt)",
|
||||
"tvdbAiring": "TheTVDB (Ausgestrahlt)",
|
||||
"tvdbAbsolute": "TheTVDB (Absolut)",
|
||||
"metadataLanguage": "Metadaten-Sprache",
|
||||
"useOriginalTitle": "Originaltitel verwenden",
|
||||
"preferredAudioLanguage": "Bevorzugte Audiosprache",
|
||||
"preferredSubtitleLanguage": "Bevorzugte Untertitelsprache",
|
||||
"subtitleMode": "Automatische Untertitelauswahl",
|
||||
"manuallySelected": "Manuell ausgewählt",
|
||||
"shownWithForeignAudio": "Bei fremdsprachigem Audio anzeigen",
|
||||
"alwaysEnabled": "Immer aktiviert"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -831,5 +831,66 @@
|
||||
"launchFailed": "Failed to open external player",
|
||||
"appNotInstalled": "${name} is not installed",
|
||||
"playInExternalPlayer": "Play in External Player"
|
||||
},
|
||||
"metadataEdit": {
|
||||
"editMetadata": "Edit...",
|
||||
"screenTitle": "Edit Metadata",
|
||||
"basicInfo": "Basic Info",
|
||||
"artwork": "Artwork",
|
||||
"advancedSettings": "Advanced Settings",
|
||||
"title": "Title",
|
||||
"sortTitle": "Sort Title",
|
||||
"originalTitle": "Original Title",
|
||||
"releaseDate": "Release Date",
|
||||
"contentRating": "Content Rating",
|
||||
"studio": "Studio",
|
||||
"tagline": "Tagline",
|
||||
"summary": "Summary",
|
||||
"poster": "Poster",
|
||||
"background": "Background",
|
||||
"selectPoster": "Select Poster",
|
||||
"selectBackground": "Select Background",
|
||||
"fromUrl": "From URL",
|
||||
"uploadFile": "Upload File",
|
||||
"enterImageUrl": "Enter image URL",
|
||||
"imageUrl": "Image URL",
|
||||
"metadataUpdated": "Metadata updated",
|
||||
"metadataUpdateFailed": "Failed to update metadata",
|
||||
"artworkUpdated": "Artwork updated",
|
||||
"artworkUpdateFailed": "Failed to update artwork",
|
||||
"noArtworkAvailable": "No artwork available",
|
||||
"notSet": "Not set",
|
||||
"libraryDefault": "Library default",
|
||||
"accountDefault": "Account default",
|
||||
"seriesDefault": "Series default",
|
||||
"episodeSorting": "Episode Sorting",
|
||||
"oldestFirst": "Oldest first",
|
||||
"newestFirst": "Newest first",
|
||||
"keep": "Keep",
|
||||
"allEpisodes": "All episodes",
|
||||
"latestEpisodes": "${count} latest episodes",
|
||||
"latestEpisode": "Latest episode",
|
||||
"episodesAddedPastDays": "Episodes added in the past ${count} days",
|
||||
"deleteAfterPlaying": "Delete Episodes After Playing",
|
||||
"never": "Never",
|
||||
"afterADay": "After a day",
|
||||
"afterAWeek": "After a week",
|
||||
"afterAMonth": "After a month",
|
||||
"onNextRefresh": "On next refresh",
|
||||
"seasons": "Seasons",
|
||||
"show": "Show",
|
||||
"hide": "Hide",
|
||||
"episodeOrdering": "Episode Ordering",
|
||||
"tmdbAiring": "The Movie Database (Aired)",
|
||||
"tvdbAiring": "TheTVDB (Aired)",
|
||||
"tvdbAbsolute": "TheTVDB (Absolute)",
|
||||
"metadataLanguage": "Metadata Language",
|
||||
"useOriginalTitle": "Use Original Title",
|
||||
"preferredAudioLanguage": "Preferred Audio Language",
|
||||
"preferredSubtitleLanguage": "Preferred Subtitle Language",
|
||||
"subtitleMode": "Auto-Select Subtitle Mode",
|
||||
"manuallySelected": "Manually selected",
|
||||
"shownWithForeignAudio": "Shown with foreign audio",
|
||||
"alwaysEnabled": "Always enabled"
|
||||
}
|
||||
}
|
||||
|
||||
+62
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"app": {
|
||||
"title": "Plezy"
|
||||
},
|
||||
},
|
||||
"auth": {
|
||||
"signInWithPlex": "Inicia sesión con Plex",
|
||||
"showQRCode": "Mostrar código QR",
|
||||
@@ -831,5 +831,66 @@
|
||||
"launchFailed": "No se pudo abrir el reproductor externo",
|
||||
"appNotInstalled": "${name} no está instalado",
|
||||
"playInExternalPlayer": "Reproducir en reproductor externo"
|
||||
},
|
||||
"metadataEdit": {
|
||||
"editMetadata": "Editar...",
|
||||
"screenTitle": "Editar metadatos",
|
||||
"basicInfo": "Información básica",
|
||||
"artwork": "Artwork",
|
||||
"advancedSettings": "Ajustes avanzados",
|
||||
"title": "Título",
|
||||
"sortTitle": "Título de ordenación",
|
||||
"originalTitle": "Título original",
|
||||
"releaseDate": "Fecha de estreno",
|
||||
"contentRating": "Clasificación de contenido",
|
||||
"studio": "Estudio",
|
||||
"tagline": "Eslogan",
|
||||
"summary": "Resumen",
|
||||
"poster": "Póster",
|
||||
"background": "Fondo",
|
||||
"selectPoster": "Seleccionar póster",
|
||||
"selectBackground": "Seleccionar fondo",
|
||||
"fromUrl": "Desde URL",
|
||||
"uploadFile": "Subir archivo",
|
||||
"enterImageUrl": "Introducir URL de imagen",
|
||||
"imageUrl": "URL de imagen",
|
||||
"metadataUpdated": "Metadatos actualizados",
|
||||
"metadataUpdateFailed": "Error al actualizar los metadatos",
|
||||
"artworkUpdated": "Artwork actualizado",
|
||||
"artworkUpdateFailed": "Error al actualizar el artwork",
|
||||
"noArtworkAvailable": "No hay artwork disponible",
|
||||
"notSet": "No establecido",
|
||||
"libraryDefault": "Predeterminado de biblioteca",
|
||||
"accountDefault": "Predeterminado de cuenta",
|
||||
"seriesDefault": "Predeterminado de serie",
|
||||
"episodeSorting": "Orden de episodios",
|
||||
"oldestFirst": "Más antiguos primero",
|
||||
"newestFirst": "Más recientes primero",
|
||||
"keep": "Conservar",
|
||||
"allEpisodes": "Todos los episodios",
|
||||
"latestEpisodes": "${count} episodios más recientes",
|
||||
"latestEpisode": "Episodio más reciente",
|
||||
"episodesAddedPastDays": "Episodios añadidos en los últimos ${count} días",
|
||||
"deleteAfterPlaying": "Eliminar episodios después de reproducir",
|
||||
"never": "Nunca",
|
||||
"afterADay": "Después de un día",
|
||||
"afterAWeek": "Después de una semana",
|
||||
"afterAMonth": "Después de un mes",
|
||||
"onNextRefresh": "En la próxima actualización",
|
||||
"seasons": "Temporadas",
|
||||
"show": "Mostrar",
|
||||
"hide": "Ocultar",
|
||||
"episodeOrdering": "Orden de episodios",
|
||||
"tmdbAiring": "The Movie Database (Emisión)",
|
||||
"tvdbAiring": "TheTVDB (Emisión)",
|
||||
"tvdbAbsolute": "TheTVDB (Absoluto)",
|
||||
"metadataLanguage": "Idioma de metadatos",
|
||||
"useOriginalTitle": "Usar título original",
|
||||
"preferredAudioLanguage": "Idioma de audio preferido",
|
||||
"preferredSubtitleLanguage": "Idioma de subtítulos preferido",
|
||||
"subtitleMode": "Selección automática de subtítulos",
|
||||
"manuallySelected": "Seleccionado manualmente",
|
||||
"shownWithForeignAudio": "Mostrar con audio extranjero",
|
||||
"alwaysEnabled": "Siempre activado"
|
||||
}
|
||||
}
|
||||
|
||||
+62
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"app": {
|
||||
"title": "Plezy"
|
||||
},
|
||||
},
|
||||
"auth": {
|
||||
"signInWithPlex": "S'inscrire avec Plex",
|
||||
"showQRCode": "Afficher le QR Code",
|
||||
@@ -831,5 +831,66 @@
|
||||
"launchFailed": "Impossible d'ouvrir le lecteur externe",
|
||||
"appNotInstalled": "${name} n'est pas installé",
|
||||
"playInExternalPlayer": "Lire dans un lecteur externe"
|
||||
},
|
||||
"metadataEdit": {
|
||||
"editMetadata": "Modifier...",
|
||||
"screenTitle": "Modifier les métadonnées",
|
||||
"basicInfo": "Informations de base",
|
||||
"artwork": "Artwork",
|
||||
"advancedSettings": "Paramètres avancés",
|
||||
"title": "Titre",
|
||||
"sortTitle": "Titre de tri",
|
||||
"originalTitle": "Titre original",
|
||||
"releaseDate": "Date de sortie",
|
||||
"contentRating": "Classification",
|
||||
"studio": "Studio",
|
||||
"tagline": "Slogan",
|
||||
"summary": "Résumé",
|
||||
"poster": "Affiche",
|
||||
"background": "Arrière-plan",
|
||||
"selectPoster": "Sélectionner l'affiche",
|
||||
"selectBackground": "Sélectionner l'arrière-plan",
|
||||
"fromUrl": "Depuis une URL",
|
||||
"uploadFile": "Importer un fichier",
|
||||
"enterImageUrl": "Entrer l'URL de l'image",
|
||||
"imageUrl": "URL de l'image",
|
||||
"metadataUpdated": "Métadonnées mises à jour",
|
||||
"metadataUpdateFailed": "Échec de la mise à jour des métadonnées",
|
||||
"artworkUpdated": "Artwork mis à jour",
|
||||
"artworkUpdateFailed": "Échec de la mise à jour de l'artwork",
|
||||
"noArtworkAvailable": "Aucun artwork disponible",
|
||||
"notSet": "Non défini",
|
||||
"libraryDefault": "Par défaut de la bibliothèque",
|
||||
"accountDefault": "Par défaut du compte",
|
||||
"seriesDefault": "Par défaut de la série",
|
||||
"episodeSorting": "Tri des épisodes",
|
||||
"oldestFirst": "Plus anciens en premier",
|
||||
"newestFirst": "Plus récents en premier",
|
||||
"keep": "Conserver",
|
||||
"allEpisodes": "Tous les épisodes",
|
||||
"latestEpisodes": "${count} derniers épisodes",
|
||||
"latestEpisode": "Dernier épisode",
|
||||
"episodesAddedPastDays": "Épisodes ajoutés ces ${count} derniers jours",
|
||||
"deleteAfterPlaying": "Supprimer les épisodes après lecture",
|
||||
"never": "Jamais",
|
||||
"afterADay": "Après un jour",
|
||||
"afterAWeek": "Après une semaine",
|
||||
"afterAMonth": "Après un mois",
|
||||
"onNextRefresh": "Au prochain rafraîchissement",
|
||||
"seasons": "Saisons",
|
||||
"show": "Afficher",
|
||||
"hide": "Masquer",
|
||||
"episodeOrdering": "Ordre des épisodes",
|
||||
"tmdbAiring": "The Movie Database (Diffusion)",
|
||||
"tvdbAiring": "TheTVDB (Diffusion)",
|
||||
"tvdbAbsolute": "TheTVDB (Absolu)",
|
||||
"metadataLanguage": "Langue des métadonnées",
|
||||
"useOriginalTitle": "Utiliser le titre original",
|
||||
"preferredAudioLanguage": "Langue audio préférée",
|
||||
"preferredSubtitleLanguage": "Langue de sous-titres préférée",
|
||||
"subtitleMode": "Sélection automatique des sous-titres",
|
||||
"manuallySelected": "Sélectionné manuellement",
|
||||
"shownWithForeignAudio": "Affichés avec audio étranger",
|
||||
"alwaysEnabled": "Toujours activé"
|
||||
}
|
||||
}
|
||||
|
||||
+62
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"app": {
|
||||
"title": "Plezy"
|
||||
},
|
||||
},
|
||||
"auth": {
|
||||
"signInWithPlex": "Accedi con Plex",
|
||||
"showQRCode": "Mostra QR Code",
|
||||
@@ -831,5 +831,66 @@
|
||||
"launchFailed": "Impossibile aprire il lettore esterno",
|
||||
"appNotInstalled": "${name} non è installato",
|
||||
"playInExternalPlayer": "Riproduci in lettore esterno"
|
||||
},
|
||||
"metadataEdit": {
|
||||
"editMetadata": "Modifica...",
|
||||
"screenTitle": "Modifica metadati",
|
||||
"basicInfo": "Informazioni di base",
|
||||
"artwork": "Artwork",
|
||||
"advancedSettings": "Impostazioni avanzate",
|
||||
"title": "Titolo",
|
||||
"sortTitle": "Titolo di ordinamento",
|
||||
"originalTitle": "Titolo originale",
|
||||
"releaseDate": "Data di uscita",
|
||||
"contentRating": "Classificazione",
|
||||
"studio": "Studio",
|
||||
"tagline": "Tagline",
|
||||
"summary": "Trama",
|
||||
"poster": "Poster",
|
||||
"background": "Sfondo",
|
||||
"selectPoster": "Seleziona poster",
|
||||
"selectBackground": "Seleziona sfondo",
|
||||
"fromUrl": "Da URL",
|
||||
"uploadFile": "Carica file",
|
||||
"enterImageUrl": "Inserisci URL immagine",
|
||||
"imageUrl": "URL immagine",
|
||||
"metadataUpdated": "Metadati aggiornati",
|
||||
"metadataUpdateFailed": "Aggiornamento metadati non riuscito",
|
||||
"artworkUpdated": "Artwork aggiornato",
|
||||
"artworkUpdateFailed": "Aggiornamento artwork non riuscito",
|
||||
"noArtworkAvailable": "Nessun artwork disponibile",
|
||||
"notSet": "Non impostato",
|
||||
"libraryDefault": "Predefinito libreria",
|
||||
"accountDefault": "Predefinito account",
|
||||
"seriesDefault": "Predefinito serie",
|
||||
"episodeSorting": "Ordinamento episodi",
|
||||
"oldestFirst": "Più vecchi prima",
|
||||
"newestFirst": "Più recenti prima",
|
||||
"keep": "Conserva",
|
||||
"allEpisodes": "Tutti gli episodi",
|
||||
"latestEpisodes": "${count} episodi più recenti",
|
||||
"latestEpisode": "Episodio più recente",
|
||||
"episodesAddedPastDays": "Episodi aggiunti negli ultimi ${count} giorni",
|
||||
"deleteAfterPlaying": "Elimina episodi dopo la riproduzione",
|
||||
"never": "Mai",
|
||||
"afterADay": "Dopo un giorno",
|
||||
"afterAWeek": "Dopo una settimana",
|
||||
"afterAMonth": "Dopo un mese",
|
||||
"onNextRefresh": "Al prossimo aggiornamento",
|
||||
"seasons": "Stagioni",
|
||||
"show": "Mostra",
|
||||
"hide": "Nascondi",
|
||||
"episodeOrdering": "Ordine episodi",
|
||||
"tmdbAiring": "The Movie Database (In onda)",
|
||||
"tvdbAiring": "TheTVDB (In onda)",
|
||||
"tvdbAbsolute": "TheTVDB (Assoluto)",
|
||||
"metadataLanguage": "Lingua metadati",
|
||||
"useOriginalTitle": "Usa titolo originale",
|
||||
"preferredAudioLanguage": "Lingua audio preferita",
|
||||
"preferredSubtitleLanguage": "Lingua sottotitoli preferita",
|
||||
"subtitleMode": "Selezione automatica sottotitoli",
|
||||
"manuallySelected": "Selezionato manualmente",
|
||||
"shownWithForeignAudio": "Mostrati con audio straniero",
|
||||
"alwaysEnabled": "Sempre attivo"
|
||||
}
|
||||
}
|
||||
|
||||
+62
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"app": {
|
||||
"title": "Plezy"
|
||||
},
|
||||
},
|
||||
"auth": {
|
||||
"signInWithPlex": "Plex 계정으로 로그인",
|
||||
"showQRCode": "QR 코드",
|
||||
@@ -831,5 +831,66 @@
|
||||
"launchFailed": "외부 플레이어를 열 수 없습니다",
|
||||
"appNotInstalled": "${name}이(가) 설치되어 있지 않습니다",
|
||||
"playInExternalPlayer": "외부 플레이어에서 재생"
|
||||
},
|
||||
"metadataEdit": {
|
||||
"editMetadata": "편집...",
|
||||
"screenTitle": "메타데이터 편집",
|
||||
"basicInfo": "기본 정보",
|
||||
"artwork": "아트워크",
|
||||
"advancedSettings": "고급 설정",
|
||||
"title": "제목",
|
||||
"sortTitle": "정렬 제목",
|
||||
"originalTitle": "원제",
|
||||
"releaseDate": "출시일",
|
||||
"contentRating": "콘텐츠 등급",
|
||||
"studio": "스튜디오",
|
||||
"tagline": "태그라인",
|
||||
"summary": "줄거리",
|
||||
"poster": "포스터",
|
||||
"background": "배경",
|
||||
"selectPoster": "포스터 선택",
|
||||
"selectBackground": "배경 선택",
|
||||
"fromUrl": "URL에서",
|
||||
"uploadFile": "파일 업로드",
|
||||
"enterImageUrl": "이미지 URL 입력",
|
||||
"imageUrl": "이미지 URL",
|
||||
"metadataUpdated": "메타데이터가 업데이트되었습니다",
|
||||
"metadataUpdateFailed": "메타데이터 업데이트 실패",
|
||||
"artworkUpdated": "아트워크가 업데이트되었습니다",
|
||||
"artworkUpdateFailed": "아트워크 업데이트 실패",
|
||||
"noArtworkAvailable": "사용 가능한 아트워크 없음",
|
||||
"notSet": "설정되지 않음",
|
||||
"libraryDefault": "라이브러리 기본값",
|
||||
"accountDefault": "계정 기본값",
|
||||
"seriesDefault": "시리즈 기본값",
|
||||
"episodeSorting": "에피소드 정렬",
|
||||
"oldestFirst": "오래된 순",
|
||||
"newestFirst": "최신 순",
|
||||
"keep": "유지",
|
||||
"allEpisodes": "모든 에피소드",
|
||||
"latestEpisodes": "최신 에피소드 ${count}개",
|
||||
"latestEpisode": "최신 에피소드",
|
||||
"episodesAddedPastDays": "최근 ${count}일 내 추가된 에피소드",
|
||||
"deleteAfterPlaying": "재생 후 에피소드 삭제",
|
||||
"never": "안 함",
|
||||
"afterADay": "하루 후",
|
||||
"afterAWeek": "일주일 후",
|
||||
"afterAMonth": "한 달 후",
|
||||
"onNextRefresh": "다음 새로고침 시",
|
||||
"seasons": "시즌",
|
||||
"show": "표시",
|
||||
"hide": "숨기기",
|
||||
"episodeOrdering": "에피소드 순서",
|
||||
"tmdbAiring": "The Movie Database (방영순)",
|
||||
"tvdbAiring": "TheTVDB (방영순)",
|
||||
"tvdbAbsolute": "TheTVDB (절대순)",
|
||||
"metadataLanguage": "메타데이터 언어",
|
||||
"useOriginalTitle": "원제 사용",
|
||||
"preferredAudioLanguage": "선호 오디오 언어",
|
||||
"preferredSubtitleLanguage": "선호 자막 언어",
|
||||
"subtitleMode": "자막 자동 선택 모드",
|
||||
"manuallySelected": "수동 선택",
|
||||
"shownWithForeignAudio": "외국어 오디오 시 표시",
|
||||
"alwaysEnabled": "항상 활성화"
|
||||
}
|
||||
}
|
||||
|
||||
+62
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"app": {
|
||||
"title": "Plezy"
|
||||
},
|
||||
},
|
||||
"auth": {
|
||||
"signInWithPlex": "Inloggen met Plex",
|
||||
"showQRCode": "Toon QR-code",
|
||||
@@ -831,5 +831,66 @@
|
||||
"launchFailed": "Kan externe speler niet openen",
|
||||
"appNotInstalled": "${name} is niet geïnstalleerd",
|
||||
"playInExternalPlayer": "Afspelen in externe speler"
|
||||
},
|
||||
"metadataEdit": {
|
||||
"editMetadata": "Bewerken...",
|
||||
"screenTitle": "Metadata bewerken",
|
||||
"basicInfo": "Basisinformatie",
|
||||
"artwork": "Artwork",
|
||||
"advancedSettings": "Geavanceerde instellingen",
|
||||
"title": "Titel",
|
||||
"sortTitle": "Sorteertitel",
|
||||
"originalTitle": "Oorspronkelijke titel",
|
||||
"releaseDate": "Releasedatum",
|
||||
"contentRating": "Leeftijdsclassificatie",
|
||||
"studio": "Studio",
|
||||
"tagline": "Tagline",
|
||||
"summary": "Samenvatting",
|
||||
"poster": "Poster",
|
||||
"background": "Achtergrond",
|
||||
"selectPoster": "Poster selecteren",
|
||||
"selectBackground": "Achtergrond selecteren",
|
||||
"fromUrl": "Vanaf URL",
|
||||
"uploadFile": "Bestand uploaden",
|
||||
"enterImageUrl": "Voer afbeeldings-URL in",
|
||||
"imageUrl": "Afbeeldings-URL",
|
||||
"metadataUpdated": "Metadata bijgewerkt",
|
||||
"metadataUpdateFailed": "Metadata bijwerken mislukt",
|
||||
"artworkUpdated": "Artwork bijgewerkt",
|
||||
"artworkUpdateFailed": "Artwork bijwerken mislukt",
|
||||
"noArtworkAvailable": "Geen artwork beschikbaar",
|
||||
"notSet": "Niet ingesteld",
|
||||
"libraryDefault": "Bibliotheekstandaard",
|
||||
"accountDefault": "Accountstandaard",
|
||||
"seriesDefault": "Seriestandaard",
|
||||
"episodeSorting": "Afleveringen sorteren",
|
||||
"oldestFirst": "Oudste eerst",
|
||||
"newestFirst": "Nieuwste eerst",
|
||||
"keep": "Bewaren",
|
||||
"allEpisodes": "Alle afleveringen",
|
||||
"latestEpisodes": "${count} nieuwste afleveringen",
|
||||
"latestEpisode": "Nieuwste aflevering",
|
||||
"episodesAddedPastDays": "Afleveringen toegevoegd in de afgelopen ${count} dagen",
|
||||
"deleteAfterPlaying": "Afleveringen verwijderen na afspelen",
|
||||
"never": "Nooit",
|
||||
"afterADay": "Na een dag",
|
||||
"afterAWeek": "Na een week",
|
||||
"afterAMonth": "Na een maand",
|
||||
"onNextRefresh": "Bij volgende verversing",
|
||||
"seasons": "Seizoenen",
|
||||
"show": "Tonen",
|
||||
"hide": "Verbergen",
|
||||
"episodeOrdering": "Afleveringsvolgorde",
|
||||
"tmdbAiring": "The Movie Database (Uitgezonden)",
|
||||
"tvdbAiring": "TheTVDB (Uitgezonden)",
|
||||
"tvdbAbsolute": "TheTVDB (Absoluut)",
|
||||
"metadataLanguage": "Metadatataal",
|
||||
"useOriginalTitle": "Oorspronkelijke titel gebruiken",
|
||||
"preferredAudioLanguage": "Voorkeurstaal audio",
|
||||
"preferredSubtitleLanguage": "Voorkeurstaal ondertiteling",
|
||||
"subtitleMode": "Automatische ondertitelselectie",
|
||||
"manuallySelected": "Handmatig geselecteerd",
|
||||
"shownWithForeignAudio": "Weergeven bij anderstalig geluid",
|
||||
"alwaysEnabled": "Altijd ingeschakeld"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
/// To regenerate, run: `dart run slang`
|
||||
///
|
||||
/// Locales: 9
|
||||
/// Strings: 6705 (745 per locale)
|
||||
/// Strings: 7236 (804 per locale)
|
||||
///
|
||||
/// Built on 2026-02-20 at 23:08 UTC
|
||||
/// Built on 2026-02-22 at 16:11 UTC
|
||||
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint, unused_import
|
||||
|
||||
@@ -74,6 +74,7 @@ class TranslationsDe with BaseTranslations<AppLocale, Translations> implements T
|
||||
@override late final _TranslationsCompanionRemoteDe companionRemote = _TranslationsCompanionRemoteDe._(_root);
|
||||
@override late final _TranslationsVideoSettingsDe videoSettings = _TranslationsVideoSettingsDe._(_root);
|
||||
@override late final _TranslationsExternalPlayerDe externalPlayer = _TranslationsExternalPlayerDe._(_root);
|
||||
@override late final _TranslationsMetadataEditDe metadataEdit = _TranslationsMetadataEditDe._(_root);
|
||||
}
|
||||
|
||||
// Path: app
|
||||
@@ -1050,6 +1051,74 @@ class _TranslationsExternalPlayerDe implements TranslationsExternalPlayerEn {
|
||||
@override String get playInExternalPlayer => 'In externem Player abspielen';
|
||||
}
|
||||
|
||||
// Path: metadataEdit
|
||||
class _TranslationsMetadataEditDe implements TranslationsMetadataEditEn {
|
||||
_TranslationsMetadataEditDe._(this._root);
|
||||
|
||||
final TranslationsDe _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get editMetadata => 'Bearbeiten...';
|
||||
@override String get screenTitle => 'Metadaten bearbeiten';
|
||||
@override String get basicInfo => 'Grundlegende Infos';
|
||||
@override String get artwork => 'Artwork';
|
||||
@override String get advancedSettings => 'Erweiterte Einstellungen';
|
||||
@override String get title => 'Titel';
|
||||
@override String get sortTitle => 'Sortiertitel';
|
||||
@override String get originalTitle => 'Originaltitel';
|
||||
@override String get releaseDate => 'Erscheinungsdatum';
|
||||
@override String get contentRating => 'Altersfreigabe';
|
||||
@override String get studio => 'Studio';
|
||||
@override String get tagline => 'Tagline';
|
||||
@override String get summary => 'Zusammenfassung';
|
||||
@override String get poster => 'Poster';
|
||||
@override String get background => 'Hintergrund';
|
||||
@override String get selectPoster => 'Poster auswählen';
|
||||
@override String get selectBackground => 'Hintergrund auswählen';
|
||||
@override String get fromUrl => 'Von URL';
|
||||
@override String get uploadFile => 'Datei hochladen';
|
||||
@override String get enterImageUrl => 'Bild-URL eingeben';
|
||||
@override String get imageUrl => 'Bild-URL';
|
||||
@override String get metadataUpdated => 'Metadaten aktualisiert';
|
||||
@override String get metadataUpdateFailed => 'Metadaten konnten nicht aktualisiert werden';
|
||||
@override String get artworkUpdated => 'Artwork aktualisiert';
|
||||
@override String get artworkUpdateFailed => 'Artwork konnte nicht aktualisiert werden';
|
||||
@override String get noArtworkAvailable => 'Kein Artwork verfügbar';
|
||||
@override String get notSet => 'Nicht festgelegt';
|
||||
@override String get libraryDefault => 'Bibliotheksstandard';
|
||||
@override String get accountDefault => 'Kontostandard';
|
||||
@override String get seriesDefault => 'Serienstandard';
|
||||
@override String get episodeSorting => 'Episodensortierung';
|
||||
@override String get oldestFirst => 'Älteste zuerst';
|
||||
@override String get newestFirst => 'Neueste zuerst';
|
||||
@override String get keep => 'Behalten';
|
||||
@override String get allEpisodes => 'Alle Episoden';
|
||||
@override String latestEpisodes({required Object count}) => '${count} neueste Episoden';
|
||||
@override String get latestEpisode => 'Neueste Episode';
|
||||
@override String episodesAddedPastDays({required Object count}) => 'Episoden der letzten ${count} Tage';
|
||||
@override String get deleteAfterPlaying => 'Episoden nach Wiedergabe löschen';
|
||||
@override String get never => 'Nie';
|
||||
@override String get afterADay => 'Nach einem Tag';
|
||||
@override String get afterAWeek => 'Nach einer Woche';
|
||||
@override String get afterAMonth => 'Nach einem Monat';
|
||||
@override String get onNextRefresh => 'Bei nächster Aktualisierung';
|
||||
@override String get seasons => 'Staffeln';
|
||||
@override String get show => 'Anzeigen';
|
||||
@override String get hide => 'Ausblenden';
|
||||
@override String get episodeOrdering => 'Episodenreihenfolge';
|
||||
@override String get tmdbAiring => 'The Movie Database (Ausgestrahlt)';
|
||||
@override String get tvdbAiring => 'TheTVDB (Ausgestrahlt)';
|
||||
@override String get tvdbAbsolute => 'TheTVDB (Absolut)';
|
||||
@override String get metadataLanguage => 'Metadaten-Sprache';
|
||||
@override String get useOriginalTitle => 'Originaltitel verwenden';
|
||||
@override String get preferredAudioLanguage => 'Bevorzugte Audiosprache';
|
||||
@override String get preferredSubtitleLanguage => 'Bevorzugte Untertitelsprache';
|
||||
@override String get subtitleMode => 'Automatische Untertitelauswahl';
|
||||
@override String get manuallySelected => 'Manuell ausgewählt';
|
||||
@override String get shownWithForeignAudio => 'Bei fremdsprachigem Audio anzeigen';
|
||||
@override String get alwaysEnabled => 'Immer aktiviert';
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
class _TranslationsHotkeysActionsDe implements TranslationsHotkeysActionsEn {
|
||||
_TranslationsHotkeysActionsDe._(this._root);
|
||||
@@ -1979,6 +2048,65 @@ extension on TranslationsDe {
|
||||
'externalPlayer.launchFailed' => 'Externer Player konnte nicht geöffnet werden',
|
||||
'externalPlayer.appNotInstalled' => ({required Object name}) => '${name} ist nicht installiert',
|
||||
'externalPlayer.playInExternalPlayer' => 'In externem Player abspielen',
|
||||
'metadataEdit.editMetadata' => 'Bearbeiten...',
|
||||
'metadataEdit.screenTitle' => 'Metadaten bearbeiten',
|
||||
'metadataEdit.basicInfo' => 'Grundlegende Infos',
|
||||
'metadataEdit.artwork' => 'Artwork',
|
||||
'metadataEdit.advancedSettings' => 'Erweiterte Einstellungen',
|
||||
'metadataEdit.title' => 'Titel',
|
||||
'metadataEdit.sortTitle' => 'Sortiertitel',
|
||||
'metadataEdit.originalTitle' => 'Originaltitel',
|
||||
'metadataEdit.releaseDate' => 'Erscheinungsdatum',
|
||||
'metadataEdit.contentRating' => 'Altersfreigabe',
|
||||
'metadataEdit.studio' => 'Studio',
|
||||
'metadataEdit.tagline' => 'Tagline',
|
||||
'metadataEdit.summary' => 'Zusammenfassung',
|
||||
'metadataEdit.poster' => 'Poster',
|
||||
'metadataEdit.background' => 'Hintergrund',
|
||||
'metadataEdit.selectPoster' => 'Poster auswählen',
|
||||
'metadataEdit.selectBackground' => 'Hintergrund auswählen',
|
||||
'metadataEdit.fromUrl' => 'Von URL',
|
||||
'metadataEdit.uploadFile' => 'Datei hochladen',
|
||||
'metadataEdit.enterImageUrl' => 'Bild-URL eingeben',
|
||||
'metadataEdit.imageUrl' => 'Bild-URL',
|
||||
'metadataEdit.metadataUpdated' => 'Metadaten aktualisiert',
|
||||
'metadataEdit.metadataUpdateFailed' => 'Metadaten konnten nicht aktualisiert werden',
|
||||
'metadataEdit.artworkUpdated' => 'Artwork aktualisiert',
|
||||
'metadataEdit.artworkUpdateFailed' => 'Artwork konnte nicht aktualisiert werden',
|
||||
'metadataEdit.noArtworkAvailable' => 'Kein Artwork verfügbar',
|
||||
'metadataEdit.notSet' => 'Nicht festgelegt',
|
||||
'metadataEdit.libraryDefault' => 'Bibliotheksstandard',
|
||||
'metadataEdit.accountDefault' => 'Kontostandard',
|
||||
'metadataEdit.seriesDefault' => 'Serienstandard',
|
||||
'metadataEdit.episodeSorting' => 'Episodensortierung',
|
||||
'metadataEdit.oldestFirst' => 'Älteste zuerst',
|
||||
'metadataEdit.newestFirst' => 'Neueste zuerst',
|
||||
'metadataEdit.keep' => 'Behalten',
|
||||
'metadataEdit.allEpisodes' => 'Alle Episoden',
|
||||
'metadataEdit.latestEpisodes' => ({required Object count}) => '${count} neueste Episoden',
|
||||
'metadataEdit.latestEpisode' => 'Neueste Episode',
|
||||
'metadataEdit.episodesAddedPastDays' => ({required Object count}) => 'Episoden der letzten ${count} Tage',
|
||||
'metadataEdit.deleteAfterPlaying' => 'Episoden nach Wiedergabe löschen',
|
||||
'metadataEdit.never' => 'Nie',
|
||||
'metadataEdit.afterADay' => 'Nach einem Tag',
|
||||
'metadataEdit.afterAWeek' => 'Nach einer Woche',
|
||||
'metadataEdit.afterAMonth' => 'Nach einem Monat',
|
||||
'metadataEdit.onNextRefresh' => 'Bei nächster Aktualisierung',
|
||||
'metadataEdit.seasons' => 'Staffeln',
|
||||
'metadataEdit.show' => 'Anzeigen',
|
||||
'metadataEdit.hide' => 'Ausblenden',
|
||||
'metadataEdit.episodeOrdering' => 'Episodenreihenfolge',
|
||||
'metadataEdit.tmdbAiring' => 'The Movie Database (Ausgestrahlt)',
|
||||
'metadataEdit.tvdbAiring' => 'TheTVDB (Ausgestrahlt)',
|
||||
'metadataEdit.tvdbAbsolute' => 'TheTVDB (Absolut)',
|
||||
'metadataEdit.metadataLanguage' => 'Metadaten-Sprache',
|
||||
'metadataEdit.useOriginalTitle' => 'Originaltitel verwenden',
|
||||
'metadataEdit.preferredAudioLanguage' => 'Bevorzugte Audiosprache',
|
||||
'metadataEdit.preferredSubtitleLanguage' => 'Bevorzugte Untertitelsprache',
|
||||
'metadataEdit.subtitleMode' => 'Automatische Untertitelauswahl',
|
||||
'metadataEdit.manuallySelected' => 'Manuell ausgewählt',
|
||||
'metadataEdit.shownWithForeignAudio' => 'Bei fremdsprachigem Audio anzeigen',
|
||||
'metadataEdit.alwaysEnabled' => 'Immer aktiviert',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -77,6 +77,7 @@ class Translations with BaseTranslations<AppLocale, Translations> {
|
||||
late final TranslationsCompanionRemoteEn companionRemote = TranslationsCompanionRemoteEn._(_root);
|
||||
late final TranslationsVideoSettingsEn videoSettings = TranslationsVideoSettingsEn._(_root);
|
||||
late final TranslationsExternalPlayerEn externalPlayer = TranslationsExternalPlayerEn._(_root);
|
||||
late final TranslationsMetadataEditEn metadataEdit = TranslationsMetadataEditEn._(_root);
|
||||
}
|
||||
|
||||
// Path: app
|
||||
@@ -2325,6 +2326,192 @@ class TranslationsExternalPlayerEn {
|
||||
String get playInExternalPlayer => 'Play in External Player';
|
||||
}
|
||||
|
||||
// Path: metadataEdit
|
||||
class TranslationsMetadataEditEn {
|
||||
TranslationsMetadataEditEn._(this._root);
|
||||
|
||||
final Translations _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
|
||||
/// en: 'Edit...'
|
||||
String get editMetadata => 'Edit...';
|
||||
|
||||
/// en: 'Edit Metadata'
|
||||
String get screenTitle => 'Edit Metadata';
|
||||
|
||||
/// en: 'Basic Info'
|
||||
String get basicInfo => 'Basic Info';
|
||||
|
||||
/// en: 'Artwork'
|
||||
String get artwork => 'Artwork';
|
||||
|
||||
/// en: 'Advanced Settings'
|
||||
String get advancedSettings => 'Advanced Settings';
|
||||
|
||||
/// en: 'Title'
|
||||
String get title => 'Title';
|
||||
|
||||
/// en: 'Sort Title'
|
||||
String get sortTitle => 'Sort Title';
|
||||
|
||||
/// en: 'Original Title'
|
||||
String get originalTitle => 'Original Title';
|
||||
|
||||
/// en: 'Release Date'
|
||||
String get releaseDate => 'Release Date';
|
||||
|
||||
/// en: 'Content Rating'
|
||||
String get contentRating => 'Content Rating';
|
||||
|
||||
/// en: 'Studio'
|
||||
String get studio => 'Studio';
|
||||
|
||||
/// en: 'Tagline'
|
||||
String get tagline => 'Tagline';
|
||||
|
||||
/// en: 'Summary'
|
||||
String get summary => 'Summary';
|
||||
|
||||
/// en: 'Poster'
|
||||
String get poster => 'Poster';
|
||||
|
||||
/// en: 'Background'
|
||||
String get background => 'Background';
|
||||
|
||||
/// en: 'Select Poster'
|
||||
String get selectPoster => 'Select Poster';
|
||||
|
||||
/// en: 'Select Background'
|
||||
String get selectBackground => 'Select Background';
|
||||
|
||||
/// en: 'From URL'
|
||||
String get fromUrl => 'From URL';
|
||||
|
||||
/// en: 'Upload File'
|
||||
String get uploadFile => 'Upload File';
|
||||
|
||||
/// en: 'Enter image URL'
|
||||
String get enterImageUrl => 'Enter image URL';
|
||||
|
||||
/// en: 'Image URL'
|
||||
String get imageUrl => 'Image URL';
|
||||
|
||||
/// en: 'Metadata updated'
|
||||
String get metadataUpdated => 'Metadata updated';
|
||||
|
||||
/// en: 'Failed to update metadata'
|
||||
String get metadataUpdateFailed => 'Failed to update metadata';
|
||||
|
||||
/// en: 'Artwork updated'
|
||||
String get artworkUpdated => 'Artwork updated';
|
||||
|
||||
/// en: 'Failed to update artwork'
|
||||
String get artworkUpdateFailed => 'Failed to update artwork';
|
||||
|
||||
/// en: 'No artwork available'
|
||||
String get noArtworkAvailable => 'No artwork available';
|
||||
|
||||
/// en: 'Not set'
|
||||
String get notSet => 'Not set';
|
||||
|
||||
/// en: 'Library default'
|
||||
String get libraryDefault => 'Library default';
|
||||
|
||||
/// en: 'Account default'
|
||||
String get accountDefault => 'Account default';
|
||||
|
||||
/// en: 'Series default'
|
||||
String get seriesDefault => 'Series default';
|
||||
|
||||
/// en: 'Episode Sorting'
|
||||
String get episodeSorting => 'Episode Sorting';
|
||||
|
||||
/// en: 'Oldest first'
|
||||
String get oldestFirst => 'Oldest first';
|
||||
|
||||
/// en: 'Newest first'
|
||||
String get newestFirst => 'Newest first';
|
||||
|
||||
/// en: 'Keep'
|
||||
String get keep => 'Keep';
|
||||
|
||||
/// en: 'All episodes'
|
||||
String get allEpisodes => 'All episodes';
|
||||
|
||||
/// en: '${count} latest episodes'
|
||||
String latestEpisodes({required Object count}) => '${count} latest episodes';
|
||||
|
||||
/// en: 'Latest episode'
|
||||
String get latestEpisode => 'Latest episode';
|
||||
|
||||
/// en: 'Episodes added in the past ${count} days'
|
||||
String episodesAddedPastDays({required Object count}) => 'Episodes added in the past ${count} days';
|
||||
|
||||
/// en: 'Delete Episodes After Playing'
|
||||
String get deleteAfterPlaying => 'Delete Episodes After Playing';
|
||||
|
||||
/// en: 'Never'
|
||||
String get never => 'Never';
|
||||
|
||||
/// en: 'After a day'
|
||||
String get afterADay => 'After a day';
|
||||
|
||||
/// en: 'After a week'
|
||||
String get afterAWeek => 'After a week';
|
||||
|
||||
/// en: 'After a month'
|
||||
String get afterAMonth => 'After a month';
|
||||
|
||||
/// en: 'On next refresh'
|
||||
String get onNextRefresh => 'On next refresh';
|
||||
|
||||
/// en: 'Seasons'
|
||||
String get seasons => 'Seasons';
|
||||
|
||||
/// en: 'Show'
|
||||
String get show => 'Show';
|
||||
|
||||
/// en: 'Hide'
|
||||
String get hide => 'Hide';
|
||||
|
||||
/// en: 'Episode Ordering'
|
||||
String get episodeOrdering => 'Episode Ordering';
|
||||
|
||||
/// en: 'The Movie Database (Aired)'
|
||||
String get tmdbAiring => 'The Movie Database (Aired)';
|
||||
|
||||
/// en: 'TheTVDB (Aired)'
|
||||
String get tvdbAiring => 'TheTVDB (Aired)';
|
||||
|
||||
/// en: 'TheTVDB (Absolute)'
|
||||
String get tvdbAbsolute => 'TheTVDB (Absolute)';
|
||||
|
||||
/// en: 'Metadata Language'
|
||||
String get metadataLanguage => 'Metadata Language';
|
||||
|
||||
/// en: 'Use Original Title'
|
||||
String get useOriginalTitle => 'Use Original Title';
|
||||
|
||||
/// en: 'Preferred Audio Language'
|
||||
String get preferredAudioLanguage => 'Preferred Audio Language';
|
||||
|
||||
/// en: 'Preferred Subtitle Language'
|
||||
String get preferredSubtitleLanguage => 'Preferred Subtitle Language';
|
||||
|
||||
/// en: 'Auto-Select Subtitle Mode'
|
||||
String get subtitleMode => 'Auto-Select Subtitle Mode';
|
||||
|
||||
/// en: 'Manually selected'
|
||||
String get manuallySelected => 'Manually selected';
|
||||
|
||||
/// en: 'Shown with foreign audio'
|
||||
String get shownWithForeignAudio => 'Shown with foreign audio';
|
||||
|
||||
/// en: 'Always enabled'
|
||||
String get alwaysEnabled => 'Always enabled';
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
class TranslationsHotkeysActionsEn {
|
||||
TranslationsHotkeysActionsEn._(this._root);
|
||||
@@ -3476,6 +3663,65 @@ extension on Translations {
|
||||
'externalPlayer.launchFailed' => 'Failed to open external player',
|
||||
'externalPlayer.appNotInstalled' => ({required Object name}) => '${name} is not installed',
|
||||
'externalPlayer.playInExternalPlayer' => 'Play in External Player',
|
||||
'metadataEdit.editMetadata' => 'Edit...',
|
||||
'metadataEdit.screenTitle' => 'Edit Metadata',
|
||||
'metadataEdit.basicInfo' => 'Basic Info',
|
||||
'metadataEdit.artwork' => 'Artwork',
|
||||
'metadataEdit.advancedSettings' => 'Advanced Settings',
|
||||
'metadataEdit.title' => 'Title',
|
||||
'metadataEdit.sortTitle' => 'Sort Title',
|
||||
'metadataEdit.originalTitle' => 'Original Title',
|
||||
'metadataEdit.releaseDate' => 'Release Date',
|
||||
'metadataEdit.contentRating' => 'Content Rating',
|
||||
'metadataEdit.studio' => 'Studio',
|
||||
'metadataEdit.tagline' => 'Tagline',
|
||||
'metadataEdit.summary' => 'Summary',
|
||||
'metadataEdit.poster' => 'Poster',
|
||||
'metadataEdit.background' => 'Background',
|
||||
'metadataEdit.selectPoster' => 'Select Poster',
|
||||
'metadataEdit.selectBackground' => 'Select Background',
|
||||
'metadataEdit.fromUrl' => 'From URL',
|
||||
'metadataEdit.uploadFile' => 'Upload File',
|
||||
'metadataEdit.enterImageUrl' => 'Enter image URL',
|
||||
'metadataEdit.imageUrl' => 'Image URL',
|
||||
'metadataEdit.metadataUpdated' => 'Metadata updated',
|
||||
'metadataEdit.metadataUpdateFailed' => 'Failed to update metadata',
|
||||
'metadataEdit.artworkUpdated' => 'Artwork updated',
|
||||
'metadataEdit.artworkUpdateFailed' => 'Failed to update artwork',
|
||||
'metadataEdit.noArtworkAvailable' => 'No artwork available',
|
||||
'metadataEdit.notSet' => 'Not set',
|
||||
'metadataEdit.libraryDefault' => 'Library default',
|
||||
'metadataEdit.accountDefault' => 'Account default',
|
||||
'metadataEdit.seriesDefault' => 'Series default',
|
||||
'metadataEdit.episodeSorting' => 'Episode Sorting',
|
||||
'metadataEdit.oldestFirst' => 'Oldest first',
|
||||
'metadataEdit.newestFirst' => 'Newest first',
|
||||
'metadataEdit.keep' => 'Keep',
|
||||
'metadataEdit.allEpisodes' => 'All episodes',
|
||||
'metadataEdit.latestEpisodes' => ({required Object count}) => '${count} latest episodes',
|
||||
'metadataEdit.latestEpisode' => 'Latest episode',
|
||||
'metadataEdit.episodesAddedPastDays' => ({required Object count}) => 'Episodes added in the past ${count} days',
|
||||
'metadataEdit.deleteAfterPlaying' => 'Delete Episodes After Playing',
|
||||
'metadataEdit.never' => 'Never',
|
||||
'metadataEdit.afterADay' => 'After a day',
|
||||
'metadataEdit.afterAWeek' => 'After a week',
|
||||
'metadataEdit.afterAMonth' => 'After a month',
|
||||
'metadataEdit.onNextRefresh' => 'On next refresh',
|
||||
'metadataEdit.seasons' => 'Seasons',
|
||||
'metadataEdit.show' => 'Show',
|
||||
'metadataEdit.hide' => 'Hide',
|
||||
'metadataEdit.episodeOrdering' => 'Episode Ordering',
|
||||
'metadataEdit.tmdbAiring' => 'The Movie Database (Aired)',
|
||||
'metadataEdit.tvdbAiring' => 'TheTVDB (Aired)',
|
||||
'metadataEdit.tvdbAbsolute' => 'TheTVDB (Absolute)',
|
||||
'metadataEdit.metadataLanguage' => 'Metadata Language',
|
||||
'metadataEdit.useOriginalTitle' => 'Use Original Title',
|
||||
'metadataEdit.preferredAudioLanguage' => 'Preferred Audio Language',
|
||||
'metadataEdit.preferredSubtitleLanguage' => 'Preferred Subtitle Language',
|
||||
'metadataEdit.subtitleMode' => 'Auto-Select Subtitle Mode',
|
||||
'metadataEdit.manuallySelected' => 'Manually selected',
|
||||
'metadataEdit.shownWithForeignAudio' => 'Shown with foreign audio',
|
||||
'metadataEdit.alwaysEnabled' => 'Always enabled',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ class TranslationsEs with BaseTranslations<AppLocale, Translations> implements T
|
||||
@override late final _TranslationsCompanionRemoteEs companionRemote = _TranslationsCompanionRemoteEs._(_root);
|
||||
@override late final _TranslationsVideoSettingsEs videoSettings = _TranslationsVideoSettingsEs._(_root);
|
||||
@override late final _TranslationsExternalPlayerEs externalPlayer = _TranslationsExternalPlayerEs._(_root);
|
||||
@override late final _TranslationsMetadataEditEs metadataEdit = _TranslationsMetadataEditEs._(_root);
|
||||
}
|
||||
|
||||
// Path: app
|
||||
@@ -1050,6 +1051,74 @@ class _TranslationsExternalPlayerEs implements TranslationsExternalPlayerEn {
|
||||
@override String get playInExternalPlayer => 'Reproducir en reproductor externo';
|
||||
}
|
||||
|
||||
// Path: metadataEdit
|
||||
class _TranslationsMetadataEditEs implements TranslationsMetadataEditEn {
|
||||
_TranslationsMetadataEditEs._(this._root);
|
||||
|
||||
final TranslationsEs _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get editMetadata => 'Editar...';
|
||||
@override String get screenTitle => 'Editar metadatos';
|
||||
@override String get basicInfo => 'Información básica';
|
||||
@override String get artwork => 'Artwork';
|
||||
@override String get advancedSettings => 'Ajustes avanzados';
|
||||
@override String get title => 'Título';
|
||||
@override String get sortTitle => 'Título de ordenación';
|
||||
@override String get originalTitle => 'Título original';
|
||||
@override String get releaseDate => 'Fecha de estreno';
|
||||
@override String get contentRating => 'Clasificación de contenido';
|
||||
@override String get studio => 'Estudio';
|
||||
@override String get tagline => 'Eslogan';
|
||||
@override String get summary => 'Resumen';
|
||||
@override String get poster => 'Póster';
|
||||
@override String get background => 'Fondo';
|
||||
@override String get selectPoster => 'Seleccionar póster';
|
||||
@override String get selectBackground => 'Seleccionar fondo';
|
||||
@override String get fromUrl => 'Desde URL';
|
||||
@override String get uploadFile => 'Subir archivo';
|
||||
@override String get enterImageUrl => 'Introducir URL de imagen';
|
||||
@override String get imageUrl => 'URL de imagen';
|
||||
@override String get metadataUpdated => 'Metadatos actualizados';
|
||||
@override String get metadataUpdateFailed => 'Error al actualizar los metadatos';
|
||||
@override String get artworkUpdated => 'Artwork actualizado';
|
||||
@override String get artworkUpdateFailed => 'Error al actualizar el artwork';
|
||||
@override String get noArtworkAvailable => 'No hay artwork disponible';
|
||||
@override String get notSet => 'No establecido';
|
||||
@override String get libraryDefault => 'Predeterminado de biblioteca';
|
||||
@override String get accountDefault => 'Predeterminado de cuenta';
|
||||
@override String get seriesDefault => 'Predeterminado de serie';
|
||||
@override String get episodeSorting => 'Orden de episodios';
|
||||
@override String get oldestFirst => 'Más antiguos primero';
|
||||
@override String get newestFirst => 'Más recientes primero';
|
||||
@override String get keep => 'Conservar';
|
||||
@override String get allEpisodes => 'Todos los episodios';
|
||||
@override String latestEpisodes({required Object count}) => '${count} episodios más recientes';
|
||||
@override String get latestEpisode => 'Episodio más reciente';
|
||||
@override String episodesAddedPastDays({required Object count}) => 'Episodios añadidos en los últimos ${count} días';
|
||||
@override String get deleteAfterPlaying => 'Eliminar episodios después de reproducir';
|
||||
@override String get never => 'Nunca';
|
||||
@override String get afterADay => 'Después de un día';
|
||||
@override String get afterAWeek => 'Después de una semana';
|
||||
@override String get afterAMonth => 'Después de un mes';
|
||||
@override String get onNextRefresh => 'En la próxima actualización';
|
||||
@override String get seasons => 'Temporadas';
|
||||
@override String get show => 'Mostrar';
|
||||
@override String get hide => 'Ocultar';
|
||||
@override String get episodeOrdering => 'Orden de episodios';
|
||||
@override String get tmdbAiring => 'The Movie Database (Emisión)';
|
||||
@override String get tvdbAiring => 'TheTVDB (Emisión)';
|
||||
@override String get tvdbAbsolute => 'TheTVDB (Absoluto)';
|
||||
@override String get metadataLanguage => 'Idioma de metadatos';
|
||||
@override String get useOriginalTitle => 'Usar título original';
|
||||
@override String get preferredAudioLanguage => 'Idioma de audio preferido';
|
||||
@override String get preferredSubtitleLanguage => 'Idioma de subtítulos preferido';
|
||||
@override String get subtitleMode => 'Selección automática de subtítulos';
|
||||
@override String get manuallySelected => 'Seleccionado manualmente';
|
||||
@override String get shownWithForeignAudio => 'Mostrar con audio extranjero';
|
||||
@override String get alwaysEnabled => 'Siempre activado';
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
class _TranslationsHotkeysActionsEs implements TranslationsHotkeysActionsEn {
|
||||
_TranslationsHotkeysActionsEs._(this._root);
|
||||
@@ -1979,6 +2048,65 @@ extension on TranslationsEs {
|
||||
'externalPlayer.launchFailed' => 'No se pudo abrir el reproductor externo',
|
||||
'externalPlayer.appNotInstalled' => ({required Object name}) => '${name} no está instalado',
|
||||
'externalPlayer.playInExternalPlayer' => 'Reproducir en reproductor externo',
|
||||
'metadataEdit.editMetadata' => 'Editar...',
|
||||
'metadataEdit.screenTitle' => 'Editar metadatos',
|
||||
'metadataEdit.basicInfo' => 'Información básica',
|
||||
'metadataEdit.artwork' => 'Artwork',
|
||||
'metadataEdit.advancedSettings' => 'Ajustes avanzados',
|
||||
'metadataEdit.title' => 'Título',
|
||||
'metadataEdit.sortTitle' => 'Título de ordenación',
|
||||
'metadataEdit.originalTitle' => 'Título original',
|
||||
'metadataEdit.releaseDate' => 'Fecha de estreno',
|
||||
'metadataEdit.contentRating' => 'Clasificación de contenido',
|
||||
'metadataEdit.studio' => 'Estudio',
|
||||
'metadataEdit.tagline' => 'Eslogan',
|
||||
'metadataEdit.summary' => 'Resumen',
|
||||
'metadataEdit.poster' => 'Póster',
|
||||
'metadataEdit.background' => 'Fondo',
|
||||
'metadataEdit.selectPoster' => 'Seleccionar póster',
|
||||
'metadataEdit.selectBackground' => 'Seleccionar fondo',
|
||||
'metadataEdit.fromUrl' => 'Desde URL',
|
||||
'metadataEdit.uploadFile' => 'Subir archivo',
|
||||
'metadataEdit.enterImageUrl' => 'Introducir URL de imagen',
|
||||
'metadataEdit.imageUrl' => 'URL de imagen',
|
||||
'metadataEdit.metadataUpdated' => 'Metadatos actualizados',
|
||||
'metadataEdit.metadataUpdateFailed' => 'Error al actualizar los metadatos',
|
||||
'metadataEdit.artworkUpdated' => 'Artwork actualizado',
|
||||
'metadataEdit.artworkUpdateFailed' => 'Error al actualizar el artwork',
|
||||
'metadataEdit.noArtworkAvailable' => 'No hay artwork disponible',
|
||||
'metadataEdit.notSet' => 'No establecido',
|
||||
'metadataEdit.libraryDefault' => 'Predeterminado de biblioteca',
|
||||
'metadataEdit.accountDefault' => 'Predeterminado de cuenta',
|
||||
'metadataEdit.seriesDefault' => 'Predeterminado de serie',
|
||||
'metadataEdit.episodeSorting' => 'Orden de episodios',
|
||||
'metadataEdit.oldestFirst' => 'Más antiguos primero',
|
||||
'metadataEdit.newestFirst' => 'Más recientes primero',
|
||||
'metadataEdit.keep' => 'Conservar',
|
||||
'metadataEdit.allEpisodes' => 'Todos los episodios',
|
||||
'metadataEdit.latestEpisodes' => ({required Object count}) => '${count} episodios más recientes',
|
||||
'metadataEdit.latestEpisode' => 'Episodio más reciente',
|
||||
'metadataEdit.episodesAddedPastDays' => ({required Object count}) => 'Episodios añadidos en los últimos ${count} días',
|
||||
'metadataEdit.deleteAfterPlaying' => 'Eliminar episodios después de reproducir',
|
||||
'metadataEdit.never' => 'Nunca',
|
||||
'metadataEdit.afterADay' => 'Después de un día',
|
||||
'metadataEdit.afterAWeek' => 'Después de una semana',
|
||||
'metadataEdit.afterAMonth' => 'Después de un mes',
|
||||
'metadataEdit.onNextRefresh' => 'En la próxima actualización',
|
||||
'metadataEdit.seasons' => 'Temporadas',
|
||||
'metadataEdit.show' => 'Mostrar',
|
||||
'metadataEdit.hide' => 'Ocultar',
|
||||
'metadataEdit.episodeOrdering' => 'Orden de episodios',
|
||||
'metadataEdit.tmdbAiring' => 'The Movie Database (Emisión)',
|
||||
'metadataEdit.tvdbAiring' => 'TheTVDB (Emisión)',
|
||||
'metadataEdit.tvdbAbsolute' => 'TheTVDB (Absoluto)',
|
||||
'metadataEdit.metadataLanguage' => 'Idioma de metadatos',
|
||||
'metadataEdit.useOriginalTitle' => 'Usar título original',
|
||||
'metadataEdit.preferredAudioLanguage' => 'Idioma de audio preferido',
|
||||
'metadataEdit.preferredSubtitleLanguage' => 'Idioma de subtítulos preferido',
|
||||
'metadataEdit.subtitleMode' => 'Selección automática de subtítulos',
|
||||
'metadataEdit.manuallySelected' => 'Seleccionado manualmente',
|
||||
'metadataEdit.shownWithForeignAudio' => 'Mostrar con audio extranjero',
|
||||
'metadataEdit.alwaysEnabled' => 'Siempre activado',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ class TranslationsFr with BaseTranslations<AppLocale, Translations> implements T
|
||||
@override late final _TranslationsCompanionRemoteFr companionRemote = _TranslationsCompanionRemoteFr._(_root);
|
||||
@override late final _TranslationsVideoSettingsFr videoSettings = _TranslationsVideoSettingsFr._(_root);
|
||||
@override late final _TranslationsExternalPlayerFr externalPlayer = _TranslationsExternalPlayerFr._(_root);
|
||||
@override late final _TranslationsMetadataEditFr metadataEdit = _TranslationsMetadataEditFr._(_root);
|
||||
}
|
||||
|
||||
// Path: app
|
||||
@@ -1050,6 +1051,74 @@ class _TranslationsExternalPlayerFr implements TranslationsExternalPlayerEn {
|
||||
@override String get playInExternalPlayer => 'Lire dans un lecteur externe';
|
||||
}
|
||||
|
||||
// Path: metadataEdit
|
||||
class _TranslationsMetadataEditFr implements TranslationsMetadataEditEn {
|
||||
_TranslationsMetadataEditFr._(this._root);
|
||||
|
||||
final TranslationsFr _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get editMetadata => 'Modifier...';
|
||||
@override String get screenTitle => 'Modifier les métadonnées';
|
||||
@override String get basicInfo => 'Informations de base';
|
||||
@override String get artwork => 'Artwork';
|
||||
@override String get advancedSettings => 'Paramètres avancés';
|
||||
@override String get title => 'Titre';
|
||||
@override String get sortTitle => 'Titre de tri';
|
||||
@override String get originalTitle => 'Titre original';
|
||||
@override String get releaseDate => 'Date de sortie';
|
||||
@override String get contentRating => 'Classification';
|
||||
@override String get studio => 'Studio';
|
||||
@override String get tagline => 'Slogan';
|
||||
@override String get summary => 'Résumé';
|
||||
@override String get poster => 'Affiche';
|
||||
@override String get background => 'Arrière-plan';
|
||||
@override String get selectPoster => 'Sélectionner l\'affiche';
|
||||
@override String get selectBackground => 'Sélectionner l\'arrière-plan';
|
||||
@override String get fromUrl => 'Depuis une URL';
|
||||
@override String get uploadFile => 'Importer un fichier';
|
||||
@override String get enterImageUrl => 'Entrer l\'URL de l\'image';
|
||||
@override String get imageUrl => 'URL de l\'image';
|
||||
@override String get metadataUpdated => 'Métadonnées mises à jour';
|
||||
@override String get metadataUpdateFailed => 'Échec de la mise à jour des métadonnées';
|
||||
@override String get artworkUpdated => 'Artwork mis à jour';
|
||||
@override String get artworkUpdateFailed => 'Échec de la mise à jour de l\'artwork';
|
||||
@override String get noArtworkAvailable => 'Aucun artwork disponible';
|
||||
@override String get notSet => 'Non défini';
|
||||
@override String get libraryDefault => 'Par défaut de la bibliothèque';
|
||||
@override String get accountDefault => 'Par défaut du compte';
|
||||
@override String get seriesDefault => 'Par défaut de la série';
|
||||
@override String get episodeSorting => 'Tri des épisodes';
|
||||
@override String get oldestFirst => 'Plus anciens en premier';
|
||||
@override String get newestFirst => 'Plus récents en premier';
|
||||
@override String get keep => 'Conserver';
|
||||
@override String get allEpisodes => 'Tous les épisodes';
|
||||
@override String latestEpisodes({required Object count}) => '${count} derniers épisodes';
|
||||
@override String get latestEpisode => 'Dernier épisode';
|
||||
@override String episodesAddedPastDays({required Object count}) => 'Épisodes ajoutés ces ${count} derniers jours';
|
||||
@override String get deleteAfterPlaying => 'Supprimer les épisodes après lecture';
|
||||
@override String get never => 'Jamais';
|
||||
@override String get afterADay => 'Après un jour';
|
||||
@override String get afterAWeek => 'Après une semaine';
|
||||
@override String get afterAMonth => 'Après un mois';
|
||||
@override String get onNextRefresh => 'Au prochain rafraîchissement';
|
||||
@override String get seasons => 'Saisons';
|
||||
@override String get show => 'Afficher';
|
||||
@override String get hide => 'Masquer';
|
||||
@override String get episodeOrdering => 'Ordre des épisodes';
|
||||
@override String get tmdbAiring => 'The Movie Database (Diffusion)';
|
||||
@override String get tvdbAiring => 'TheTVDB (Diffusion)';
|
||||
@override String get tvdbAbsolute => 'TheTVDB (Absolu)';
|
||||
@override String get metadataLanguage => 'Langue des métadonnées';
|
||||
@override String get useOriginalTitle => 'Utiliser le titre original';
|
||||
@override String get preferredAudioLanguage => 'Langue audio préférée';
|
||||
@override String get preferredSubtitleLanguage => 'Langue de sous-titres préférée';
|
||||
@override String get subtitleMode => 'Sélection automatique des sous-titres';
|
||||
@override String get manuallySelected => 'Sélectionné manuellement';
|
||||
@override String get shownWithForeignAudio => 'Affichés avec audio étranger';
|
||||
@override String get alwaysEnabled => 'Toujours activé';
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
class _TranslationsHotkeysActionsFr implements TranslationsHotkeysActionsEn {
|
||||
_TranslationsHotkeysActionsFr._(this._root);
|
||||
@@ -1979,6 +2048,65 @@ extension on TranslationsFr {
|
||||
'externalPlayer.launchFailed' => 'Impossible d\'ouvrir le lecteur externe',
|
||||
'externalPlayer.appNotInstalled' => ({required Object name}) => '${name} n\'est pas installé',
|
||||
'externalPlayer.playInExternalPlayer' => 'Lire dans un lecteur externe',
|
||||
'metadataEdit.editMetadata' => 'Modifier...',
|
||||
'metadataEdit.screenTitle' => 'Modifier les métadonnées',
|
||||
'metadataEdit.basicInfo' => 'Informations de base',
|
||||
'metadataEdit.artwork' => 'Artwork',
|
||||
'metadataEdit.advancedSettings' => 'Paramètres avancés',
|
||||
'metadataEdit.title' => 'Titre',
|
||||
'metadataEdit.sortTitle' => 'Titre de tri',
|
||||
'metadataEdit.originalTitle' => 'Titre original',
|
||||
'metadataEdit.releaseDate' => 'Date de sortie',
|
||||
'metadataEdit.contentRating' => 'Classification',
|
||||
'metadataEdit.studio' => 'Studio',
|
||||
'metadataEdit.tagline' => 'Slogan',
|
||||
'metadataEdit.summary' => 'Résumé',
|
||||
'metadataEdit.poster' => 'Affiche',
|
||||
'metadataEdit.background' => 'Arrière-plan',
|
||||
'metadataEdit.selectPoster' => 'Sélectionner l\'affiche',
|
||||
'metadataEdit.selectBackground' => 'Sélectionner l\'arrière-plan',
|
||||
'metadataEdit.fromUrl' => 'Depuis une URL',
|
||||
'metadataEdit.uploadFile' => 'Importer un fichier',
|
||||
'metadataEdit.enterImageUrl' => 'Entrer l\'URL de l\'image',
|
||||
'metadataEdit.imageUrl' => 'URL de l\'image',
|
||||
'metadataEdit.metadataUpdated' => 'Métadonnées mises à jour',
|
||||
'metadataEdit.metadataUpdateFailed' => 'Échec de la mise à jour des métadonnées',
|
||||
'metadataEdit.artworkUpdated' => 'Artwork mis à jour',
|
||||
'metadataEdit.artworkUpdateFailed' => 'Échec de la mise à jour de l\'artwork',
|
||||
'metadataEdit.noArtworkAvailable' => 'Aucun artwork disponible',
|
||||
'metadataEdit.notSet' => 'Non défini',
|
||||
'metadataEdit.libraryDefault' => 'Par défaut de la bibliothèque',
|
||||
'metadataEdit.accountDefault' => 'Par défaut du compte',
|
||||
'metadataEdit.seriesDefault' => 'Par défaut de la série',
|
||||
'metadataEdit.episodeSorting' => 'Tri des épisodes',
|
||||
'metadataEdit.oldestFirst' => 'Plus anciens en premier',
|
||||
'metadataEdit.newestFirst' => 'Plus récents en premier',
|
||||
'metadataEdit.keep' => 'Conserver',
|
||||
'metadataEdit.allEpisodes' => 'Tous les épisodes',
|
||||
'metadataEdit.latestEpisodes' => ({required Object count}) => '${count} derniers épisodes',
|
||||
'metadataEdit.latestEpisode' => 'Dernier épisode',
|
||||
'metadataEdit.episodesAddedPastDays' => ({required Object count}) => 'Épisodes ajoutés ces ${count} derniers jours',
|
||||
'metadataEdit.deleteAfterPlaying' => 'Supprimer les épisodes après lecture',
|
||||
'metadataEdit.never' => 'Jamais',
|
||||
'metadataEdit.afterADay' => 'Après un jour',
|
||||
'metadataEdit.afterAWeek' => 'Après une semaine',
|
||||
'metadataEdit.afterAMonth' => 'Après un mois',
|
||||
'metadataEdit.onNextRefresh' => 'Au prochain rafraîchissement',
|
||||
'metadataEdit.seasons' => 'Saisons',
|
||||
'metadataEdit.show' => 'Afficher',
|
||||
'metadataEdit.hide' => 'Masquer',
|
||||
'metadataEdit.episodeOrdering' => 'Ordre des épisodes',
|
||||
'metadataEdit.tmdbAiring' => 'The Movie Database (Diffusion)',
|
||||
'metadataEdit.tvdbAiring' => 'TheTVDB (Diffusion)',
|
||||
'metadataEdit.tvdbAbsolute' => 'TheTVDB (Absolu)',
|
||||
'metadataEdit.metadataLanguage' => 'Langue des métadonnées',
|
||||
'metadataEdit.useOriginalTitle' => 'Utiliser le titre original',
|
||||
'metadataEdit.preferredAudioLanguage' => 'Langue audio préférée',
|
||||
'metadataEdit.preferredSubtitleLanguage' => 'Langue de sous-titres préférée',
|
||||
'metadataEdit.subtitleMode' => 'Sélection automatique des sous-titres',
|
||||
'metadataEdit.manuallySelected' => 'Sélectionné manuellement',
|
||||
'metadataEdit.shownWithForeignAudio' => 'Affichés avec audio étranger',
|
||||
'metadataEdit.alwaysEnabled' => 'Toujours activé',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ class TranslationsIt with BaseTranslations<AppLocale, Translations> implements T
|
||||
@override late final _TranslationsCompanionRemoteIt companionRemote = _TranslationsCompanionRemoteIt._(_root);
|
||||
@override late final _TranslationsVideoSettingsIt videoSettings = _TranslationsVideoSettingsIt._(_root);
|
||||
@override late final _TranslationsExternalPlayerIt externalPlayer = _TranslationsExternalPlayerIt._(_root);
|
||||
@override late final _TranslationsMetadataEditIt metadataEdit = _TranslationsMetadataEditIt._(_root);
|
||||
}
|
||||
|
||||
// Path: app
|
||||
@@ -1050,6 +1051,74 @@ class _TranslationsExternalPlayerIt implements TranslationsExternalPlayerEn {
|
||||
@override String get playInExternalPlayer => 'Riproduci in lettore esterno';
|
||||
}
|
||||
|
||||
// Path: metadataEdit
|
||||
class _TranslationsMetadataEditIt implements TranslationsMetadataEditEn {
|
||||
_TranslationsMetadataEditIt._(this._root);
|
||||
|
||||
final TranslationsIt _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get editMetadata => 'Modifica...';
|
||||
@override String get screenTitle => 'Modifica metadati';
|
||||
@override String get basicInfo => 'Informazioni di base';
|
||||
@override String get artwork => 'Artwork';
|
||||
@override String get advancedSettings => 'Impostazioni avanzate';
|
||||
@override String get title => 'Titolo';
|
||||
@override String get sortTitle => 'Titolo di ordinamento';
|
||||
@override String get originalTitle => 'Titolo originale';
|
||||
@override String get releaseDate => 'Data di uscita';
|
||||
@override String get contentRating => 'Classificazione';
|
||||
@override String get studio => 'Studio';
|
||||
@override String get tagline => 'Tagline';
|
||||
@override String get summary => 'Trama';
|
||||
@override String get poster => 'Poster';
|
||||
@override String get background => 'Sfondo';
|
||||
@override String get selectPoster => 'Seleziona poster';
|
||||
@override String get selectBackground => 'Seleziona sfondo';
|
||||
@override String get fromUrl => 'Da URL';
|
||||
@override String get uploadFile => 'Carica file';
|
||||
@override String get enterImageUrl => 'Inserisci URL immagine';
|
||||
@override String get imageUrl => 'URL immagine';
|
||||
@override String get metadataUpdated => 'Metadati aggiornati';
|
||||
@override String get metadataUpdateFailed => 'Aggiornamento metadati non riuscito';
|
||||
@override String get artworkUpdated => 'Artwork aggiornato';
|
||||
@override String get artworkUpdateFailed => 'Aggiornamento artwork non riuscito';
|
||||
@override String get noArtworkAvailable => 'Nessun artwork disponibile';
|
||||
@override String get notSet => 'Non impostato';
|
||||
@override String get libraryDefault => 'Predefinito libreria';
|
||||
@override String get accountDefault => 'Predefinito account';
|
||||
@override String get seriesDefault => 'Predefinito serie';
|
||||
@override String get episodeSorting => 'Ordinamento episodi';
|
||||
@override String get oldestFirst => 'Più vecchi prima';
|
||||
@override String get newestFirst => 'Più recenti prima';
|
||||
@override String get keep => 'Conserva';
|
||||
@override String get allEpisodes => 'Tutti gli episodi';
|
||||
@override String latestEpisodes({required Object count}) => '${count} episodi più recenti';
|
||||
@override String get latestEpisode => 'Episodio più recente';
|
||||
@override String episodesAddedPastDays({required Object count}) => 'Episodi aggiunti negli ultimi ${count} giorni';
|
||||
@override String get deleteAfterPlaying => 'Elimina episodi dopo la riproduzione';
|
||||
@override String get never => 'Mai';
|
||||
@override String get afterADay => 'Dopo un giorno';
|
||||
@override String get afterAWeek => 'Dopo una settimana';
|
||||
@override String get afterAMonth => 'Dopo un mese';
|
||||
@override String get onNextRefresh => 'Al prossimo aggiornamento';
|
||||
@override String get seasons => 'Stagioni';
|
||||
@override String get show => 'Mostra';
|
||||
@override String get hide => 'Nascondi';
|
||||
@override String get episodeOrdering => 'Ordine episodi';
|
||||
@override String get tmdbAiring => 'The Movie Database (In onda)';
|
||||
@override String get tvdbAiring => 'TheTVDB (In onda)';
|
||||
@override String get tvdbAbsolute => 'TheTVDB (Assoluto)';
|
||||
@override String get metadataLanguage => 'Lingua metadati';
|
||||
@override String get useOriginalTitle => 'Usa titolo originale';
|
||||
@override String get preferredAudioLanguage => 'Lingua audio preferita';
|
||||
@override String get preferredSubtitleLanguage => 'Lingua sottotitoli preferita';
|
||||
@override String get subtitleMode => 'Selezione automatica sottotitoli';
|
||||
@override String get manuallySelected => 'Selezionato manualmente';
|
||||
@override String get shownWithForeignAudio => 'Mostrati con audio straniero';
|
||||
@override String get alwaysEnabled => 'Sempre attivo';
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
class _TranslationsHotkeysActionsIt implements TranslationsHotkeysActionsEn {
|
||||
_TranslationsHotkeysActionsIt._(this._root);
|
||||
@@ -1979,6 +2048,65 @@ extension on TranslationsIt {
|
||||
'externalPlayer.launchFailed' => 'Impossibile aprire il lettore esterno',
|
||||
'externalPlayer.appNotInstalled' => ({required Object name}) => '${name} non è installato',
|
||||
'externalPlayer.playInExternalPlayer' => 'Riproduci in lettore esterno',
|
||||
'metadataEdit.editMetadata' => 'Modifica...',
|
||||
'metadataEdit.screenTitle' => 'Modifica metadati',
|
||||
'metadataEdit.basicInfo' => 'Informazioni di base',
|
||||
'metadataEdit.artwork' => 'Artwork',
|
||||
'metadataEdit.advancedSettings' => 'Impostazioni avanzate',
|
||||
'metadataEdit.title' => 'Titolo',
|
||||
'metadataEdit.sortTitle' => 'Titolo di ordinamento',
|
||||
'metadataEdit.originalTitle' => 'Titolo originale',
|
||||
'metadataEdit.releaseDate' => 'Data di uscita',
|
||||
'metadataEdit.contentRating' => 'Classificazione',
|
||||
'metadataEdit.studio' => 'Studio',
|
||||
'metadataEdit.tagline' => 'Tagline',
|
||||
'metadataEdit.summary' => 'Trama',
|
||||
'metadataEdit.poster' => 'Poster',
|
||||
'metadataEdit.background' => 'Sfondo',
|
||||
'metadataEdit.selectPoster' => 'Seleziona poster',
|
||||
'metadataEdit.selectBackground' => 'Seleziona sfondo',
|
||||
'metadataEdit.fromUrl' => 'Da URL',
|
||||
'metadataEdit.uploadFile' => 'Carica file',
|
||||
'metadataEdit.enterImageUrl' => 'Inserisci URL immagine',
|
||||
'metadataEdit.imageUrl' => 'URL immagine',
|
||||
'metadataEdit.metadataUpdated' => 'Metadati aggiornati',
|
||||
'metadataEdit.metadataUpdateFailed' => 'Aggiornamento metadati non riuscito',
|
||||
'metadataEdit.artworkUpdated' => 'Artwork aggiornato',
|
||||
'metadataEdit.artworkUpdateFailed' => 'Aggiornamento artwork non riuscito',
|
||||
'metadataEdit.noArtworkAvailable' => 'Nessun artwork disponibile',
|
||||
'metadataEdit.notSet' => 'Non impostato',
|
||||
'metadataEdit.libraryDefault' => 'Predefinito libreria',
|
||||
'metadataEdit.accountDefault' => 'Predefinito account',
|
||||
'metadataEdit.seriesDefault' => 'Predefinito serie',
|
||||
'metadataEdit.episodeSorting' => 'Ordinamento episodi',
|
||||
'metadataEdit.oldestFirst' => 'Più vecchi prima',
|
||||
'metadataEdit.newestFirst' => 'Più recenti prima',
|
||||
'metadataEdit.keep' => 'Conserva',
|
||||
'metadataEdit.allEpisodes' => 'Tutti gli episodi',
|
||||
'metadataEdit.latestEpisodes' => ({required Object count}) => '${count} episodi più recenti',
|
||||
'metadataEdit.latestEpisode' => 'Episodio più recente',
|
||||
'metadataEdit.episodesAddedPastDays' => ({required Object count}) => 'Episodi aggiunti negli ultimi ${count} giorni',
|
||||
'metadataEdit.deleteAfterPlaying' => 'Elimina episodi dopo la riproduzione',
|
||||
'metadataEdit.never' => 'Mai',
|
||||
'metadataEdit.afterADay' => 'Dopo un giorno',
|
||||
'metadataEdit.afterAWeek' => 'Dopo una settimana',
|
||||
'metadataEdit.afterAMonth' => 'Dopo un mese',
|
||||
'metadataEdit.onNextRefresh' => 'Al prossimo aggiornamento',
|
||||
'metadataEdit.seasons' => 'Stagioni',
|
||||
'metadataEdit.show' => 'Mostra',
|
||||
'metadataEdit.hide' => 'Nascondi',
|
||||
'metadataEdit.episodeOrdering' => 'Ordine episodi',
|
||||
'metadataEdit.tmdbAiring' => 'The Movie Database (In onda)',
|
||||
'metadataEdit.tvdbAiring' => 'TheTVDB (In onda)',
|
||||
'metadataEdit.tvdbAbsolute' => 'TheTVDB (Assoluto)',
|
||||
'metadataEdit.metadataLanguage' => 'Lingua metadati',
|
||||
'metadataEdit.useOriginalTitle' => 'Usa titolo originale',
|
||||
'metadataEdit.preferredAudioLanguage' => 'Lingua audio preferita',
|
||||
'metadataEdit.preferredSubtitleLanguage' => 'Lingua sottotitoli preferita',
|
||||
'metadataEdit.subtitleMode' => 'Selezione automatica sottotitoli',
|
||||
'metadataEdit.manuallySelected' => 'Selezionato manualmente',
|
||||
'metadataEdit.shownWithForeignAudio' => 'Mostrati con audio straniero',
|
||||
'metadataEdit.alwaysEnabled' => 'Sempre attivo',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ class TranslationsKo with BaseTranslations<AppLocale, Translations> implements T
|
||||
@override late final _TranslationsCompanionRemoteKo companionRemote = _TranslationsCompanionRemoteKo._(_root);
|
||||
@override late final _TranslationsVideoSettingsKo videoSettings = _TranslationsVideoSettingsKo._(_root);
|
||||
@override late final _TranslationsExternalPlayerKo externalPlayer = _TranslationsExternalPlayerKo._(_root);
|
||||
@override late final _TranslationsMetadataEditKo metadataEdit = _TranslationsMetadataEditKo._(_root);
|
||||
}
|
||||
|
||||
// Path: app
|
||||
@@ -1050,6 +1051,74 @@ class _TranslationsExternalPlayerKo implements TranslationsExternalPlayerEn {
|
||||
@override String get playInExternalPlayer => '외부 플레이어에서 재생';
|
||||
}
|
||||
|
||||
// Path: metadataEdit
|
||||
class _TranslationsMetadataEditKo implements TranslationsMetadataEditEn {
|
||||
_TranslationsMetadataEditKo._(this._root);
|
||||
|
||||
final TranslationsKo _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get editMetadata => '편집...';
|
||||
@override String get screenTitle => '메타데이터 편집';
|
||||
@override String get basicInfo => '기본 정보';
|
||||
@override String get artwork => '아트워크';
|
||||
@override String get advancedSettings => '고급 설정';
|
||||
@override String get title => '제목';
|
||||
@override String get sortTitle => '정렬 제목';
|
||||
@override String get originalTitle => '원제';
|
||||
@override String get releaseDate => '출시일';
|
||||
@override String get contentRating => '콘텐츠 등급';
|
||||
@override String get studio => '스튜디오';
|
||||
@override String get tagline => '태그라인';
|
||||
@override String get summary => '줄거리';
|
||||
@override String get poster => '포스터';
|
||||
@override String get background => '배경';
|
||||
@override String get selectPoster => '포스터 선택';
|
||||
@override String get selectBackground => '배경 선택';
|
||||
@override String get fromUrl => 'URL에서';
|
||||
@override String get uploadFile => '파일 업로드';
|
||||
@override String get enterImageUrl => '이미지 URL 입력';
|
||||
@override String get imageUrl => '이미지 URL';
|
||||
@override String get metadataUpdated => '메타데이터가 업데이트되었습니다';
|
||||
@override String get metadataUpdateFailed => '메타데이터 업데이트 실패';
|
||||
@override String get artworkUpdated => '아트워크가 업데이트되었습니다';
|
||||
@override String get artworkUpdateFailed => '아트워크 업데이트 실패';
|
||||
@override String get noArtworkAvailable => '사용 가능한 아트워크 없음';
|
||||
@override String get notSet => '설정되지 않음';
|
||||
@override String get libraryDefault => '라이브러리 기본값';
|
||||
@override String get accountDefault => '계정 기본값';
|
||||
@override String get seriesDefault => '시리즈 기본값';
|
||||
@override String get episodeSorting => '에피소드 정렬';
|
||||
@override String get oldestFirst => '오래된 순';
|
||||
@override String get newestFirst => '최신 순';
|
||||
@override String get keep => '유지';
|
||||
@override String get allEpisodes => '모든 에피소드';
|
||||
@override String latestEpisodes({required Object count}) => '최신 에피소드 ${count}개';
|
||||
@override String get latestEpisode => '최신 에피소드';
|
||||
@override String episodesAddedPastDays({required Object count}) => '최근 ${count}일 내 추가된 에피소드';
|
||||
@override String get deleteAfterPlaying => '재생 후 에피소드 삭제';
|
||||
@override String get never => '안 함';
|
||||
@override String get afterADay => '하루 후';
|
||||
@override String get afterAWeek => '일주일 후';
|
||||
@override String get afterAMonth => '한 달 후';
|
||||
@override String get onNextRefresh => '다음 새로고침 시';
|
||||
@override String get seasons => '시즌';
|
||||
@override String get show => '표시';
|
||||
@override String get hide => '숨기기';
|
||||
@override String get episodeOrdering => '에피소드 순서';
|
||||
@override String get tmdbAiring => 'The Movie Database (방영순)';
|
||||
@override String get tvdbAiring => 'TheTVDB (방영순)';
|
||||
@override String get tvdbAbsolute => 'TheTVDB (절대순)';
|
||||
@override String get metadataLanguage => '메타데이터 언어';
|
||||
@override String get useOriginalTitle => '원제 사용';
|
||||
@override String get preferredAudioLanguage => '선호 오디오 언어';
|
||||
@override String get preferredSubtitleLanguage => '선호 자막 언어';
|
||||
@override String get subtitleMode => '자막 자동 선택 모드';
|
||||
@override String get manuallySelected => '수동 선택';
|
||||
@override String get shownWithForeignAudio => '외국어 오디오 시 표시';
|
||||
@override String get alwaysEnabled => '항상 활성화';
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
class _TranslationsHotkeysActionsKo implements TranslationsHotkeysActionsEn {
|
||||
_TranslationsHotkeysActionsKo._(this._root);
|
||||
@@ -1979,6 +2048,65 @@ extension on TranslationsKo {
|
||||
'externalPlayer.launchFailed' => '외부 플레이어를 열 수 없습니다',
|
||||
'externalPlayer.appNotInstalled' => ({required Object name}) => '${name}이(가) 설치되어 있지 않습니다',
|
||||
'externalPlayer.playInExternalPlayer' => '외부 플레이어에서 재생',
|
||||
'metadataEdit.editMetadata' => '편집...',
|
||||
'metadataEdit.screenTitle' => '메타데이터 편집',
|
||||
'metadataEdit.basicInfo' => '기본 정보',
|
||||
'metadataEdit.artwork' => '아트워크',
|
||||
'metadataEdit.advancedSettings' => '고급 설정',
|
||||
'metadataEdit.title' => '제목',
|
||||
'metadataEdit.sortTitle' => '정렬 제목',
|
||||
'metadataEdit.originalTitle' => '원제',
|
||||
'metadataEdit.releaseDate' => '출시일',
|
||||
'metadataEdit.contentRating' => '콘텐츠 등급',
|
||||
'metadataEdit.studio' => '스튜디오',
|
||||
'metadataEdit.tagline' => '태그라인',
|
||||
'metadataEdit.summary' => '줄거리',
|
||||
'metadataEdit.poster' => '포스터',
|
||||
'metadataEdit.background' => '배경',
|
||||
'metadataEdit.selectPoster' => '포스터 선택',
|
||||
'metadataEdit.selectBackground' => '배경 선택',
|
||||
'metadataEdit.fromUrl' => 'URL에서',
|
||||
'metadataEdit.uploadFile' => '파일 업로드',
|
||||
'metadataEdit.enterImageUrl' => '이미지 URL 입력',
|
||||
'metadataEdit.imageUrl' => '이미지 URL',
|
||||
'metadataEdit.metadataUpdated' => '메타데이터가 업데이트되었습니다',
|
||||
'metadataEdit.metadataUpdateFailed' => '메타데이터 업데이트 실패',
|
||||
'metadataEdit.artworkUpdated' => '아트워크가 업데이트되었습니다',
|
||||
'metadataEdit.artworkUpdateFailed' => '아트워크 업데이트 실패',
|
||||
'metadataEdit.noArtworkAvailable' => '사용 가능한 아트워크 없음',
|
||||
'metadataEdit.notSet' => '설정되지 않음',
|
||||
'metadataEdit.libraryDefault' => '라이브러리 기본값',
|
||||
'metadataEdit.accountDefault' => '계정 기본값',
|
||||
'metadataEdit.seriesDefault' => '시리즈 기본값',
|
||||
'metadataEdit.episodeSorting' => '에피소드 정렬',
|
||||
'metadataEdit.oldestFirst' => '오래된 순',
|
||||
'metadataEdit.newestFirst' => '최신 순',
|
||||
'metadataEdit.keep' => '유지',
|
||||
'metadataEdit.allEpisodes' => '모든 에피소드',
|
||||
'metadataEdit.latestEpisodes' => ({required Object count}) => '최신 에피소드 ${count}개',
|
||||
'metadataEdit.latestEpisode' => '최신 에피소드',
|
||||
'metadataEdit.episodesAddedPastDays' => ({required Object count}) => '최근 ${count}일 내 추가된 에피소드',
|
||||
'metadataEdit.deleteAfterPlaying' => '재생 후 에피소드 삭제',
|
||||
'metadataEdit.never' => '안 함',
|
||||
'metadataEdit.afterADay' => '하루 후',
|
||||
'metadataEdit.afterAWeek' => '일주일 후',
|
||||
'metadataEdit.afterAMonth' => '한 달 후',
|
||||
'metadataEdit.onNextRefresh' => '다음 새로고침 시',
|
||||
'metadataEdit.seasons' => '시즌',
|
||||
'metadataEdit.show' => '표시',
|
||||
'metadataEdit.hide' => '숨기기',
|
||||
'metadataEdit.episodeOrdering' => '에피소드 순서',
|
||||
'metadataEdit.tmdbAiring' => 'The Movie Database (방영순)',
|
||||
'metadataEdit.tvdbAiring' => 'TheTVDB (방영순)',
|
||||
'metadataEdit.tvdbAbsolute' => 'TheTVDB (절대순)',
|
||||
'metadataEdit.metadataLanguage' => '메타데이터 언어',
|
||||
'metadataEdit.useOriginalTitle' => '원제 사용',
|
||||
'metadataEdit.preferredAudioLanguage' => '선호 오디오 언어',
|
||||
'metadataEdit.preferredSubtitleLanguage' => '선호 자막 언어',
|
||||
'metadataEdit.subtitleMode' => '자막 자동 선택 모드',
|
||||
'metadataEdit.manuallySelected' => '수동 선택',
|
||||
'metadataEdit.shownWithForeignAudio' => '외국어 오디오 시 표시',
|
||||
'metadataEdit.alwaysEnabled' => '항상 활성화',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ class TranslationsNl with BaseTranslations<AppLocale, Translations> implements T
|
||||
@override late final _TranslationsCompanionRemoteNl companionRemote = _TranslationsCompanionRemoteNl._(_root);
|
||||
@override late final _TranslationsVideoSettingsNl videoSettings = _TranslationsVideoSettingsNl._(_root);
|
||||
@override late final _TranslationsExternalPlayerNl externalPlayer = _TranslationsExternalPlayerNl._(_root);
|
||||
@override late final _TranslationsMetadataEditNl metadataEdit = _TranslationsMetadataEditNl._(_root);
|
||||
}
|
||||
|
||||
// Path: app
|
||||
@@ -1050,6 +1051,74 @@ class _TranslationsExternalPlayerNl implements TranslationsExternalPlayerEn {
|
||||
@override String get playInExternalPlayer => 'Afspelen in externe speler';
|
||||
}
|
||||
|
||||
// Path: metadataEdit
|
||||
class _TranslationsMetadataEditNl implements TranslationsMetadataEditEn {
|
||||
_TranslationsMetadataEditNl._(this._root);
|
||||
|
||||
final TranslationsNl _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get editMetadata => 'Bewerken...';
|
||||
@override String get screenTitle => 'Metadata bewerken';
|
||||
@override String get basicInfo => 'Basisinformatie';
|
||||
@override String get artwork => 'Artwork';
|
||||
@override String get advancedSettings => 'Geavanceerde instellingen';
|
||||
@override String get title => 'Titel';
|
||||
@override String get sortTitle => 'Sorteertitel';
|
||||
@override String get originalTitle => 'Oorspronkelijke titel';
|
||||
@override String get releaseDate => 'Releasedatum';
|
||||
@override String get contentRating => 'Leeftijdsclassificatie';
|
||||
@override String get studio => 'Studio';
|
||||
@override String get tagline => 'Tagline';
|
||||
@override String get summary => 'Samenvatting';
|
||||
@override String get poster => 'Poster';
|
||||
@override String get background => 'Achtergrond';
|
||||
@override String get selectPoster => 'Poster selecteren';
|
||||
@override String get selectBackground => 'Achtergrond selecteren';
|
||||
@override String get fromUrl => 'Vanaf URL';
|
||||
@override String get uploadFile => 'Bestand uploaden';
|
||||
@override String get enterImageUrl => 'Voer afbeeldings-URL in';
|
||||
@override String get imageUrl => 'Afbeeldings-URL';
|
||||
@override String get metadataUpdated => 'Metadata bijgewerkt';
|
||||
@override String get metadataUpdateFailed => 'Metadata bijwerken mislukt';
|
||||
@override String get artworkUpdated => 'Artwork bijgewerkt';
|
||||
@override String get artworkUpdateFailed => 'Artwork bijwerken mislukt';
|
||||
@override String get noArtworkAvailable => 'Geen artwork beschikbaar';
|
||||
@override String get notSet => 'Niet ingesteld';
|
||||
@override String get libraryDefault => 'Bibliotheekstandaard';
|
||||
@override String get accountDefault => 'Accountstandaard';
|
||||
@override String get seriesDefault => 'Seriestandaard';
|
||||
@override String get episodeSorting => 'Afleveringen sorteren';
|
||||
@override String get oldestFirst => 'Oudste eerst';
|
||||
@override String get newestFirst => 'Nieuwste eerst';
|
||||
@override String get keep => 'Bewaren';
|
||||
@override String get allEpisodes => 'Alle afleveringen';
|
||||
@override String latestEpisodes({required Object count}) => '${count} nieuwste afleveringen';
|
||||
@override String get latestEpisode => 'Nieuwste aflevering';
|
||||
@override String episodesAddedPastDays({required Object count}) => 'Afleveringen toegevoegd in de afgelopen ${count} dagen';
|
||||
@override String get deleteAfterPlaying => 'Afleveringen verwijderen na afspelen';
|
||||
@override String get never => 'Nooit';
|
||||
@override String get afterADay => 'Na een dag';
|
||||
@override String get afterAWeek => 'Na een week';
|
||||
@override String get afterAMonth => 'Na een maand';
|
||||
@override String get onNextRefresh => 'Bij volgende verversing';
|
||||
@override String get seasons => 'Seizoenen';
|
||||
@override String get show => 'Tonen';
|
||||
@override String get hide => 'Verbergen';
|
||||
@override String get episodeOrdering => 'Afleveringsvolgorde';
|
||||
@override String get tmdbAiring => 'The Movie Database (Uitgezonden)';
|
||||
@override String get tvdbAiring => 'TheTVDB (Uitgezonden)';
|
||||
@override String get tvdbAbsolute => 'TheTVDB (Absoluut)';
|
||||
@override String get metadataLanguage => 'Metadatataal';
|
||||
@override String get useOriginalTitle => 'Oorspronkelijke titel gebruiken';
|
||||
@override String get preferredAudioLanguage => 'Voorkeurstaal audio';
|
||||
@override String get preferredSubtitleLanguage => 'Voorkeurstaal ondertiteling';
|
||||
@override String get subtitleMode => 'Automatische ondertitelselectie';
|
||||
@override String get manuallySelected => 'Handmatig geselecteerd';
|
||||
@override String get shownWithForeignAudio => 'Weergeven bij anderstalig geluid';
|
||||
@override String get alwaysEnabled => 'Altijd ingeschakeld';
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
class _TranslationsHotkeysActionsNl implements TranslationsHotkeysActionsEn {
|
||||
_TranslationsHotkeysActionsNl._(this._root);
|
||||
@@ -1979,6 +2048,65 @@ extension on TranslationsNl {
|
||||
'externalPlayer.launchFailed' => 'Kan externe speler niet openen',
|
||||
'externalPlayer.appNotInstalled' => ({required Object name}) => '${name} is niet geïnstalleerd',
|
||||
'externalPlayer.playInExternalPlayer' => 'Afspelen in externe speler',
|
||||
'metadataEdit.editMetadata' => 'Bewerken...',
|
||||
'metadataEdit.screenTitle' => 'Metadata bewerken',
|
||||
'metadataEdit.basicInfo' => 'Basisinformatie',
|
||||
'metadataEdit.artwork' => 'Artwork',
|
||||
'metadataEdit.advancedSettings' => 'Geavanceerde instellingen',
|
||||
'metadataEdit.title' => 'Titel',
|
||||
'metadataEdit.sortTitle' => 'Sorteertitel',
|
||||
'metadataEdit.originalTitle' => 'Oorspronkelijke titel',
|
||||
'metadataEdit.releaseDate' => 'Releasedatum',
|
||||
'metadataEdit.contentRating' => 'Leeftijdsclassificatie',
|
||||
'metadataEdit.studio' => 'Studio',
|
||||
'metadataEdit.tagline' => 'Tagline',
|
||||
'metadataEdit.summary' => 'Samenvatting',
|
||||
'metadataEdit.poster' => 'Poster',
|
||||
'metadataEdit.background' => 'Achtergrond',
|
||||
'metadataEdit.selectPoster' => 'Poster selecteren',
|
||||
'metadataEdit.selectBackground' => 'Achtergrond selecteren',
|
||||
'metadataEdit.fromUrl' => 'Vanaf URL',
|
||||
'metadataEdit.uploadFile' => 'Bestand uploaden',
|
||||
'metadataEdit.enterImageUrl' => 'Voer afbeeldings-URL in',
|
||||
'metadataEdit.imageUrl' => 'Afbeeldings-URL',
|
||||
'metadataEdit.metadataUpdated' => 'Metadata bijgewerkt',
|
||||
'metadataEdit.metadataUpdateFailed' => 'Metadata bijwerken mislukt',
|
||||
'metadataEdit.artworkUpdated' => 'Artwork bijgewerkt',
|
||||
'metadataEdit.artworkUpdateFailed' => 'Artwork bijwerken mislukt',
|
||||
'metadataEdit.noArtworkAvailable' => 'Geen artwork beschikbaar',
|
||||
'metadataEdit.notSet' => 'Niet ingesteld',
|
||||
'metadataEdit.libraryDefault' => 'Bibliotheekstandaard',
|
||||
'metadataEdit.accountDefault' => 'Accountstandaard',
|
||||
'metadataEdit.seriesDefault' => 'Seriestandaard',
|
||||
'metadataEdit.episodeSorting' => 'Afleveringen sorteren',
|
||||
'metadataEdit.oldestFirst' => 'Oudste eerst',
|
||||
'metadataEdit.newestFirst' => 'Nieuwste eerst',
|
||||
'metadataEdit.keep' => 'Bewaren',
|
||||
'metadataEdit.allEpisodes' => 'Alle afleveringen',
|
||||
'metadataEdit.latestEpisodes' => ({required Object count}) => '${count} nieuwste afleveringen',
|
||||
'metadataEdit.latestEpisode' => 'Nieuwste aflevering',
|
||||
'metadataEdit.episodesAddedPastDays' => ({required Object count}) => 'Afleveringen toegevoegd in de afgelopen ${count} dagen',
|
||||
'metadataEdit.deleteAfterPlaying' => 'Afleveringen verwijderen na afspelen',
|
||||
'metadataEdit.never' => 'Nooit',
|
||||
'metadataEdit.afterADay' => 'Na een dag',
|
||||
'metadataEdit.afterAWeek' => 'Na een week',
|
||||
'metadataEdit.afterAMonth' => 'Na een maand',
|
||||
'metadataEdit.onNextRefresh' => 'Bij volgende verversing',
|
||||
'metadataEdit.seasons' => 'Seizoenen',
|
||||
'metadataEdit.show' => 'Tonen',
|
||||
'metadataEdit.hide' => 'Verbergen',
|
||||
'metadataEdit.episodeOrdering' => 'Afleveringsvolgorde',
|
||||
'metadataEdit.tmdbAiring' => 'The Movie Database (Uitgezonden)',
|
||||
'metadataEdit.tvdbAiring' => 'TheTVDB (Uitgezonden)',
|
||||
'metadataEdit.tvdbAbsolute' => 'TheTVDB (Absoluut)',
|
||||
'metadataEdit.metadataLanguage' => 'Metadatataal',
|
||||
'metadataEdit.useOriginalTitle' => 'Oorspronkelijke titel gebruiken',
|
||||
'metadataEdit.preferredAudioLanguage' => 'Voorkeurstaal audio',
|
||||
'metadataEdit.preferredSubtitleLanguage' => 'Voorkeurstaal ondertiteling',
|
||||
'metadataEdit.subtitleMode' => 'Automatische ondertitelselectie',
|
||||
'metadataEdit.manuallySelected' => 'Handmatig geselecteerd',
|
||||
'metadataEdit.shownWithForeignAudio' => 'Weergeven bij anderstalig geluid',
|
||||
'metadataEdit.alwaysEnabled' => 'Altijd ingeschakeld',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ class TranslationsSv with BaseTranslations<AppLocale, Translations> implements T
|
||||
@override late final _TranslationsCompanionRemoteSv companionRemote = _TranslationsCompanionRemoteSv._(_root);
|
||||
@override late final _TranslationsVideoSettingsSv videoSettings = _TranslationsVideoSettingsSv._(_root);
|
||||
@override late final _TranslationsExternalPlayerSv externalPlayer = _TranslationsExternalPlayerSv._(_root);
|
||||
@override late final _TranslationsMetadataEditSv metadataEdit = _TranslationsMetadataEditSv._(_root);
|
||||
}
|
||||
|
||||
// Path: app
|
||||
@@ -1050,6 +1051,74 @@ class _TranslationsExternalPlayerSv implements TranslationsExternalPlayerEn {
|
||||
@override String get playInExternalPlayer => 'Spela i extern spelare';
|
||||
}
|
||||
|
||||
// Path: metadataEdit
|
||||
class _TranslationsMetadataEditSv implements TranslationsMetadataEditEn {
|
||||
_TranslationsMetadataEditSv._(this._root);
|
||||
|
||||
final TranslationsSv _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get editMetadata => 'Redigera...';
|
||||
@override String get screenTitle => 'Redigera metadata';
|
||||
@override String get basicInfo => 'Grundläggande info';
|
||||
@override String get artwork => 'Artwork';
|
||||
@override String get advancedSettings => 'Avancerade inställningar';
|
||||
@override String get title => 'Titel';
|
||||
@override String get sortTitle => 'Sorteringstitel';
|
||||
@override String get originalTitle => 'Originaltitel';
|
||||
@override String get releaseDate => 'Utgivningsdatum';
|
||||
@override String get contentRating => 'Åldersgräns';
|
||||
@override String get studio => 'Studio';
|
||||
@override String get tagline => 'Tagline';
|
||||
@override String get summary => 'Sammanfattning';
|
||||
@override String get poster => 'Poster';
|
||||
@override String get background => 'Bakgrund';
|
||||
@override String get selectPoster => 'Välj poster';
|
||||
@override String get selectBackground => 'Välj bakgrund';
|
||||
@override String get fromUrl => 'Från URL';
|
||||
@override String get uploadFile => 'Ladda upp fil';
|
||||
@override String get enterImageUrl => 'Ange bild-URL';
|
||||
@override String get imageUrl => 'Bild-URL';
|
||||
@override String get metadataUpdated => 'Metadata uppdaterad';
|
||||
@override String get metadataUpdateFailed => 'Kunde inte uppdatera metadata';
|
||||
@override String get artworkUpdated => 'Artwork uppdaterad';
|
||||
@override String get artworkUpdateFailed => 'Kunde inte uppdatera artwork';
|
||||
@override String get noArtworkAvailable => 'Ingen artwork tillgänglig';
|
||||
@override String get notSet => 'Inte angiven';
|
||||
@override String get libraryDefault => 'Biblioteksstandard';
|
||||
@override String get accountDefault => 'Kontostandard';
|
||||
@override String get seriesDefault => 'Seriestandard';
|
||||
@override String get episodeSorting => 'Avsnittsortering';
|
||||
@override String get oldestFirst => 'Äldst först';
|
||||
@override String get newestFirst => 'Nyast först';
|
||||
@override String get keep => 'Behåll';
|
||||
@override String get allEpisodes => 'Alla avsnitt';
|
||||
@override String latestEpisodes({required Object count}) => '${count} senaste avsnitten';
|
||||
@override String get latestEpisode => 'Senaste avsnittet';
|
||||
@override String episodesAddedPastDays({required Object count}) => 'Avsnitt tillagda de senaste ${count} dagarna';
|
||||
@override String get deleteAfterPlaying => 'Ta bort avsnitt efter uppspelning';
|
||||
@override String get never => 'Aldrig';
|
||||
@override String get afterADay => 'Efter en dag';
|
||||
@override String get afterAWeek => 'Efter en vecka';
|
||||
@override String get afterAMonth => 'Efter en månad';
|
||||
@override String get onNextRefresh => 'Vid nästa uppdatering';
|
||||
@override String get seasons => 'Säsonger';
|
||||
@override String get show => 'Visa';
|
||||
@override String get hide => 'Dölj';
|
||||
@override String get episodeOrdering => 'Avsnittsordning';
|
||||
@override String get tmdbAiring => 'The Movie Database (Sändning)';
|
||||
@override String get tvdbAiring => 'TheTVDB (Sändning)';
|
||||
@override String get tvdbAbsolute => 'TheTVDB (Absolut)';
|
||||
@override String get metadataLanguage => 'Metadataspråk';
|
||||
@override String get useOriginalTitle => 'Använd originaltitel';
|
||||
@override String get preferredAudioLanguage => 'Föredraget ljudspråk';
|
||||
@override String get preferredSubtitleLanguage => 'Föredraget undertextspråk';
|
||||
@override String get subtitleMode => 'Automatiskt val av undertexter';
|
||||
@override String get manuallySelected => 'Manuellt vald';
|
||||
@override String get shownWithForeignAudio => 'Visas vid främmande ljud';
|
||||
@override String get alwaysEnabled => 'Alltid aktiverad';
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
class _TranslationsHotkeysActionsSv implements TranslationsHotkeysActionsEn {
|
||||
_TranslationsHotkeysActionsSv._(this._root);
|
||||
@@ -1979,6 +2048,65 @@ extension on TranslationsSv {
|
||||
'externalPlayer.launchFailed' => 'Kunde inte öppna extern spelare',
|
||||
'externalPlayer.appNotInstalled' => ({required Object name}) => '${name} är inte installerad',
|
||||
'externalPlayer.playInExternalPlayer' => 'Spela i extern spelare',
|
||||
'metadataEdit.editMetadata' => 'Redigera...',
|
||||
'metadataEdit.screenTitle' => 'Redigera metadata',
|
||||
'metadataEdit.basicInfo' => 'Grundläggande info',
|
||||
'metadataEdit.artwork' => 'Artwork',
|
||||
'metadataEdit.advancedSettings' => 'Avancerade inställningar',
|
||||
'metadataEdit.title' => 'Titel',
|
||||
'metadataEdit.sortTitle' => 'Sorteringstitel',
|
||||
'metadataEdit.originalTitle' => 'Originaltitel',
|
||||
'metadataEdit.releaseDate' => 'Utgivningsdatum',
|
||||
'metadataEdit.contentRating' => 'Åldersgräns',
|
||||
'metadataEdit.studio' => 'Studio',
|
||||
'metadataEdit.tagline' => 'Tagline',
|
||||
'metadataEdit.summary' => 'Sammanfattning',
|
||||
'metadataEdit.poster' => 'Poster',
|
||||
'metadataEdit.background' => 'Bakgrund',
|
||||
'metadataEdit.selectPoster' => 'Välj poster',
|
||||
'metadataEdit.selectBackground' => 'Välj bakgrund',
|
||||
'metadataEdit.fromUrl' => 'Från URL',
|
||||
'metadataEdit.uploadFile' => 'Ladda upp fil',
|
||||
'metadataEdit.enterImageUrl' => 'Ange bild-URL',
|
||||
'metadataEdit.imageUrl' => 'Bild-URL',
|
||||
'metadataEdit.metadataUpdated' => 'Metadata uppdaterad',
|
||||
'metadataEdit.metadataUpdateFailed' => 'Kunde inte uppdatera metadata',
|
||||
'metadataEdit.artworkUpdated' => 'Artwork uppdaterad',
|
||||
'metadataEdit.artworkUpdateFailed' => 'Kunde inte uppdatera artwork',
|
||||
'metadataEdit.noArtworkAvailable' => 'Ingen artwork tillgänglig',
|
||||
'metadataEdit.notSet' => 'Inte angiven',
|
||||
'metadataEdit.libraryDefault' => 'Biblioteksstandard',
|
||||
'metadataEdit.accountDefault' => 'Kontostandard',
|
||||
'metadataEdit.seriesDefault' => 'Seriestandard',
|
||||
'metadataEdit.episodeSorting' => 'Avsnittsortering',
|
||||
'metadataEdit.oldestFirst' => 'Äldst först',
|
||||
'metadataEdit.newestFirst' => 'Nyast först',
|
||||
'metadataEdit.keep' => 'Behåll',
|
||||
'metadataEdit.allEpisodes' => 'Alla avsnitt',
|
||||
'metadataEdit.latestEpisodes' => ({required Object count}) => '${count} senaste avsnitten',
|
||||
'metadataEdit.latestEpisode' => 'Senaste avsnittet',
|
||||
'metadataEdit.episodesAddedPastDays' => ({required Object count}) => 'Avsnitt tillagda de senaste ${count} dagarna',
|
||||
'metadataEdit.deleteAfterPlaying' => 'Ta bort avsnitt efter uppspelning',
|
||||
'metadataEdit.never' => 'Aldrig',
|
||||
'metadataEdit.afterADay' => 'Efter en dag',
|
||||
'metadataEdit.afterAWeek' => 'Efter en vecka',
|
||||
'metadataEdit.afterAMonth' => 'Efter en månad',
|
||||
'metadataEdit.onNextRefresh' => 'Vid nästa uppdatering',
|
||||
'metadataEdit.seasons' => 'Säsonger',
|
||||
'metadataEdit.show' => 'Visa',
|
||||
'metadataEdit.hide' => 'Dölj',
|
||||
'metadataEdit.episodeOrdering' => 'Avsnittsordning',
|
||||
'metadataEdit.tmdbAiring' => 'The Movie Database (Sändning)',
|
||||
'metadataEdit.tvdbAiring' => 'TheTVDB (Sändning)',
|
||||
'metadataEdit.tvdbAbsolute' => 'TheTVDB (Absolut)',
|
||||
'metadataEdit.metadataLanguage' => 'Metadataspråk',
|
||||
'metadataEdit.useOriginalTitle' => 'Använd originaltitel',
|
||||
'metadataEdit.preferredAudioLanguage' => 'Föredraget ljudspråk',
|
||||
'metadataEdit.preferredSubtitleLanguage' => 'Föredraget undertextspråk',
|
||||
'metadataEdit.subtitleMode' => 'Automatiskt val av undertexter',
|
||||
'metadataEdit.manuallySelected' => 'Manuellt vald',
|
||||
'metadataEdit.shownWithForeignAudio' => 'Visas vid främmande ljud',
|
||||
'metadataEdit.alwaysEnabled' => 'Alltid aktiverad',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ class TranslationsZh with BaseTranslations<AppLocale, Translations> implements T
|
||||
@override late final _TranslationsCompanionRemoteZh companionRemote = _TranslationsCompanionRemoteZh._(_root);
|
||||
@override late final _TranslationsVideoSettingsZh videoSettings = _TranslationsVideoSettingsZh._(_root);
|
||||
@override late final _TranslationsExternalPlayerZh externalPlayer = _TranslationsExternalPlayerZh._(_root);
|
||||
@override late final _TranslationsMetadataEditZh metadataEdit = _TranslationsMetadataEditZh._(_root);
|
||||
}
|
||||
|
||||
// Path: app
|
||||
@@ -1050,6 +1051,74 @@ class _TranslationsExternalPlayerZh implements TranslationsExternalPlayerEn {
|
||||
@override String get playInExternalPlayer => '在外部播放器中播放';
|
||||
}
|
||||
|
||||
// Path: metadataEdit
|
||||
class _TranslationsMetadataEditZh implements TranslationsMetadataEditEn {
|
||||
_TranslationsMetadataEditZh._(this._root);
|
||||
|
||||
final TranslationsZh _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get editMetadata => '编辑...';
|
||||
@override String get screenTitle => '编辑元数据';
|
||||
@override String get basicInfo => '基本信息';
|
||||
@override String get artwork => '封面图片';
|
||||
@override String get advancedSettings => '高级设置';
|
||||
@override String get title => '标题';
|
||||
@override String get sortTitle => '排序标题';
|
||||
@override String get originalTitle => '原始标题';
|
||||
@override String get releaseDate => '上映日期';
|
||||
@override String get contentRating => '内容分级';
|
||||
@override String get studio => '制片厂';
|
||||
@override String get tagline => '标语';
|
||||
@override String get summary => '简介';
|
||||
@override String get poster => '海报';
|
||||
@override String get background => '背景';
|
||||
@override String get selectPoster => '选择海报';
|
||||
@override String get selectBackground => '选择背景';
|
||||
@override String get fromUrl => '从 URL';
|
||||
@override String get uploadFile => '上传文件';
|
||||
@override String get enterImageUrl => '输入图片 URL';
|
||||
@override String get imageUrl => '图片 URL';
|
||||
@override String get metadataUpdated => '元数据已更新';
|
||||
@override String get metadataUpdateFailed => '元数据更新失败';
|
||||
@override String get artworkUpdated => '封面图片已更新';
|
||||
@override String get artworkUpdateFailed => '封面图片更新失败';
|
||||
@override String get noArtworkAvailable => '没有可用的封面图片';
|
||||
@override String get notSet => '未设置';
|
||||
@override String get libraryDefault => '媒体库默认';
|
||||
@override String get accountDefault => '账户默认';
|
||||
@override String get seriesDefault => '剧集默认';
|
||||
@override String get episodeSorting => '剧集排序';
|
||||
@override String get oldestFirst => '最旧优先';
|
||||
@override String get newestFirst => '最新优先';
|
||||
@override String get keep => '保留';
|
||||
@override String get allEpisodes => '所有剧集';
|
||||
@override String latestEpisodes({required Object count}) => '最新 ${count} 集';
|
||||
@override String get latestEpisode => '最新一集';
|
||||
@override String episodesAddedPastDays({required Object count}) => '过去 ${count} 天内添加的剧集';
|
||||
@override String get deleteAfterPlaying => '播放后删除剧集';
|
||||
@override String get never => '从不';
|
||||
@override String get afterADay => '一天后';
|
||||
@override String get afterAWeek => '一周后';
|
||||
@override String get afterAMonth => '一个月后';
|
||||
@override String get onNextRefresh => '下次刷新时';
|
||||
@override String get seasons => '季';
|
||||
@override String get show => '显示';
|
||||
@override String get hide => '隐藏';
|
||||
@override String get episodeOrdering => '剧集排列顺序';
|
||||
@override String get tmdbAiring => 'The Movie Database(播出顺序)';
|
||||
@override String get tvdbAiring => 'TheTVDB(播出顺序)';
|
||||
@override String get tvdbAbsolute => 'TheTVDB(绝对顺序)';
|
||||
@override String get metadataLanguage => '元数据语言';
|
||||
@override String get useOriginalTitle => '使用原始标题';
|
||||
@override String get preferredAudioLanguage => '首选音频语言';
|
||||
@override String get preferredSubtitleLanguage => '首选字幕语言';
|
||||
@override String get subtitleMode => '自动选择字幕模式';
|
||||
@override String get manuallySelected => '手动选择';
|
||||
@override String get shownWithForeignAudio => '外语音频时显示';
|
||||
@override String get alwaysEnabled => '始终启用';
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
class _TranslationsHotkeysActionsZh implements TranslationsHotkeysActionsEn {
|
||||
_TranslationsHotkeysActionsZh._(this._root);
|
||||
@@ -1979,6 +2048,65 @@ extension on TranslationsZh {
|
||||
'externalPlayer.launchFailed' => '无法打开外部播放器',
|
||||
'externalPlayer.appNotInstalled' => ({required Object name}) => '${name} 未安装',
|
||||
'externalPlayer.playInExternalPlayer' => '在外部播放器中播放',
|
||||
'metadataEdit.editMetadata' => '编辑...',
|
||||
'metadataEdit.screenTitle' => '编辑元数据',
|
||||
'metadataEdit.basicInfo' => '基本信息',
|
||||
'metadataEdit.artwork' => '封面图片',
|
||||
'metadataEdit.advancedSettings' => '高级设置',
|
||||
'metadataEdit.title' => '标题',
|
||||
'metadataEdit.sortTitle' => '排序标题',
|
||||
'metadataEdit.originalTitle' => '原始标题',
|
||||
'metadataEdit.releaseDate' => '上映日期',
|
||||
'metadataEdit.contentRating' => '内容分级',
|
||||
'metadataEdit.studio' => '制片厂',
|
||||
'metadataEdit.tagline' => '标语',
|
||||
'metadataEdit.summary' => '简介',
|
||||
'metadataEdit.poster' => '海报',
|
||||
'metadataEdit.background' => '背景',
|
||||
'metadataEdit.selectPoster' => '选择海报',
|
||||
'metadataEdit.selectBackground' => '选择背景',
|
||||
'metadataEdit.fromUrl' => '从 URL',
|
||||
'metadataEdit.uploadFile' => '上传文件',
|
||||
'metadataEdit.enterImageUrl' => '输入图片 URL',
|
||||
'metadataEdit.imageUrl' => '图片 URL',
|
||||
'metadataEdit.metadataUpdated' => '元数据已更新',
|
||||
'metadataEdit.metadataUpdateFailed' => '元数据更新失败',
|
||||
'metadataEdit.artworkUpdated' => '封面图片已更新',
|
||||
'metadataEdit.artworkUpdateFailed' => '封面图片更新失败',
|
||||
'metadataEdit.noArtworkAvailable' => '没有可用的封面图片',
|
||||
'metadataEdit.notSet' => '未设置',
|
||||
'metadataEdit.libraryDefault' => '媒体库默认',
|
||||
'metadataEdit.accountDefault' => '账户默认',
|
||||
'metadataEdit.seriesDefault' => '剧集默认',
|
||||
'metadataEdit.episodeSorting' => '剧集排序',
|
||||
'metadataEdit.oldestFirst' => '最旧优先',
|
||||
'metadataEdit.newestFirst' => '最新优先',
|
||||
'metadataEdit.keep' => '保留',
|
||||
'metadataEdit.allEpisodes' => '所有剧集',
|
||||
'metadataEdit.latestEpisodes' => ({required Object count}) => '最新 ${count} 集',
|
||||
'metadataEdit.latestEpisode' => '最新一集',
|
||||
'metadataEdit.episodesAddedPastDays' => ({required Object count}) => '过去 ${count} 天内添加的剧集',
|
||||
'metadataEdit.deleteAfterPlaying' => '播放后删除剧集',
|
||||
'metadataEdit.never' => '从不',
|
||||
'metadataEdit.afterADay' => '一天后',
|
||||
'metadataEdit.afterAWeek' => '一周后',
|
||||
'metadataEdit.afterAMonth' => '一个月后',
|
||||
'metadataEdit.onNextRefresh' => '下次刷新时',
|
||||
'metadataEdit.seasons' => '季',
|
||||
'metadataEdit.show' => '显示',
|
||||
'metadataEdit.hide' => '隐藏',
|
||||
'metadataEdit.episodeOrdering' => '剧集排列顺序',
|
||||
'metadataEdit.tmdbAiring' => 'The Movie Database(播出顺序)',
|
||||
'metadataEdit.tvdbAiring' => 'TheTVDB(播出顺序)',
|
||||
'metadataEdit.tvdbAbsolute' => 'TheTVDB(绝对顺序)',
|
||||
'metadataEdit.metadataLanguage' => '元数据语言',
|
||||
'metadataEdit.useOriginalTitle' => '使用原始标题',
|
||||
'metadataEdit.preferredAudioLanguage' => '首选音频语言',
|
||||
'metadataEdit.preferredSubtitleLanguage' => '首选字幕语言',
|
||||
'metadataEdit.subtitleMode' => '自动选择字幕模式',
|
||||
'metadataEdit.manuallySelected' => '手动选择',
|
||||
'metadataEdit.shownWithForeignAudio' => '外语音频时显示',
|
||||
'metadataEdit.alwaysEnabled' => '始终启用',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
+62
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"app": {
|
||||
"title": "Plezy"
|
||||
},
|
||||
},
|
||||
"auth": {
|
||||
"signInWithPlex": "Logga in med Plex",
|
||||
"showQRCode": "Visa QR-kod",
|
||||
@@ -831,5 +831,66 @@
|
||||
"launchFailed": "Kunde inte öppna extern spelare",
|
||||
"appNotInstalled": "${name} är inte installerad",
|
||||
"playInExternalPlayer": "Spela i extern spelare"
|
||||
},
|
||||
"metadataEdit": {
|
||||
"editMetadata": "Redigera...",
|
||||
"screenTitle": "Redigera metadata",
|
||||
"basicInfo": "Grundläggande info",
|
||||
"artwork": "Artwork",
|
||||
"advancedSettings": "Avancerade inställningar",
|
||||
"title": "Titel",
|
||||
"sortTitle": "Sorteringstitel",
|
||||
"originalTitle": "Originaltitel",
|
||||
"releaseDate": "Utgivningsdatum",
|
||||
"contentRating": "Åldersgräns",
|
||||
"studio": "Studio",
|
||||
"tagline": "Tagline",
|
||||
"summary": "Sammanfattning",
|
||||
"poster": "Poster",
|
||||
"background": "Bakgrund",
|
||||
"selectPoster": "Välj poster",
|
||||
"selectBackground": "Välj bakgrund",
|
||||
"fromUrl": "Från URL",
|
||||
"uploadFile": "Ladda upp fil",
|
||||
"enterImageUrl": "Ange bild-URL",
|
||||
"imageUrl": "Bild-URL",
|
||||
"metadataUpdated": "Metadata uppdaterad",
|
||||
"metadataUpdateFailed": "Kunde inte uppdatera metadata",
|
||||
"artworkUpdated": "Artwork uppdaterad",
|
||||
"artworkUpdateFailed": "Kunde inte uppdatera artwork",
|
||||
"noArtworkAvailable": "Ingen artwork tillgänglig",
|
||||
"notSet": "Inte angiven",
|
||||
"libraryDefault": "Biblioteksstandard",
|
||||
"accountDefault": "Kontostandard",
|
||||
"seriesDefault": "Seriestandard",
|
||||
"episodeSorting": "Avsnittsortering",
|
||||
"oldestFirst": "Äldst först",
|
||||
"newestFirst": "Nyast först",
|
||||
"keep": "Behåll",
|
||||
"allEpisodes": "Alla avsnitt",
|
||||
"latestEpisodes": "${count} senaste avsnitten",
|
||||
"latestEpisode": "Senaste avsnittet",
|
||||
"episodesAddedPastDays": "Avsnitt tillagda de senaste ${count} dagarna",
|
||||
"deleteAfterPlaying": "Ta bort avsnitt efter uppspelning",
|
||||
"never": "Aldrig",
|
||||
"afterADay": "Efter en dag",
|
||||
"afterAWeek": "Efter en vecka",
|
||||
"afterAMonth": "Efter en månad",
|
||||
"onNextRefresh": "Vid nästa uppdatering",
|
||||
"seasons": "Säsonger",
|
||||
"show": "Visa",
|
||||
"hide": "Dölj",
|
||||
"episodeOrdering": "Avsnittsordning",
|
||||
"tmdbAiring": "The Movie Database (Sändning)",
|
||||
"tvdbAiring": "TheTVDB (Sändning)",
|
||||
"tvdbAbsolute": "TheTVDB (Absolut)",
|
||||
"metadataLanguage": "Metadataspråk",
|
||||
"useOriginalTitle": "Använd originaltitel",
|
||||
"preferredAudioLanguage": "Föredraget ljudspråk",
|
||||
"preferredSubtitleLanguage": "Föredraget undertextspråk",
|
||||
"subtitleMode": "Automatiskt val av undertexter",
|
||||
"manuallySelected": "Manuellt vald",
|
||||
"shownWithForeignAudio": "Visas vid främmande ljud",
|
||||
"alwaysEnabled": "Alltid aktiverad"
|
||||
}
|
||||
}
|
||||
|
||||
+62
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"app": {
|
||||
"title": "Plezy"
|
||||
},
|
||||
},
|
||||
"auth": {
|
||||
"signInWithPlex": "使用 Plex 登录",
|
||||
"showQRCode": "显示二维码",
|
||||
@@ -831,5 +831,66 @@
|
||||
"launchFailed": "无法打开外部播放器",
|
||||
"appNotInstalled": "${name} 未安装",
|
||||
"playInExternalPlayer": "在外部播放器中播放"
|
||||
},
|
||||
"metadataEdit": {
|
||||
"editMetadata": "编辑...",
|
||||
"screenTitle": "编辑元数据",
|
||||
"basicInfo": "基本信息",
|
||||
"artwork": "封面图片",
|
||||
"advancedSettings": "高级设置",
|
||||
"title": "标题",
|
||||
"sortTitle": "排序标题",
|
||||
"originalTitle": "原始标题",
|
||||
"releaseDate": "上映日期",
|
||||
"contentRating": "内容分级",
|
||||
"studio": "制片厂",
|
||||
"tagline": "标语",
|
||||
"summary": "简介",
|
||||
"poster": "海报",
|
||||
"background": "背景",
|
||||
"selectPoster": "选择海报",
|
||||
"selectBackground": "选择背景",
|
||||
"fromUrl": "从 URL",
|
||||
"uploadFile": "上传文件",
|
||||
"enterImageUrl": "输入图片 URL",
|
||||
"imageUrl": "图片 URL",
|
||||
"metadataUpdated": "元数据已更新",
|
||||
"metadataUpdateFailed": "元数据更新失败",
|
||||
"artworkUpdated": "封面图片已更新",
|
||||
"artworkUpdateFailed": "封面图片更新失败",
|
||||
"noArtworkAvailable": "没有可用的封面图片",
|
||||
"notSet": "未设置",
|
||||
"libraryDefault": "媒体库默认",
|
||||
"accountDefault": "账户默认",
|
||||
"seriesDefault": "剧集默认",
|
||||
"episodeSorting": "剧集排序",
|
||||
"oldestFirst": "最旧优先",
|
||||
"newestFirst": "最新优先",
|
||||
"keep": "保留",
|
||||
"allEpisodes": "所有剧集",
|
||||
"latestEpisodes": "最新 ${count} 集",
|
||||
"latestEpisode": "最新一集",
|
||||
"episodesAddedPastDays": "过去 ${count} 天内添加的剧集",
|
||||
"deleteAfterPlaying": "播放后删除剧集",
|
||||
"never": "从不",
|
||||
"afterADay": "一天后",
|
||||
"afterAWeek": "一周后",
|
||||
"afterAMonth": "一个月后",
|
||||
"onNextRefresh": "下次刷新时",
|
||||
"seasons": "季",
|
||||
"show": "显示",
|
||||
"hide": "隐藏",
|
||||
"episodeOrdering": "剧集排列顺序",
|
||||
"tmdbAiring": "The Movie Database(播出顺序)",
|
||||
"tvdbAiring": "TheTVDB(播出顺序)",
|
||||
"tvdbAbsolute": "TheTVDB(绝对顺序)",
|
||||
"metadataLanguage": "元数据语言",
|
||||
"useOriginalTitle": "使用原始标题",
|
||||
"preferredAudioLanguage": "首选音频语言",
|
||||
"preferredSubtitleLanguage": "首选字幕语言",
|
||||
"subtitleMode": "自动选择字幕模式",
|
||||
"manuallySelected": "手动选择",
|
||||
"shownWithForeignAudio": "外语音频时显示",
|
||||
"alwaysEnabled": "始终启用"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,18 @@ enum PlexMediaType {
|
||||
|
||||
/// Whether this type can be played directly
|
||||
bool get isPlayable => isVideo || this == track;
|
||||
|
||||
/// Plex API type number for metadata editing endpoints
|
||||
int get typeNumber => switch (this) {
|
||||
PlexMediaType.movie => 1,
|
||||
PlexMediaType.show => 2,
|
||||
PlexMediaType.season => 3,
|
||||
PlexMediaType.episode => 4,
|
||||
PlexMediaType.artist => 8,
|
||||
PlexMediaType.album => 9,
|
||||
PlexMediaType.track => 10,
|
||||
_ => 0,
|
||||
};
|
||||
}
|
||||
|
||||
@JsonSerializable()
|
||||
@@ -81,6 +93,8 @@ class PlexMetadata with MultiServerFields {
|
||||
final int? librarySectionID; // Library section ID this item belongs to
|
||||
final String? ratingImage; // Rating source URI (e.g. rottentomatoes://image.rating.ripe)
|
||||
final String? audienceRatingImage; // Audience rating source URI
|
||||
final String? tagline;
|
||||
final String? originalTitle;
|
||||
final String? subtype; // Clip subtype: "trailer", "behindTheScenes", "deleted", etc.
|
||||
final int? extraType; // Numeric extra type identifier
|
||||
final String? primaryExtraKey; // Points to main trailer (e.g., "/library/metadata/52601")
|
||||
@@ -161,6 +175,8 @@ class PlexMetadata with MultiServerFields {
|
||||
this.librarySectionID,
|
||||
this.ratingImage,
|
||||
this.audienceRatingImage,
|
||||
this.tagline,
|
||||
this.originalTitle,
|
||||
this.subtype,
|
||||
this.extraType,
|
||||
this.primaryExtraKey,
|
||||
@@ -214,6 +230,8 @@ class PlexMetadata with MultiServerFields {
|
||||
int? librarySectionID,
|
||||
String? ratingImage,
|
||||
String? audienceRatingImage,
|
||||
String? tagline,
|
||||
String? originalTitle,
|
||||
String? subtype,
|
||||
int? extraType,
|
||||
String? primaryExtraKey,
|
||||
@@ -265,6 +283,8 @@ class PlexMetadata with MultiServerFields {
|
||||
librarySectionID: librarySectionID ?? this.librarySectionID,
|
||||
ratingImage: ratingImage ?? this.ratingImage,
|
||||
audienceRatingImage: audienceRatingImage ?? this.audienceRatingImage,
|
||||
tagline: tagline ?? this.tagline,
|
||||
originalTitle: originalTitle ?? this.originalTitle,
|
||||
subtype: subtype ?? this.subtype,
|
||||
extraType: extraType ?? this.extraType,
|
||||
primaryExtraKey: primaryExtraKey ?? this.primaryExtraKey,
|
||||
|
||||
@@ -50,6 +50,8 @@ PlexMetadata _$PlexMetadataFromJson(Map<String, dynamic> json) => PlexMetadata(
|
||||
librarySectionID: (json['librarySectionID'] as num?)?.toInt(),
|
||||
ratingImage: json['ratingImage'] as String?,
|
||||
audienceRatingImage: json['audienceRatingImage'] as String?,
|
||||
tagline: json['tagline'] as String?,
|
||||
originalTitle: json['originalTitle'] as String?,
|
||||
subtype: json['subtype'] as String?,
|
||||
extraType: (json['extraType'] as num?)?.toInt(),
|
||||
primaryExtraKey: json['primaryExtraKey'] as String?,
|
||||
@@ -100,6 +102,8 @@ Map<String, dynamic> _$PlexMetadataToJson(PlexMetadata instance) => <String, dyn
|
||||
'librarySectionID': instance.librarySectionID,
|
||||
'ratingImage': instance.ratingImage,
|
||||
'audienceRatingImage': instance.audienceRatingImage,
|
||||
'tagline': instance.tagline,
|
||||
'originalTitle': instance.originalTitle,
|
||||
'subtype': instance.subtype,
|
||||
'extraType': instance.extraType,
|
||||
'primaryExtraKey': instance.primaryExtraKey,
|
||||
|
||||
@@ -47,6 +47,7 @@ import '../mixins/watch_state_aware.dart';
|
||||
import '../mixins/deletion_aware.dart';
|
||||
import '../utils/watch_state_notifier.dart';
|
||||
import '../utils/deletion_notifier.dart';
|
||||
import 'metadata_edit_screen.dart';
|
||||
import 'season_detail_screen.dart';
|
||||
|
||||
class MediaDetailScreen extends StatefulWidget {
|
||||
@@ -703,6 +704,25 @@ class _MediaDetailScreenState extends State<MediaDetailScreen> with WatchStateAw
|
||||
iconSize: 20,
|
||||
style: IconButton.styleFrom(minimumSize: const Size(48, 48), maximumSize: const Size(48, 48)),
|
||||
),
|
||||
// Edit metadata button (hidden in offline mode)
|
||||
if (!widget.isOffline) ...[
|
||||
const SizedBox(width: 12),
|
||||
IconButton.filledTonal(
|
||||
onPressed: () async {
|
||||
final result = await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => MetadataEditScreen(metadata: metadata)),
|
||||
);
|
||||
if (result == true && mounted) {
|
||||
_loadFullMetadata();
|
||||
}
|
||||
},
|
||||
icon: const AppIcon(Symbols.edit_rounded, fill: 1),
|
||||
tooltip: t.metadataEdit.editMetadata,
|
||||
iconSize: 20,
|
||||
style: IconButton.styleFrom(minimumSize: const Size(48, 48), maximumSize: const Size(48, 48)),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -0,0 +1,717 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
import '../focus/focusable_button.dart';
|
||||
import '../i18n/strings.g.dart';
|
||||
import '../models/plex_metadata.dart';
|
||||
import '../services/plex_client.dart';
|
||||
import '../utils/dialogs.dart';
|
||||
import '../utils/language_codes.dart';
|
||||
import '../utils/provider_extensions.dart';
|
||||
import '../utils/snackbar_helper.dart';
|
||||
import '../widgets/app_icon.dart';
|
||||
import '../widgets/artwork_picker_dialog.dart';
|
||||
import '../widgets/focusable_list_tile.dart';
|
||||
import '../widgets/focused_scroll_scaffold.dart';
|
||||
import '../widgets/plex_optimized_image.dart';
|
||||
|
||||
class MetadataEditScreen extends StatefulWidget {
|
||||
final PlexMetadata metadata;
|
||||
|
||||
const MetadataEditScreen({super.key, required this.metadata});
|
||||
|
||||
@override
|
||||
State<MetadataEditScreen> createState() => _MetadataEditScreenState();
|
||||
}
|
||||
|
||||
class _MetadataEditScreenState extends State<MetadataEditScreen> {
|
||||
late PlexClient _client;
|
||||
PlexMetadata? _fullMetadata;
|
||||
bool _isLoading = true;
|
||||
bool _isSaving = false;
|
||||
|
||||
// Text field values
|
||||
String? _title;
|
||||
String? _titleSort;
|
||||
String? _originalTitle;
|
||||
String? _originallyAvailableAt;
|
||||
String? _contentRating;
|
||||
String? _studio;
|
||||
String? _tagline;
|
||||
String? _summary;
|
||||
|
||||
// Original values for change detection
|
||||
String? _origTitle;
|
||||
String? _origTitleSort;
|
||||
String? _origOriginalTitle;
|
||||
String? _origOriginallyAvailableAt;
|
||||
String? _origContentRating;
|
||||
String? _origStudio;
|
||||
String? _origTagline;
|
||||
String? _origSummary;
|
||||
|
||||
// Advanced prefs (loaded from metadata JSON)
|
||||
final Map<String, String> _currentPrefs = {};
|
||||
|
||||
bool get _hasChanges =>
|
||||
_title != _origTitle ||
|
||||
_titleSort != _origTitleSort ||
|
||||
_originalTitle != _origOriginalTitle ||
|
||||
_originallyAvailableAt != _origOriginallyAvailableAt ||
|
||||
_contentRating != _origContentRating ||
|
||||
_studio != _origStudio ||
|
||||
_tagline != _origTagline ||
|
||||
_summary != _origSummary;
|
||||
|
||||
PlexMediaType get _mediaType => widget.metadata.mediaType;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_client = context.getClientWithFallback(widget.metadata.serverId);
|
||||
_loadMetadata();
|
||||
}
|
||||
|
||||
Future<void> _loadMetadata() async {
|
||||
try {
|
||||
final meta = await _client.getMetadataWithImages(widget.metadata.ratingKey);
|
||||
if (!mounted) return;
|
||||
if (meta != null) {
|
||||
_fullMetadata = meta;
|
||||
_initFieldsFromMetadata(meta);
|
||||
} else {
|
||||
_initFieldsFromMetadata(widget.metadata);
|
||||
}
|
||||
setState(() => _isLoading = false);
|
||||
} catch (e) {
|
||||
if (!mounted) return;
|
||||
_initFieldsFromMetadata(widget.metadata);
|
||||
setState(() => _isLoading = false);
|
||||
}
|
||||
}
|
||||
|
||||
void _initFieldsFromMetadata(PlexMetadata meta) {
|
||||
_title = meta.title;
|
||||
_titleSort = meta.titleSort ?? '';
|
||||
_originalTitle = meta.originalTitle ?? '';
|
||||
_originallyAvailableAt = meta.originallyAvailableAt ?? '';
|
||||
_contentRating = meta.contentRating ?? '';
|
||||
_studio = meta.studio ?? '';
|
||||
_tagline = meta.tagline ?? '';
|
||||
_summary = meta.summary ?? '';
|
||||
|
||||
_origTitle = _title;
|
||||
_origTitleSort = _titleSort;
|
||||
_origOriginalTitle = _originalTitle;
|
||||
_origOriginallyAvailableAt = _originallyAvailableAt;
|
||||
_origContentRating = _contentRating;
|
||||
_origStudio = _studio;
|
||||
_origTagline = _tagline;
|
||||
_origSummary = _summary;
|
||||
}
|
||||
|
||||
Future<void> _save() async {
|
||||
if (!_hasChanges || _isSaving) return;
|
||||
|
||||
final sectionId = _fullMetadata?.librarySectionID ?? widget.metadata.librarySectionID;
|
||||
if (sectionId == null) {
|
||||
if (mounted) showErrorSnackBar(context, t.metadataEdit.metadataUpdateFailed);
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() => _isSaving = true);
|
||||
|
||||
final success = await _client.updateMetadata(
|
||||
sectionId: sectionId,
|
||||
ratingKey: widget.metadata.ratingKey,
|
||||
typeNumber: _mediaType.typeNumber,
|
||||
title: _title != _origTitle ? _title : null,
|
||||
titleSort: _titleSort != _origTitleSort ? _titleSort : null,
|
||||
originalTitle: _originalTitle != _origOriginalTitle ? _originalTitle : null,
|
||||
originallyAvailableAt: _originallyAvailableAt != _origOriginallyAvailableAt ? _originallyAvailableAt : null,
|
||||
contentRating: _contentRating != _origContentRating ? _contentRating : null,
|
||||
studio: _studio != _origStudio ? _studio : null,
|
||||
tagline: _tagline != _origTagline ? _tagline : null,
|
||||
summary: _summary != _origSummary ? _summary : null,
|
||||
);
|
||||
|
||||
if (!mounted) return;
|
||||
setState(() => _isSaving = false);
|
||||
|
||||
if (success) {
|
||||
showSuccessSnackBar(context, t.metadataEdit.metadataUpdated);
|
||||
Navigator.pop(context, true);
|
||||
} else {
|
||||
showErrorSnackBar(context, t.metadataEdit.metadataUpdateFailed);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _editTextField({
|
||||
required String title,
|
||||
required String label,
|
||||
required String? currentValue,
|
||||
required ValueChanged<String> onChanged,
|
||||
bool multiline = false,
|
||||
}) async {
|
||||
final String? result;
|
||||
if (multiline) {
|
||||
result = await showMultilineTextInputDialog(
|
||||
context,
|
||||
title: title,
|
||||
labelText: label,
|
||||
initialValue: currentValue,
|
||||
);
|
||||
} else {
|
||||
result = await showTextInputDialog(
|
||||
context,
|
||||
title: title,
|
||||
labelText: label,
|
||||
hintText: '',
|
||||
initialValue: currentValue,
|
||||
);
|
||||
}
|
||||
|
||||
if (result != null && mounted) {
|
||||
final value = result;
|
||||
setState(() => onChanged(value));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _editDate() async {
|
||||
DateTime initial = DateTime.now();
|
||||
if (_originallyAvailableAt != null && _originallyAvailableAt!.isNotEmpty) {
|
||||
final parsed = DateTime.tryParse(_originallyAvailableAt!);
|
||||
if (parsed != null) initial = parsed;
|
||||
}
|
||||
|
||||
final picked = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: initial,
|
||||
firstDate: DateTime(1800),
|
||||
lastDate: DateTime(2200),
|
||||
);
|
||||
|
||||
if (picked != null && mounted) {
|
||||
setState(() {
|
||||
_originallyAvailableAt =
|
||||
'${picked.year}-${picked.month.toString().padLeft(2, '0')}-${picked.day.toString().padLeft(2, '0')}';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _openArtworkPicker(String element) async {
|
||||
final result = await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (context) => ArtworkPickerDialog(
|
||||
client: _client,
|
||||
ratingKey: widget.metadata.ratingKey,
|
||||
element: element,
|
||||
),
|
||||
);
|
||||
|
||||
if (result == true && mounted) {
|
||||
// Reload metadata to get updated artwork paths
|
||||
_loadMetadata();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _showAdvancedSettingDialog({
|
||||
required String title,
|
||||
required String prefKey,
|
||||
required List<({String value, String label})> options,
|
||||
}) async {
|
||||
// Determine current value from metadata or default
|
||||
final currentValue = _currentPrefs[prefKey] ?? _getMetadataPrefValue(prefKey);
|
||||
|
||||
final result = await showDialog<String>(
|
||||
context: context,
|
||||
builder: (dialogContext) {
|
||||
String? selected = currentValue;
|
||||
return StatefulBuilder(
|
||||
builder: (context, setDialogState) {
|
||||
return AlertDialog(
|
||||
title: Text(title),
|
||||
content: SizedBox(
|
||||
width: double.maxFinite,
|
||||
child: ListView(
|
||||
shrinkWrap: true,
|
||||
children: options.map((option) {
|
||||
return FocusableRadioListTile<String>(
|
||||
title: Text(option.label),
|
||||
value: option.value,
|
||||
groupValue: selected,
|
||||
onChanged: (val) {
|
||||
setDialogState(() => selected = val);
|
||||
Navigator.pop(dialogContext, val);
|
||||
},
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
FocusableButton(
|
||||
autofocus: true,
|
||||
onPressed: () => Navigator.pop(dialogContext),
|
||||
child: TextButton(
|
||||
onPressed: () => Navigator.pop(dialogContext),
|
||||
child: Text(t.common.cancel),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
if (result != null && mounted) {
|
||||
setState(() => _currentPrefs[prefKey] = result);
|
||||
await _client.updateMetadataPrefs(widget.metadata.ratingKey, {prefKey: result});
|
||||
}
|
||||
}
|
||||
|
||||
String _getMetadataPrefValue(String key) {
|
||||
// These prefs appear as keys on the raw metadata JSON when non-default.
|
||||
// Since we use typed models, we check known fields.
|
||||
final meta = _fullMetadata ?? widget.metadata;
|
||||
switch (key) {
|
||||
case 'audioLanguage':
|
||||
return meta.audioLanguage ?? '';
|
||||
case 'subtitleLanguage':
|
||||
return meta.subtitleLanguage ?? '';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
String _getDisplayValueForPref(String prefKey, List<({String value, String label})> options) {
|
||||
final val = _currentPrefs[prefKey] ?? _getMetadataPrefValue(prefKey);
|
||||
for (final option in options) {
|
||||
if (option.value == val) return option.label;
|
||||
}
|
||||
return options.first.label;
|
||||
}
|
||||
|
||||
// ===== Field visibility =====
|
||||
|
||||
bool get _showSortTitle => _mediaType != PlexMediaType.season;
|
||||
bool get _showOriginalTitle => _mediaType == PlexMediaType.movie || _mediaType == PlexMediaType.show;
|
||||
bool get _showReleaseDate => _mediaType != PlexMediaType.season;
|
||||
bool get _showContentRating => _mediaType != PlexMediaType.season;
|
||||
bool get _showStudio => _mediaType == PlexMediaType.movie || _mediaType == PlexMediaType.show;
|
||||
bool get _showTagline => _mediaType == PlexMediaType.movie || _mediaType == PlexMediaType.show;
|
||||
bool get _showBackground =>
|
||||
_mediaType == PlexMediaType.movie || _mediaType == PlexMediaType.show || _mediaType == PlexMediaType.episode;
|
||||
bool get _showAdvanced => _mediaType != PlexMediaType.episode;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (_isLoading) {
|
||||
return FocusedScrollScaffold(
|
||||
title: Text(t.metadataEdit.screenTitle),
|
||||
slivers: [const SliverFillRemaining(child: Center(child: CircularProgressIndicator()))],
|
||||
);
|
||||
}
|
||||
|
||||
return FocusedScrollScaffold(
|
||||
title: Text(t.metadataEdit.screenTitle),
|
||||
actions: [
|
||||
if (_isSaving)
|
||||
const Padding(
|
||||
padding: EdgeInsets.all(12),
|
||||
child: SizedBox(width: 24, height: 24, child: CircularProgressIndicator(strokeWidth: 2)),
|
||||
)
|
||||
else
|
||||
IconButton(
|
||||
onPressed: _hasChanges ? _save : null,
|
||||
icon: const AppIcon(Symbols.check_rounded, fill: 1),
|
||||
),
|
||||
],
|
||||
slivers: [
|
||||
SliverPadding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
sliver: SliverList(
|
||||
delegate: SliverChildListDelegate([
|
||||
_buildBasicInfoCard(),
|
||||
const SizedBox(height: 16),
|
||||
_buildArtworkCard(),
|
||||
if (_showAdvanced) ...[
|
||||
const SizedBox(height: 16),
|
||||
_buildAdvancedSettingsCard(),
|
||||
],
|
||||
]),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildBasicInfoCard() {
|
||||
return Card(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Text(
|
||||
t.metadataEdit.basicInfo,
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
_buildFieldTile(
|
||||
label: t.metadataEdit.title,
|
||||
value: _title,
|
||||
onTap: () => _editTextField(
|
||||
title: t.metadataEdit.title,
|
||||
label: t.metadataEdit.title,
|
||||
currentValue: _title,
|
||||
onChanged: (v) => _title = v,
|
||||
),
|
||||
),
|
||||
if (_showSortTitle)
|
||||
_buildFieldTile(
|
||||
label: t.metadataEdit.sortTitle,
|
||||
value: _titleSort,
|
||||
onTap: () => _editTextField(
|
||||
title: t.metadataEdit.sortTitle,
|
||||
label: t.metadataEdit.sortTitle,
|
||||
currentValue: _titleSort,
|
||||
onChanged: (v) => _titleSort = v,
|
||||
),
|
||||
),
|
||||
if (_showOriginalTitle)
|
||||
_buildFieldTile(
|
||||
label: t.metadataEdit.originalTitle,
|
||||
value: _originalTitle,
|
||||
onTap: () => _editTextField(
|
||||
title: t.metadataEdit.originalTitle,
|
||||
label: t.metadataEdit.originalTitle,
|
||||
currentValue: _originalTitle,
|
||||
onChanged: (v) => _originalTitle = v,
|
||||
),
|
||||
),
|
||||
if (_showReleaseDate)
|
||||
_buildFieldTile(
|
||||
label: t.metadataEdit.releaseDate,
|
||||
value: _originallyAvailableAt,
|
||||
onTap: _editDate,
|
||||
),
|
||||
if (_showContentRating)
|
||||
_buildFieldTile(
|
||||
label: t.metadataEdit.contentRating,
|
||||
value: _contentRating,
|
||||
onTap: () => _editTextField(
|
||||
title: t.metadataEdit.contentRating,
|
||||
label: t.metadataEdit.contentRating,
|
||||
currentValue: _contentRating,
|
||||
onChanged: (v) => _contentRating = v,
|
||||
),
|
||||
),
|
||||
if (_showStudio)
|
||||
_buildFieldTile(
|
||||
label: t.metadataEdit.studio,
|
||||
value: _studio,
|
||||
onTap: () => _editTextField(
|
||||
title: t.metadataEdit.studio,
|
||||
label: t.metadataEdit.studio,
|
||||
currentValue: _studio,
|
||||
onChanged: (v) => _studio = v,
|
||||
),
|
||||
),
|
||||
if (_showTagline)
|
||||
_buildFieldTile(
|
||||
label: t.metadataEdit.tagline,
|
||||
value: _tagline,
|
||||
onTap: () => _editTextField(
|
||||
title: t.metadataEdit.tagline,
|
||||
label: t.metadataEdit.tagline,
|
||||
currentValue: _tagline,
|
||||
onChanged: (v) => _tagline = v,
|
||||
),
|
||||
),
|
||||
_buildFieldTile(
|
||||
label: t.metadataEdit.summary,
|
||||
value: _summary,
|
||||
onTap: () => _editTextField(
|
||||
title: t.metadataEdit.summary,
|
||||
label: t.metadataEdit.summary,
|
||||
currentValue: _summary,
|
||||
onChanged: (v) => _summary = v,
|
||||
multiline: true,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildFieldTile({required String label, String? value, required VoidCallback onTap}) {
|
||||
final displayValue = (value == null || value.isEmpty) ? t.metadataEdit.notSet : value;
|
||||
final isNotSet = value == null || value.isEmpty;
|
||||
|
||||
return ListTile(
|
||||
title: Text(label),
|
||||
subtitle: Text(
|
||||
displayValue,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: isNotSet ? TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant.withValues(alpha: 0.5)) : null,
|
||||
),
|
||||
trailing: const AppIcon(Symbols.chevron_right_rounded),
|
||||
onTap: onTap,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildArtworkCard() {
|
||||
final meta = _fullMetadata ?? widget.metadata;
|
||||
|
||||
return Card(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Text(
|
||||
t.metadataEdit.artwork,
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
leading: SizedBox(
|
||||
width: 40,
|
||||
height: 60,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
child: PlexOptimizedImage(
|
||||
client: _client,
|
||||
imagePath: meta.thumb,
|
||||
width: 40,
|
||||
height: 60,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
title: Text(t.metadataEdit.poster),
|
||||
trailing: const AppIcon(Symbols.chevron_right_rounded),
|
||||
onTap: () => _openArtworkPicker('posters'),
|
||||
),
|
||||
if (_showBackground)
|
||||
ListTile(
|
||||
leading: SizedBox(
|
||||
width: 80,
|
||||
height: 45,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
child: PlexOptimizedImage(
|
||||
client: _client,
|
||||
imagePath: meta.art,
|
||||
width: 80,
|
||||
height: 45,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
title: Text(t.metadataEdit.background),
|
||||
trailing: const AppIcon(Symbols.chevron_right_rounded),
|
||||
onTap: () => _openArtworkPicker('arts'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildAdvancedSettingsCard() {
|
||||
return Card(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Text(
|
||||
t.metadataEdit.advancedSettings,
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
if (_mediaType == PlexMediaType.show) ..._buildShowAdvancedSettings(),
|
||||
if (_mediaType == PlexMediaType.movie) ..._buildMovieAdvancedSettings(),
|
||||
if (_mediaType == PlexMediaType.season) ..._buildSeasonAdvancedSettings(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> _buildShowAdvancedSettings() {
|
||||
return [
|
||||
_buildAdvancedTile(
|
||||
title: t.metadataEdit.episodeSorting,
|
||||
prefKey: 'episodeSort',
|
||||
options: [
|
||||
(value: '-1', label: t.metadataEdit.libraryDefault),
|
||||
(value: '0', label: t.metadataEdit.oldestFirst),
|
||||
(value: '1', label: t.metadataEdit.newestFirst),
|
||||
],
|
||||
),
|
||||
_buildAdvancedTile(
|
||||
title: t.metadataEdit.keep,
|
||||
prefKey: 'autoDeletionItemPolicyUnwatchedLibrary',
|
||||
options: [
|
||||
(value: '0', label: t.metadataEdit.allEpisodes),
|
||||
(value: '5', label: t.metadataEdit.latestEpisodes(count: '5')),
|
||||
(value: '3', label: t.metadataEdit.latestEpisodes(count: '3')),
|
||||
(value: '1', label: t.metadataEdit.latestEpisode),
|
||||
(value: '-3', label: t.metadataEdit.episodesAddedPastDays(count: '3')),
|
||||
(value: '-7', label: t.metadataEdit.episodesAddedPastDays(count: '7')),
|
||||
(value: '-30', label: t.metadataEdit.episodesAddedPastDays(count: '30')),
|
||||
],
|
||||
),
|
||||
_buildAdvancedTile(
|
||||
title: t.metadataEdit.deleteAfterPlaying,
|
||||
prefKey: 'autoDeletionItemPolicyWatchedLibrary',
|
||||
options: [
|
||||
(value: '0', label: t.metadataEdit.never),
|
||||
(value: '1', label: t.metadataEdit.afterADay),
|
||||
(value: '7', label: t.metadataEdit.afterAWeek),
|
||||
(value: '30', label: t.metadataEdit.afterAMonth),
|
||||
(value: '100', label: t.metadataEdit.onNextRefresh),
|
||||
],
|
||||
),
|
||||
_buildAdvancedTile(
|
||||
title: t.metadataEdit.seasons,
|
||||
prefKey: 'flattenSeasons',
|
||||
options: [
|
||||
(value: '-1', label: t.metadataEdit.libraryDefault),
|
||||
(value: '0', label: t.metadataEdit.show),
|
||||
(value: '1', label: t.metadataEdit.hide),
|
||||
],
|
||||
),
|
||||
_buildAdvancedTile(
|
||||
title: t.metadataEdit.episodeOrdering,
|
||||
prefKey: 'showOrdering',
|
||||
options: [
|
||||
(value: '', label: t.metadataEdit.libraryDefault),
|
||||
(value: 'tmdbAiring', label: t.metadataEdit.tmdbAiring),
|
||||
(value: 'tvdbAiring', label: t.metadataEdit.tvdbAiring),
|
||||
(value: 'tvdbAbsolute', label: t.metadataEdit.tvdbAbsolute),
|
||||
],
|
||||
),
|
||||
_buildAdvancedTile(
|
||||
title: t.metadataEdit.metadataLanguage,
|
||||
prefKey: 'languageOverride',
|
||||
options: _metadataLanguageOptions(t.metadataEdit.libraryDefault),
|
||||
),
|
||||
_buildAdvancedTile(
|
||||
title: t.metadataEdit.useOriginalTitle,
|
||||
prefKey: 'useOriginalTitle',
|
||||
options: [
|
||||
(value: '-1', label: t.metadataEdit.libraryDefault),
|
||||
(value: '0', label: t.common.no),
|
||||
(value: '1', label: t.common.yes),
|
||||
],
|
||||
),
|
||||
_buildAdvancedTile(
|
||||
title: t.metadataEdit.preferredAudioLanguage,
|
||||
prefKey: 'audioLanguage',
|
||||
options: _audioSubtitleLanguageOptions(t.metadataEdit.accountDefault),
|
||||
),
|
||||
_buildAdvancedTile(
|
||||
title: t.metadataEdit.preferredSubtitleLanguage,
|
||||
prefKey: 'subtitleLanguage',
|
||||
options: _audioSubtitleLanguageOptions(t.metadataEdit.accountDefault),
|
||||
),
|
||||
_buildAdvancedTile(
|
||||
title: t.metadataEdit.subtitleMode,
|
||||
prefKey: 'subtitleMode',
|
||||
options: [
|
||||
(value: '-1', label: t.metadataEdit.accountDefault),
|
||||
(value: '0', label: t.metadataEdit.manuallySelected),
|
||||
(value: '1', label: t.metadataEdit.shownWithForeignAudio),
|
||||
(value: '2', label: t.metadataEdit.alwaysEnabled),
|
||||
],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
List<Widget> _buildMovieAdvancedSettings() {
|
||||
return [
|
||||
_buildAdvancedTile(
|
||||
title: t.metadataEdit.metadataLanguage,
|
||||
prefKey: 'languageOverride',
|
||||
options: _metadataLanguageOptions(t.metadataEdit.libraryDefault),
|
||||
),
|
||||
_buildAdvancedTile(
|
||||
title: t.metadataEdit.useOriginalTitle,
|
||||
prefKey: 'useOriginalTitle',
|
||||
options: [
|
||||
(value: '-1', label: t.metadataEdit.libraryDefault),
|
||||
(value: '0', label: t.common.no),
|
||||
(value: '1', label: t.common.yes),
|
||||
],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
List<Widget> _buildSeasonAdvancedSettings() {
|
||||
return [
|
||||
_buildAdvancedTile(
|
||||
title: t.metadataEdit.preferredAudioLanguage,
|
||||
prefKey: 'audioLanguage',
|
||||
options: _audioSubtitleLanguageOptions(t.metadataEdit.seriesDefault),
|
||||
),
|
||||
_buildAdvancedTile(
|
||||
title: t.metadataEdit.preferredSubtitleLanguage,
|
||||
prefKey: 'subtitleLanguage',
|
||||
options: _audioSubtitleLanguageOptions(t.metadataEdit.seriesDefault),
|
||||
),
|
||||
_buildAdvancedTile(
|
||||
title: t.metadataEdit.subtitleMode,
|
||||
prefKey: 'subtitleMode',
|
||||
options: [
|
||||
(value: '-1', label: t.metadataEdit.seriesDefault),
|
||||
(value: '0', label: t.metadataEdit.manuallySelected),
|
||||
(value: '1', label: t.metadataEdit.shownWithForeignAudio),
|
||||
(value: '2', label: t.metadataEdit.alwaysEnabled),
|
||||
],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
Widget _buildAdvancedTile({
|
||||
required String title,
|
||||
required String prefKey,
|
||||
required List<({String value, String label})> options,
|
||||
}) {
|
||||
return ListTile(
|
||||
title: Text(title),
|
||||
subtitle: Text(_getDisplayValueForPref(prefKey, options)),
|
||||
trailing: const AppIcon(Symbols.chevron_right_rounded),
|
||||
onTap: () => _showAdvancedSettingDialog(title: title, prefKey: prefKey, options: options),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ===== Language option lists =====
|
||||
|
||||
// Plex locale codes for metadata agent language.
|
||||
const _plexLocaleCodes = [
|
||||
'ar-SA', 'bg-BG', 'ca-ES', 'zh-CN', 'zh-HK', 'zh-TW', 'hr-HR', 'cs-CZ',
|
||||
'da-DK', 'nl-NL', 'en-US', 'en-AU', 'en-CA', 'en-GB', 'et-EE', 'fi-FI',
|
||||
'fr-FR', 'fr-CA', 'de-DE', 'el-GR', 'he-IL', 'hi-IN', 'hu-HU', 'is-IS',
|
||||
'id-ID', 'it-IT', 'ja-JP', 'ko-KR', 'lv-LV', 'lt-LT', 'nb-NO', 'fa-IR',
|
||||
'pl-PL', 'pt-BR', 'pt-PT', 'ro-RO', 'ru-RU', 'sk-SK', 'es-ES', 'es-MX',
|
||||
'sv-SE', 'th-TH', 'tr-TR', 'uk-UA', 'vi-VN',
|
||||
];
|
||||
|
||||
// Common 2-letter codes shown at the top of audio/subtitle pickers.
|
||||
const _commonAudioSubtitleCodes = ['en', 'ja', 'fr', 'de', 'it', 'es', 'pt', 'ru', 'ar'];
|
||||
|
||||
List<({String value, String label})> _buildLanguageOptions(String defaultLabel, List<String> codes) {
|
||||
return [
|
||||
(value: '', label: defaultLabel),
|
||||
...codes.map((c) => (value: c, label: LanguageCodes.getDisplayName(c))),
|
||||
];
|
||||
}
|
||||
|
||||
List<({String value, String label})> _metadataLanguageOptions(String defaultLabel) =>
|
||||
_buildLanguageOptions(defaultLabel, _plexLocaleCodes);
|
||||
|
||||
List<({String value, String label})> _audioSubtitleLanguageOptions(String defaultLabel) =>
|
||||
_buildLanguageOptions(defaultLabel, [..._commonAudioSubtitleCodes, ..._plexLocaleCodes]);
|
||||
@@ -1565,6 +1565,94 @@ class PlexClient {
|
||||
);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Metadata Editing Methods
|
||||
// ============================================================================
|
||||
|
||||
/// Update metadata fields for a media item
|
||||
Future<bool> updateMetadata({
|
||||
required int sectionId,
|
||||
required String ratingKey,
|
||||
required int typeNumber,
|
||||
String? title,
|
||||
String? titleSort,
|
||||
String? originalTitle,
|
||||
String? originallyAvailableAt,
|
||||
String? contentRating,
|
||||
String? studio,
|
||||
String? tagline,
|
||||
String? summary,
|
||||
}) {
|
||||
final queryParams = <String, dynamic>{
|
||||
'type': typeNumber,
|
||||
'id': ratingKey,
|
||||
};
|
||||
|
||||
void addField(String name, String? value) {
|
||||
if (value != null) {
|
||||
queryParams['$name.value'] = value;
|
||||
queryParams['$name.locked'] = '1';
|
||||
}
|
||||
}
|
||||
|
||||
addField('title', title);
|
||||
addField('titleSort', titleSort);
|
||||
addField('originalTitle', originalTitle);
|
||||
addField('originallyAvailableAt', originallyAvailableAt);
|
||||
addField('contentRating', contentRating);
|
||||
addField('studio', studio);
|
||||
addField('tagline', tagline);
|
||||
addField('summary', summary);
|
||||
|
||||
return _wrapBoolApiCall(
|
||||
() => _dio.put('/library/sections/$sectionId/all', queryParameters: queryParams),
|
||||
'Failed to update metadata',
|
||||
);
|
||||
}
|
||||
|
||||
/// Get available artwork (posters or backgrounds) for a media item
|
||||
Future<List<Map<String, dynamic>>> getAvailableArtwork(String ratingKey, String element) async {
|
||||
try {
|
||||
final response = await _dio.get('/library/metadata/$ratingKey/$element');
|
||||
final container = _getMediaContainer(response);
|
||||
if (container != null && container['Metadata'] != null) {
|
||||
return (container['Metadata'] as List).cast<Map<String, dynamic>>();
|
||||
}
|
||||
return [];
|
||||
} catch (e) {
|
||||
appLogger.e('Failed to get available artwork', error: e);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/// Set artwork from a URL (can be a Plex internal path or external URL)
|
||||
Future<bool> setArtworkFromUrl(String ratingKey, String element, String url) {
|
||||
return _wrapBoolApiCall(
|
||||
() => _dio.post('/library/metadata/$ratingKey/$element', queryParameters: {'url': url}),
|
||||
'Failed to set artwork from URL',
|
||||
);
|
||||
}
|
||||
|
||||
/// Upload artwork from binary data
|
||||
Future<bool> uploadArtwork(String ratingKey, String element, List<int> bytes) {
|
||||
return _wrapBoolApiCall(
|
||||
() => _dio.post(
|
||||
'/library/metadata/$ratingKey/$element',
|
||||
data: bytes,
|
||||
options: Options(headers: {'Content-Length': bytes.length}),
|
||||
),
|
||||
'Failed to upload artwork',
|
||||
);
|
||||
}
|
||||
|
||||
/// Update per-media advanced preferences
|
||||
Future<bool> updateMetadataPrefs(String ratingKey, Map<String, String> prefs) {
|
||||
return _wrapBoolApiCall(
|
||||
() => _dio.put('/library/metadata/$ratingKey/prefs', queryParameters: prefs),
|
||||
'Failed to update metadata preferences',
|
||||
);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Collection Methods
|
||||
// ============================================================================
|
||||
|
||||
@@ -135,6 +135,81 @@ Future<String?> showTextInputDialog(
|
||||
);
|
||||
}
|
||||
|
||||
/// Shows a multiline text input dialog for editing longer text like summaries.
|
||||
/// Returns the entered text, or null if cancelled.
|
||||
/// Allows empty text to be submitted (for clearing fields).
|
||||
Future<String?> showMultilineTextInputDialog(
|
||||
BuildContext context, {
|
||||
required String title,
|
||||
required String labelText,
|
||||
String? initialValue,
|
||||
}) {
|
||||
return showDialog<String>(
|
||||
context: context,
|
||||
builder: (context) => _MultilineTextInputDialog(title: title, labelText: labelText, initialValue: initialValue),
|
||||
);
|
||||
}
|
||||
|
||||
class _MultilineTextInputDialog extends StatefulWidget {
|
||||
final String title;
|
||||
final String labelText;
|
||||
final String? initialValue;
|
||||
|
||||
const _MultilineTextInputDialog({required this.title, required this.labelText, this.initialValue});
|
||||
|
||||
@override
|
||||
State<_MultilineTextInputDialog> createState() => _MultilineTextInputDialogState();
|
||||
}
|
||||
|
||||
class _MultilineTextInputDialogState extends State<_MultilineTextInputDialog> {
|
||||
late final TextEditingController _controller;
|
||||
final _saveFocusNode = FocusNode();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = TextEditingController(text: widget.initialValue);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller.dispose();
|
||||
_saveFocusNode.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text(widget.title),
|
||||
content: SizedBox(
|
||||
width: 400,
|
||||
child: TextField(
|
||||
controller: _controller,
|
||||
autofocus: true,
|
||||
decoration: InputDecoration(labelText: widget.labelText),
|
||||
maxLines: 8,
|
||||
minLines: 3,
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
FocusableButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: TextButton(onPressed: () => Navigator.pop(context), child: Text(t.common.cancel)),
|
||||
),
|
||||
FocusableButton(
|
||||
focusNode: _saveFocusNode,
|
||||
onPressed: () => Navigator.pop(context, _controller.text),
|
||||
child: TextButton(
|
||||
onPressed: () => Navigator.pop(context, _controller.text),
|
||||
child: Text(t.common.save),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _TextInputDialog extends StatefulWidget {
|
||||
final String title;
|
||||
final String labelText;
|
||||
|
||||
@@ -70,6 +70,38 @@ class LanguageCodes {
|
||||
return variations.toList();
|
||||
}
|
||||
|
||||
/// Get a display name for a language/locale code.
|
||||
/// Handles plain codes ("en" → "English") and locale codes ("en-US" → "English",
|
||||
/// "en-AU" → "English (Australia)").
|
||||
/// Uses [_regionNames] for the country qualifier on non-primary variants.
|
||||
static String getDisplayName(String code) {
|
||||
if (code.isEmpty) return code;
|
||||
|
||||
// Plain language code (e.g. "en", "ja")
|
||||
if (!code.contains('-')) {
|
||||
return getLanguageName(code) ?? code;
|
||||
}
|
||||
|
||||
// Locale code (e.g. "en-US", "zh-TW")
|
||||
final parts = code.split('-');
|
||||
final langName = getLanguageName(parts[0]) ?? parts[0];
|
||||
final region = parts.length > 1 ? _regionNames[parts[1]] : null;
|
||||
return region != null ? '$langName ($region)' : langName;
|
||||
}
|
||||
|
||||
// Region qualifiers for Plex locale codes that differ from the primary variant.
|
||||
// Only entries where Plex shows a country qualifier in its UI are listed.
|
||||
static const _regionNames = <String, String>{
|
||||
'AU': 'Australia',
|
||||
'BR': 'Brazil',
|
||||
'CA': 'Canada',
|
||||
'GB': 'UK',
|
||||
'HK': 'Hong Kong',
|
||||
'MX': 'Mexico',
|
||||
'PT': 'Portugal',
|
||||
'TW': 'Taiwan',
|
||||
};
|
||||
|
||||
/// Get the English name of a language from its code
|
||||
static String? getLanguageName(String languageCode) {
|
||||
if (_codes == null) return null;
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
import '../focus/focusable_button.dart';
|
||||
import '../focus/focusable_wrapper.dart';
|
||||
import '../i18n/strings.g.dart';
|
||||
import '../services/plex_client.dart';
|
||||
import '../utils/dialogs.dart';
|
||||
import '../utils/snackbar_helper.dart';
|
||||
import '../widgets/app_icon.dart';
|
||||
import '../widgets/plex_optimized_image.dart';
|
||||
|
||||
class ArtworkPickerDialog extends StatefulWidget {
|
||||
final PlexClient client;
|
||||
final String ratingKey;
|
||||
final String element; // "posters" or "arts"
|
||||
|
||||
const ArtworkPickerDialog({
|
||||
super.key,
|
||||
required this.client,
|
||||
required this.ratingKey,
|
||||
required this.element,
|
||||
});
|
||||
|
||||
@override
|
||||
State<ArtworkPickerDialog> createState() => _ArtworkPickerDialogState();
|
||||
}
|
||||
|
||||
class _ArtworkPickerDialogState extends State<ArtworkPickerDialog> {
|
||||
List<Map<String, dynamic>>? _artworkList;
|
||||
bool _isLoading = true;
|
||||
bool _isApplying = false;
|
||||
|
||||
bool get _isPosters => widget.element == 'posters';
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadArtwork();
|
||||
}
|
||||
|
||||
Future<void> _loadArtwork() async {
|
||||
final artwork = await widget.client.getAvailableArtwork(widget.ratingKey, widget.element);
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
_artworkList = artwork;
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _selectArtwork(Map<String, dynamic> artwork) async {
|
||||
final key = artwork['key'] as String?;
|
||||
if (key == null || _isApplying) return;
|
||||
|
||||
setState(() => _isApplying = true);
|
||||
|
||||
final success = await widget.client.setArtworkFromUrl(widget.ratingKey, widget.element, key);
|
||||
|
||||
if (!mounted) return;
|
||||
setState(() => _isApplying = false);
|
||||
|
||||
if (success) {
|
||||
showSuccessSnackBar(context, t.metadataEdit.artworkUpdated);
|
||||
Navigator.pop(context, true);
|
||||
} else {
|
||||
showErrorSnackBar(context, t.metadataEdit.artworkUpdateFailed);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _addFromUrl() async {
|
||||
final url = await showTextInputDialog(
|
||||
context,
|
||||
title: t.metadataEdit.fromUrl,
|
||||
labelText: t.metadataEdit.imageUrl,
|
||||
hintText: t.metadataEdit.enterImageUrl,
|
||||
);
|
||||
|
||||
if (url == null || url.isEmpty || !mounted) return;
|
||||
|
||||
setState(() => _isApplying = true);
|
||||
|
||||
final success = await widget.client.setArtworkFromUrl(widget.ratingKey, widget.element, url);
|
||||
|
||||
if (!mounted) return;
|
||||
setState(() => _isApplying = false);
|
||||
|
||||
if (success) {
|
||||
showSuccessSnackBar(context, t.metadataEdit.artworkUpdated);
|
||||
Navigator.pop(context, true);
|
||||
} else {
|
||||
showErrorSnackBar(context, t.metadataEdit.artworkUpdateFailed);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _uploadFile() async {
|
||||
final result = await FilePicker.platform.pickFiles(
|
||||
type: FileType.image,
|
||||
withData: true,
|
||||
);
|
||||
|
||||
if (result == null || result.files.isEmpty || !mounted) return;
|
||||
|
||||
final bytes = result.files.first.bytes;
|
||||
if (bytes == null) return;
|
||||
|
||||
setState(() => _isApplying = true);
|
||||
|
||||
final success = await widget.client.uploadArtwork(widget.ratingKey, widget.element, bytes);
|
||||
|
||||
if (!mounted) return;
|
||||
setState(() => _isApplying = false);
|
||||
|
||||
if (success) {
|
||||
showSuccessSnackBar(context, t.metadataEdit.artworkUpdated);
|
||||
Navigator.pop(context, true);
|
||||
} else {
|
||||
showErrorSnackBar(context, t.metadataEdit.artworkUpdateFailed);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final title = _isPosters ? t.metadataEdit.selectPoster : t.metadataEdit.selectBackground;
|
||||
|
||||
return AlertDialog(
|
||||
title: Text(title),
|
||||
content: SizedBox(
|
||||
width: 500,
|
||||
height: 400,
|
||||
child: _isLoading
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: _artworkList == null || _artworkList!.isEmpty
|
||||
? Center(child: Text(t.metadataEdit.noArtworkAvailable))
|
||||
: _buildGrid(),
|
||||
),
|
||||
actions: [
|
||||
if (_isApplying)
|
||||
const Padding(
|
||||
padding: EdgeInsets.all(8),
|
||||
child: SizedBox(width: 24, height: 24, child: CircularProgressIndicator(strokeWidth: 2)),
|
||||
),
|
||||
FocusableButton(
|
||||
onPressed: _addFromUrl,
|
||||
child: TextButton.icon(
|
||||
onPressed: _addFromUrl,
|
||||
icon: const AppIcon(Symbols.link_rounded, size: 18),
|
||||
label: Text(t.metadataEdit.fromUrl),
|
||||
),
|
||||
),
|
||||
FocusableButton(
|
||||
onPressed: _uploadFile,
|
||||
child: TextButton.icon(
|
||||
onPressed: _uploadFile,
|
||||
icon: const AppIcon(Symbols.upload_rounded, size: 18),
|
||||
label: Text(t.metadataEdit.uploadFile),
|
||||
),
|
||||
),
|
||||
FocusableButton(
|
||||
autofocus: true,
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: Text(t.common.cancel),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildGrid() {
|
||||
final crossAxisCount = _isPosters ? 3 : 2;
|
||||
final aspectRatio = _isPosters ? 2.0 / 3.0 : 16.0 / 9.0;
|
||||
|
||||
return GridView.builder(
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
crossAxisCount: crossAxisCount,
|
||||
crossAxisSpacing: 8,
|
||||
mainAxisSpacing: 8,
|
||||
childAspectRatio: aspectRatio,
|
||||
),
|
||||
itemCount: _artworkList!.length,
|
||||
itemBuilder: (context, index) {
|
||||
final artwork = _artworkList![index];
|
||||
final thumbUrl = artwork['thumb'] as String?;
|
||||
final isSelected = artwork['selected'] == true;
|
||||
|
||||
return FocusableWrapper(
|
||||
borderRadius: 8,
|
||||
onSelect: () => _selectArtwork(artwork),
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surfaceContainerHighest,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: PlexOptimizedImage(
|
||||
client: widget.client,
|
||||
imagePath: thumbUrl,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (isSelected)
|
||||
Positioned(
|
||||
right: 6,
|
||||
bottom: 6,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(4),
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(Symbols.check_rounded, size: 16, color: Theme.of(context).colorScheme.onPrimary),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import '../services/external_player_service.dart';
|
||||
import '../focus/focusable_button.dart';
|
||||
import '../focus/dpad_navigator.dart';
|
||||
import '../screens/media_detail_screen.dart';
|
||||
import '../screens/metadata_edit_screen.dart';
|
||||
import '../screens/season_detail_screen.dart';
|
||||
import '../utils/smart_deletion_handler.dart';
|
||||
import '../utils/deletion_notifier.dart';
|
||||
@@ -199,6 +200,16 @@ class MediaContextMenuState extends State<MediaContextMenu> {
|
||||
);
|
||||
}
|
||||
|
||||
// Edit Metadata (for movies, shows, seasons, and episodes)
|
||||
if (mediaType == PlexMediaType.movie ||
|
||||
mediaType == PlexMediaType.show ||
|
||||
mediaType == PlexMediaType.season ||
|
||||
mediaType == PlexMediaType.episode) {
|
||||
menuActions.add(
|
||||
_MenuAction(value: 'edit_metadata', icon: Symbols.edit_rounded, label: t.metadataEdit.editMetadata),
|
||||
);
|
||||
}
|
||||
|
||||
// Remove from Collection (only when viewing items within a collection)
|
||||
if (widget.collectionId != null) {
|
||||
menuActions.add(
|
||||
@@ -415,6 +426,17 @@ class MediaContextMenuState extends State<MediaContextMenu> {
|
||||
}
|
||||
break;
|
||||
|
||||
case 'edit_metadata':
|
||||
didNavigate = true;
|
||||
if (context.mounted) {
|
||||
await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => MetadataEditScreen(metadata: metadata!)),
|
||||
);
|
||||
widget.onRefresh?.call(metadata!.ratingKey);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'remove_from_collection':
|
||||
await _handleRemoveFromCollection(context, metadata!);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user