@@ -347,6 +347,19 @@
|
||||
"playFromBeginning": "Afspil fra begyndelsen",
|
||||
"playVersion": "Afspil version..."
|
||||
},
|
||||
"rateSheet": {
|
||||
"title": "Bedøm",
|
||||
"server": "Server",
|
||||
"starValue": "${rating} / 5",
|
||||
"scoreValue": "${score} / 10",
|
||||
"setScore": "Angiv en score",
|
||||
"notRated": "Ikke bedømt",
|
||||
"liked": "Synes godt om",
|
||||
"notLiked": "Ikke liket",
|
||||
"saved": "Gemt",
|
||||
"notAvailable": "Intet match fundet",
|
||||
"noConnectedTrackers": "Forbind en tracker i Indstillinger for at bedømme der."
|
||||
},
|
||||
"accessibility": {
|
||||
"mediaCardMovie": "${title}, film",
|
||||
"mediaCardShow": "${title}, TV-serie",
|
||||
|
||||
@@ -347,6 +347,19 @@
|
||||
"playFromBeginning": "Von Anfang an abspielen",
|
||||
"playVersion": "Version abspielen..."
|
||||
},
|
||||
"rateSheet": {
|
||||
"title": "Bewerten",
|
||||
"server": "Server",
|
||||
"starValue": "${rating} / 5",
|
||||
"scoreValue": "${score} / 10",
|
||||
"setScore": "Eine Wertung festlegen",
|
||||
"notRated": "Nicht bewertet",
|
||||
"liked": "Gefällt mir",
|
||||
"notLiked": "Nicht geliket",
|
||||
"saved": "Gespeichert",
|
||||
"notAvailable": "Keine Übereinstimmung gefunden",
|
||||
"noConnectedTrackers": "Verbinde einen Tracker in den Einstellungen, um dort zu bewerten."
|
||||
},
|
||||
"accessibility": {
|
||||
"mediaCardMovie": "${title}, Film",
|
||||
"mediaCardShow": "${title}, Serie",
|
||||
|
||||
@@ -347,6 +347,19 @@
|
||||
"playFromBeginning": "Play from Beginning",
|
||||
"playVersion": "Play Version..."
|
||||
},
|
||||
"rateSheet": {
|
||||
"title": "Rate",
|
||||
"server": "Server",
|
||||
"starValue": "${rating} / 5",
|
||||
"scoreValue": "${score} / 10",
|
||||
"setScore": "Set a score",
|
||||
"notRated": "Not rated",
|
||||
"liked": "Liked",
|
||||
"notLiked": "Not liked",
|
||||
"saved": "Saved",
|
||||
"notAvailable": "No match found",
|
||||
"noConnectedTrackers": "Connect a tracker in Settings to rate there."
|
||||
},
|
||||
"accessibility": {
|
||||
"mediaCardMovie": "${title}, movie",
|
||||
"mediaCardShow": "${title}, TV show",
|
||||
|
||||
@@ -347,6 +347,19 @@
|
||||
"playFromBeginning": "Reproducir desde el inicio",
|
||||
"playVersion": "Reproducir versión..."
|
||||
},
|
||||
"rateSheet": {
|
||||
"title": "Calificar",
|
||||
"server": "Servidor",
|
||||
"starValue": "${rating} / 5",
|
||||
"scoreValue": "${score} / 10",
|
||||
"setScore": "Establecer puntuación",
|
||||
"notRated": "Sin calificar",
|
||||
"liked": "Me gusta",
|
||||
"notLiked": "Sin Me gusta",
|
||||
"saved": "Guardado",
|
||||
"notAvailable": "No se encontró coincidencia",
|
||||
"noConnectedTrackers": "Conecta un tracker en Ajustes para calificar allí."
|
||||
},
|
||||
"accessibility": {
|
||||
"mediaCardMovie": "${title}, película",
|
||||
"mediaCardShow": "${title}, serie de TV",
|
||||
|
||||
@@ -347,6 +347,19 @@
|
||||
"playFromBeginning": "Lire depuis le début",
|
||||
"playVersion": "Lire la version..."
|
||||
},
|
||||
"rateSheet": {
|
||||
"title": "Noter",
|
||||
"server": "Serveur",
|
||||
"starValue": "${rating} / 5",
|
||||
"scoreValue": "${score} / 10",
|
||||
"setScore": "Définir une note",
|
||||
"notRated": "Non noté",
|
||||
"liked": "Aimé",
|
||||
"notLiked": "Non aimé",
|
||||
"saved": "Enregistré",
|
||||
"notAvailable": "Aucune correspondance trouvée",
|
||||
"noConnectedTrackers": "Connectez un tracker dans Paramètres pour y noter."
|
||||
},
|
||||
"accessibility": {
|
||||
"mediaCardMovie": "${title}, film",
|
||||
"mediaCardShow": "${title}, show TV",
|
||||
|
||||
@@ -347,6 +347,19 @@
|
||||
"playFromBeginning": "Riproduci dall'inizio",
|
||||
"playVersion": "Riproduci versione..."
|
||||
},
|
||||
"rateSheet": {
|
||||
"title": "Valuta",
|
||||
"server": "Server",
|
||||
"starValue": "${rating} / 5",
|
||||
"scoreValue": "${score} / 10",
|
||||
"setScore": "Imposta un punteggio",
|
||||
"notRated": "Non valutato",
|
||||
"liked": "Mi piace",
|
||||
"notLiked": "Non contrassegnato con Mi piace",
|
||||
"saved": "Salvato",
|
||||
"notAvailable": "Nessuna corrispondenza trovata",
|
||||
"noConnectedTrackers": "Collega un tracker in Impostazioni per valutarlo lì."
|
||||
},
|
||||
"accessibility": {
|
||||
"mediaCardMovie": "${title}, film",
|
||||
"mediaCardShow": "${title}, serie TV",
|
||||
|
||||
@@ -347,6 +347,19 @@
|
||||
"playFromBeginning": "最初から再生",
|
||||
"playVersion": "バージョンを再生..."
|
||||
},
|
||||
"rateSheet": {
|
||||
"title": "評価",
|
||||
"server": "サーバー",
|
||||
"starValue": "${rating} / 5",
|
||||
"scoreValue": "${score} / 10",
|
||||
"setScore": "スコアを設定",
|
||||
"notRated": "未評価",
|
||||
"liked": "いいね済み",
|
||||
"notLiked": "いいねなし",
|
||||
"saved": "保存済み",
|
||||
"notAvailable": "一致なし",
|
||||
"noConnectedTrackers": "設定でトラッカーを接続すると、そこで評価できます。"
|
||||
},
|
||||
"accessibility": {
|
||||
"mediaCardMovie": "${title}、映画",
|
||||
"mediaCardShow": "${title}、テレビ番組",
|
||||
|
||||
@@ -347,6 +347,19 @@
|
||||
"playFromBeginning": "처음부터 재생",
|
||||
"playVersion": "버전 재생..."
|
||||
},
|
||||
"rateSheet": {
|
||||
"title": "평가",
|
||||
"server": "서버",
|
||||
"starValue": "${rating} / 5",
|
||||
"scoreValue": "${score} / 10",
|
||||
"setScore": "점수 설정",
|
||||
"notRated": "평가 없음",
|
||||
"liked": "좋아요",
|
||||
"notLiked": "좋아요 아님",
|
||||
"saved": "저장됨",
|
||||
"notAvailable": "일치 항목 없음",
|
||||
"noConnectedTrackers": "설정에서 트래커를 연결하면 거기에도 평가할 수 있습니다."
|
||||
},
|
||||
"accessibility": {
|
||||
"mediaCardMovie": "${title}, 영화",
|
||||
"mediaCardShow": "${title}, TV 프로그램",
|
||||
|
||||
@@ -347,6 +347,19 @@
|
||||
"playFromBeginning": "Spill fra begynnelsen",
|
||||
"playVersion": "Spill av versjon..."
|
||||
},
|
||||
"rateSheet": {
|
||||
"title": "Vurder",
|
||||
"server": "Server",
|
||||
"starValue": "${rating} / 5",
|
||||
"scoreValue": "${score} / 10",
|
||||
"setScore": "Sett en poengsum",
|
||||
"notRated": "Ikke vurdert",
|
||||
"liked": "Likt",
|
||||
"notLiked": "Ikke likt",
|
||||
"saved": "Lagret",
|
||||
"notAvailable": "Ingen treff",
|
||||
"noConnectedTrackers": "Koble til en sporer i Innstillinger for å vurdere der."
|
||||
},
|
||||
"accessibility": {
|
||||
"mediaCardMovie": "${title}, film",
|
||||
"mediaCardShow": "${title}, TV-serie",
|
||||
|
||||
@@ -347,6 +347,19 @@
|
||||
"playFromBeginning": "Afspelen vanaf het begin",
|
||||
"playVersion": "Versie afspelen..."
|
||||
},
|
||||
"rateSheet": {
|
||||
"title": "Beoordelen",
|
||||
"server": "Server",
|
||||
"starValue": "${rating} / 5",
|
||||
"scoreValue": "${score} / 10",
|
||||
"setScore": "Score instellen",
|
||||
"notRated": "Niet beoordeeld",
|
||||
"liked": "Geliket",
|
||||
"notLiked": "Niet geliket",
|
||||
"saved": "Opgeslagen",
|
||||
"notAvailable": "Geen match gevonden",
|
||||
"noConnectedTrackers": "Verbind een tracker in Instellingen om daar te beoordelen."
|
||||
},
|
||||
"accessibility": {
|
||||
"mediaCardMovie": "${title}, film",
|
||||
"mediaCardShow": "${title}, TV-serie",
|
||||
|
||||
@@ -347,6 +347,19 @@
|
||||
"playFromBeginning": "Odtwórz od początku",
|
||||
"playVersion": "Odtwórz wersję..."
|
||||
},
|
||||
"rateSheet": {
|
||||
"title": "Oceń",
|
||||
"server": "Serwer",
|
||||
"starValue": "${rating} / 5",
|
||||
"scoreValue": "${score} / 10",
|
||||
"setScore": "Ustaw ocenę",
|
||||
"notRated": "Nie oceniono",
|
||||
"liked": "Polubione",
|
||||
"notLiked": "Nie polubiono",
|
||||
"saved": "Zapisano",
|
||||
"notAvailable": "Nie znaleziono dopasowania",
|
||||
"noConnectedTrackers": "Połącz tracker w Ustawieniach, aby tam oceniać."
|
||||
},
|
||||
"accessibility": {
|
||||
"mediaCardMovie": "${title}, film",
|
||||
"mediaCardShow": "${title}, serial TV",
|
||||
|
||||
@@ -347,6 +347,19 @@
|
||||
"playFromBeginning": "Reproduzir do início",
|
||||
"playVersion": "Reproduzir versão..."
|
||||
},
|
||||
"rateSheet": {
|
||||
"title": "Avaliar",
|
||||
"server": "Servidor",
|
||||
"starValue": "${rating} / 5",
|
||||
"scoreValue": "${score} / 10",
|
||||
"setScore": "Definir pontuação",
|
||||
"notRated": "Sem avaliação",
|
||||
"liked": "Gostei",
|
||||
"notLiked": "Não marcado como gostei",
|
||||
"saved": "Salvo",
|
||||
"notAvailable": "Nenhuma correspondência encontrada",
|
||||
"noConnectedTrackers": "Conecte um rastreador em Configurações para avaliar lá."
|
||||
},
|
||||
"accessibility": {
|
||||
"mediaCardMovie": "${title}, filme",
|
||||
"mediaCardShow": "${title}, série de TV",
|
||||
|
||||
@@ -347,6 +347,19 @@
|
||||
"playFromBeginning": "Воспроизвести сначала",
|
||||
"playVersion": "Воспроизвести версию..."
|
||||
},
|
||||
"rateSheet": {
|
||||
"title": "Оценить",
|
||||
"server": "Сервер",
|
||||
"starValue": "${rating} / 5",
|
||||
"scoreValue": "${score} / 10",
|
||||
"setScore": "Установить оценку",
|
||||
"notRated": "Без оценки",
|
||||
"liked": "Понравилось",
|
||||
"notLiked": "Не отмечено понравившимся",
|
||||
"saved": "Сохранено",
|
||||
"notAvailable": "Совпадений не найдено",
|
||||
"noConnectedTrackers": "Подключите трекер в настройках, чтобы оценивать там."
|
||||
},
|
||||
"accessibility": {
|
||||
"mediaCardMovie": "${title}, фильм",
|
||||
"mediaCardShow": "${title}, сериал",
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
/// To regenerate, run: `dart run slang`
|
||||
///
|
||||
/// Locales: 15
|
||||
/// Strings: 17295 (1153 per locale)
|
||||
/// Strings: 17460 (1164 per locale)
|
||||
///
|
||||
/// Built on 2026-05-13 at 05:26 UTC
|
||||
/// Built on 2026-05-16 at 13:41 UTC
|
||||
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint, unused_import
|
||||
|
||||
@@ -49,6 +49,7 @@ class TranslationsDa extends Translations with BaseTranslations<AppLocale, Trans
|
||||
@override late final _TranslationsHotkeysDa hotkeys = _TranslationsHotkeysDa._(_root);
|
||||
@override late final _TranslationsFileInfoDa fileInfo = _TranslationsFileInfoDa._(_root);
|
||||
@override late final _TranslationsMediaMenuDa mediaMenu = _TranslationsMediaMenuDa._(_root);
|
||||
@override late final _TranslationsRateSheetDa rateSheet = _TranslationsRateSheetDa._(_root);
|
||||
@override late final _TranslationsAccessibilityDa accessibility = _TranslationsAccessibilityDa._(_root);
|
||||
@override late final _TranslationsTooltipsDa tooltips = _TranslationsTooltipsDa._(_root);
|
||||
@override late final _TranslationsVideoControlsDa videoControls = _TranslationsVideoControlsDa._(_root);
|
||||
@@ -481,6 +482,26 @@ class _TranslationsMediaMenuDa extends TranslationsMediaMenuEn {
|
||||
@override String get playVersion => 'Afspil version...';
|
||||
}
|
||||
|
||||
// Path: rateSheet
|
||||
class _TranslationsRateSheetDa extends TranslationsRateSheetEn {
|
||||
_TranslationsRateSheetDa._(TranslationsDa root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsDa _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Bedøm';
|
||||
@override String get server => 'Server';
|
||||
@override String starValue({required Object rating}) => '${rating} / 5';
|
||||
@override String scoreValue({required Object score}) => '${score} / 10';
|
||||
@override String get setScore => 'Angiv en score';
|
||||
@override String get notRated => 'Ikke bedømt';
|
||||
@override String get liked => 'Synes godt om';
|
||||
@override String get notLiked => 'Ikke liket';
|
||||
@override String get saved => 'Gemt';
|
||||
@override String get notAvailable => 'Intet match fundet';
|
||||
@override String get noConnectedTrackers => 'Forbind en tracker i Indstillinger for at bedømme der.';
|
||||
}
|
||||
|
||||
// Path: accessibility
|
||||
class _TranslationsAccessibilityDa extends TranslationsAccessibilityEn {
|
||||
_TranslationsAccessibilityDa._(TranslationsDa root) : this._root = root, super.internal(root);
|
||||
@@ -2098,6 +2119,17 @@ extension on TranslationsDa {
|
||||
'mediaMenu.rate' => 'Bedøm',
|
||||
'mediaMenu.playFromBeginning' => 'Afspil fra begyndelsen',
|
||||
'mediaMenu.playVersion' => 'Afspil version...',
|
||||
'rateSheet.title' => 'Bedøm',
|
||||
'rateSheet.server' => 'Server',
|
||||
'rateSheet.starValue' => ({required Object rating}) => '${rating} / 5',
|
||||
'rateSheet.scoreValue' => ({required Object score}) => '${score} / 10',
|
||||
'rateSheet.setScore' => 'Angiv en score',
|
||||
'rateSheet.notRated' => 'Ikke bedømt',
|
||||
'rateSheet.liked' => 'Synes godt om',
|
||||
'rateSheet.notLiked' => 'Ikke liket',
|
||||
'rateSheet.saved' => 'Gemt',
|
||||
'rateSheet.notAvailable' => 'Intet match fundet',
|
||||
'rateSheet.noConnectedTrackers' => 'Forbind en tracker i Indstillinger for at bedømme der.',
|
||||
'accessibility.mediaCardMovie' => ({required Object title}) => '${title}, film',
|
||||
'accessibility.mediaCardShow' => ({required Object title}) => '${title}, TV-serie',
|
||||
'accessibility.mediaCardEpisode' => ({required Object title, required Object episodeInfo}) => '${title}, ${episodeInfo}',
|
||||
@@ -2273,6 +2305,8 @@ extension on TranslationsDa {
|
||||
'profiles.summaryMultiple' => ({required Object count}) => '${count} profiler',
|
||||
'profiles.removeConnectionTitle' => 'Fjern forbindelse?',
|
||||
'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Fjern ${displayName}s adgang til ${connectionLabel}. Andre profiler beholder den.',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.deleteProfileTitle' => 'Slet profil?',
|
||||
'profiles.deleteProfileMessage' => ({required Object displayName}) => 'Fjern ${displayName} og forbindelserne. Servere forbliver tilgængelige.',
|
||||
'profiles.profileNameLabel' => 'Profilnavn',
|
||||
@@ -2284,8 +2318,6 @@ extension on TranslationsDa {
|
||||
'profiles.confirmPinTitle' => 'Bekræft PIN',
|
||||
'profiles.pinSet' => 'PIN angivet',
|
||||
'profiles.changePin' => 'Skift',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.removePin' => 'Fjern',
|
||||
'profiles.connectionsLabel' => 'Forbindelser',
|
||||
'profiles.add' => 'Tilføj',
|
||||
@@ -2787,6 +2819,8 @@ extension on TranslationsDa {
|
||||
'metadataEdit.selectSquareArt' => 'Vælg kvadratisk billede',
|
||||
'metadataEdit.fromUrl' => 'Fra URL',
|
||||
'metadataEdit.uploadFile' => 'Upload fil',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.enterImageUrl' => 'Indtast billed-URL',
|
||||
'metadataEdit.imageUrl' => 'Billed-URL',
|
||||
'metadataEdit.metadataUpdated' => 'Metadata opdateret',
|
||||
@@ -2798,8 +2832,6 @@ extension on TranslationsDa {
|
||||
'metadataEdit.libraryDefault' => 'Biblioteksstandard',
|
||||
'metadataEdit.accountDefault' => 'Kontostandard',
|
||||
'metadataEdit.seriesDefault' => 'Seriestandard',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.episodeSorting' => 'Episodesortering',
|
||||
'metadataEdit.oldestFirst' => 'Ældste først',
|
||||
'metadataEdit.newestFirst' => 'Nyeste først',
|
||||
|
||||
@@ -49,6 +49,7 @@ class TranslationsDe extends Translations with BaseTranslations<AppLocale, Trans
|
||||
@override late final _TranslationsHotkeysDe hotkeys = _TranslationsHotkeysDe._(_root);
|
||||
@override late final _TranslationsFileInfoDe fileInfo = _TranslationsFileInfoDe._(_root);
|
||||
@override late final _TranslationsMediaMenuDe mediaMenu = _TranslationsMediaMenuDe._(_root);
|
||||
@override late final _TranslationsRateSheetDe rateSheet = _TranslationsRateSheetDe._(_root);
|
||||
@override late final _TranslationsAccessibilityDe accessibility = _TranslationsAccessibilityDe._(_root);
|
||||
@override late final _TranslationsTooltipsDe tooltips = _TranslationsTooltipsDe._(_root);
|
||||
@override late final _TranslationsVideoControlsDe videoControls = _TranslationsVideoControlsDe._(_root);
|
||||
@@ -481,6 +482,26 @@ class _TranslationsMediaMenuDe extends TranslationsMediaMenuEn {
|
||||
@override String get playVersion => 'Version abspielen...';
|
||||
}
|
||||
|
||||
// Path: rateSheet
|
||||
class _TranslationsRateSheetDe extends TranslationsRateSheetEn {
|
||||
_TranslationsRateSheetDe._(TranslationsDe root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsDe _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Bewerten';
|
||||
@override String get server => 'Server';
|
||||
@override String starValue({required Object rating}) => '${rating} / 5';
|
||||
@override String scoreValue({required Object score}) => '${score} / 10';
|
||||
@override String get setScore => 'Eine Wertung festlegen';
|
||||
@override String get notRated => 'Nicht bewertet';
|
||||
@override String get liked => 'Gefällt mir';
|
||||
@override String get notLiked => 'Nicht geliket';
|
||||
@override String get saved => 'Gespeichert';
|
||||
@override String get notAvailable => 'Keine Übereinstimmung gefunden';
|
||||
@override String get noConnectedTrackers => 'Verbinde einen Tracker in den Einstellungen, um dort zu bewerten.';
|
||||
}
|
||||
|
||||
// Path: accessibility
|
||||
class _TranslationsAccessibilityDe extends TranslationsAccessibilityEn {
|
||||
_TranslationsAccessibilityDe._(TranslationsDe root) : this._root = root, super.internal(root);
|
||||
@@ -2098,6 +2119,17 @@ extension on TranslationsDe {
|
||||
'mediaMenu.rate' => 'Bewerten',
|
||||
'mediaMenu.playFromBeginning' => 'Von Anfang an abspielen',
|
||||
'mediaMenu.playVersion' => 'Version abspielen...',
|
||||
'rateSheet.title' => 'Bewerten',
|
||||
'rateSheet.server' => 'Server',
|
||||
'rateSheet.starValue' => ({required Object rating}) => '${rating} / 5',
|
||||
'rateSheet.scoreValue' => ({required Object score}) => '${score} / 10',
|
||||
'rateSheet.setScore' => 'Eine Wertung festlegen',
|
||||
'rateSheet.notRated' => 'Nicht bewertet',
|
||||
'rateSheet.liked' => 'Gefällt mir',
|
||||
'rateSheet.notLiked' => 'Nicht geliket',
|
||||
'rateSheet.saved' => 'Gespeichert',
|
||||
'rateSheet.notAvailable' => 'Keine Übereinstimmung gefunden',
|
||||
'rateSheet.noConnectedTrackers' => 'Verbinde einen Tracker in den Einstellungen, um dort zu bewerten.',
|
||||
'accessibility.mediaCardMovie' => ({required Object title}) => '${title}, Film',
|
||||
'accessibility.mediaCardShow' => ({required Object title}) => '${title}, Serie',
|
||||
'accessibility.mediaCardEpisode' => ({required Object title, required Object episodeInfo}) => '${title}, ${episodeInfo}',
|
||||
@@ -2273,6 +2305,8 @@ extension on TranslationsDe {
|
||||
'profiles.summaryMultiple' => ({required Object count}) => '${count} Profile',
|
||||
'profiles.removeConnectionTitle' => 'Verbindung entfernen?',
|
||||
'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Zugriff von ${displayName} auf ${connectionLabel} entfernen. Andere Profile behalten ihn.',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.deleteProfileTitle' => 'Profil löschen?',
|
||||
'profiles.deleteProfileMessage' => ({required Object displayName}) => '${displayName} und Verbindungen entfernen. Server bleiben verfügbar.',
|
||||
'profiles.profileNameLabel' => 'Profilname',
|
||||
@@ -2284,8 +2318,6 @@ extension on TranslationsDe {
|
||||
'profiles.confirmPinTitle' => 'PIN bestätigen',
|
||||
'profiles.pinSet' => 'PIN festgelegt',
|
||||
'profiles.changePin' => 'Ändern',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.removePin' => 'Entfernen',
|
||||
'profiles.connectionsLabel' => 'Verbindungen',
|
||||
'profiles.add' => 'Hinzufügen',
|
||||
@@ -2787,6 +2819,8 @@ extension on TranslationsDe {
|
||||
'metadataEdit.selectSquareArt' => 'Quadratisches Bild auswählen',
|
||||
'metadataEdit.fromUrl' => 'Von URL',
|
||||
'metadataEdit.uploadFile' => 'Datei hochladen',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.enterImageUrl' => 'Bild-URL eingeben',
|
||||
'metadataEdit.imageUrl' => 'Bild-URL',
|
||||
'metadataEdit.metadataUpdated' => 'Metadaten aktualisiert',
|
||||
@@ -2798,8 +2832,6 @@ extension on TranslationsDe {
|
||||
'metadataEdit.libraryDefault' => 'Bibliotheksstandard',
|
||||
'metadataEdit.accountDefault' => 'Kontostandard',
|
||||
'metadataEdit.seriesDefault' => 'Serienstandard',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.episodeSorting' => 'Episodensortierung',
|
||||
'metadataEdit.oldestFirst' => 'Älteste zuerst',
|
||||
'metadataEdit.newestFirst' => 'Neueste zuerst',
|
||||
|
||||
@@ -50,6 +50,7 @@ class Translations with BaseTranslations<AppLocale, Translations> {
|
||||
late final TranslationsHotkeysEn hotkeys = TranslationsHotkeysEn.internal(_root);
|
||||
late final TranslationsFileInfoEn fileInfo = TranslationsFileInfoEn.internal(_root);
|
||||
late final TranslationsMediaMenuEn mediaMenu = TranslationsMediaMenuEn.internal(_root);
|
||||
late final TranslationsRateSheetEn rateSheet = TranslationsRateSheetEn.internal(_root);
|
||||
late final TranslationsAccessibilityEn accessibility = TranslationsAccessibilityEn.internal(_root);
|
||||
late final TranslationsTooltipsEn tooltips = TranslationsTooltipsEn.internal(_root);
|
||||
late final TranslationsVideoControlsEn videoControls = TranslationsVideoControlsEn.internal(_root);
|
||||
@@ -1093,6 +1094,48 @@ class TranslationsMediaMenuEn {
|
||||
String get playVersion => 'Play Version...';
|
||||
}
|
||||
|
||||
// Path: rateSheet
|
||||
class TranslationsRateSheetEn {
|
||||
TranslationsRateSheetEn.internal(this._root);
|
||||
|
||||
final Translations _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
|
||||
/// en: 'Rate'
|
||||
String get title => 'Rate';
|
||||
|
||||
/// en: 'Server'
|
||||
String get server => 'Server';
|
||||
|
||||
/// en: '${rating} / 5'
|
||||
String starValue({required Object rating}) => '${rating} / 5';
|
||||
|
||||
/// en: '${score} / 10'
|
||||
String scoreValue({required Object score}) => '${score} / 10';
|
||||
|
||||
/// en: 'Set a score'
|
||||
String get setScore => 'Set a score';
|
||||
|
||||
/// en: 'Not rated'
|
||||
String get notRated => 'Not rated';
|
||||
|
||||
/// en: 'Liked'
|
||||
String get liked => 'Liked';
|
||||
|
||||
/// en: 'Not liked'
|
||||
String get notLiked => 'Not liked';
|
||||
|
||||
/// en: 'Saved'
|
||||
String get saved => 'Saved';
|
||||
|
||||
/// en: 'No match found'
|
||||
String get notAvailable => 'No match found';
|
||||
|
||||
/// en: 'Connect a tracker in Settings to rate there.'
|
||||
String get noConnectedTrackers => 'Connect a tracker in Settings to rate there.';
|
||||
}
|
||||
|
||||
// Path: accessibility
|
||||
class TranslationsAccessibilityEn {
|
||||
TranslationsAccessibilityEn.internal(this._root);
|
||||
@@ -4410,6 +4453,17 @@ extension on Translations {
|
||||
'mediaMenu.rate' => 'Rate',
|
||||
'mediaMenu.playFromBeginning' => 'Play from Beginning',
|
||||
'mediaMenu.playVersion' => 'Play Version...',
|
||||
'rateSheet.title' => 'Rate',
|
||||
'rateSheet.server' => 'Server',
|
||||
'rateSheet.starValue' => ({required Object rating}) => '${rating} / 5',
|
||||
'rateSheet.scoreValue' => ({required Object score}) => '${score} / 10',
|
||||
'rateSheet.setScore' => 'Set a score',
|
||||
'rateSheet.notRated' => 'Not rated',
|
||||
'rateSheet.liked' => 'Liked',
|
||||
'rateSheet.notLiked' => 'Not liked',
|
||||
'rateSheet.saved' => 'Saved',
|
||||
'rateSheet.notAvailable' => 'No match found',
|
||||
'rateSheet.noConnectedTrackers' => 'Connect a tracker in Settings to rate there.',
|
||||
'accessibility.mediaCardMovie' => ({required Object title}) => '${title}, movie',
|
||||
'accessibility.mediaCardShow' => ({required Object title}) => '${title}, TV show',
|
||||
'accessibility.mediaCardEpisode' => ({required Object title, required Object episodeInfo}) => '${title}, ${episodeInfo}',
|
||||
@@ -4585,6 +4639,8 @@ extension on Translations {
|
||||
'profiles.summaryMultiple' => ({required Object count}) => '${count} profiles',
|
||||
'profiles.removeConnectionTitle' => 'Remove connection?',
|
||||
'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Remove ${displayName}\'s access to ${connectionLabel}. Other profiles keep it.',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.deleteProfileTitle' => 'Delete profile?',
|
||||
'profiles.deleteProfileMessage' => ({required Object displayName}) => 'Remove ${displayName} and its connections. Servers stay available.',
|
||||
'profiles.profileNameLabel' => 'Profile name',
|
||||
@@ -4596,8 +4652,6 @@ extension on Translations {
|
||||
'profiles.confirmPinTitle' => 'Confirm PIN',
|
||||
'profiles.pinSet' => 'PIN set',
|
||||
'profiles.changePin' => 'Change',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.removePin' => 'Remove',
|
||||
'profiles.connectionsLabel' => 'Connections',
|
||||
'profiles.add' => 'Add',
|
||||
@@ -5099,6 +5153,8 @@ extension on Translations {
|
||||
'metadataEdit.selectSquareArt' => 'Select Square Art',
|
||||
'metadataEdit.fromUrl' => 'From URL',
|
||||
'metadataEdit.uploadFile' => 'Upload File',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.enterImageUrl' => 'Enter image URL',
|
||||
'metadataEdit.imageUrl' => 'Image URL',
|
||||
'metadataEdit.metadataUpdated' => 'Metadata updated',
|
||||
@@ -5110,8 +5166,6 @@ extension on Translations {
|
||||
'metadataEdit.libraryDefault' => 'Library default',
|
||||
'metadataEdit.accountDefault' => 'Account default',
|
||||
'metadataEdit.seriesDefault' => 'Series default',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.episodeSorting' => 'Episode Sorting',
|
||||
'metadataEdit.oldestFirst' => 'Oldest first',
|
||||
'metadataEdit.newestFirst' => 'Newest first',
|
||||
|
||||
@@ -49,6 +49,7 @@ class TranslationsEs extends Translations with BaseTranslations<AppLocale, Trans
|
||||
@override late final _TranslationsHotkeysEs hotkeys = _TranslationsHotkeysEs._(_root);
|
||||
@override late final _TranslationsFileInfoEs fileInfo = _TranslationsFileInfoEs._(_root);
|
||||
@override late final _TranslationsMediaMenuEs mediaMenu = _TranslationsMediaMenuEs._(_root);
|
||||
@override late final _TranslationsRateSheetEs rateSheet = _TranslationsRateSheetEs._(_root);
|
||||
@override late final _TranslationsAccessibilityEs accessibility = _TranslationsAccessibilityEs._(_root);
|
||||
@override late final _TranslationsTooltipsEs tooltips = _TranslationsTooltipsEs._(_root);
|
||||
@override late final _TranslationsVideoControlsEs videoControls = _TranslationsVideoControlsEs._(_root);
|
||||
@@ -481,6 +482,26 @@ class _TranslationsMediaMenuEs extends TranslationsMediaMenuEn {
|
||||
@override String get playVersion => 'Reproducir versión...';
|
||||
}
|
||||
|
||||
// Path: rateSheet
|
||||
class _TranslationsRateSheetEs extends TranslationsRateSheetEn {
|
||||
_TranslationsRateSheetEs._(TranslationsEs root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsEs _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Calificar';
|
||||
@override String get server => 'Servidor';
|
||||
@override String starValue({required Object rating}) => '${rating} / 5';
|
||||
@override String scoreValue({required Object score}) => '${score} / 10';
|
||||
@override String get setScore => 'Establecer puntuación';
|
||||
@override String get notRated => 'Sin calificar';
|
||||
@override String get liked => 'Me gusta';
|
||||
@override String get notLiked => 'Sin Me gusta';
|
||||
@override String get saved => 'Guardado';
|
||||
@override String get notAvailable => 'No se encontró coincidencia';
|
||||
@override String get noConnectedTrackers => 'Conecta un tracker en Ajustes para calificar allí.';
|
||||
}
|
||||
|
||||
// Path: accessibility
|
||||
class _TranslationsAccessibilityEs extends TranslationsAccessibilityEn {
|
||||
_TranslationsAccessibilityEs._(TranslationsEs root) : this._root = root, super.internal(root);
|
||||
@@ -2098,6 +2119,17 @@ extension on TranslationsEs {
|
||||
'mediaMenu.rate' => 'Calificar',
|
||||
'mediaMenu.playFromBeginning' => 'Reproducir desde el inicio',
|
||||
'mediaMenu.playVersion' => 'Reproducir versión...',
|
||||
'rateSheet.title' => 'Calificar',
|
||||
'rateSheet.server' => 'Servidor',
|
||||
'rateSheet.starValue' => ({required Object rating}) => '${rating} / 5',
|
||||
'rateSheet.scoreValue' => ({required Object score}) => '${score} / 10',
|
||||
'rateSheet.setScore' => 'Establecer puntuación',
|
||||
'rateSheet.notRated' => 'Sin calificar',
|
||||
'rateSheet.liked' => 'Me gusta',
|
||||
'rateSheet.notLiked' => 'Sin Me gusta',
|
||||
'rateSheet.saved' => 'Guardado',
|
||||
'rateSheet.notAvailable' => 'No se encontró coincidencia',
|
||||
'rateSheet.noConnectedTrackers' => 'Conecta un tracker en Ajustes para calificar allí.',
|
||||
'accessibility.mediaCardMovie' => ({required Object title}) => '${title}, película',
|
||||
'accessibility.mediaCardShow' => ({required Object title}) => '${title}, serie de TV',
|
||||
'accessibility.mediaCardEpisode' => ({required Object title, required Object episodeInfo}) => '${title}, ${episodeInfo}',
|
||||
@@ -2273,6 +2305,8 @@ extension on TranslationsEs {
|
||||
'profiles.summaryMultiple' => ({required Object count}) => '${count} perfiles',
|
||||
'profiles.removeConnectionTitle' => '¿Eliminar conexión?',
|
||||
'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Eliminar el acceso de ${displayName} a ${connectionLabel}. Los demás perfiles lo conservan.',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.deleteProfileTitle' => '¿Eliminar perfil?',
|
||||
'profiles.deleteProfileMessage' => ({required Object displayName}) => 'Eliminar ${displayName} y sus conexiones. Los servidores seguirán disponibles.',
|
||||
'profiles.profileNameLabel' => 'Nombre del perfil',
|
||||
@@ -2284,8 +2318,6 @@ extension on TranslationsEs {
|
||||
'profiles.confirmPinTitle' => 'Confirmar PIN',
|
||||
'profiles.pinSet' => 'PIN establecido',
|
||||
'profiles.changePin' => 'Cambiar',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.removePin' => 'Eliminar',
|
||||
'profiles.connectionsLabel' => 'Conexiones',
|
||||
'profiles.add' => 'Añadir',
|
||||
@@ -2787,6 +2819,8 @@ extension on TranslationsEs {
|
||||
'metadataEdit.selectSquareArt' => 'Seleccionar imagen cuadrada',
|
||||
'metadataEdit.fromUrl' => 'Desde URL',
|
||||
'metadataEdit.uploadFile' => 'Subir archivo',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.enterImageUrl' => 'Introducir URL de imagen',
|
||||
'metadataEdit.imageUrl' => 'URL de imagen',
|
||||
'metadataEdit.metadataUpdated' => 'Metadatos actualizados',
|
||||
@@ -2798,8 +2832,6 @@ extension on TranslationsEs {
|
||||
'metadataEdit.libraryDefault' => 'Predeterminado de biblioteca',
|
||||
'metadataEdit.accountDefault' => 'Predeterminado de cuenta',
|
||||
'metadataEdit.seriesDefault' => 'Predeterminado de serie',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.episodeSorting' => 'Orden de episodios',
|
||||
'metadataEdit.oldestFirst' => 'Más antiguos primero',
|
||||
'metadataEdit.newestFirst' => 'Más recientes primero',
|
||||
|
||||
@@ -49,6 +49,7 @@ class TranslationsFr extends Translations with BaseTranslations<AppLocale, Trans
|
||||
@override late final _TranslationsHotkeysFr hotkeys = _TranslationsHotkeysFr._(_root);
|
||||
@override late final _TranslationsFileInfoFr fileInfo = _TranslationsFileInfoFr._(_root);
|
||||
@override late final _TranslationsMediaMenuFr mediaMenu = _TranslationsMediaMenuFr._(_root);
|
||||
@override late final _TranslationsRateSheetFr rateSheet = _TranslationsRateSheetFr._(_root);
|
||||
@override late final _TranslationsAccessibilityFr accessibility = _TranslationsAccessibilityFr._(_root);
|
||||
@override late final _TranslationsTooltipsFr tooltips = _TranslationsTooltipsFr._(_root);
|
||||
@override late final _TranslationsVideoControlsFr videoControls = _TranslationsVideoControlsFr._(_root);
|
||||
@@ -481,6 +482,26 @@ class _TranslationsMediaMenuFr extends TranslationsMediaMenuEn {
|
||||
@override String get playVersion => 'Lire la version...';
|
||||
}
|
||||
|
||||
// Path: rateSheet
|
||||
class _TranslationsRateSheetFr extends TranslationsRateSheetEn {
|
||||
_TranslationsRateSheetFr._(TranslationsFr root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsFr _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Noter';
|
||||
@override String get server => 'Serveur';
|
||||
@override String starValue({required Object rating}) => '${rating} / 5';
|
||||
@override String scoreValue({required Object score}) => '${score} / 10';
|
||||
@override String get setScore => 'Définir une note';
|
||||
@override String get notRated => 'Non noté';
|
||||
@override String get liked => 'Aimé';
|
||||
@override String get notLiked => 'Non aimé';
|
||||
@override String get saved => 'Enregistré';
|
||||
@override String get notAvailable => 'Aucune correspondance trouvée';
|
||||
@override String get noConnectedTrackers => 'Connectez un tracker dans Paramètres pour y noter.';
|
||||
}
|
||||
|
||||
// Path: accessibility
|
||||
class _TranslationsAccessibilityFr extends TranslationsAccessibilityEn {
|
||||
_TranslationsAccessibilityFr._(TranslationsFr root) : this._root = root, super.internal(root);
|
||||
@@ -2098,6 +2119,17 @@ extension on TranslationsFr {
|
||||
'mediaMenu.rate' => 'Noter',
|
||||
'mediaMenu.playFromBeginning' => 'Lire depuis le début',
|
||||
'mediaMenu.playVersion' => 'Lire la version...',
|
||||
'rateSheet.title' => 'Noter',
|
||||
'rateSheet.server' => 'Serveur',
|
||||
'rateSheet.starValue' => ({required Object rating}) => '${rating} / 5',
|
||||
'rateSheet.scoreValue' => ({required Object score}) => '${score} / 10',
|
||||
'rateSheet.setScore' => 'Définir une note',
|
||||
'rateSheet.notRated' => 'Non noté',
|
||||
'rateSheet.liked' => 'Aimé',
|
||||
'rateSheet.notLiked' => 'Non aimé',
|
||||
'rateSheet.saved' => 'Enregistré',
|
||||
'rateSheet.notAvailable' => 'Aucune correspondance trouvée',
|
||||
'rateSheet.noConnectedTrackers' => 'Connectez un tracker dans Paramètres pour y noter.',
|
||||
'accessibility.mediaCardMovie' => ({required Object title}) => '${title}, film',
|
||||
'accessibility.mediaCardShow' => ({required Object title}) => '${title}, show TV',
|
||||
'accessibility.mediaCardEpisode' => ({required Object title, required Object episodeInfo}) => '${title}, ${episodeInfo}',
|
||||
@@ -2273,6 +2305,8 @@ extension on TranslationsFr {
|
||||
'profiles.summaryMultiple' => ({required Object count}) => '${count} profils',
|
||||
'profiles.removeConnectionTitle' => 'Retirer la connexion ?',
|
||||
'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Supprimer l\'accès de ${displayName} à ${connectionLabel}. Les autres profils le conservent.',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.deleteProfileTitle' => 'Supprimer le profil ?',
|
||||
'profiles.deleteProfileMessage' => ({required Object displayName}) => 'Supprimer ${displayName} et ses connexions. Les serveurs restent disponibles.',
|
||||
'profiles.profileNameLabel' => 'Nom du profil',
|
||||
@@ -2284,8 +2318,6 @@ extension on TranslationsFr {
|
||||
'profiles.confirmPinTitle' => 'Confirmer le PIN',
|
||||
'profiles.pinSet' => 'PIN défini',
|
||||
'profiles.changePin' => 'Modifier',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.removePin' => 'Retirer',
|
||||
'profiles.connectionsLabel' => 'Connexions',
|
||||
'profiles.add' => 'Ajouter',
|
||||
@@ -2787,6 +2819,8 @@ extension on TranslationsFr {
|
||||
'metadataEdit.selectSquareArt' => 'Sélectionner l\'image carrée',
|
||||
'metadataEdit.fromUrl' => 'Depuis une URL',
|
||||
'metadataEdit.uploadFile' => 'Importer un fichier',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.enterImageUrl' => 'Entrer l\'URL de l\'image',
|
||||
'metadataEdit.imageUrl' => 'URL de l\'image',
|
||||
'metadataEdit.metadataUpdated' => 'Métadonnées mises à jour',
|
||||
@@ -2798,8 +2832,6 @@ extension on TranslationsFr {
|
||||
'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',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.episodeSorting' => 'Tri des épisodes',
|
||||
'metadataEdit.oldestFirst' => 'Plus anciens en premier',
|
||||
'metadataEdit.newestFirst' => 'Plus récents en premier',
|
||||
|
||||
@@ -49,6 +49,7 @@ class TranslationsIt extends Translations with BaseTranslations<AppLocale, Trans
|
||||
@override late final _TranslationsHotkeysIt hotkeys = _TranslationsHotkeysIt._(_root);
|
||||
@override late final _TranslationsFileInfoIt fileInfo = _TranslationsFileInfoIt._(_root);
|
||||
@override late final _TranslationsMediaMenuIt mediaMenu = _TranslationsMediaMenuIt._(_root);
|
||||
@override late final _TranslationsRateSheetIt rateSheet = _TranslationsRateSheetIt._(_root);
|
||||
@override late final _TranslationsAccessibilityIt accessibility = _TranslationsAccessibilityIt._(_root);
|
||||
@override late final _TranslationsTooltipsIt tooltips = _TranslationsTooltipsIt._(_root);
|
||||
@override late final _TranslationsVideoControlsIt videoControls = _TranslationsVideoControlsIt._(_root);
|
||||
@@ -481,6 +482,26 @@ class _TranslationsMediaMenuIt extends TranslationsMediaMenuEn {
|
||||
@override String get playVersion => 'Riproduci versione...';
|
||||
}
|
||||
|
||||
// Path: rateSheet
|
||||
class _TranslationsRateSheetIt extends TranslationsRateSheetEn {
|
||||
_TranslationsRateSheetIt._(TranslationsIt root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsIt _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Valuta';
|
||||
@override String get server => 'Server';
|
||||
@override String starValue({required Object rating}) => '${rating} / 5';
|
||||
@override String scoreValue({required Object score}) => '${score} / 10';
|
||||
@override String get setScore => 'Imposta un punteggio';
|
||||
@override String get notRated => 'Non valutato';
|
||||
@override String get liked => 'Mi piace';
|
||||
@override String get notLiked => 'Non contrassegnato con Mi piace';
|
||||
@override String get saved => 'Salvato';
|
||||
@override String get notAvailable => 'Nessuna corrispondenza trovata';
|
||||
@override String get noConnectedTrackers => 'Collega un tracker in Impostazioni per valutarlo lì.';
|
||||
}
|
||||
|
||||
// Path: accessibility
|
||||
class _TranslationsAccessibilityIt extends TranslationsAccessibilityEn {
|
||||
_TranslationsAccessibilityIt._(TranslationsIt root) : this._root = root, super.internal(root);
|
||||
@@ -2098,6 +2119,17 @@ extension on TranslationsIt {
|
||||
'mediaMenu.rate' => 'Valuta',
|
||||
'mediaMenu.playFromBeginning' => 'Riproduci dall\'inizio',
|
||||
'mediaMenu.playVersion' => 'Riproduci versione...',
|
||||
'rateSheet.title' => 'Valuta',
|
||||
'rateSheet.server' => 'Server',
|
||||
'rateSheet.starValue' => ({required Object rating}) => '${rating} / 5',
|
||||
'rateSheet.scoreValue' => ({required Object score}) => '${score} / 10',
|
||||
'rateSheet.setScore' => 'Imposta un punteggio',
|
||||
'rateSheet.notRated' => 'Non valutato',
|
||||
'rateSheet.liked' => 'Mi piace',
|
||||
'rateSheet.notLiked' => 'Non contrassegnato con Mi piace',
|
||||
'rateSheet.saved' => 'Salvato',
|
||||
'rateSheet.notAvailable' => 'Nessuna corrispondenza trovata',
|
||||
'rateSheet.noConnectedTrackers' => 'Collega un tracker in Impostazioni per valutarlo lì.',
|
||||
'accessibility.mediaCardMovie' => ({required Object title}) => '${title}, film',
|
||||
'accessibility.mediaCardShow' => ({required Object title}) => '${title}, serie TV',
|
||||
'accessibility.mediaCardEpisode' => ({required Object title, required Object episodeInfo}) => '${title}, ${episodeInfo}',
|
||||
@@ -2273,6 +2305,8 @@ extension on TranslationsIt {
|
||||
'profiles.summaryMultiple' => ({required Object count}) => '${count} profili',
|
||||
'profiles.removeConnectionTitle' => 'Rimuovere la connessione?',
|
||||
'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Rimuovi l\'accesso di ${displayName} a ${connectionLabel}. Gli altri profili lo mantengono.',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.deleteProfileTitle' => 'Eliminare il profilo?',
|
||||
'profiles.deleteProfileMessage' => ({required Object displayName}) => 'Rimuovi ${displayName} e le sue connessioni. I server restano disponibili.',
|
||||
'profiles.profileNameLabel' => 'Nome profilo',
|
||||
@@ -2284,8 +2318,6 @@ extension on TranslationsIt {
|
||||
'profiles.confirmPinTitle' => 'Conferma PIN',
|
||||
'profiles.pinSet' => 'PIN impostato',
|
||||
'profiles.changePin' => 'Cambia',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.removePin' => 'Rimuovi',
|
||||
'profiles.connectionsLabel' => 'Connessioni',
|
||||
'profiles.add' => 'Aggiungi',
|
||||
@@ -2787,6 +2819,8 @@ extension on TranslationsIt {
|
||||
'metadataEdit.selectSquareArt' => 'Seleziona immagine quadrata',
|
||||
'metadataEdit.fromUrl' => 'Da URL',
|
||||
'metadataEdit.uploadFile' => 'Carica file',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.enterImageUrl' => 'Inserisci URL immagine',
|
||||
'metadataEdit.imageUrl' => 'URL immagine',
|
||||
'metadataEdit.metadataUpdated' => 'Metadati aggiornati',
|
||||
@@ -2798,8 +2832,6 @@ extension on TranslationsIt {
|
||||
'metadataEdit.libraryDefault' => 'Predefinito libreria',
|
||||
'metadataEdit.accountDefault' => 'Predefinito account',
|
||||
'metadataEdit.seriesDefault' => 'Predefinito serie',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.episodeSorting' => 'Ordinamento episodi',
|
||||
'metadataEdit.oldestFirst' => 'Più vecchi prima',
|
||||
'metadataEdit.newestFirst' => 'Più recenti prima',
|
||||
|
||||
@@ -49,6 +49,7 @@ class TranslationsJa extends Translations with BaseTranslations<AppLocale, Trans
|
||||
@override late final _TranslationsHotkeysJa hotkeys = _TranslationsHotkeysJa._(_root);
|
||||
@override late final _TranslationsFileInfoJa fileInfo = _TranslationsFileInfoJa._(_root);
|
||||
@override late final _TranslationsMediaMenuJa mediaMenu = _TranslationsMediaMenuJa._(_root);
|
||||
@override late final _TranslationsRateSheetJa rateSheet = _TranslationsRateSheetJa._(_root);
|
||||
@override late final _TranslationsAccessibilityJa accessibility = _TranslationsAccessibilityJa._(_root);
|
||||
@override late final _TranslationsTooltipsJa tooltips = _TranslationsTooltipsJa._(_root);
|
||||
@override late final _TranslationsVideoControlsJa videoControls = _TranslationsVideoControlsJa._(_root);
|
||||
@@ -481,6 +482,26 @@ class _TranslationsMediaMenuJa extends TranslationsMediaMenuEn {
|
||||
@override String get playVersion => 'バージョンを再生...';
|
||||
}
|
||||
|
||||
// Path: rateSheet
|
||||
class _TranslationsRateSheetJa extends TranslationsRateSheetEn {
|
||||
_TranslationsRateSheetJa._(TranslationsJa root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsJa _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => '評価';
|
||||
@override String get server => 'サーバー';
|
||||
@override String starValue({required Object rating}) => '${rating} / 5';
|
||||
@override String scoreValue({required Object score}) => '${score} / 10';
|
||||
@override String get setScore => 'スコアを設定';
|
||||
@override String get notRated => '未評価';
|
||||
@override String get liked => 'いいね済み';
|
||||
@override String get notLiked => 'いいねなし';
|
||||
@override String get saved => '保存済み';
|
||||
@override String get notAvailable => '一致なし';
|
||||
@override String get noConnectedTrackers => '設定でトラッカーを接続すると、そこで評価できます。';
|
||||
}
|
||||
|
||||
// Path: accessibility
|
||||
class _TranslationsAccessibilityJa extends TranslationsAccessibilityEn {
|
||||
_TranslationsAccessibilityJa._(TranslationsJa root) : this._root = root, super.internal(root);
|
||||
@@ -2098,6 +2119,17 @@ extension on TranslationsJa {
|
||||
'mediaMenu.rate' => '評価',
|
||||
'mediaMenu.playFromBeginning' => '最初から再生',
|
||||
'mediaMenu.playVersion' => 'バージョンを再生...',
|
||||
'rateSheet.title' => '評価',
|
||||
'rateSheet.server' => 'サーバー',
|
||||
'rateSheet.starValue' => ({required Object rating}) => '${rating} / 5',
|
||||
'rateSheet.scoreValue' => ({required Object score}) => '${score} / 10',
|
||||
'rateSheet.setScore' => 'スコアを設定',
|
||||
'rateSheet.notRated' => '未評価',
|
||||
'rateSheet.liked' => 'いいね済み',
|
||||
'rateSheet.notLiked' => 'いいねなし',
|
||||
'rateSheet.saved' => '保存済み',
|
||||
'rateSheet.notAvailable' => '一致なし',
|
||||
'rateSheet.noConnectedTrackers' => '設定でトラッカーを接続すると、そこで評価できます。',
|
||||
'accessibility.mediaCardMovie' => ({required Object title}) => '${title}、映画',
|
||||
'accessibility.mediaCardShow' => ({required Object title}) => '${title}、テレビ番組',
|
||||
'accessibility.mediaCardEpisode' => ({required Object title, required Object episodeInfo}) => '${title}、${episodeInfo}',
|
||||
@@ -2273,6 +2305,8 @@ extension on TranslationsJa {
|
||||
'profiles.summaryMultiple' => ({required Object count}) => '${count}個のプロファイル',
|
||||
'profiles.removeConnectionTitle' => '接続を削除しますか?',
|
||||
'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => '${displayName}の${connectionLabel}へのアクセスを削除します。他のプロフィールには残ります。',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.deleteProfileTitle' => 'プロファイルを削除しますか?',
|
||||
'profiles.deleteProfileMessage' => ({required Object displayName}) => '${displayName}とその接続を削除します。サーバーは引き続き利用できます。',
|
||||
'profiles.profileNameLabel' => 'プロファイル名',
|
||||
@@ -2284,8 +2318,6 @@ extension on TranslationsJa {
|
||||
'profiles.confirmPinTitle' => 'PINを確認',
|
||||
'profiles.pinSet' => 'PIN設定済み',
|
||||
'profiles.changePin' => '変更',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.removePin' => '削除',
|
||||
'profiles.connectionsLabel' => '接続',
|
||||
'profiles.add' => '追加',
|
||||
@@ -2787,6 +2819,8 @@ extension on TranslationsJa {
|
||||
'metadataEdit.selectSquareArt' => '正方形アートを選択',
|
||||
'metadataEdit.fromUrl' => 'URLから',
|
||||
'metadataEdit.uploadFile' => 'ファイルをアップロード',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.enterImageUrl' => '画像URLを入力',
|
||||
'metadataEdit.imageUrl' => '画像URL',
|
||||
'metadataEdit.metadataUpdated' => 'メタデータを更新しました',
|
||||
@@ -2798,8 +2832,6 @@ extension on TranslationsJa {
|
||||
'metadataEdit.libraryDefault' => 'ライブラリのデフォルト',
|
||||
'metadataEdit.accountDefault' => 'アカウントのデフォルト',
|
||||
'metadataEdit.seriesDefault' => 'シリーズのデフォルト',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.episodeSorting' => 'エピソードの並べ替え',
|
||||
'metadataEdit.oldestFirst' => '古い順',
|
||||
'metadataEdit.newestFirst' => '新しい順',
|
||||
|
||||
@@ -49,6 +49,7 @@ class TranslationsKo extends Translations with BaseTranslations<AppLocale, Trans
|
||||
@override late final _TranslationsHotkeysKo hotkeys = _TranslationsHotkeysKo._(_root);
|
||||
@override late final _TranslationsFileInfoKo fileInfo = _TranslationsFileInfoKo._(_root);
|
||||
@override late final _TranslationsMediaMenuKo mediaMenu = _TranslationsMediaMenuKo._(_root);
|
||||
@override late final _TranslationsRateSheetKo rateSheet = _TranslationsRateSheetKo._(_root);
|
||||
@override late final _TranslationsAccessibilityKo accessibility = _TranslationsAccessibilityKo._(_root);
|
||||
@override late final _TranslationsTooltipsKo tooltips = _TranslationsTooltipsKo._(_root);
|
||||
@override late final _TranslationsVideoControlsKo videoControls = _TranslationsVideoControlsKo._(_root);
|
||||
@@ -481,6 +482,26 @@ class _TranslationsMediaMenuKo extends TranslationsMediaMenuEn {
|
||||
@override String get playVersion => '버전 재생...';
|
||||
}
|
||||
|
||||
// Path: rateSheet
|
||||
class _TranslationsRateSheetKo extends TranslationsRateSheetEn {
|
||||
_TranslationsRateSheetKo._(TranslationsKo root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsKo _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => '평가';
|
||||
@override String get server => '서버';
|
||||
@override String starValue({required Object rating}) => '${rating} / 5';
|
||||
@override String scoreValue({required Object score}) => '${score} / 10';
|
||||
@override String get setScore => '점수 설정';
|
||||
@override String get notRated => '평가 없음';
|
||||
@override String get liked => '좋아요';
|
||||
@override String get notLiked => '좋아요 아님';
|
||||
@override String get saved => '저장됨';
|
||||
@override String get notAvailable => '일치 항목 없음';
|
||||
@override String get noConnectedTrackers => '설정에서 트래커를 연결하면 거기에도 평가할 수 있습니다.';
|
||||
}
|
||||
|
||||
// Path: accessibility
|
||||
class _TranslationsAccessibilityKo extends TranslationsAccessibilityEn {
|
||||
_TranslationsAccessibilityKo._(TranslationsKo root) : this._root = root, super.internal(root);
|
||||
@@ -2098,6 +2119,17 @@ extension on TranslationsKo {
|
||||
'mediaMenu.rate' => '평가',
|
||||
'mediaMenu.playFromBeginning' => '처음부터 재생',
|
||||
'mediaMenu.playVersion' => '버전 재생...',
|
||||
'rateSheet.title' => '평가',
|
||||
'rateSheet.server' => '서버',
|
||||
'rateSheet.starValue' => ({required Object rating}) => '${rating} / 5',
|
||||
'rateSheet.scoreValue' => ({required Object score}) => '${score} / 10',
|
||||
'rateSheet.setScore' => '점수 설정',
|
||||
'rateSheet.notRated' => '평가 없음',
|
||||
'rateSheet.liked' => '좋아요',
|
||||
'rateSheet.notLiked' => '좋아요 아님',
|
||||
'rateSheet.saved' => '저장됨',
|
||||
'rateSheet.notAvailable' => '일치 항목 없음',
|
||||
'rateSheet.noConnectedTrackers' => '설정에서 트래커를 연결하면 거기에도 평가할 수 있습니다.',
|
||||
'accessibility.mediaCardMovie' => ({required Object title}) => '${title}, 영화',
|
||||
'accessibility.mediaCardShow' => ({required Object title}) => '${title}, TV 프로그램',
|
||||
'accessibility.mediaCardEpisode' => ({required Object title, required Object episodeInfo}) => '${title}, ${episodeInfo}',
|
||||
@@ -2273,6 +2305,8 @@ extension on TranslationsKo {
|
||||
'profiles.summaryMultiple' => ({required Object count}) => '${count}개 프로필',
|
||||
'profiles.removeConnectionTitle' => '연결을 제거하시겠습니까?',
|
||||
'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => '${displayName}의 ${connectionLabel} 접근 권한을 제거합니다. 다른 프로필에는 유지됩니다.',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.deleteProfileTitle' => '프로필을 삭제하시겠습니까?',
|
||||
'profiles.deleteProfileMessage' => ({required Object displayName}) => '${displayName} 및 해당 연결을 제거합니다. 서버는 계속 사용할 수 있습니다.',
|
||||
'profiles.profileNameLabel' => '프로필 이름',
|
||||
@@ -2284,8 +2318,6 @@ extension on TranslationsKo {
|
||||
'profiles.confirmPinTitle' => 'PIN 확인',
|
||||
'profiles.pinSet' => 'PIN 설정됨',
|
||||
'profiles.changePin' => '변경',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.removePin' => '제거',
|
||||
'profiles.connectionsLabel' => '연결',
|
||||
'profiles.add' => '추가',
|
||||
@@ -2787,6 +2819,8 @@ extension on TranslationsKo {
|
||||
'metadataEdit.selectSquareArt' => '정사각형 아트 선택',
|
||||
'metadataEdit.fromUrl' => 'URL에서',
|
||||
'metadataEdit.uploadFile' => '파일 업로드',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.enterImageUrl' => '이미지 URL 입력',
|
||||
'metadataEdit.imageUrl' => '이미지 URL',
|
||||
'metadataEdit.metadataUpdated' => '메타데이터가 업데이트되었습니다',
|
||||
@@ -2798,8 +2832,6 @@ extension on TranslationsKo {
|
||||
'metadataEdit.libraryDefault' => '라이브러리 기본값',
|
||||
'metadataEdit.accountDefault' => '계정 기본값',
|
||||
'metadataEdit.seriesDefault' => '시리즈 기본값',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.episodeSorting' => '에피소드 정렬',
|
||||
'metadataEdit.oldestFirst' => '오래된 순',
|
||||
'metadataEdit.newestFirst' => '최신 순',
|
||||
|
||||
@@ -49,6 +49,7 @@ class TranslationsNb extends Translations with BaseTranslations<AppLocale, Trans
|
||||
@override late final _TranslationsHotkeysNb hotkeys = _TranslationsHotkeysNb._(_root);
|
||||
@override late final _TranslationsFileInfoNb fileInfo = _TranslationsFileInfoNb._(_root);
|
||||
@override late final _TranslationsMediaMenuNb mediaMenu = _TranslationsMediaMenuNb._(_root);
|
||||
@override late final _TranslationsRateSheetNb rateSheet = _TranslationsRateSheetNb._(_root);
|
||||
@override late final _TranslationsAccessibilityNb accessibility = _TranslationsAccessibilityNb._(_root);
|
||||
@override late final _TranslationsTooltipsNb tooltips = _TranslationsTooltipsNb._(_root);
|
||||
@override late final _TranslationsVideoControlsNb videoControls = _TranslationsVideoControlsNb._(_root);
|
||||
@@ -481,6 +482,26 @@ class _TranslationsMediaMenuNb extends TranslationsMediaMenuEn {
|
||||
@override String get playVersion => 'Spill av versjon...';
|
||||
}
|
||||
|
||||
// Path: rateSheet
|
||||
class _TranslationsRateSheetNb extends TranslationsRateSheetEn {
|
||||
_TranslationsRateSheetNb._(TranslationsNb root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsNb _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Vurder';
|
||||
@override String get server => 'Server';
|
||||
@override String starValue({required Object rating}) => '${rating} / 5';
|
||||
@override String scoreValue({required Object score}) => '${score} / 10';
|
||||
@override String get setScore => 'Sett en poengsum';
|
||||
@override String get notRated => 'Ikke vurdert';
|
||||
@override String get liked => 'Likt';
|
||||
@override String get notLiked => 'Ikke likt';
|
||||
@override String get saved => 'Lagret';
|
||||
@override String get notAvailable => 'Ingen treff';
|
||||
@override String get noConnectedTrackers => 'Koble til en sporer i Innstillinger for å vurdere der.';
|
||||
}
|
||||
|
||||
// Path: accessibility
|
||||
class _TranslationsAccessibilityNb extends TranslationsAccessibilityEn {
|
||||
_TranslationsAccessibilityNb._(TranslationsNb root) : this._root = root, super.internal(root);
|
||||
@@ -2098,6 +2119,17 @@ extension on TranslationsNb {
|
||||
'mediaMenu.rate' => 'Vurder',
|
||||
'mediaMenu.playFromBeginning' => 'Spill fra begynnelsen',
|
||||
'mediaMenu.playVersion' => 'Spill av versjon...',
|
||||
'rateSheet.title' => 'Vurder',
|
||||
'rateSheet.server' => 'Server',
|
||||
'rateSheet.starValue' => ({required Object rating}) => '${rating} / 5',
|
||||
'rateSheet.scoreValue' => ({required Object score}) => '${score} / 10',
|
||||
'rateSheet.setScore' => 'Sett en poengsum',
|
||||
'rateSheet.notRated' => 'Ikke vurdert',
|
||||
'rateSheet.liked' => 'Likt',
|
||||
'rateSheet.notLiked' => 'Ikke likt',
|
||||
'rateSheet.saved' => 'Lagret',
|
||||
'rateSheet.notAvailable' => 'Ingen treff',
|
||||
'rateSheet.noConnectedTrackers' => 'Koble til en sporer i Innstillinger for å vurdere der.',
|
||||
'accessibility.mediaCardMovie' => ({required Object title}) => '${title}, film',
|
||||
'accessibility.mediaCardShow' => ({required Object title}) => '${title}, TV-serie',
|
||||
'accessibility.mediaCardEpisode' => ({required Object title, required Object episodeInfo}) => '${title}, ${episodeInfo}',
|
||||
@@ -2273,6 +2305,8 @@ extension on TranslationsNb {
|
||||
'profiles.summaryMultiple' => ({required Object count}) => '${count} profiler',
|
||||
'profiles.removeConnectionTitle' => 'Fjerne tilkobling?',
|
||||
'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Fjern ${displayName}s tilgang til ${connectionLabel}. Andre profiler beholder den.',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.deleteProfileTitle' => 'Slette profil?',
|
||||
'profiles.deleteProfileMessage' => ({required Object displayName}) => 'Fjern ${displayName} og tilkoblingene. Servere forblir tilgjengelige.',
|
||||
'profiles.profileNameLabel' => 'Profilnavn',
|
||||
@@ -2284,8 +2318,6 @@ extension on TranslationsNb {
|
||||
'profiles.confirmPinTitle' => 'Bekreft PIN',
|
||||
'profiles.pinSet' => 'PIN satt',
|
||||
'profiles.changePin' => 'Endre',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.removePin' => 'Fjern',
|
||||
'profiles.connectionsLabel' => 'Tilkoblinger',
|
||||
'profiles.add' => 'Legg til',
|
||||
@@ -2787,6 +2819,8 @@ extension on TranslationsNb {
|
||||
'metadataEdit.selectSquareArt' => 'Velg kvadratisk bilde',
|
||||
'metadataEdit.fromUrl' => 'Fra URL',
|
||||
'metadataEdit.uploadFile' => 'Last opp fil',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.enterImageUrl' => 'Skriv inn bilde-URL',
|
||||
'metadataEdit.imageUrl' => 'Bilde-URL',
|
||||
'metadataEdit.metadataUpdated' => 'Metadata oppdatert',
|
||||
@@ -2798,8 +2832,6 @@ extension on TranslationsNb {
|
||||
'metadataEdit.libraryDefault' => 'Bibliotekstandard',
|
||||
'metadataEdit.accountDefault' => 'Kontostandard',
|
||||
'metadataEdit.seriesDefault' => 'Seriestandard',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.episodeSorting' => 'Episodesortering',
|
||||
'metadataEdit.oldestFirst' => 'Eldste først',
|
||||
'metadataEdit.newestFirst' => 'Nyeste først',
|
||||
|
||||
@@ -49,6 +49,7 @@ class TranslationsNl extends Translations with BaseTranslations<AppLocale, Trans
|
||||
@override late final _TranslationsHotkeysNl hotkeys = _TranslationsHotkeysNl._(_root);
|
||||
@override late final _TranslationsFileInfoNl fileInfo = _TranslationsFileInfoNl._(_root);
|
||||
@override late final _TranslationsMediaMenuNl mediaMenu = _TranslationsMediaMenuNl._(_root);
|
||||
@override late final _TranslationsRateSheetNl rateSheet = _TranslationsRateSheetNl._(_root);
|
||||
@override late final _TranslationsAccessibilityNl accessibility = _TranslationsAccessibilityNl._(_root);
|
||||
@override late final _TranslationsTooltipsNl tooltips = _TranslationsTooltipsNl._(_root);
|
||||
@override late final _TranslationsVideoControlsNl videoControls = _TranslationsVideoControlsNl._(_root);
|
||||
@@ -481,6 +482,26 @@ class _TranslationsMediaMenuNl extends TranslationsMediaMenuEn {
|
||||
@override String get playVersion => 'Versie afspelen...';
|
||||
}
|
||||
|
||||
// Path: rateSheet
|
||||
class _TranslationsRateSheetNl extends TranslationsRateSheetEn {
|
||||
_TranslationsRateSheetNl._(TranslationsNl root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsNl _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Beoordelen';
|
||||
@override String get server => 'Server';
|
||||
@override String starValue({required Object rating}) => '${rating} / 5';
|
||||
@override String scoreValue({required Object score}) => '${score} / 10';
|
||||
@override String get setScore => 'Score instellen';
|
||||
@override String get notRated => 'Niet beoordeeld';
|
||||
@override String get liked => 'Geliket';
|
||||
@override String get notLiked => 'Niet geliket';
|
||||
@override String get saved => 'Opgeslagen';
|
||||
@override String get notAvailable => 'Geen match gevonden';
|
||||
@override String get noConnectedTrackers => 'Verbind een tracker in Instellingen om daar te beoordelen.';
|
||||
}
|
||||
|
||||
// Path: accessibility
|
||||
class _TranslationsAccessibilityNl extends TranslationsAccessibilityEn {
|
||||
_TranslationsAccessibilityNl._(TranslationsNl root) : this._root = root, super.internal(root);
|
||||
@@ -2098,6 +2119,17 @@ extension on TranslationsNl {
|
||||
'mediaMenu.rate' => 'Beoordelen',
|
||||
'mediaMenu.playFromBeginning' => 'Afspelen vanaf het begin',
|
||||
'mediaMenu.playVersion' => 'Versie afspelen...',
|
||||
'rateSheet.title' => 'Beoordelen',
|
||||
'rateSheet.server' => 'Server',
|
||||
'rateSheet.starValue' => ({required Object rating}) => '${rating} / 5',
|
||||
'rateSheet.scoreValue' => ({required Object score}) => '${score} / 10',
|
||||
'rateSheet.setScore' => 'Score instellen',
|
||||
'rateSheet.notRated' => 'Niet beoordeeld',
|
||||
'rateSheet.liked' => 'Geliket',
|
||||
'rateSheet.notLiked' => 'Niet geliket',
|
||||
'rateSheet.saved' => 'Opgeslagen',
|
||||
'rateSheet.notAvailable' => 'Geen match gevonden',
|
||||
'rateSheet.noConnectedTrackers' => 'Verbind een tracker in Instellingen om daar te beoordelen.',
|
||||
'accessibility.mediaCardMovie' => ({required Object title}) => '${title}, film',
|
||||
'accessibility.mediaCardShow' => ({required Object title}) => '${title}, TV-serie',
|
||||
'accessibility.mediaCardEpisode' => ({required Object title, required Object episodeInfo}) => '${title}, ${episodeInfo}',
|
||||
@@ -2273,6 +2305,8 @@ extension on TranslationsNl {
|
||||
'profiles.summaryMultiple' => ({required Object count}) => '${count} profielen',
|
||||
'profiles.removeConnectionTitle' => 'Verbinding verwijderen?',
|
||||
'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Verwijder ${displayName}s toegang tot ${connectionLabel}. Andere profielen behouden die.',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.deleteProfileTitle' => 'Profiel verwijderen?',
|
||||
'profiles.deleteProfileMessage' => ({required Object displayName}) => 'Verwijder ${displayName} en de verbindingen. Servers blijven beschikbaar.',
|
||||
'profiles.profileNameLabel' => 'Profielnaam',
|
||||
@@ -2284,8 +2318,6 @@ extension on TranslationsNl {
|
||||
'profiles.confirmPinTitle' => 'PIN bevestigen',
|
||||
'profiles.pinSet' => 'PIN ingesteld',
|
||||
'profiles.changePin' => 'Wijzigen',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.removePin' => 'Verwijderen',
|
||||
'profiles.connectionsLabel' => 'Verbindingen',
|
||||
'profiles.add' => 'Toevoegen',
|
||||
@@ -2787,6 +2819,8 @@ extension on TranslationsNl {
|
||||
'metadataEdit.selectSquareArt' => 'Vierkante afbeelding selecteren',
|
||||
'metadataEdit.fromUrl' => 'Vanaf URL',
|
||||
'metadataEdit.uploadFile' => 'Bestand uploaden',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.enterImageUrl' => 'Voer afbeeldings-URL in',
|
||||
'metadataEdit.imageUrl' => 'Afbeeldings-URL',
|
||||
'metadataEdit.metadataUpdated' => 'Metadata bijgewerkt',
|
||||
@@ -2798,8 +2832,6 @@ extension on TranslationsNl {
|
||||
'metadataEdit.libraryDefault' => 'Bibliotheekstandaard',
|
||||
'metadataEdit.accountDefault' => 'Accountstandaard',
|
||||
'metadataEdit.seriesDefault' => 'Seriestandaard',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.episodeSorting' => 'Afleveringen sorteren',
|
||||
'metadataEdit.oldestFirst' => 'Oudste eerst',
|
||||
'metadataEdit.newestFirst' => 'Nieuwste eerst',
|
||||
|
||||
@@ -49,6 +49,7 @@ class TranslationsPl extends Translations with BaseTranslations<AppLocale, Trans
|
||||
@override late final _TranslationsHotkeysPl hotkeys = _TranslationsHotkeysPl._(_root);
|
||||
@override late final _TranslationsFileInfoPl fileInfo = _TranslationsFileInfoPl._(_root);
|
||||
@override late final _TranslationsMediaMenuPl mediaMenu = _TranslationsMediaMenuPl._(_root);
|
||||
@override late final _TranslationsRateSheetPl rateSheet = _TranslationsRateSheetPl._(_root);
|
||||
@override late final _TranslationsAccessibilityPl accessibility = _TranslationsAccessibilityPl._(_root);
|
||||
@override late final _TranslationsTooltipsPl tooltips = _TranslationsTooltipsPl._(_root);
|
||||
@override late final _TranslationsVideoControlsPl videoControls = _TranslationsVideoControlsPl._(_root);
|
||||
@@ -481,6 +482,26 @@ class _TranslationsMediaMenuPl extends TranslationsMediaMenuEn {
|
||||
@override String get playVersion => 'Odtwórz wersję...';
|
||||
}
|
||||
|
||||
// Path: rateSheet
|
||||
class _TranslationsRateSheetPl extends TranslationsRateSheetEn {
|
||||
_TranslationsRateSheetPl._(TranslationsPl root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsPl _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Oceń';
|
||||
@override String get server => 'Serwer';
|
||||
@override String starValue({required Object rating}) => '${rating} / 5';
|
||||
@override String scoreValue({required Object score}) => '${score} / 10';
|
||||
@override String get setScore => 'Ustaw ocenę';
|
||||
@override String get notRated => 'Nie oceniono';
|
||||
@override String get liked => 'Polubione';
|
||||
@override String get notLiked => 'Nie polubiono';
|
||||
@override String get saved => 'Zapisano';
|
||||
@override String get notAvailable => 'Nie znaleziono dopasowania';
|
||||
@override String get noConnectedTrackers => 'Połącz tracker w Ustawieniach, aby tam oceniać.';
|
||||
}
|
||||
|
||||
// Path: accessibility
|
||||
class _TranslationsAccessibilityPl extends TranslationsAccessibilityEn {
|
||||
_TranslationsAccessibilityPl._(TranslationsPl root) : this._root = root, super.internal(root);
|
||||
@@ -2098,6 +2119,17 @@ extension on TranslationsPl {
|
||||
'mediaMenu.rate' => 'Oceń',
|
||||
'mediaMenu.playFromBeginning' => 'Odtwórz od początku',
|
||||
'mediaMenu.playVersion' => 'Odtwórz wersję...',
|
||||
'rateSheet.title' => 'Oceń',
|
||||
'rateSheet.server' => 'Serwer',
|
||||
'rateSheet.starValue' => ({required Object rating}) => '${rating} / 5',
|
||||
'rateSheet.scoreValue' => ({required Object score}) => '${score} / 10',
|
||||
'rateSheet.setScore' => 'Ustaw ocenę',
|
||||
'rateSheet.notRated' => 'Nie oceniono',
|
||||
'rateSheet.liked' => 'Polubione',
|
||||
'rateSheet.notLiked' => 'Nie polubiono',
|
||||
'rateSheet.saved' => 'Zapisano',
|
||||
'rateSheet.notAvailable' => 'Nie znaleziono dopasowania',
|
||||
'rateSheet.noConnectedTrackers' => 'Połącz tracker w Ustawieniach, aby tam oceniać.',
|
||||
'accessibility.mediaCardMovie' => ({required Object title}) => '${title}, film',
|
||||
'accessibility.mediaCardShow' => ({required Object title}) => '${title}, serial TV',
|
||||
'accessibility.mediaCardEpisode' => ({required Object title, required Object episodeInfo}) => '${title}, ${episodeInfo}',
|
||||
@@ -2273,6 +2305,8 @@ extension on TranslationsPl {
|
||||
'profiles.summaryMultiple' => ({required Object count}) => '${count} profili',
|
||||
'profiles.removeConnectionTitle' => 'Usunąć połączenie?',
|
||||
'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Usuń dostęp ${displayName} do ${connectionLabel}. Inne profile go zachowają.',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.deleteProfileTitle' => 'Usunąć profil?',
|
||||
'profiles.deleteProfileMessage' => ({required Object displayName}) => 'Usuń ${displayName} i jego połączenia. Serwery pozostaną dostępne.',
|
||||
'profiles.profileNameLabel' => 'Nazwa profilu',
|
||||
@@ -2284,8 +2318,6 @@ extension on TranslationsPl {
|
||||
'profiles.confirmPinTitle' => 'Potwierdź PIN',
|
||||
'profiles.pinSet' => 'PIN ustawiony',
|
||||
'profiles.changePin' => 'Zmień',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.removePin' => 'Usuń',
|
||||
'profiles.connectionsLabel' => 'Połączenia',
|
||||
'profiles.add' => 'Dodaj',
|
||||
@@ -2787,6 +2819,8 @@ extension on TranslationsPl {
|
||||
'metadataEdit.selectSquareArt' => 'Wybierz kwadratowy obraz',
|
||||
'metadataEdit.fromUrl' => 'Z URL',
|
||||
'metadataEdit.uploadFile' => 'Prześlij plik',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.enterImageUrl' => 'Wprowadź URL obrazu',
|
||||
'metadataEdit.imageUrl' => 'URL obrazu',
|
||||
'metadataEdit.metadataUpdated' => 'Metadane zaktualizowane',
|
||||
@@ -2798,8 +2832,6 @@ extension on TranslationsPl {
|
||||
'metadataEdit.libraryDefault' => 'Domyślne biblioteki',
|
||||
'metadataEdit.accountDefault' => 'Domyślne konta',
|
||||
'metadataEdit.seriesDefault' => 'Domyślne serialu',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.episodeSorting' => 'Sortowanie odcinków',
|
||||
'metadataEdit.oldestFirst' => 'Najstarsze najpierw',
|
||||
'metadataEdit.newestFirst' => 'Najnowsze najpierw',
|
||||
|
||||
@@ -49,6 +49,7 @@ class TranslationsPt extends Translations with BaseTranslations<AppLocale, Trans
|
||||
@override late final _TranslationsHotkeysPt hotkeys = _TranslationsHotkeysPt._(_root);
|
||||
@override late final _TranslationsFileInfoPt fileInfo = _TranslationsFileInfoPt._(_root);
|
||||
@override late final _TranslationsMediaMenuPt mediaMenu = _TranslationsMediaMenuPt._(_root);
|
||||
@override late final _TranslationsRateSheetPt rateSheet = _TranslationsRateSheetPt._(_root);
|
||||
@override late final _TranslationsAccessibilityPt accessibility = _TranslationsAccessibilityPt._(_root);
|
||||
@override late final _TranslationsTooltipsPt tooltips = _TranslationsTooltipsPt._(_root);
|
||||
@override late final _TranslationsVideoControlsPt videoControls = _TranslationsVideoControlsPt._(_root);
|
||||
@@ -481,6 +482,26 @@ class _TranslationsMediaMenuPt extends TranslationsMediaMenuEn {
|
||||
@override String get playVersion => 'Reproduzir versão...';
|
||||
}
|
||||
|
||||
// Path: rateSheet
|
||||
class _TranslationsRateSheetPt extends TranslationsRateSheetEn {
|
||||
_TranslationsRateSheetPt._(TranslationsPt root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsPt _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Avaliar';
|
||||
@override String get server => 'Servidor';
|
||||
@override String starValue({required Object rating}) => '${rating} / 5';
|
||||
@override String scoreValue({required Object score}) => '${score} / 10';
|
||||
@override String get setScore => 'Definir pontuação';
|
||||
@override String get notRated => 'Sem avaliação';
|
||||
@override String get liked => 'Gostei';
|
||||
@override String get notLiked => 'Não marcado como gostei';
|
||||
@override String get saved => 'Salvo';
|
||||
@override String get notAvailable => 'Nenhuma correspondência encontrada';
|
||||
@override String get noConnectedTrackers => 'Conecte um rastreador em Configurações para avaliar lá.';
|
||||
}
|
||||
|
||||
// Path: accessibility
|
||||
class _TranslationsAccessibilityPt extends TranslationsAccessibilityEn {
|
||||
_TranslationsAccessibilityPt._(TranslationsPt root) : this._root = root, super.internal(root);
|
||||
@@ -2098,6 +2119,17 @@ extension on TranslationsPt {
|
||||
'mediaMenu.rate' => 'Avaliar',
|
||||
'mediaMenu.playFromBeginning' => 'Reproduzir do início',
|
||||
'mediaMenu.playVersion' => 'Reproduzir versão...',
|
||||
'rateSheet.title' => 'Avaliar',
|
||||
'rateSheet.server' => 'Servidor',
|
||||
'rateSheet.starValue' => ({required Object rating}) => '${rating} / 5',
|
||||
'rateSheet.scoreValue' => ({required Object score}) => '${score} / 10',
|
||||
'rateSheet.setScore' => 'Definir pontuação',
|
||||
'rateSheet.notRated' => 'Sem avaliação',
|
||||
'rateSheet.liked' => 'Gostei',
|
||||
'rateSheet.notLiked' => 'Não marcado como gostei',
|
||||
'rateSheet.saved' => 'Salvo',
|
||||
'rateSheet.notAvailable' => 'Nenhuma correspondência encontrada',
|
||||
'rateSheet.noConnectedTrackers' => 'Conecte um rastreador em Configurações para avaliar lá.',
|
||||
'accessibility.mediaCardMovie' => ({required Object title}) => '${title}, filme',
|
||||
'accessibility.mediaCardShow' => ({required Object title}) => '${title}, série de TV',
|
||||
'accessibility.mediaCardEpisode' => ({required Object title, required Object episodeInfo}) => '${title}, ${episodeInfo}',
|
||||
@@ -2273,6 +2305,8 @@ extension on TranslationsPt {
|
||||
'profiles.summaryMultiple' => ({required Object count}) => '${count} perfis',
|
||||
'profiles.removeConnectionTitle' => 'Remover conexão?',
|
||||
'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Remover acesso de ${displayName} a ${connectionLabel}. Outros perfis mantêm o acesso.',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.deleteProfileTitle' => 'Excluir perfil?',
|
||||
'profiles.deleteProfileMessage' => ({required Object displayName}) => 'Remover ${displayName} e suas conexões. Servidores continuam disponíveis.',
|
||||
'profiles.profileNameLabel' => 'Nome do perfil',
|
||||
@@ -2284,8 +2318,6 @@ extension on TranslationsPt {
|
||||
'profiles.confirmPinTitle' => 'Confirmar PIN',
|
||||
'profiles.pinSet' => 'PIN definido',
|
||||
'profiles.changePin' => 'Alterar',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.removePin' => 'Remover',
|
||||
'profiles.connectionsLabel' => 'Conexões',
|
||||
'profiles.add' => 'Adicionar',
|
||||
@@ -2787,6 +2819,8 @@ extension on TranslationsPt {
|
||||
'metadataEdit.selectSquareArt' => 'Selecionar Imagem Quadrada',
|
||||
'metadataEdit.fromUrl' => 'Da URL',
|
||||
'metadataEdit.uploadFile' => 'Enviar Arquivo',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.enterImageUrl' => 'Insira a URL da imagem',
|
||||
'metadataEdit.imageUrl' => 'URL da Imagem',
|
||||
'metadataEdit.metadataUpdated' => 'Metadados atualizados',
|
||||
@@ -2798,8 +2832,6 @@ extension on TranslationsPt {
|
||||
'metadataEdit.libraryDefault' => 'Padrão da biblioteca',
|
||||
'metadataEdit.accountDefault' => 'Padrão da conta',
|
||||
'metadataEdit.seriesDefault' => 'Padrão da série',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.episodeSorting' => 'Ordenação de Episódios',
|
||||
'metadataEdit.oldestFirst' => 'Mais antigos primeiro',
|
||||
'metadataEdit.newestFirst' => 'Mais recentes primeiro',
|
||||
|
||||
@@ -49,6 +49,7 @@ class TranslationsRu extends Translations with BaseTranslations<AppLocale, Trans
|
||||
@override late final _TranslationsHotkeysRu hotkeys = _TranslationsHotkeysRu._(_root);
|
||||
@override late final _TranslationsFileInfoRu fileInfo = _TranslationsFileInfoRu._(_root);
|
||||
@override late final _TranslationsMediaMenuRu mediaMenu = _TranslationsMediaMenuRu._(_root);
|
||||
@override late final _TranslationsRateSheetRu rateSheet = _TranslationsRateSheetRu._(_root);
|
||||
@override late final _TranslationsAccessibilityRu accessibility = _TranslationsAccessibilityRu._(_root);
|
||||
@override late final _TranslationsTooltipsRu tooltips = _TranslationsTooltipsRu._(_root);
|
||||
@override late final _TranslationsVideoControlsRu videoControls = _TranslationsVideoControlsRu._(_root);
|
||||
@@ -481,6 +482,26 @@ class _TranslationsMediaMenuRu extends TranslationsMediaMenuEn {
|
||||
@override String get playVersion => 'Воспроизвести версию...';
|
||||
}
|
||||
|
||||
// Path: rateSheet
|
||||
class _TranslationsRateSheetRu extends TranslationsRateSheetEn {
|
||||
_TranslationsRateSheetRu._(TranslationsRu root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsRu _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Оценить';
|
||||
@override String get server => 'Сервер';
|
||||
@override String starValue({required Object rating}) => '${rating} / 5';
|
||||
@override String scoreValue({required Object score}) => '${score} / 10';
|
||||
@override String get setScore => 'Установить оценку';
|
||||
@override String get notRated => 'Без оценки';
|
||||
@override String get liked => 'Понравилось';
|
||||
@override String get notLiked => 'Не отмечено понравившимся';
|
||||
@override String get saved => 'Сохранено';
|
||||
@override String get notAvailable => 'Совпадений не найдено';
|
||||
@override String get noConnectedTrackers => 'Подключите трекер в настройках, чтобы оценивать там.';
|
||||
}
|
||||
|
||||
// Path: accessibility
|
||||
class _TranslationsAccessibilityRu extends TranslationsAccessibilityEn {
|
||||
_TranslationsAccessibilityRu._(TranslationsRu root) : this._root = root, super.internal(root);
|
||||
@@ -2098,6 +2119,17 @@ extension on TranslationsRu {
|
||||
'mediaMenu.rate' => 'Оценить',
|
||||
'mediaMenu.playFromBeginning' => 'Воспроизвести сначала',
|
||||
'mediaMenu.playVersion' => 'Воспроизвести версию...',
|
||||
'rateSheet.title' => 'Оценить',
|
||||
'rateSheet.server' => 'Сервер',
|
||||
'rateSheet.starValue' => ({required Object rating}) => '${rating} / 5',
|
||||
'rateSheet.scoreValue' => ({required Object score}) => '${score} / 10',
|
||||
'rateSheet.setScore' => 'Установить оценку',
|
||||
'rateSheet.notRated' => 'Без оценки',
|
||||
'rateSheet.liked' => 'Понравилось',
|
||||
'rateSheet.notLiked' => 'Не отмечено понравившимся',
|
||||
'rateSheet.saved' => 'Сохранено',
|
||||
'rateSheet.notAvailable' => 'Совпадений не найдено',
|
||||
'rateSheet.noConnectedTrackers' => 'Подключите трекер в настройках, чтобы оценивать там.',
|
||||
'accessibility.mediaCardMovie' => ({required Object title}) => '${title}, фильм',
|
||||
'accessibility.mediaCardShow' => ({required Object title}) => '${title}, сериал',
|
||||
'accessibility.mediaCardEpisode' => ({required Object title, required Object episodeInfo}) => '${title}, ${episodeInfo}',
|
||||
@@ -2273,6 +2305,8 @@ extension on TranslationsRu {
|
||||
'profiles.summaryMultiple' => ({required Object count}) => '${count} профилей',
|
||||
'profiles.removeConnectionTitle' => 'Удалить соединение?',
|
||||
'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Удалить доступ ${displayName} к ${connectionLabel}. У других профилей он останется.',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.deleteProfileTitle' => 'Удалить профиль?',
|
||||
'profiles.deleteProfileMessage' => ({required Object displayName}) => 'Удалить ${displayName} и его подключения. Серверы останутся доступны.',
|
||||
'profiles.profileNameLabel' => 'Имя профиля',
|
||||
@@ -2284,8 +2318,6 @@ extension on TranslationsRu {
|
||||
'profiles.confirmPinTitle' => 'Подтвердить PIN',
|
||||
'profiles.pinSet' => 'PIN установлен',
|
||||
'profiles.changePin' => 'Изменить',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.removePin' => 'Удалить',
|
||||
'profiles.connectionsLabel' => 'Соединения',
|
||||
'profiles.add' => 'Добавить',
|
||||
@@ -2787,6 +2819,8 @@ extension on TranslationsRu {
|
||||
'metadataEdit.selectSquareArt' => 'Выбрать квадратное изображение',
|
||||
'metadataEdit.fromUrl' => 'По URL',
|
||||
'metadataEdit.uploadFile' => 'Загрузить файл',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.enterImageUrl' => 'Введите URL изображения',
|
||||
'metadataEdit.imageUrl' => 'URL изображения',
|
||||
'metadataEdit.metadataUpdated' => 'Метаданные обновлены',
|
||||
@@ -2798,8 +2832,6 @@ extension on TranslationsRu {
|
||||
'metadataEdit.libraryDefault' => 'По умолчанию библиотеки',
|
||||
'metadataEdit.accountDefault' => 'По умолчанию аккаунта',
|
||||
'metadataEdit.seriesDefault' => 'По умолчанию сериала',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.episodeSorting' => 'Сортировка эпизодов',
|
||||
'metadataEdit.oldestFirst' => 'Сначала старые',
|
||||
'metadataEdit.newestFirst' => 'Сначала новые',
|
||||
|
||||
@@ -49,6 +49,7 @@ class TranslationsSv extends Translations with BaseTranslations<AppLocale, Trans
|
||||
@override late final _TranslationsHotkeysSv hotkeys = _TranslationsHotkeysSv._(_root);
|
||||
@override late final _TranslationsFileInfoSv fileInfo = _TranslationsFileInfoSv._(_root);
|
||||
@override late final _TranslationsMediaMenuSv mediaMenu = _TranslationsMediaMenuSv._(_root);
|
||||
@override late final _TranslationsRateSheetSv rateSheet = _TranslationsRateSheetSv._(_root);
|
||||
@override late final _TranslationsAccessibilitySv accessibility = _TranslationsAccessibilitySv._(_root);
|
||||
@override late final _TranslationsTooltipsSv tooltips = _TranslationsTooltipsSv._(_root);
|
||||
@override late final _TranslationsVideoControlsSv videoControls = _TranslationsVideoControlsSv._(_root);
|
||||
@@ -481,6 +482,26 @@ class _TranslationsMediaMenuSv extends TranslationsMediaMenuEn {
|
||||
@override String get playVersion => 'Spela version...';
|
||||
}
|
||||
|
||||
// Path: rateSheet
|
||||
class _TranslationsRateSheetSv extends TranslationsRateSheetEn {
|
||||
_TranslationsRateSheetSv._(TranslationsSv root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsSv _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Betygsätt';
|
||||
@override String get server => 'Server';
|
||||
@override String starValue({required Object rating}) => '${rating} / 5';
|
||||
@override String scoreValue({required Object score}) => '${score} / 10';
|
||||
@override String get setScore => 'Ange betyg';
|
||||
@override String get notRated => 'Inte betygsatt';
|
||||
@override String get liked => 'Gillad';
|
||||
@override String get notLiked => 'Inte gillad';
|
||||
@override String get saved => 'Sparat';
|
||||
@override String get notAvailable => 'Ingen matchning hittades';
|
||||
@override String get noConnectedTrackers => 'Anslut en spårare i Inställningar för att betygsätta där.';
|
||||
}
|
||||
|
||||
// Path: accessibility
|
||||
class _TranslationsAccessibilitySv extends TranslationsAccessibilityEn {
|
||||
_TranslationsAccessibilitySv._(TranslationsSv root) : this._root = root, super.internal(root);
|
||||
@@ -2098,6 +2119,17 @@ extension on TranslationsSv {
|
||||
'mediaMenu.rate' => 'Betygsätt',
|
||||
'mediaMenu.playFromBeginning' => 'Spela från början',
|
||||
'mediaMenu.playVersion' => 'Spela version...',
|
||||
'rateSheet.title' => 'Betygsätt',
|
||||
'rateSheet.server' => 'Server',
|
||||
'rateSheet.starValue' => ({required Object rating}) => '${rating} / 5',
|
||||
'rateSheet.scoreValue' => ({required Object score}) => '${score} / 10',
|
||||
'rateSheet.setScore' => 'Ange betyg',
|
||||
'rateSheet.notRated' => 'Inte betygsatt',
|
||||
'rateSheet.liked' => 'Gillad',
|
||||
'rateSheet.notLiked' => 'Inte gillad',
|
||||
'rateSheet.saved' => 'Sparat',
|
||||
'rateSheet.notAvailable' => 'Ingen matchning hittades',
|
||||
'rateSheet.noConnectedTrackers' => 'Anslut en spårare i Inställningar för att betygsätta där.',
|
||||
'accessibility.mediaCardMovie' => ({required Object title}) => '${title}, film',
|
||||
'accessibility.mediaCardShow' => ({required Object title}) => '${title}, TV-serie',
|
||||
'accessibility.mediaCardEpisode' => ({required Object title, required Object episodeInfo}) => '${title}, ${episodeInfo}',
|
||||
@@ -2273,6 +2305,8 @@ extension on TranslationsSv {
|
||||
'profiles.summaryMultiple' => ({required Object count}) => '${count} profiler',
|
||||
'profiles.removeConnectionTitle' => 'Ta bort anslutning?',
|
||||
'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Ta bort ${displayName}s åtkomst till ${connectionLabel}. Andra profiler behåller den.',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.deleteProfileTitle' => 'Ta bort profil?',
|
||||
'profiles.deleteProfileMessage' => ({required Object displayName}) => 'Ta bort ${displayName} och dess anslutningar. Servrar förblir tillgängliga.',
|
||||
'profiles.profileNameLabel' => 'Profilnamn',
|
||||
@@ -2284,8 +2318,6 @@ extension on TranslationsSv {
|
||||
'profiles.confirmPinTitle' => 'Bekräfta PIN',
|
||||
'profiles.pinSet' => 'PIN angiven',
|
||||
'profiles.changePin' => 'Ändra',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.removePin' => 'Ta bort',
|
||||
'profiles.connectionsLabel' => 'Anslutningar',
|
||||
'profiles.add' => 'Lägg till',
|
||||
@@ -2787,6 +2819,8 @@ extension on TranslationsSv {
|
||||
'metadataEdit.selectSquareArt' => 'Välj kvadratisk bild',
|
||||
'metadataEdit.fromUrl' => 'Från URL',
|
||||
'metadataEdit.uploadFile' => 'Ladda upp fil',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.enterImageUrl' => 'Ange bild-URL',
|
||||
'metadataEdit.imageUrl' => 'Bild-URL',
|
||||
'metadataEdit.metadataUpdated' => 'Metadata uppdaterad',
|
||||
@@ -2798,8 +2832,6 @@ extension on TranslationsSv {
|
||||
'metadataEdit.libraryDefault' => 'Biblioteksstandard',
|
||||
'metadataEdit.accountDefault' => 'Kontostandard',
|
||||
'metadataEdit.seriesDefault' => 'Seriestandard',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.episodeSorting' => 'Avsnittsortering',
|
||||
'metadataEdit.oldestFirst' => 'Äldst först',
|
||||
'metadataEdit.newestFirst' => 'Nyast först',
|
||||
|
||||
@@ -49,6 +49,7 @@ class TranslationsZh extends Translations with BaseTranslations<AppLocale, Trans
|
||||
@override late final _TranslationsHotkeysZh hotkeys = _TranslationsHotkeysZh._(_root);
|
||||
@override late final _TranslationsFileInfoZh fileInfo = _TranslationsFileInfoZh._(_root);
|
||||
@override late final _TranslationsMediaMenuZh mediaMenu = _TranslationsMediaMenuZh._(_root);
|
||||
@override late final _TranslationsRateSheetZh rateSheet = _TranslationsRateSheetZh._(_root);
|
||||
@override late final _TranslationsAccessibilityZh accessibility = _TranslationsAccessibilityZh._(_root);
|
||||
@override late final _TranslationsTooltipsZh tooltips = _TranslationsTooltipsZh._(_root);
|
||||
@override late final _TranslationsVideoControlsZh videoControls = _TranslationsVideoControlsZh._(_root);
|
||||
@@ -481,6 +482,26 @@ class _TranslationsMediaMenuZh extends TranslationsMediaMenuEn {
|
||||
@override String get playVersion => '播放版本...';
|
||||
}
|
||||
|
||||
// Path: rateSheet
|
||||
class _TranslationsRateSheetZh extends TranslationsRateSheetEn {
|
||||
_TranslationsRateSheetZh._(TranslationsZh root) : this._root = root, super.internal(root);
|
||||
|
||||
final TranslationsZh _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => '评分';
|
||||
@override String get server => '服务器';
|
||||
@override String starValue({required Object rating}) => '${rating} / 5';
|
||||
@override String scoreValue({required Object score}) => '${score} / 10';
|
||||
@override String get setScore => '设置分数';
|
||||
@override String get notRated => '未评分';
|
||||
@override String get liked => '已喜欢';
|
||||
@override String get notLiked => '未喜欢';
|
||||
@override String get saved => '已保存';
|
||||
@override String get notAvailable => '未找到匹配项';
|
||||
@override String get noConnectedTrackers => '在设置中连接跟踪器即可在那里评分。';
|
||||
}
|
||||
|
||||
// Path: accessibility
|
||||
class _TranslationsAccessibilityZh extends TranslationsAccessibilityEn {
|
||||
_TranslationsAccessibilityZh._(TranslationsZh root) : this._root = root, super.internal(root);
|
||||
@@ -2098,6 +2119,17 @@ extension on TranslationsZh {
|
||||
'mediaMenu.rate' => '评分',
|
||||
'mediaMenu.playFromBeginning' => '从头播放',
|
||||
'mediaMenu.playVersion' => '播放版本...',
|
||||
'rateSheet.title' => '评分',
|
||||
'rateSheet.server' => '服务器',
|
||||
'rateSheet.starValue' => ({required Object rating}) => '${rating} / 5',
|
||||
'rateSheet.scoreValue' => ({required Object score}) => '${score} / 10',
|
||||
'rateSheet.setScore' => '设置分数',
|
||||
'rateSheet.notRated' => '未评分',
|
||||
'rateSheet.liked' => '已喜欢',
|
||||
'rateSheet.notLiked' => '未喜欢',
|
||||
'rateSheet.saved' => '已保存',
|
||||
'rateSheet.notAvailable' => '未找到匹配项',
|
||||
'rateSheet.noConnectedTrackers' => '在设置中连接跟踪器即可在那里评分。',
|
||||
'accessibility.mediaCardMovie' => ({required Object title}) => '${title}, 电影',
|
||||
'accessibility.mediaCardShow' => ({required Object title}) => '${title}, 电视剧',
|
||||
'accessibility.mediaCardEpisode' => ({required Object title, required Object episodeInfo}) => '${title}, ${episodeInfo}',
|
||||
@@ -2273,6 +2305,8 @@ extension on TranslationsZh {
|
||||
'profiles.summaryMultiple' => ({required Object count}) => '${count} 个配置文件',
|
||||
'profiles.removeConnectionTitle' => '移除连接?',
|
||||
'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => '移除 ${displayName} 对 ${connectionLabel} 的访问。其他个人资料仍保留。',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.deleteProfileTitle' => '删除配置文件?',
|
||||
'profiles.deleteProfileMessage' => ({required Object displayName}) => '移除 ${displayName} 及其连接。服务器仍可用。',
|
||||
'profiles.profileNameLabel' => '配置文件名称',
|
||||
@@ -2284,8 +2318,6 @@ extension on TranslationsZh {
|
||||
'profiles.confirmPinTitle' => '确认 PIN',
|
||||
'profiles.pinSet' => '已设置 PIN',
|
||||
'profiles.changePin' => '更改',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'profiles.removePin' => '移除',
|
||||
'profiles.connectionsLabel' => '连接',
|
||||
'profiles.add' => '添加',
|
||||
@@ -2787,6 +2819,8 @@ extension on TranslationsZh {
|
||||
'metadataEdit.selectSquareArt' => '选择方形图片',
|
||||
'metadataEdit.fromUrl' => '从 URL',
|
||||
'metadataEdit.uploadFile' => '上传文件',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.enterImageUrl' => '输入图片 URL',
|
||||
'metadataEdit.imageUrl' => '图片 URL',
|
||||
'metadataEdit.metadataUpdated' => '元数据已更新',
|
||||
@@ -2798,8 +2832,6 @@ extension on TranslationsZh {
|
||||
'metadataEdit.libraryDefault' => '媒体库默认',
|
||||
'metadataEdit.accountDefault' => '账户默认',
|
||||
'metadataEdit.seriesDefault' => '剧集默认',
|
||||
_ => null,
|
||||
} ?? switch (path) {
|
||||
'metadataEdit.episodeSorting' => '剧集排序',
|
||||
'metadataEdit.oldestFirst' => '最旧优先',
|
||||
'metadataEdit.newestFirst' => '最新优先',
|
||||
|
||||
@@ -347,6 +347,19 @@
|
||||
"playFromBeginning": "Spela från början",
|
||||
"playVersion": "Spela version..."
|
||||
},
|
||||
"rateSheet": {
|
||||
"title": "Betygsätt",
|
||||
"server": "Server",
|
||||
"starValue": "${rating} / 5",
|
||||
"scoreValue": "${score} / 10",
|
||||
"setScore": "Ange betyg",
|
||||
"notRated": "Inte betygsatt",
|
||||
"liked": "Gillad",
|
||||
"notLiked": "Inte gillad",
|
||||
"saved": "Sparat",
|
||||
"notAvailable": "Ingen matchning hittades",
|
||||
"noConnectedTrackers": "Anslut en spårare i Inställningar för att betygsätta där."
|
||||
},
|
||||
"accessibility": {
|
||||
"mediaCardMovie": "${title}, film",
|
||||
"mediaCardShow": "${title}, TV-serie",
|
||||
|
||||
@@ -347,6 +347,19 @@
|
||||
"playFromBeginning": "从头播放",
|
||||
"playVersion": "播放版本..."
|
||||
},
|
||||
"rateSheet": {
|
||||
"title": "评分",
|
||||
"server": "服务器",
|
||||
"starValue": "${rating} / 5",
|
||||
"scoreValue": "${score} / 10",
|
||||
"setScore": "设置分数",
|
||||
"notRated": "未评分",
|
||||
"liked": "已喜欢",
|
||||
"notLiked": "未喜欢",
|
||||
"saved": "已保存",
|
||||
"notAvailable": "未找到匹配项",
|
||||
"noConnectedTrackers": "在设置中连接跟踪器即可在那里评分。"
|
||||
},
|
||||
"accessibility": {
|
||||
"mediaCardMovie": "${title}, 电影",
|
||||
"mediaCardShow": "${title}, 电视剧",
|
||||
|
||||
@@ -20,7 +20,6 @@ import '../focus/focusable_wrapper.dart';
|
||||
import '../focus/key_event_utils.dart';
|
||||
import '../focus/input_mode_tracker.dart';
|
||||
import '../widgets/focus_builders.dart';
|
||||
import '../exceptions/media_server_exceptions.dart';
|
||||
import '../media/media_backend.dart';
|
||||
import '../media/media_hub.dart';
|
||||
import '../utils/provider_extensions.dart';
|
||||
@@ -774,9 +773,7 @@ class _MediaDetailScreenState extends State<MediaDetailScreen>
|
||||
return ListenableBuilder(
|
||||
listenable: _ratingChipFocusNode,
|
||||
builder: (context, _) {
|
||||
final activate = isNumeric
|
||||
? () => _showRatingDialog(context, metadata, starValue)
|
||||
: () => _toggleLike(metadata);
|
||||
final activate = () => _showRatingDialog(context, metadata);
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
final isKeyboardMode = InputModeTracker.isKeyboardMode(context);
|
||||
final showFocus = _ratingChipFocusNode.hasFocus && isKeyboardMode;
|
||||
@@ -831,57 +828,16 @@ class _MediaDetailScreenState extends State<MediaDetailScreen>
|
||||
);
|
||||
}
|
||||
|
||||
/// Like/unlike toggle for backends that only support binary ratings
|
||||
/// (Jellyfin). Maps to [MediaServerClient.rate] with 10 (like) or -1
|
||||
/// (clear) — the Jellyfin client routes those through POST/DELETE on
|
||||
/// `/UserItems/{id}/Rating`.
|
||||
Future<void> _toggleLike(MediaItem metadata) async {
|
||||
final client = _getMediaClientForMetadata(context);
|
||||
if (client == null) return;
|
||||
final wasLiked = metadata.userRating != null && metadata.userRating! >= 6;
|
||||
final newRating = wasLiked ? -1.0 : 10.0;
|
||||
try {
|
||||
await client.rate(metadata, newRating);
|
||||
setStateIfMounted(() {
|
||||
_fullMetadata = _fullMetadata?.copyWith(userRating: wasLiked ? 0 : 10);
|
||||
});
|
||||
} on MediaServerHttpException catch (e) {
|
||||
appLogger.w('Failed to toggle rating', error: e);
|
||||
if (mounted) showErrorSnackBar(context, t.errors.failedToRate);
|
||||
}
|
||||
}
|
||||
|
||||
void _showRatingDialog(BuildContext sheetContext, MediaItem metadata, double currentStarValue) {
|
||||
void _showRatingDialog(BuildContext sheetContext, MediaItem metadata) {
|
||||
OverlaySheetController.showAdaptive(
|
||||
sheetContext,
|
||||
builder: (context) => RatingBottomSheet(
|
||||
currentRating: currentStarValue,
|
||||
onRate: (stars) async {
|
||||
final client = _getMediaClientForMetadata(this.context);
|
||||
if (client == null) return;
|
||||
final plexRating = stars * 2.0; // Convert 0-5 stars to 0-10 scale
|
||||
try {
|
||||
await client.rate(metadata, plexRating);
|
||||
setStateIfMounted(() {
|
||||
_fullMetadata = _fullMetadata?.copyWith(userRating: plexRating);
|
||||
});
|
||||
} on MediaServerHttpException catch (e) {
|
||||
appLogger.w('Failed to set rating', error: e);
|
||||
if (mounted) showErrorSnackBar(this.context, t.errors.failedToRate);
|
||||
}
|
||||
},
|
||||
onClear: () async {
|
||||
final client = _getMediaClientForMetadata(this.context);
|
||||
if (client == null) return;
|
||||
try {
|
||||
await client.rate(metadata, -1);
|
||||
setStateIfMounted(() {
|
||||
_fullMetadata = _fullMetadata?.copyWith(userRating: 0);
|
||||
});
|
||||
} on MediaServerHttpException catch (e) {
|
||||
appLogger.w('Failed to clear rating', error: e);
|
||||
if (mounted) showErrorSnackBar(this.context, t.errors.failedToRate);
|
||||
}
|
||||
item: metadata,
|
||||
serverClient: _getMediaClientForMetadata(this.context),
|
||||
onServerRatingChanged: (rating) {
|
||||
setStateIfMounted(() {
|
||||
_fullMetadata = (_fullMetadata ?? widget.metadata).copyWith(userRating: rating);
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
@@ -50,6 +50,37 @@ class AnilistClient {
|
||||
await query(mutation, variables: {'mediaId': mediaId, 'progress': progress, 'status': status});
|
||||
}
|
||||
|
||||
Future<void> setMediaListScore({required int mediaId, required int score}) async {
|
||||
const mutation = '''
|
||||
mutation(\$mediaId: Int, \$scoreRaw: Int) {
|
||||
SaveMediaListEntry(mediaId: \$mediaId, scoreRaw: \$scoreRaw) {
|
||||
id
|
||||
}
|
||||
}
|
||||
''';
|
||||
await query(mutation, variables: {'mediaId': mediaId, 'scoreRaw': score.clamp(0, 10).toInt() * 10});
|
||||
}
|
||||
|
||||
Future<int?> getMediaListScore(int mediaId) async {
|
||||
const mediaQuery = '''
|
||||
query(\$mediaId: Int) {
|
||||
Media(id: \$mediaId, type: ANIME) {
|
||||
mediaListEntry {
|
||||
scoreRaw: score(format: POINT_100)
|
||||
}
|
||||
}
|
||||
}
|
||||
''';
|
||||
final data = await query(mediaQuery, variables: {'mediaId': mediaId});
|
||||
final media = data['Media'];
|
||||
if (media is! Map) return null;
|
||||
final entry = media['mediaListEntry'];
|
||||
if (entry is! Map) return null;
|
||||
final scoreRaw = flexibleInt(entry['scoreRaw']);
|
||||
if (scoreRaw == null || scoreRaw <= 0) return null;
|
||||
return (scoreRaw / 10).round().clamp(1, 10).toInt();
|
||||
}
|
||||
|
||||
Future<int?> getAnimeEpisodeCount(int mediaId) async {
|
||||
const mediaQuery = '''
|
||||
query(\$mediaId: Int) {
|
||||
|
||||
@@ -5,6 +5,7 @@ import '../../../utils/app_logger.dart';
|
||||
import '../../settings_service.dart';
|
||||
import '../tracker.dart';
|
||||
import '../tracker_constants.dart';
|
||||
import '../tracker_id_resolver.dart';
|
||||
import 'anilist_client.dart';
|
||||
import 'anilist_session.dart';
|
||||
|
||||
@@ -63,6 +64,32 @@ class AnilistTracker extends TrackerBase {
|
||||
appLogger.d('AniList: saved entry (anilist=$anilistId, progress=$watched, status=$status)');
|
||||
}
|
||||
|
||||
Future<void> rate(TrackerRatingContext ctx, int score) async {
|
||||
final client = _client;
|
||||
final anilistId = ctx.ids.anime?.anilist;
|
||||
if (client == null || anilistId == null) throw const TrackerRatingUnavailableException('AniList');
|
||||
|
||||
final clamped = score.clamp(1, 10).toInt();
|
||||
await client.setMediaListScore(mediaId: anilistId, score: clamped);
|
||||
appLogger.d('AniList: updated score (anilist=$anilistId, score=$clamped)');
|
||||
}
|
||||
|
||||
Future<void> clearRating(TrackerRatingContext ctx) async {
|
||||
final client = _client;
|
||||
final anilistId = ctx.ids.anime?.anilist;
|
||||
if (client == null || anilistId == null) throw const TrackerRatingUnavailableException('AniList');
|
||||
|
||||
await client.setMediaListScore(mediaId: anilistId, score: 0);
|
||||
appLogger.d('AniList: cleared score (anilist=$anilistId)');
|
||||
}
|
||||
|
||||
Future<int?> getRating(TrackerRatingContext ctx) async {
|
||||
final client = _client;
|
||||
final anilistId = ctx.ids.anime?.anilist;
|
||||
if (client == null || anilistId == null) throw const TrackerRatingUnavailableException('AniList');
|
||||
return client.getMediaListScore(anilistId);
|
||||
}
|
||||
|
||||
Future<int?> _episodeCount(AnilistClient client, int anilistId) {
|
||||
final existing = _episodeCountLoads[anilistId];
|
||||
if (existing != null) return existing;
|
||||
|
||||
@@ -60,6 +60,20 @@ class MalClient {
|
||||
await _request('PUT', '/anime/$animeId/my_list_status', formBody: fields);
|
||||
}
|
||||
|
||||
Future<int?> getMyListScore(int animeId) async {
|
||||
try {
|
||||
final res = await _request('GET', '/anime/$animeId?fields=my_list_status');
|
||||
if (res is! Map) return null;
|
||||
final myListStatus = res['my_list_status'];
|
||||
if (myListStatus is! Map) return null;
|
||||
final score = flexibleInt(myListStatus['score']);
|
||||
return score != null && score > 0 ? score : null;
|
||||
} on MalApiException catch (e) {
|
||||
if (e.statusCode == 404) return null;
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<int?> getAnimeEpisodeCount(int animeId) async {
|
||||
final res = await _request('GET', '/anime/$animeId?fields=num_episodes');
|
||||
if (res is! Map) return null;
|
||||
|
||||
@@ -5,6 +5,7 @@ import '../../../utils/app_logger.dart';
|
||||
import '../../settings_service.dart';
|
||||
import '../tracker.dart';
|
||||
import '../tracker_constants.dart';
|
||||
import '../tracker_id_resolver.dart';
|
||||
import 'mal_client.dart';
|
||||
import 'mal_session.dart';
|
||||
|
||||
@@ -80,6 +81,32 @@ class MalTracker extends TrackerBase {
|
||||
appLogger.d('MAL: updated list status (mal=$malId, fields=$fields)');
|
||||
}
|
||||
|
||||
Future<void> rate(TrackerRatingContext ctx, int score) async {
|
||||
final client = _client;
|
||||
final malId = ctx.ids.anime?.mal;
|
||||
if (client == null || malId == null) throw const TrackerRatingUnavailableException('MAL');
|
||||
|
||||
final clamped = score.clamp(1, 10).toInt();
|
||||
await client.updateMyListStatus(malId, {'score': '$clamped'});
|
||||
appLogger.d('MAL: updated score (mal=$malId, score=$clamped)');
|
||||
}
|
||||
|
||||
Future<void> clearRating(TrackerRatingContext ctx) async {
|
||||
final client = _client;
|
||||
final malId = ctx.ids.anime?.mal;
|
||||
if (client == null || malId == null) throw const TrackerRatingUnavailableException('MAL');
|
||||
|
||||
await client.updateMyListStatus(malId, {'score': '0'});
|
||||
appLogger.d('MAL: cleared score (mal=$malId)');
|
||||
}
|
||||
|
||||
Future<int?> getRating(TrackerRatingContext ctx) async {
|
||||
final client = _client;
|
||||
final malId = ctx.ids.anime?.mal;
|
||||
if (client == null || malId == null) throw const TrackerRatingUnavailableException('MAL');
|
||||
return client.getMyListScore(malId);
|
||||
}
|
||||
|
||||
Future<int?> _episodeCount(MalClient client, int malId) {
|
||||
final existing = _episodeCountLoads[malId];
|
||||
if (existing != null) return existing;
|
||||
|
||||
@@ -39,6 +39,17 @@ class SimklClient {
|
||||
/// ```
|
||||
Future<void> addToHistory(Map<String, dynamic> body) => _request('POST', '/sync/history', body: body);
|
||||
|
||||
Future<void> addRatings(Map<String, dynamic> body) => _request('POST', '/sync/ratings', body: body);
|
||||
|
||||
Future<void> removeRatings(Map<String, dynamic> body) => _request('POST', '/sync/ratings/remove', body: body);
|
||||
|
||||
Future<List<dynamic>> getRatings(String type) async {
|
||||
final res = await _request('GET', '/sync/ratings/$type');
|
||||
if (res is List) return res;
|
||||
if (res is Map && res[type] is List) return res[type] as List<dynamic>;
|
||||
return const [];
|
||||
}
|
||||
|
||||
Future<dynamic> _request(String method, String path, {Map<String, dynamic>? body}) async {
|
||||
final uri = Uri.parse('${SimklConstants.apiBase}$path');
|
||||
final headers = SimklConstants.headers(accessToken: session.accessToken);
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import '../../../models/trackers/anime_ids.dart';
|
||||
import '../../../models/trackers/tracker_context.dart';
|
||||
import '../../../utils/app_logger.dart';
|
||||
import '../../../utils/external_ids.dart';
|
||||
import '../../../utils/json_utils.dart';
|
||||
import '../../settings_service.dart';
|
||||
import '../tracker.dart';
|
||||
import '../tracker_constants.dart';
|
||||
import '../tracker_id_resolver.dart';
|
||||
import 'simkl_client.dart';
|
||||
import 'simkl_session.dart';
|
||||
|
||||
@@ -35,9 +41,11 @@ class SimklTracker extends TrackerBase {
|
||||
@override
|
||||
bool readEnabledSetting(SettingsService settings) => settings.read(SettingsService.enableSimklScrobble);
|
||||
|
||||
void rebindSession(SimklSession? session, {required void Function() onSessionInvalidated}) {
|
||||
void rebindSession(SimklSession? session, {required void Function() onSessionInvalidated, http.Client? httpClient}) {
|
||||
_client?.dispose();
|
||||
_client = session != null ? SimklClient(session, onSessionInvalidated: onSessionInvalidated) : null;
|
||||
_client = session != null
|
||||
? SimklClient(session, onSessionInvalidated: onSessionInvalidated, httpClient: httpClient)
|
||||
: null;
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -45,7 +53,7 @@ class SimklTracker extends TrackerBase {
|
||||
final client = _client;
|
||||
if (client == null) return;
|
||||
|
||||
final ids = _buildIds(ctx);
|
||||
final ids = _buildIds(external: ctx.external, anime: ctx.anime);
|
||||
if (ids.isEmpty) return;
|
||||
|
||||
final body = ctx.isMovie
|
||||
@@ -74,17 +82,90 @@ class SimklTracker extends TrackerBase {
|
||||
appLogger.d('Simkl: marked watched (ids=$ids, isMovie=${ctx.isMovie})');
|
||||
}
|
||||
|
||||
Future<int?> getRating(TrackerRatingContext ctx) async {
|
||||
final client = _client;
|
||||
if (client == null) throw const TrackerRatingUnavailableException('Simkl');
|
||||
final ids = _buildIds(external: ctx.ids.external, anime: ctx.ids.anime);
|
||||
if (ids.isEmpty) throw const TrackerRatingUnavailableException('Simkl');
|
||||
|
||||
final types = ctx.isMovie ? const ['movies'] : const ['shows', 'anime'];
|
||||
for (final type in types) {
|
||||
final entries = await client.getRatings(type);
|
||||
for (final entry in entries) {
|
||||
if (entry is! Map) continue;
|
||||
final map = entry.cast<String, dynamic>();
|
||||
final media = map[ctx.isMovie ? 'movie' : 'show'];
|
||||
final remoteIds = _nestedIds(media) ?? _nestedIds(map);
|
||||
if (!_idsMatch(remoteIds, ids)) continue;
|
||||
final rating = flexibleInt(map['user_rating']) ?? flexibleInt(map['rating']);
|
||||
return rating != null && rating > 0 ? rating.clamp(1, 10).toInt() : null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<void> rate(TrackerRatingContext ctx, int score) async {
|
||||
final client = _client;
|
||||
if (client == null) throw const TrackerRatingUnavailableException('Simkl');
|
||||
final ids = _buildIds(external: ctx.ids.external, anime: ctx.ids.anime);
|
||||
if (ids.isEmpty) throw const TrackerRatingUnavailableException('Simkl');
|
||||
|
||||
final clamped = score.clamp(1, 10).toInt();
|
||||
await client.addRatings(_ratingBody(ctx, ids, rating: clamped));
|
||||
appLogger.d('Simkl: updated score (ids=$ids, score=$clamped)');
|
||||
}
|
||||
|
||||
Future<void> clearRating(TrackerRatingContext ctx) async {
|
||||
final client = _client;
|
||||
if (client == null) throw const TrackerRatingUnavailableException('Simkl');
|
||||
final ids = _buildIds(external: ctx.ids.external, anime: ctx.ids.anime);
|
||||
if (ids.isEmpty) throw const TrackerRatingUnavailableException('Simkl');
|
||||
|
||||
await client.removeRatings(_ratingBody(ctx, ids));
|
||||
appLogger.d('Simkl: cleared score (ids=$ids)');
|
||||
}
|
||||
|
||||
Map<String, dynamic> _ratingBody(TrackerRatingContext ctx, Map<String, Object> ids, {int? rating}) {
|
||||
final item = {'ids': ids, if (rating != null) 'rating': rating};
|
||||
return ctx.isMovie
|
||||
? {
|
||||
'movies': [item],
|
||||
}
|
||||
: {
|
||||
'shows': [item],
|
||||
};
|
||||
}
|
||||
|
||||
Map<String, dynamic>? _nestedIds(Object? value) {
|
||||
if (value is! Map) return null;
|
||||
final ids = value['ids'];
|
||||
return ids is Map ? ids.cast<String, dynamic>() : null;
|
||||
}
|
||||
|
||||
bool _idsMatch(Map<String, dynamic>? remoteIds, Map<String, Object> localIds) {
|
||||
if (remoteIds == null) return false;
|
||||
for (final entry in localIds.entries) {
|
||||
final remote = remoteIds[entry.key];
|
||||
if (remote == null) continue;
|
||||
if (entry.value is String && remote.toString() == entry.value) return true;
|
||||
final remoteInt = flexibleInt(remote);
|
||||
final localInt = flexibleInt(entry.value);
|
||||
if (remoteInt != null && localInt != null && remoteInt == localInt) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Prefer Fribb's simkl_id for precision; otherwise send whatever Plex
|
||||
/// exposes. Simkl accepts tvdb/imdb/tmdb in both movie and show shapes.
|
||||
Map<String, Object> _buildIds(TrackerContext ctx) {
|
||||
Map<String, Object> _buildIds({required ExternalIds external, required AnimeIds? anime}) {
|
||||
final ids = <String, Object>{};
|
||||
final simklId = ctx.anime?.simkl;
|
||||
final simklId = anime?.simkl;
|
||||
if (simklId != null) ids['simkl'] = simklId;
|
||||
final tvdb = ctx.external.tvdb;
|
||||
final tvdb = external.tvdb;
|
||||
if (tvdb != null) ids['tvdb'] = tvdb;
|
||||
final tmdb = ctx.external.tmdb;
|
||||
final tmdb = external.tmdb;
|
||||
if (tmdb != null) ids['tmdb'] = tmdb;
|
||||
final imdb = ctx.external.imdb;
|
||||
final imdb = external.imdb;
|
||||
if (imdb != null) ids['imdb'] = imdb;
|
||||
return ids;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,15 @@ abstract class Tracker {
|
||||
Future<void> markWatched(TrackerContext ctx);
|
||||
}
|
||||
|
||||
class TrackerRatingUnavailableException implements Exception {
|
||||
final String trackerName;
|
||||
|
||||
const TrackerRatingUnavailableException(this.trackerName);
|
||||
|
||||
@override
|
||||
String toString() => 'TrackerRatingUnavailableException($trackerName)';
|
||||
}
|
||||
|
||||
/// Shared enabled-state bookkeeping. Subclasses override [hasActiveClient],
|
||||
/// [readEnabledSetting], and [markWatched].
|
||||
abstract class TrackerBase implements Tracker {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import '../../media/media_item.dart';
|
||||
import '../../media/media_kind.dart';
|
||||
import '../../media/media_server_client.dart';
|
||||
import '../../models/trackers/anime_ids.dart';
|
||||
import '../../models/trackers/fribb_mapping_row.dart';
|
||||
@@ -27,6 +28,22 @@ class TrackerIds {
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolved IDs for manually rating a media item on external trackers.
|
||||
///
|
||||
/// For TV items, [ids.external] is the show-level ID set. Trakt can then rate
|
||||
/// the show/season/episode through nested season/episode numbers, while MAL,
|
||||
/// AniList, and Simkl rate the mapped anime/show entry itself.
|
||||
class TrackerRatingContext {
|
||||
final TrackerIds ids;
|
||||
final MediaKind kind;
|
||||
final int? season;
|
||||
final int? episodeNumber;
|
||||
|
||||
const TrackerRatingContext({required this.ids, required this.kind, this.season, this.episodeNumber});
|
||||
|
||||
bool get isMovie => kind == MediaKind.movie;
|
||||
}
|
||||
|
||||
/// Resolves item ids → tracker external IDs. Returns both backend-native
|
||||
/// external IDs (used by Trakt and by Simkl for non-anime matches) and Fribb
|
||||
/// anime IDs (used by MAL/AniList, and by Simkl for anime precision).
|
||||
@@ -100,6 +117,46 @@ class TrackerIdResolver {
|
||||
return ids.withAnimeProgress(progress);
|
||||
}
|
||||
|
||||
/// Resolve IDs for manual tracker ratings. Ratings can be attached to a
|
||||
/// movie, show, season, or episode from the detail screen/context menu.
|
||||
Future<TrackerRatingContext?> resolveForRating(MediaItem item) async {
|
||||
switch (item.kind) {
|
||||
case MediaKind.movie:
|
||||
final ids = await resolveForMovie(item.id);
|
||||
return ids == null ? null : TrackerRatingContext(ids: ids, kind: MediaKind.movie);
|
||||
case MediaKind.show:
|
||||
final ids = await _resolveShow(item.id);
|
||||
return ids == null ? null : TrackerRatingContext(ids: ids, kind: MediaKind.show);
|
||||
case MediaKind.season:
|
||||
final showId = item.parentId;
|
||||
final season = item.index ?? item.parentIndex;
|
||||
if (showId == null || showId.isEmpty || season == null) return null;
|
||||
final ids = await _resolveShow(showId, season: season);
|
||||
return ids == null ? null : TrackerRatingContext(ids: ids, kind: MediaKind.season, season: season);
|
||||
case MediaKind.episode:
|
||||
final season = item.parentIndex;
|
||||
final number = item.index;
|
||||
if (season == null || number == null) return null;
|
||||
final ids = await resolveShowForEpisode(item);
|
||||
return ids == null
|
||||
? null
|
||||
: TrackerRatingContext(ids: ids, kind: MediaKind.episode, season: season, episodeNumber: number);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<TrackerIds?> _resolveShow(String showId, {int? season}) async {
|
||||
if (showId.isEmpty) return null;
|
||||
final cacheKey = season != null ? '$showId#s$season' : showId;
|
||||
if (_cache.containsKey(cacheKey)) return _cache[cacheKey];
|
||||
|
||||
final external = await _fetchExternalIds(showId);
|
||||
final ids = await _build(external, isEpisodeSeason: season, isMovie: false);
|
||||
_cache[cacheKey] = ids;
|
||||
return ids;
|
||||
}
|
||||
|
||||
void clearCache() {
|
||||
_cache.clear();
|
||||
_animeProgress.clearCache();
|
||||
|
||||
@@ -59,6 +59,16 @@ class TraktClient {
|
||||
Future<void> removeFromHistory(TraktScrobbleRequest item) =>
|
||||
_request('POST', '/sync/history/remove', body: item.toHistoryRemoveBody());
|
||||
|
||||
Future<void> addRatings(Map<String, dynamic> body) =>
|
||||
_request('POST', '/sync/ratings', body: body, allowStatuses: const {200, 201});
|
||||
|
||||
Future<void> removeRatings(Map<String, dynamic> body) => _request('POST', '/sync/ratings/remove', body: body);
|
||||
|
||||
Future<List<dynamic>> getRatings(String type) async {
|
||||
final res = await _request('GET', '/sync/ratings/$type');
|
||||
return res is List ? res : const [];
|
||||
}
|
||||
|
||||
/// Refresh the access token. Coalesces concurrent calls so
|
||||
/// duplicate POSTs don't race when multiple in-flight requests hit 401.
|
||||
Future<TraktSession> refresh() => _refreshCoalescer.run(_doRefresh);
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import '../../media/media_item.dart';
|
||||
import '../../media/media_kind.dart';
|
||||
import '../../media/media_server_client.dart';
|
||||
import '../../models/trakt/trakt_ids.dart';
|
||||
import '../../models/trakt/trakt_scrobble_request.dart';
|
||||
import '../../utils/app_logger.dart';
|
||||
import '../../utils/json_utils.dart';
|
||||
import '../settings_service.dart';
|
||||
import '../trackers/tracker.dart';
|
||||
import '../trackers/tracker_constants.dart';
|
||||
import '../trackers/tracker_id_resolver.dart';
|
||||
import 'trakt_client.dart';
|
||||
@@ -66,12 +70,46 @@ class TraktScrobbleService {
|
||||
|
||||
/// Switch to a different account. Cancels any in-flight scrobble for the
|
||||
/// previous account so we don't send a stop event to the wrong user.
|
||||
void rebindToProfile(TraktSession? session, {required void Function() onSessionInvalidated}) {
|
||||
void rebindToProfile(
|
||||
TraktSession? session, {
|
||||
required void Function() onSessionInvalidated,
|
||||
http.Client? httpClient,
|
||||
}) {
|
||||
_client?.dispose();
|
||||
_client = session != null ? TraktClient(session, onSessionInvalidated: onSessionInvalidated) : null;
|
||||
_client = session != null
|
||||
? TraktClient(session, onSessionInvalidated: onSessionInvalidated, httpClient: httpClient)
|
||||
: null;
|
||||
cancelInFlight();
|
||||
}
|
||||
|
||||
Future<int?> getRating(TrackerRatingContext ctx) async {
|
||||
final client = _client;
|
||||
if (client == null) throw const TrackerRatingUnavailableException('Trakt');
|
||||
final localIds = TraktIds.fromExternal(ctx.ids.external).toJson();
|
||||
if (localIds.isEmpty) throw const TrackerRatingUnavailableException('Trakt');
|
||||
|
||||
final entries = await client.getRatings(_ratingType(ctx));
|
||||
for (final entry in entries) {
|
||||
if (entry is! Map) continue;
|
||||
if (!_ratingEntryMatches(ctx, entry.cast<String, dynamic>(), localIds)) continue;
|
||||
final rating = flexibleInt(entry['rating']);
|
||||
return rating != null && rating > 0 ? rating.clamp(1, 10).toInt() : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<void> rate(TrackerRatingContext ctx, int score) async {
|
||||
final client = _client;
|
||||
if (client == null) throw const TrackerRatingUnavailableException('Trakt');
|
||||
await client.addRatings(_ratingBody(ctx, rating: score.clamp(1, 10).toInt()));
|
||||
}
|
||||
|
||||
Future<void> clearRating(TrackerRatingContext ctx) async {
|
||||
final client = _client;
|
||||
if (client == null) throw const TrackerRatingUnavailableException('Trakt');
|
||||
await client.removeRatings(_ratingBody(ctx));
|
||||
}
|
||||
|
||||
/// Drop the current scrobble state without sending a stop. Called on profile
|
||||
/// switch and when the service is disabled mid-playback.
|
||||
void cancelInFlight() {
|
||||
@@ -86,6 +124,100 @@ class TraktScrobbleService {
|
||||
|
||||
bool get _canScrobble => _isEnabled && _client != null;
|
||||
|
||||
String _ratingType(TrackerRatingContext ctx) => switch (ctx.kind) {
|
||||
MediaKind.movie => 'movies',
|
||||
MediaKind.show => 'shows',
|
||||
MediaKind.season => 'seasons',
|
||||
MediaKind.episode => 'episodes',
|
||||
_ => throw const TrackerRatingUnavailableException('Trakt'),
|
||||
};
|
||||
|
||||
bool _ratingEntryMatches(TrackerRatingContext ctx, Map<String, dynamic> entry, Map<String, dynamic> localIds) {
|
||||
final show = entry['show'];
|
||||
final movie = entry['movie'];
|
||||
return switch (ctx.kind) {
|
||||
MediaKind.movie => _idsMatch(_nestedIds(movie), localIds),
|
||||
MediaKind.show => _idsMatch(_nestedIds(show), localIds),
|
||||
MediaKind.season => _idsMatch(_nestedIds(show), localIds) && _numberMatches(entry['season'], ctx.season),
|
||||
MediaKind.episode =>
|
||||
_idsMatch(_nestedIds(show), localIds) &&
|
||||
_numberMatches(entry['episode'], ctx.episodeNumber) &&
|
||||
_seasonMatches(entry['episode'], ctx.season),
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
||||
Map<String, dynamic>? _nestedIds(Object? value) {
|
||||
if (value is! Map) return null;
|
||||
final ids = value['ids'];
|
||||
return ids is Map ? ids.cast<String, dynamic>() : null;
|
||||
}
|
||||
|
||||
bool _idsMatch(Map<String, dynamic>? remoteIds, Map<String, dynamic> localIds) {
|
||||
if (remoteIds == null) return false;
|
||||
for (final entry in localIds.entries) {
|
||||
final local = entry.value;
|
||||
if (local == null) continue;
|
||||
final remote = remoteIds[entry.key];
|
||||
if (remote == null) continue;
|
||||
if (local is String && remote.toString() == local) return true;
|
||||
final remoteInt = flexibleInt(remote);
|
||||
final localInt = flexibleInt(local);
|
||||
if (remoteInt != null && localInt != null && remoteInt == localInt) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool _numberMatches(Object? value, int? expected) {
|
||||
if (expected == null || value is! Map) return false;
|
||||
return flexibleInt(value['number']) == expected;
|
||||
}
|
||||
|
||||
bool _seasonMatches(Object? value, int? expected) {
|
||||
if (expected == null || value is! Map) return false;
|
||||
return flexibleInt(value['season']) == expected;
|
||||
}
|
||||
|
||||
Map<String, dynamic> _ratingBody(TrackerRatingContext ctx, {int? rating}) {
|
||||
final ids = TraktIds.fromExternal(ctx.ids.external).toJson();
|
||||
final item = {'ids': ids, if (rating != null) 'rating': rating};
|
||||
|
||||
return switch (ctx.kind) {
|
||||
MediaKind.movie => {
|
||||
'movies': [item],
|
||||
},
|
||||
MediaKind.show => {
|
||||
'shows': [item],
|
||||
},
|
||||
MediaKind.season => {
|
||||
'shows': [
|
||||
{
|
||||
'ids': ids,
|
||||
'seasons': [
|
||||
{'number': ctx.season, if (rating != null) 'rating': rating},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
MediaKind.episode => {
|
||||
'shows': [
|
||||
{
|
||||
'ids': ids,
|
||||
'seasons': [
|
||||
{
|
||||
'number': ctx.season,
|
||||
'episodes': [
|
||||
{'number': ctx.episodeNumber, if (rating != null) 'rating': rating},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
_ => throw const TrackerRatingUnavailableException('Trakt'),
|
||||
};
|
||||
}
|
||||
|
||||
Future<void> startPlayback(MediaItem metadata, MediaServerClient client, {bool isLive = false}) async {
|
||||
if (!_canScrobble) return;
|
||||
if (isLive) return;
|
||||
|
||||
@@ -5,7 +5,6 @@ import 'package:flutter/material.dart';
|
||||
import 'package:plezy/widgets/app_icon.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import '../exceptions/media_server_exceptions.dart';
|
||||
import '../media/media_backend.dart';
|
||||
import '../media/media_item.dart';
|
||||
import '../media/media_kind.dart';
|
||||
@@ -1116,32 +1115,13 @@ class MediaContextMenuState extends State<MediaContextMenu> {
|
||||
}
|
||||
|
||||
Future<void> _showRatingSheet(BuildContext context, MediaItem item, MediaServerClient client) async {
|
||||
final currentStarValue = (item.userRating != null && item.userRating! > 0) ? item.userRating! / 2.0 : 0.0;
|
||||
await OverlaySheetController.showAdaptive(
|
||||
context,
|
||||
showDragHandle: true,
|
||||
builder: (context) => RatingBottomSheet(
|
||||
currentRating: currentStarValue,
|
||||
onRate: (stars) async {
|
||||
// 0-10 scale used by both Plex and Jellyfin rate endpoints.
|
||||
final rating = stars * 2.0;
|
||||
try {
|
||||
await client.rate(item, rating);
|
||||
widget.onRefresh?.call(item.id);
|
||||
} on MediaServerHttpException catch (e) {
|
||||
appLogger.w('Failed to set rating', error: e);
|
||||
if (context.mounted) showErrorSnackBar(context, t.errors.failedToRate);
|
||||
}
|
||||
},
|
||||
onClear: () async {
|
||||
try {
|
||||
await client.rate(item, -1);
|
||||
widget.onRefresh?.call(item.id);
|
||||
} on MediaServerHttpException catch (e) {
|
||||
appLogger.w('Failed to clear rating', error: e);
|
||||
if (context.mounted) showErrorSnackBar(context, t.errors.failedToRate);
|
||||
}
|
||||
},
|
||||
item: item,
|
||||
serverClient: client,
|
||||
onServerRatingChanged: (_) => widget.onRefresh?.call(item.id),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user