@@ -1046,6 +1046,20 @@
|
||||
"body": "Scan denne QR-kode med din telefon, eller åbn URL'en nedenfor på en enhed med browser.",
|
||||
"openToSignIn": "Åbn ${service} for at logge ind",
|
||||
"urlCopied": "URL kopieret"
|
||||
},
|
||||
"libraryFilter": {
|
||||
"title": "Bibliotekfilter",
|
||||
"subtitleAllSyncing": "Synkroniserer alle biblioteker",
|
||||
"subtitleNoneSyncing": "Intet synkroniseres",
|
||||
"subtitleBlocked": "${count} blokeret",
|
||||
"subtitleAllowed": "${count} tilladt",
|
||||
"mode": "Filtertilstand",
|
||||
"modeBlacklist": "Sortliste",
|
||||
"modeWhitelist": "Hvidliste",
|
||||
"modeHintBlacklist": "Synkroniser alle biblioteker undtagen dem du markerer nedenfor.",
|
||||
"modeHintWhitelist": "Synkroniser kun de biblioteker du markerer nedenfor.",
|
||||
"libraries": "Biblioteker",
|
||||
"noLibraries": "Ingen biblioteker tilgængelige"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,6 +1046,20 @@
|
||||
"body": "Scanne diesen QR-Code mit deinem Handy oder öffne die URL unten auf einem Gerät mit Browser.",
|
||||
"openToSignIn": "${service} zum Anmelden öffnen",
|
||||
"urlCopied": "URL kopiert"
|
||||
},
|
||||
"libraryFilter": {
|
||||
"title": "Bibliothekfilter",
|
||||
"subtitleAllSyncing": "Alle Bibliotheken werden synchronisiert",
|
||||
"subtitleNoneSyncing": "Nichts wird synchronisiert",
|
||||
"subtitleBlocked": "${count} blockiert",
|
||||
"subtitleAllowed": "${count} erlaubt",
|
||||
"mode": "Filtermodus",
|
||||
"modeBlacklist": "Blacklist",
|
||||
"modeWhitelist": "Whitelist",
|
||||
"modeHintBlacklist": "Alle Bibliotheken außer den unten markierten synchronisieren.",
|
||||
"modeHintWhitelist": "Nur die unten markierten Bibliotheken synchronisieren.",
|
||||
"libraries": "Bibliotheken",
|
||||
"noLibraries": "Keine Bibliotheken verfügbar"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,6 +1046,20 @@
|
||||
"body": "Scan this QR code with your phone, or open the URL below on any device with a browser.",
|
||||
"openToSignIn": "Open ${service} to sign in",
|
||||
"urlCopied": "URL copied"
|
||||
},
|
||||
"libraryFilter": {
|
||||
"title": "Library filter",
|
||||
"subtitleAllSyncing": "Syncing all libraries",
|
||||
"subtitleNoneSyncing": "Nothing syncing",
|
||||
"subtitleBlocked": "${count} blocked",
|
||||
"subtitleAllowed": "${count} allowed",
|
||||
"mode": "Filter mode",
|
||||
"modeBlacklist": "Blacklist",
|
||||
"modeWhitelist": "Whitelist",
|
||||
"modeHintBlacklist": "Sync every library except the ones checked below.",
|
||||
"modeHintWhitelist": "Sync only the libraries checked below.",
|
||||
"libraries": "Libraries",
|
||||
"noLibraries": "No libraries available"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,6 +1046,20 @@
|
||||
"body": "Escanea este código QR con tu teléfono, o abre la URL de abajo en cualquier dispositivo con navegador.",
|
||||
"openToSignIn": "Abrir ${service} para iniciar sesión",
|
||||
"urlCopied": "URL copiada"
|
||||
},
|
||||
"libraryFilter": {
|
||||
"title": "Filtro de bibliotecas",
|
||||
"subtitleAllSyncing": "Sincronizando todas las bibliotecas",
|
||||
"subtitleNoneSyncing": "Nada se sincroniza",
|
||||
"subtitleBlocked": "${count} bloqueadas",
|
||||
"subtitleAllowed": "${count} permitidas",
|
||||
"mode": "Modo de filtro",
|
||||
"modeBlacklist": "Lista negra",
|
||||
"modeWhitelist": "Lista blanca",
|
||||
"modeHintBlacklist": "Sincronizar todas las bibliotecas excepto las marcadas abajo.",
|
||||
"modeHintWhitelist": "Sincronizar solo las bibliotecas marcadas abajo.",
|
||||
"libraries": "Bibliotecas",
|
||||
"noLibraries": "No hay bibliotecas disponibles"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,6 +1046,20 @@
|
||||
"body": "Scannez ce code QR avec votre téléphone, ou ouvrez l'URL ci-dessous sur un appareil équipé d'un navigateur.",
|
||||
"openToSignIn": "Ouvrir ${service} pour se connecter",
|
||||
"urlCopied": "URL copiée"
|
||||
},
|
||||
"libraryFilter": {
|
||||
"title": "Filtre de bibliothèques",
|
||||
"subtitleAllSyncing": "Synchronisation de toutes les bibliothèques",
|
||||
"subtitleNoneSyncing": "Aucune synchronisation",
|
||||
"subtitleBlocked": "${count} bloquées",
|
||||
"subtitleAllowed": "${count} autorisées",
|
||||
"mode": "Mode de filtrage",
|
||||
"modeBlacklist": "Liste noire",
|
||||
"modeWhitelist": "Liste blanche",
|
||||
"modeHintBlacklist": "Synchroniser toutes les bibliothèques sauf celles cochées ci-dessous.",
|
||||
"modeHintWhitelist": "Synchroniser uniquement les bibliothèques cochées ci-dessous.",
|
||||
"libraries": "Bibliothèques",
|
||||
"noLibraries": "Aucune bibliothèque disponible"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,6 +1046,20 @@
|
||||
"body": "Scansiona questo codice QR con il telefono oppure apri l'URL sottostante su un dispositivo con browser.",
|
||||
"openToSignIn": "Apri ${service} per accedere",
|
||||
"urlCopied": "URL copiato"
|
||||
},
|
||||
"libraryFilter": {
|
||||
"title": "Filtro librerie",
|
||||
"subtitleAllSyncing": "Sincronizzazione di tutte le librerie",
|
||||
"subtitleNoneSyncing": "Nulla da sincronizzare",
|
||||
"subtitleBlocked": "${count} bloccate",
|
||||
"subtitleAllowed": "${count} consentite",
|
||||
"mode": "Modalità filtro",
|
||||
"modeBlacklist": "Lista nera",
|
||||
"modeWhitelist": "Lista bianca",
|
||||
"modeHintBlacklist": "Sincronizza tutte le librerie tranne quelle selezionate sotto.",
|
||||
"modeHintWhitelist": "Sincronizza solo le librerie selezionate sotto.",
|
||||
"libraries": "Librerie",
|
||||
"noLibraries": "Nessuna libreria disponibile"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,6 +1046,20 @@
|
||||
"body": "このQRコードをスマートフォンで読み取るか、下のURLをブラウザで開いてください。",
|
||||
"openToSignIn": "${service} を開いてサインイン",
|
||||
"urlCopied": "URLをコピーしました"
|
||||
},
|
||||
"libraryFilter": {
|
||||
"title": "ライブラリフィルター",
|
||||
"subtitleAllSyncing": "すべてのライブラリを同期中",
|
||||
"subtitleNoneSyncing": "同期なし",
|
||||
"subtitleBlocked": "${count} 件をブロック",
|
||||
"subtitleAllowed": "${count} 件を許可",
|
||||
"mode": "フィルターモード",
|
||||
"modeBlacklist": "ブロックリスト",
|
||||
"modeWhitelist": "許可リスト",
|
||||
"modeHintBlacklist": "下でチェックしたライブラリ以外をすべて同期します。",
|
||||
"modeHintWhitelist": "下でチェックしたライブラリのみ同期します。",
|
||||
"libraries": "ライブラリ",
|
||||
"noLibraries": "利用できるライブラリがありません"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,6 +1046,20 @@
|
||||
"body": "휴대전화로 이 QR 코드를 스캔하거나 아래 URL을 브라우저가 있는 기기에서 여세요.",
|
||||
"openToSignIn": "로그인하려면 ${service} 열기",
|
||||
"urlCopied": "URL이 복사되었습니다"
|
||||
},
|
||||
"libraryFilter": {
|
||||
"title": "라이브러리 필터",
|
||||
"subtitleAllSyncing": "모든 라이브러리 동기화 중",
|
||||
"subtitleNoneSyncing": "동기화 안 함",
|
||||
"subtitleBlocked": "${count}개 차단됨",
|
||||
"subtitleAllowed": "${count}개 허용됨",
|
||||
"mode": "필터 모드",
|
||||
"modeBlacklist": "차단 목록",
|
||||
"modeWhitelist": "허용 목록",
|
||||
"modeHintBlacklist": "아래에 선택한 라이브러리를 제외한 모든 라이브러리를 동기화합니다.",
|
||||
"modeHintWhitelist": "아래에 선택한 라이브러리만 동기화합니다.",
|
||||
"libraries": "라이브러리",
|
||||
"noLibraries": "사용 가능한 라이브러리가 없습니다"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,6 +1046,20 @@
|
||||
"body": "Skann denne QR-koden med telefonen din, eller åpne URL-en under på en enhet med nettleser.",
|
||||
"openToSignIn": "Åpne ${service} for å logge inn",
|
||||
"urlCopied": "URL kopiert"
|
||||
},
|
||||
"libraryFilter": {
|
||||
"title": "Biblioteksfilter",
|
||||
"subtitleAllSyncing": "Synkroniserer alle biblioteker",
|
||||
"subtitleNoneSyncing": "Ingenting synkroniseres",
|
||||
"subtitleBlocked": "${count} blokkert",
|
||||
"subtitleAllowed": "${count} tillatt",
|
||||
"mode": "Filtermodus",
|
||||
"modeBlacklist": "Svarteliste",
|
||||
"modeWhitelist": "Hviteliste",
|
||||
"modeHintBlacklist": "Synkroniser alle biblioteker bortsett fra dem du markerer nedenfor.",
|
||||
"modeHintWhitelist": "Synkroniser kun bibliotekene du markerer nedenfor.",
|
||||
"libraries": "Biblioteker",
|
||||
"noLibraries": "Ingen biblioteker tilgjengelige"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,6 +1046,20 @@
|
||||
"body": "Scan deze QR-code met je telefoon, of open onderstaande URL op een apparaat met browser.",
|
||||
"openToSignIn": "${service} openen om aan te melden",
|
||||
"urlCopied": "URL gekopieerd"
|
||||
},
|
||||
"libraryFilter": {
|
||||
"title": "Bibliotheekfilter",
|
||||
"subtitleAllSyncing": "Alle bibliotheken synchroniseren",
|
||||
"subtitleNoneSyncing": "Niets wordt gesynchroniseerd",
|
||||
"subtitleBlocked": "${count} geblokkeerd",
|
||||
"subtitleAllowed": "${count} toegestaan",
|
||||
"mode": "Filtermodus",
|
||||
"modeBlacklist": "Zwarte lijst",
|
||||
"modeWhitelist": "Witte lijst",
|
||||
"modeHintBlacklist": "Synchroniseer alle bibliotheken behalve die hieronder aangevinkt zijn.",
|
||||
"modeHintWhitelist": "Synchroniseer alleen de hieronder aangevinkte bibliotheken.",
|
||||
"libraries": "Bibliotheken",
|
||||
"noLibraries": "Geen bibliotheken beschikbaar"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,6 +1046,20 @@
|
||||
"body": "Zeskanuj ten kod QR telefonem lub otwórz poniższy adres URL na dowolnym urządzeniu z przeglądarką.",
|
||||
"openToSignIn": "Otwórz ${service}, aby się zalogować",
|
||||
"urlCopied": "URL skopiowany"
|
||||
},
|
||||
"libraryFilter": {
|
||||
"title": "Filtr bibliotek",
|
||||
"subtitleAllSyncing": "Synchronizowanie wszystkich bibliotek",
|
||||
"subtitleNoneSyncing": "Nic nie synchronizuje",
|
||||
"subtitleBlocked": "${count} zablokowanych",
|
||||
"subtitleAllowed": "${count} dozwolonych",
|
||||
"mode": "Tryb filtra",
|
||||
"modeBlacklist": "Czarna lista",
|
||||
"modeWhitelist": "Biała lista",
|
||||
"modeHintBlacklist": "Synchronizuj wszystkie biblioteki oprócz zaznaczonych poniżej.",
|
||||
"modeHintWhitelist": "Synchronizuj tylko biblioteki zaznaczone poniżej.",
|
||||
"libraries": "Biblioteki",
|
||||
"noLibraries": "Brak dostępnych bibliotek"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,6 +1046,20 @@
|
||||
"body": "Escaneie este código QR com o celular, ou abra o URL abaixo em qualquer dispositivo com navegador.",
|
||||
"openToSignIn": "Abrir ${service} para entrar",
|
||||
"urlCopied": "URL copiado"
|
||||
},
|
||||
"libraryFilter": {
|
||||
"title": "Filtro de bibliotecas",
|
||||
"subtitleAllSyncing": "Sincronizando todas as bibliotecas",
|
||||
"subtitleNoneSyncing": "Nada a sincronizar",
|
||||
"subtitleBlocked": "${count} bloqueadas",
|
||||
"subtitleAllowed": "${count} permitidas",
|
||||
"mode": "Modo de filtro",
|
||||
"modeBlacklist": "Lista negra",
|
||||
"modeWhitelist": "Lista branca",
|
||||
"modeHintBlacklist": "Sincronizar todas as bibliotecas exceto as marcadas abaixo.",
|
||||
"modeHintWhitelist": "Sincronizar apenas as bibliotecas marcadas abaixo.",
|
||||
"libraries": "Bibliotecas",
|
||||
"noLibraries": "Nenhuma biblioteca disponível"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,6 +1046,20 @@
|
||||
"body": "Отсканируйте этот QR-код телефоном или откройте ссылку ниже на любом устройстве с браузером.",
|
||||
"openToSignIn": "Открыть ${service} для входа",
|
||||
"urlCopied": "URL скопирован"
|
||||
},
|
||||
"libraryFilter": {
|
||||
"title": "Фильтр библиотек",
|
||||
"subtitleAllSyncing": "Синхронизация всех библиотек",
|
||||
"subtitleNoneSyncing": "Ничего не синхронизируется",
|
||||
"subtitleBlocked": "${count} заблокировано",
|
||||
"subtitleAllowed": "${count} разрешено",
|
||||
"mode": "Режим фильтра",
|
||||
"modeBlacklist": "Чёрный список",
|
||||
"modeWhitelist": "Белый список",
|
||||
"modeHintBlacklist": "Синхронизировать все библиотеки, кроме отмеченных ниже.",
|
||||
"modeHintWhitelist": "Синхронизировать только библиотеки, отмеченные ниже.",
|
||||
"libraries": "Библиотеки",
|
||||
"noLibraries": "Библиотеки недоступны"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
/// To regenerate, run: `dart run slang`
|
||||
///
|
||||
/// Locales: 15
|
||||
/// Strings: 14205 (947 per locale)
|
||||
/// Strings: 14385 (959 per locale)
|
||||
///
|
||||
/// Built on 2026-04-24 at 07:00 UTC
|
||||
/// Built on 2026-04-24 at 08:07 UTC
|
||||
|
||||
// coverage:ignore-file
|
||||
// ignore_for_file: type=lint, unused_import
|
||||
|
||||
@@ -1299,6 +1299,7 @@ class _TranslationsTrackersDa implements TranslationsTrackersEn {
|
||||
@override late final _TranslationsTrackersServicesDa services = _TranslationsTrackersServicesDa._(_root);
|
||||
@override late final _TranslationsTrackersDeviceCodeDa deviceCode = _TranslationsTrackersDeviceCodeDa._(_root);
|
||||
@override late final _TranslationsTrackersOauthProxyDa oauthProxy = _TranslationsTrackersOauthProxyDa._(_root);
|
||||
@override late final _TranslationsTrackersLibraryFilterDa libraryFilter = _TranslationsTrackersLibraryFilterDa._(_root);
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
@@ -1496,6 +1497,27 @@ class _TranslationsTrackersOauthProxyDa implements TranslationsTrackersOauthProx
|
||||
@override String get urlCopied => 'URL kopieret';
|
||||
}
|
||||
|
||||
// Path: trackers.libraryFilter
|
||||
class _TranslationsTrackersLibraryFilterDa implements TranslationsTrackersLibraryFilterEn {
|
||||
_TranslationsTrackersLibraryFilterDa._(this._root);
|
||||
|
||||
final TranslationsDa _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Bibliotekfilter';
|
||||
@override String get subtitleAllSyncing => 'Synkroniserer alle biblioteker';
|
||||
@override String get subtitleNoneSyncing => 'Intet synkroniseres';
|
||||
@override String subtitleBlocked({required Object count}) => '${count} blokeret';
|
||||
@override String subtitleAllowed({required Object count}) => '${count} tilladt';
|
||||
@override String get mode => 'Filtertilstand';
|
||||
@override String get modeBlacklist => 'Sortliste';
|
||||
@override String get modeWhitelist => 'Hvidliste';
|
||||
@override String get modeHintBlacklist => 'Synkroniser alle biblioteker undtagen dem du markerer nedenfor.';
|
||||
@override String get modeHintWhitelist => 'Synkroniser kun de biblioteker du markerer nedenfor.';
|
||||
@override String get libraries => 'Biblioteker';
|
||||
@override String get noLibraries => 'Ingen biblioteker tilgængelige';
|
||||
}
|
||||
|
||||
/// The flat map containing all translations for locale <da>.
|
||||
/// Only for edge cases! For simple maps, use the map function of this library.
|
||||
///
|
||||
@@ -2453,6 +2475,18 @@ extension on TranslationsDa {
|
||||
'trackers.oauthProxy.body' => 'Scan denne QR-kode med din telefon, eller åbn URL\'en nedenfor på en enhed med browser.',
|
||||
'trackers.oauthProxy.openToSignIn' => ({required Object service}) => 'Åbn ${service} for at logge ind',
|
||||
'trackers.oauthProxy.urlCopied' => 'URL kopieret',
|
||||
'trackers.libraryFilter.title' => 'Bibliotekfilter',
|
||||
'trackers.libraryFilter.subtitleAllSyncing' => 'Synkroniserer alle biblioteker',
|
||||
'trackers.libraryFilter.subtitleNoneSyncing' => 'Intet synkroniseres',
|
||||
'trackers.libraryFilter.subtitleBlocked' => ({required Object count}) => '${count} blokeret',
|
||||
'trackers.libraryFilter.subtitleAllowed' => ({required Object count}) => '${count} tilladt',
|
||||
'trackers.libraryFilter.mode' => 'Filtertilstand',
|
||||
'trackers.libraryFilter.modeBlacklist' => 'Sortliste',
|
||||
'trackers.libraryFilter.modeWhitelist' => 'Hvidliste',
|
||||
'trackers.libraryFilter.modeHintBlacklist' => 'Synkroniser alle biblioteker undtagen dem du markerer nedenfor.',
|
||||
'trackers.libraryFilter.modeHintWhitelist' => 'Synkroniser kun de biblioteker du markerer nedenfor.',
|
||||
'trackers.libraryFilter.libraries' => 'Biblioteker',
|
||||
'trackers.libraryFilter.noLibraries' => 'Ingen biblioteker tilgængelige',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1299,6 +1299,7 @@ class _TranslationsTrackersDe implements TranslationsTrackersEn {
|
||||
@override late final _TranslationsTrackersServicesDe services = _TranslationsTrackersServicesDe._(_root);
|
||||
@override late final _TranslationsTrackersDeviceCodeDe deviceCode = _TranslationsTrackersDeviceCodeDe._(_root);
|
||||
@override late final _TranslationsTrackersOauthProxyDe oauthProxy = _TranslationsTrackersOauthProxyDe._(_root);
|
||||
@override late final _TranslationsTrackersLibraryFilterDe libraryFilter = _TranslationsTrackersLibraryFilterDe._(_root);
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
@@ -1496,6 +1497,27 @@ class _TranslationsTrackersOauthProxyDe implements TranslationsTrackersOauthProx
|
||||
@override String get urlCopied => 'URL kopiert';
|
||||
}
|
||||
|
||||
// Path: trackers.libraryFilter
|
||||
class _TranslationsTrackersLibraryFilterDe implements TranslationsTrackersLibraryFilterEn {
|
||||
_TranslationsTrackersLibraryFilterDe._(this._root);
|
||||
|
||||
final TranslationsDe _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Bibliothekfilter';
|
||||
@override String get subtitleAllSyncing => 'Alle Bibliotheken werden synchronisiert';
|
||||
@override String get subtitleNoneSyncing => 'Nichts wird synchronisiert';
|
||||
@override String subtitleBlocked({required Object count}) => '${count} blockiert';
|
||||
@override String subtitleAllowed({required Object count}) => '${count} erlaubt';
|
||||
@override String get mode => 'Filtermodus';
|
||||
@override String get modeBlacklist => 'Blacklist';
|
||||
@override String get modeWhitelist => 'Whitelist';
|
||||
@override String get modeHintBlacklist => 'Alle Bibliotheken außer den unten markierten synchronisieren.';
|
||||
@override String get modeHintWhitelist => 'Nur die unten markierten Bibliotheken synchronisieren.';
|
||||
@override String get libraries => 'Bibliotheken';
|
||||
@override String get noLibraries => 'Keine Bibliotheken verfügbar';
|
||||
}
|
||||
|
||||
/// The flat map containing all translations for locale <de>.
|
||||
/// Only for edge cases! For simple maps, use the map function of this library.
|
||||
///
|
||||
@@ -2453,6 +2475,18 @@ extension on TranslationsDe {
|
||||
'trackers.oauthProxy.body' => 'Scanne diesen QR-Code mit deinem Handy oder öffne die URL unten auf einem Gerät mit Browser.',
|
||||
'trackers.oauthProxy.openToSignIn' => ({required Object service}) => '${service} zum Anmelden öffnen',
|
||||
'trackers.oauthProxy.urlCopied' => 'URL kopiert',
|
||||
'trackers.libraryFilter.title' => 'Bibliothekfilter',
|
||||
'trackers.libraryFilter.subtitleAllSyncing' => 'Alle Bibliotheken werden synchronisiert',
|
||||
'trackers.libraryFilter.subtitleNoneSyncing' => 'Nichts wird synchronisiert',
|
||||
'trackers.libraryFilter.subtitleBlocked' => ({required Object count}) => '${count} blockiert',
|
||||
'trackers.libraryFilter.subtitleAllowed' => ({required Object count}) => '${count} erlaubt',
|
||||
'trackers.libraryFilter.mode' => 'Filtermodus',
|
||||
'trackers.libraryFilter.modeBlacklist' => 'Blacklist',
|
||||
'trackers.libraryFilter.modeWhitelist' => 'Whitelist',
|
||||
'trackers.libraryFilter.modeHintBlacklist' => 'Alle Bibliotheken außer den unten markierten synchronisieren.',
|
||||
'trackers.libraryFilter.modeHintWhitelist' => 'Nur die unten markierten Bibliotheken synchronisieren.',
|
||||
'trackers.libraryFilter.libraries' => 'Bibliotheken',
|
||||
'trackers.libraryFilter.noLibraries' => 'Keine Bibliotheken verfügbar',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2991,6 +2991,7 @@ class TranslationsTrackersEn {
|
||||
late final TranslationsTrackersServicesEn services = TranslationsTrackersServicesEn._(_root);
|
||||
late final TranslationsTrackersDeviceCodeEn deviceCode = TranslationsTrackersDeviceCodeEn._(_root);
|
||||
late final TranslationsTrackersOauthProxyEn oauthProxy = TranslationsTrackersOauthProxyEn._(_root);
|
||||
late final TranslationsTrackersLibraryFilterEn libraryFilter = TranslationsTrackersLibraryFilterEn._(_root);
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
@@ -3398,6 +3399,51 @@ class TranslationsTrackersOauthProxyEn {
|
||||
String get urlCopied => 'URL copied';
|
||||
}
|
||||
|
||||
// Path: trackers.libraryFilter
|
||||
class TranslationsTrackersLibraryFilterEn {
|
||||
TranslationsTrackersLibraryFilterEn._(this._root);
|
||||
|
||||
final Translations _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
|
||||
/// en: 'Library filter'
|
||||
String get title => 'Library filter';
|
||||
|
||||
/// en: 'Syncing all libraries'
|
||||
String get subtitleAllSyncing => 'Syncing all libraries';
|
||||
|
||||
/// en: 'Nothing syncing'
|
||||
String get subtitleNoneSyncing => 'Nothing syncing';
|
||||
|
||||
/// en: '${count} blocked'
|
||||
String subtitleBlocked({required Object count}) => '${count} blocked';
|
||||
|
||||
/// en: '${count} allowed'
|
||||
String subtitleAllowed({required Object count}) => '${count} allowed';
|
||||
|
||||
/// en: 'Filter mode'
|
||||
String get mode => 'Filter mode';
|
||||
|
||||
/// en: 'Blacklist'
|
||||
String get modeBlacklist => 'Blacklist';
|
||||
|
||||
/// en: 'Whitelist'
|
||||
String get modeWhitelist => 'Whitelist';
|
||||
|
||||
/// en: 'Sync every library except the ones checked below.'
|
||||
String get modeHintBlacklist => 'Sync every library except the ones checked below.';
|
||||
|
||||
/// en: 'Sync only the libraries checked below.'
|
||||
String get modeHintWhitelist => 'Sync only the libraries checked below.';
|
||||
|
||||
/// en: 'Libraries'
|
||||
String get libraries => 'Libraries';
|
||||
|
||||
/// en: 'No libraries available'
|
||||
String get noLibraries => 'No libraries available';
|
||||
}
|
||||
|
||||
/// The flat map containing all translations for locale <en>.
|
||||
/// Only for edge cases! For simple maps, use the map function of this library.
|
||||
///
|
||||
@@ -4355,6 +4401,18 @@ extension on Translations {
|
||||
'trackers.oauthProxy.body' => 'Scan this QR code with your phone, or open the URL below on any device with a browser.',
|
||||
'trackers.oauthProxy.openToSignIn' => ({required Object service}) => 'Open ${service} to sign in',
|
||||
'trackers.oauthProxy.urlCopied' => 'URL copied',
|
||||
'trackers.libraryFilter.title' => 'Library filter',
|
||||
'trackers.libraryFilter.subtitleAllSyncing' => 'Syncing all libraries',
|
||||
'trackers.libraryFilter.subtitleNoneSyncing' => 'Nothing syncing',
|
||||
'trackers.libraryFilter.subtitleBlocked' => ({required Object count}) => '${count} blocked',
|
||||
'trackers.libraryFilter.subtitleAllowed' => ({required Object count}) => '${count} allowed',
|
||||
'trackers.libraryFilter.mode' => 'Filter mode',
|
||||
'trackers.libraryFilter.modeBlacklist' => 'Blacklist',
|
||||
'trackers.libraryFilter.modeWhitelist' => 'Whitelist',
|
||||
'trackers.libraryFilter.modeHintBlacklist' => 'Sync every library except the ones checked below.',
|
||||
'trackers.libraryFilter.modeHintWhitelist' => 'Sync only the libraries checked below.',
|
||||
'trackers.libraryFilter.libraries' => 'Libraries',
|
||||
'trackers.libraryFilter.noLibraries' => 'No libraries available',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1299,6 +1299,7 @@ class _TranslationsTrackersEs implements TranslationsTrackersEn {
|
||||
@override late final _TranslationsTrackersServicesEs services = _TranslationsTrackersServicesEs._(_root);
|
||||
@override late final _TranslationsTrackersDeviceCodeEs deviceCode = _TranslationsTrackersDeviceCodeEs._(_root);
|
||||
@override late final _TranslationsTrackersOauthProxyEs oauthProxy = _TranslationsTrackersOauthProxyEs._(_root);
|
||||
@override late final _TranslationsTrackersLibraryFilterEs libraryFilter = _TranslationsTrackersLibraryFilterEs._(_root);
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
@@ -1496,6 +1497,27 @@ class _TranslationsTrackersOauthProxyEs implements TranslationsTrackersOauthProx
|
||||
@override String get urlCopied => 'URL copiada';
|
||||
}
|
||||
|
||||
// Path: trackers.libraryFilter
|
||||
class _TranslationsTrackersLibraryFilterEs implements TranslationsTrackersLibraryFilterEn {
|
||||
_TranslationsTrackersLibraryFilterEs._(this._root);
|
||||
|
||||
final TranslationsEs _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Filtro de bibliotecas';
|
||||
@override String get subtitleAllSyncing => 'Sincronizando todas las bibliotecas';
|
||||
@override String get subtitleNoneSyncing => 'Nada se sincroniza';
|
||||
@override String subtitleBlocked({required Object count}) => '${count} bloqueadas';
|
||||
@override String subtitleAllowed({required Object count}) => '${count} permitidas';
|
||||
@override String get mode => 'Modo de filtro';
|
||||
@override String get modeBlacklist => 'Lista negra';
|
||||
@override String get modeWhitelist => 'Lista blanca';
|
||||
@override String get modeHintBlacklist => 'Sincronizar todas las bibliotecas excepto las marcadas abajo.';
|
||||
@override String get modeHintWhitelist => 'Sincronizar solo las bibliotecas marcadas abajo.';
|
||||
@override String get libraries => 'Bibliotecas';
|
||||
@override String get noLibraries => 'No hay bibliotecas disponibles';
|
||||
}
|
||||
|
||||
/// The flat map containing all translations for locale <es>.
|
||||
/// Only for edge cases! For simple maps, use the map function of this library.
|
||||
///
|
||||
@@ -2453,6 +2475,18 @@ extension on TranslationsEs {
|
||||
'trackers.oauthProxy.body' => 'Escanea este código QR con tu teléfono, o abre la URL de abajo en cualquier dispositivo con navegador.',
|
||||
'trackers.oauthProxy.openToSignIn' => ({required Object service}) => 'Abrir ${service} para iniciar sesión',
|
||||
'trackers.oauthProxy.urlCopied' => 'URL copiada',
|
||||
'trackers.libraryFilter.title' => 'Filtro de bibliotecas',
|
||||
'trackers.libraryFilter.subtitleAllSyncing' => 'Sincronizando todas las bibliotecas',
|
||||
'trackers.libraryFilter.subtitleNoneSyncing' => 'Nada se sincroniza',
|
||||
'trackers.libraryFilter.subtitleBlocked' => ({required Object count}) => '${count} bloqueadas',
|
||||
'trackers.libraryFilter.subtitleAllowed' => ({required Object count}) => '${count} permitidas',
|
||||
'trackers.libraryFilter.mode' => 'Modo de filtro',
|
||||
'trackers.libraryFilter.modeBlacklist' => 'Lista negra',
|
||||
'trackers.libraryFilter.modeWhitelist' => 'Lista blanca',
|
||||
'trackers.libraryFilter.modeHintBlacklist' => 'Sincronizar todas las bibliotecas excepto las marcadas abajo.',
|
||||
'trackers.libraryFilter.modeHintWhitelist' => 'Sincronizar solo las bibliotecas marcadas abajo.',
|
||||
'trackers.libraryFilter.libraries' => 'Bibliotecas',
|
||||
'trackers.libraryFilter.noLibraries' => 'No hay bibliotecas disponibles',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1299,6 +1299,7 @@ class _TranslationsTrackersFr implements TranslationsTrackersEn {
|
||||
@override late final _TranslationsTrackersServicesFr services = _TranslationsTrackersServicesFr._(_root);
|
||||
@override late final _TranslationsTrackersDeviceCodeFr deviceCode = _TranslationsTrackersDeviceCodeFr._(_root);
|
||||
@override late final _TranslationsTrackersOauthProxyFr oauthProxy = _TranslationsTrackersOauthProxyFr._(_root);
|
||||
@override late final _TranslationsTrackersLibraryFilterFr libraryFilter = _TranslationsTrackersLibraryFilterFr._(_root);
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
@@ -1496,6 +1497,27 @@ class _TranslationsTrackersOauthProxyFr implements TranslationsTrackersOauthProx
|
||||
@override String get urlCopied => 'URL copiée';
|
||||
}
|
||||
|
||||
// Path: trackers.libraryFilter
|
||||
class _TranslationsTrackersLibraryFilterFr implements TranslationsTrackersLibraryFilterEn {
|
||||
_TranslationsTrackersLibraryFilterFr._(this._root);
|
||||
|
||||
final TranslationsFr _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Filtre de bibliothèques';
|
||||
@override String get subtitleAllSyncing => 'Synchronisation de toutes les bibliothèques';
|
||||
@override String get subtitleNoneSyncing => 'Aucune synchronisation';
|
||||
@override String subtitleBlocked({required Object count}) => '${count} bloquées';
|
||||
@override String subtitleAllowed({required Object count}) => '${count} autorisées';
|
||||
@override String get mode => 'Mode de filtrage';
|
||||
@override String get modeBlacklist => 'Liste noire';
|
||||
@override String get modeWhitelist => 'Liste blanche';
|
||||
@override String get modeHintBlacklist => 'Synchroniser toutes les bibliothèques sauf celles cochées ci-dessous.';
|
||||
@override String get modeHintWhitelist => 'Synchroniser uniquement les bibliothèques cochées ci-dessous.';
|
||||
@override String get libraries => 'Bibliothèques';
|
||||
@override String get noLibraries => 'Aucune bibliothèque disponible';
|
||||
}
|
||||
|
||||
/// The flat map containing all translations for locale <fr>.
|
||||
/// Only for edge cases! For simple maps, use the map function of this library.
|
||||
///
|
||||
@@ -2453,6 +2475,18 @@ extension on TranslationsFr {
|
||||
'trackers.oauthProxy.body' => 'Scannez ce code QR avec votre téléphone, ou ouvrez l\'URL ci-dessous sur un appareil équipé d\'un navigateur.',
|
||||
'trackers.oauthProxy.openToSignIn' => ({required Object service}) => 'Ouvrir ${service} pour se connecter',
|
||||
'trackers.oauthProxy.urlCopied' => 'URL copiée',
|
||||
'trackers.libraryFilter.title' => 'Filtre de bibliothèques',
|
||||
'trackers.libraryFilter.subtitleAllSyncing' => 'Synchronisation de toutes les bibliothèques',
|
||||
'trackers.libraryFilter.subtitleNoneSyncing' => 'Aucune synchronisation',
|
||||
'trackers.libraryFilter.subtitleBlocked' => ({required Object count}) => '${count} bloquées',
|
||||
'trackers.libraryFilter.subtitleAllowed' => ({required Object count}) => '${count} autorisées',
|
||||
'trackers.libraryFilter.mode' => 'Mode de filtrage',
|
||||
'trackers.libraryFilter.modeBlacklist' => 'Liste noire',
|
||||
'trackers.libraryFilter.modeWhitelist' => 'Liste blanche',
|
||||
'trackers.libraryFilter.modeHintBlacklist' => 'Synchroniser toutes les bibliothèques sauf celles cochées ci-dessous.',
|
||||
'trackers.libraryFilter.modeHintWhitelist' => 'Synchroniser uniquement les bibliothèques cochées ci-dessous.',
|
||||
'trackers.libraryFilter.libraries' => 'Bibliothèques',
|
||||
'trackers.libraryFilter.noLibraries' => 'Aucune bibliothèque disponible',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1299,6 +1299,7 @@ class _TranslationsTrackersIt implements TranslationsTrackersEn {
|
||||
@override late final _TranslationsTrackersServicesIt services = _TranslationsTrackersServicesIt._(_root);
|
||||
@override late final _TranslationsTrackersDeviceCodeIt deviceCode = _TranslationsTrackersDeviceCodeIt._(_root);
|
||||
@override late final _TranslationsTrackersOauthProxyIt oauthProxy = _TranslationsTrackersOauthProxyIt._(_root);
|
||||
@override late final _TranslationsTrackersLibraryFilterIt libraryFilter = _TranslationsTrackersLibraryFilterIt._(_root);
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
@@ -1496,6 +1497,27 @@ class _TranslationsTrackersOauthProxyIt implements TranslationsTrackersOauthProx
|
||||
@override String get urlCopied => 'URL copiato';
|
||||
}
|
||||
|
||||
// Path: trackers.libraryFilter
|
||||
class _TranslationsTrackersLibraryFilterIt implements TranslationsTrackersLibraryFilterEn {
|
||||
_TranslationsTrackersLibraryFilterIt._(this._root);
|
||||
|
||||
final TranslationsIt _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Filtro librerie';
|
||||
@override String get subtitleAllSyncing => 'Sincronizzazione di tutte le librerie';
|
||||
@override String get subtitleNoneSyncing => 'Nulla da sincronizzare';
|
||||
@override String subtitleBlocked({required Object count}) => '${count} bloccate';
|
||||
@override String subtitleAllowed({required Object count}) => '${count} consentite';
|
||||
@override String get mode => 'Modalità filtro';
|
||||
@override String get modeBlacklist => 'Lista nera';
|
||||
@override String get modeWhitelist => 'Lista bianca';
|
||||
@override String get modeHintBlacklist => 'Sincronizza tutte le librerie tranne quelle selezionate sotto.';
|
||||
@override String get modeHintWhitelist => 'Sincronizza solo le librerie selezionate sotto.';
|
||||
@override String get libraries => 'Librerie';
|
||||
@override String get noLibraries => 'Nessuna libreria disponibile';
|
||||
}
|
||||
|
||||
/// The flat map containing all translations for locale <it>.
|
||||
/// Only for edge cases! For simple maps, use the map function of this library.
|
||||
///
|
||||
@@ -2453,6 +2475,18 @@ extension on TranslationsIt {
|
||||
'trackers.oauthProxy.body' => 'Scansiona questo codice QR con il telefono oppure apri l\'URL sottostante su un dispositivo con browser.',
|
||||
'trackers.oauthProxy.openToSignIn' => ({required Object service}) => 'Apri ${service} per accedere',
|
||||
'trackers.oauthProxy.urlCopied' => 'URL copiato',
|
||||
'trackers.libraryFilter.title' => 'Filtro librerie',
|
||||
'trackers.libraryFilter.subtitleAllSyncing' => 'Sincronizzazione di tutte le librerie',
|
||||
'trackers.libraryFilter.subtitleNoneSyncing' => 'Nulla da sincronizzare',
|
||||
'trackers.libraryFilter.subtitleBlocked' => ({required Object count}) => '${count} bloccate',
|
||||
'trackers.libraryFilter.subtitleAllowed' => ({required Object count}) => '${count} consentite',
|
||||
'trackers.libraryFilter.mode' => 'Modalità filtro',
|
||||
'trackers.libraryFilter.modeBlacklist' => 'Lista nera',
|
||||
'trackers.libraryFilter.modeWhitelist' => 'Lista bianca',
|
||||
'trackers.libraryFilter.modeHintBlacklist' => 'Sincronizza tutte le librerie tranne quelle selezionate sotto.',
|
||||
'trackers.libraryFilter.modeHintWhitelist' => 'Sincronizza solo le librerie selezionate sotto.',
|
||||
'trackers.libraryFilter.libraries' => 'Librerie',
|
||||
'trackers.libraryFilter.noLibraries' => 'Nessuna libreria disponibile',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1299,6 +1299,7 @@ class _TranslationsTrackersJa implements TranslationsTrackersEn {
|
||||
@override late final _TranslationsTrackersServicesJa services = _TranslationsTrackersServicesJa._(_root);
|
||||
@override late final _TranslationsTrackersDeviceCodeJa deviceCode = _TranslationsTrackersDeviceCodeJa._(_root);
|
||||
@override late final _TranslationsTrackersOauthProxyJa oauthProxy = _TranslationsTrackersOauthProxyJa._(_root);
|
||||
@override late final _TranslationsTrackersLibraryFilterJa libraryFilter = _TranslationsTrackersLibraryFilterJa._(_root);
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
@@ -1496,6 +1497,27 @@ class _TranslationsTrackersOauthProxyJa implements TranslationsTrackersOauthProx
|
||||
@override String get urlCopied => 'URLをコピーしました';
|
||||
}
|
||||
|
||||
// Path: trackers.libraryFilter
|
||||
class _TranslationsTrackersLibraryFilterJa implements TranslationsTrackersLibraryFilterEn {
|
||||
_TranslationsTrackersLibraryFilterJa._(this._root);
|
||||
|
||||
final TranslationsJa _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'ライブラリフィルター';
|
||||
@override String get subtitleAllSyncing => 'すべてのライブラリを同期中';
|
||||
@override String get subtitleNoneSyncing => '同期なし';
|
||||
@override String subtitleBlocked({required Object count}) => '${count} 件をブロック';
|
||||
@override String subtitleAllowed({required Object count}) => '${count} 件を許可';
|
||||
@override String get mode => 'フィルターモード';
|
||||
@override String get modeBlacklist => 'ブロックリスト';
|
||||
@override String get modeWhitelist => '許可リスト';
|
||||
@override String get modeHintBlacklist => '下でチェックしたライブラリ以外をすべて同期します。';
|
||||
@override String get modeHintWhitelist => '下でチェックしたライブラリのみ同期します。';
|
||||
@override String get libraries => 'ライブラリ';
|
||||
@override String get noLibraries => '利用できるライブラリがありません';
|
||||
}
|
||||
|
||||
/// The flat map containing all translations for locale <ja>.
|
||||
/// Only for edge cases! For simple maps, use the map function of this library.
|
||||
///
|
||||
@@ -2453,6 +2475,18 @@ extension on TranslationsJa {
|
||||
'trackers.oauthProxy.body' => 'このQRコードをスマートフォンで読み取るか、下のURLをブラウザで開いてください。',
|
||||
'trackers.oauthProxy.openToSignIn' => ({required Object service}) => '${service} を開いてサインイン',
|
||||
'trackers.oauthProxy.urlCopied' => 'URLをコピーしました',
|
||||
'trackers.libraryFilter.title' => 'ライブラリフィルター',
|
||||
'trackers.libraryFilter.subtitleAllSyncing' => 'すべてのライブラリを同期中',
|
||||
'trackers.libraryFilter.subtitleNoneSyncing' => '同期なし',
|
||||
'trackers.libraryFilter.subtitleBlocked' => ({required Object count}) => '${count} 件をブロック',
|
||||
'trackers.libraryFilter.subtitleAllowed' => ({required Object count}) => '${count} 件を許可',
|
||||
'trackers.libraryFilter.mode' => 'フィルターモード',
|
||||
'trackers.libraryFilter.modeBlacklist' => 'ブロックリスト',
|
||||
'trackers.libraryFilter.modeWhitelist' => '許可リスト',
|
||||
'trackers.libraryFilter.modeHintBlacklist' => '下でチェックしたライブラリ以外をすべて同期します。',
|
||||
'trackers.libraryFilter.modeHintWhitelist' => '下でチェックしたライブラリのみ同期します。',
|
||||
'trackers.libraryFilter.libraries' => 'ライブラリ',
|
||||
'trackers.libraryFilter.noLibraries' => '利用できるライブラリがありません',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1299,6 +1299,7 @@ class _TranslationsTrackersKo implements TranslationsTrackersEn {
|
||||
@override late final _TranslationsTrackersServicesKo services = _TranslationsTrackersServicesKo._(_root);
|
||||
@override late final _TranslationsTrackersDeviceCodeKo deviceCode = _TranslationsTrackersDeviceCodeKo._(_root);
|
||||
@override late final _TranslationsTrackersOauthProxyKo oauthProxy = _TranslationsTrackersOauthProxyKo._(_root);
|
||||
@override late final _TranslationsTrackersLibraryFilterKo libraryFilter = _TranslationsTrackersLibraryFilterKo._(_root);
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
@@ -1496,6 +1497,27 @@ class _TranslationsTrackersOauthProxyKo implements TranslationsTrackersOauthProx
|
||||
@override String get urlCopied => 'URL이 복사되었습니다';
|
||||
}
|
||||
|
||||
// Path: trackers.libraryFilter
|
||||
class _TranslationsTrackersLibraryFilterKo implements TranslationsTrackersLibraryFilterEn {
|
||||
_TranslationsTrackersLibraryFilterKo._(this._root);
|
||||
|
||||
final TranslationsKo _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => '라이브러리 필터';
|
||||
@override String get subtitleAllSyncing => '모든 라이브러리 동기화 중';
|
||||
@override String get subtitleNoneSyncing => '동기화 안 함';
|
||||
@override String subtitleBlocked({required Object count}) => '${count}개 차단됨';
|
||||
@override String subtitleAllowed({required Object count}) => '${count}개 허용됨';
|
||||
@override String get mode => '필터 모드';
|
||||
@override String get modeBlacklist => '차단 목록';
|
||||
@override String get modeWhitelist => '허용 목록';
|
||||
@override String get modeHintBlacklist => '아래에 선택한 라이브러리를 제외한 모든 라이브러리를 동기화합니다.';
|
||||
@override String get modeHintWhitelist => '아래에 선택한 라이브러리만 동기화합니다.';
|
||||
@override String get libraries => '라이브러리';
|
||||
@override String get noLibraries => '사용 가능한 라이브러리가 없습니다';
|
||||
}
|
||||
|
||||
/// The flat map containing all translations for locale <ko>.
|
||||
/// Only for edge cases! For simple maps, use the map function of this library.
|
||||
///
|
||||
@@ -2453,6 +2475,18 @@ extension on TranslationsKo {
|
||||
'trackers.oauthProxy.body' => '휴대전화로 이 QR 코드를 스캔하거나 아래 URL을 브라우저가 있는 기기에서 여세요.',
|
||||
'trackers.oauthProxy.openToSignIn' => ({required Object service}) => '로그인하려면 ${service} 열기',
|
||||
'trackers.oauthProxy.urlCopied' => 'URL이 복사되었습니다',
|
||||
'trackers.libraryFilter.title' => '라이브러리 필터',
|
||||
'trackers.libraryFilter.subtitleAllSyncing' => '모든 라이브러리 동기화 중',
|
||||
'trackers.libraryFilter.subtitleNoneSyncing' => '동기화 안 함',
|
||||
'trackers.libraryFilter.subtitleBlocked' => ({required Object count}) => '${count}개 차단됨',
|
||||
'trackers.libraryFilter.subtitleAllowed' => ({required Object count}) => '${count}개 허용됨',
|
||||
'trackers.libraryFilter.mode' => '필터 모드',
|
||||
'trackers.libraryFilter.modeBlacklist' => '차단 목록',
|
||||
'trackers.libraryFilter.modeWhitelist' => '허용 목록',
|
||||
'trackers.libraryFilter.modeHintBlacklist' => '아래에 선택한 라이브러리를 제외한 모든 라이브러리를 동기화합니다.',
|
||||
'trackers.libraryFilter.modeHintWhitelist' => '아래에 선택한 라이브러리만 동기화합니다.',
|
||||
'trackers.libraryFilter.libraries' => '라이브러리',
|
||||
'trackers.libraryFilter.noLibraries' => '사용 가능한 라이브러리가 없습니다',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1299,6 +1299,7 @@ class _TranslationsTrackersNb implements TranslationsTrackersEn {
|
||||
@override late final _TranslationsTrackersServicesNb services = _TranslationsTrackersServicesNb._(_root);
|
||||
@override late final _TranslationsTrackersDeviceCodeNb deviceCode = _TranslationsTrackersDeviceCodeNb._(_root);
|
||||
@override late final _TranslationsTrackersOauthProxyNb oauthProxy = _TranslationsTrackersOauthProxyNb._(_root);
|
||||
@override late final _TranslationsTrackersLibraryFilterNb libraryFilter = _TranslationsTrackersLibraryFilterNb._(_root);
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
@@ -1496,6 +1497,27 @@ class _TranslationsTrackersOauthProxyNb implements TranslationsTrackersOauthProx
|
||||
@override String get urlCopied => 'URL kopiert';
|
||||
}
|
||||
|
||||
// Path: trackers.libraryFilter
|
||||
class _TranslationsTrackersLibraryFilterNb implements TranslationsTrackersLibraryFilterEn {
|
||||
_TranslationsTrackersLibraryFilterNb._(this._root);
|
||||
|
||||
final TranslationsNb _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Biblioteksfilter';
|
||||
@override String get subtitleAllSyncing => 'Synkroniserer alle biblioteker';
|
||||
@override String get subtitleNoneSyncing => 'Ingenting synkroniseres';
|
||||
@override String subtitleBlocked({required Object count}) => '${count} blokkert';
|
||||
@override String subtitleAllowed({required Object count}) => '${count} tillatt';
|
||||
@override String get mode => 'Filtermodus';
|
||||
@override String get modeBlacklist => 'Svarteliste';
|
||||
@override String get modeWhitelist => 'Hviteliste';
|
||||
@override String get modeHintBlacklist => 'Synkroniser alle biblioteker bortsett fra dem du markerer nedenfor.';
|
||||
@override String get modeHintWhitelist => 'Synkroniser kun bibliotekene du markerer nedenfor.';
|
||||
@override String get libraries => 'Biblioteker';
|
||||
@override String get noLibraries => 'Ingen biblioteker tilgjengelige';
|
||||
}
|
||||
|
||||
/// The flat map containing all translations for locale <nb>.
|
||||
/// Only for edge cases! For simple maps, use the map function of this library.
|
||||
///
|
||||
@@ -2453,6 +2475,18 @@ extension on TranslationsNb {
|
||||
'trackers.oauthProxy.body' => 'Skann denne QR-koden med telefonen din, eller åpne URL-en under på en enhet med nettleser.',
|
||||
'trackers.oauthProxy.openToSignIn' => ({required Object service}) => 'Åpne ${service} for å logge inn',
|
||||
'trackers.oauthProxy.urlCopied' => 'URL kopiert',
|
||||
'trackers.libraryFilter.title' => 'Biblioteksfilter',
|
||||
'trackers.libraryFilter.subtitleAllSyncing' => 'Synkroniserer alle biblioteker',
|
||||
'trackers.libraryFilter.subtitleNoneSyncing' => 'Ingenting synkroniseres',
|
||||
'trackers.libraryFilter.subtitleBlocked' => ({required Object count}) => '${count} blokkert',
|
||||
'trackers.libraryFilter.subtitleAllowed' => ({required Object count}) => '${count} tillatt',
|
||||
'trackers.libraryFilter.mode' => 'Filtermodus',
|
||||
'trackers.libraryFilter.modeBlacklist' => 'Svarteliste',
|
||||
'trackers.libraryFilter.modeWhitelist' => 'Hviteliste',
|
||||
'trackers.libraryFilter.modeHintBlacklist' => 'Synkroniser alle biblioteker bortsett fra dem du markerer nedenfor.',
|
||||
'trackers.libraryFilter.modeHintWhitelist' => 'Synkroniser kun bibliotekene du markerer nedenfor.',
|
||||
'trackers.libraryFilter.libraries' => 'Biblioteker',
|
||||
'trackers.libraryFilter.noLibraries' => 'Ingen biblioteker tilgjengelige',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1299,6 +1299,7 @@ class _TranslationsTrackersNl implements TranslationsTrackersEn {
|
||||
@override late final _TranslationsTrackersServicesNl services = _TranslationsTrackersServicesNl._(_root);
|
||||
@override late final _TranslationsTrackersDeviceCodeNl deviceCode = _TranslationsTrackersDeviceCodeNl._(_root);
|
||||
@override late final _TranslationsTrackersOauthProxyNl oauthProxy = _TranslationsTrackersOauthProxyNl._(_root);
|
||||
@override late final _TranslationsTrackersLibraryFilterNl libraryFilter = _TranslationsTrackersLibraryFilterNl._(_root);
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
@@ -1496,6 +1497,27 @@ class _TranslationsTrackersOauthProxyNl implements TranslationsTrackersOauthProx
|
||||
@override String get urlCopied => 'URL gekopieerd';
|
||||
}
|
||||
|
||||
// Path: trackers.libraryFilter
|
||||
class _TranslationsTrackersLibraryFilterNl implements TranslationsTrackersLibraryFilterEn {
|
||||
_TranslationsTrackersLibraryFilterNl._(this._root);
|
||||
|
||||
final TranslationsNl _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Bibliotheekfilter';
|
||||
@override String get subtitleAllSyncing => 'Alle bibliotheken synchroniseren';
|
||||
@override String get subtitleNoneSyncing => 'Niets wordt gesynchroniseerd';
|
||||
@override String subtitleBlocked({required Object count}) => '${count} geblokkeerd';
|
||||
@override String subtitleAllowed({required Object count}) => '${count} toegestaan';
|
||||
@override String get mode => 'Filtermodus';
|
||||
@override String get modeBlacklist => 'Zwarte lijst';
|
||||
@override String get modeWhitelist => 'Witte lijst';
|
||||
@override String get modeHintBlacklist => 'Synchroniseer alle bibliotheken behalve die hieronder aangevinkt zijn.';
|
||||
@override String get modeHintWhitelist => 'Synchroniseer alleen de hieronder aangevinkte bibliotheken.';
|
||||
@override String get libraries => 'Bibliotheken';
|
||||
@override String get noLibraries => 'Geen bibliotheken beschikbaar';
|
||||
}
|
||||
|
||||
/// The flat map containing all translations for locale <nl>.
|
||||
/// Only for edge cases! For simple maps, use the map function of this library.
|
||||
///
|
||||
@@ -2453,6 +2475,18 @@ extension on TranslationsNl {
|
||||
'trackers.oauthProxy.body' => 'Scan deze QR-code met je telefoon, of open onderstaande URL op een apparaat met browser.',
|
||||
'trackers.oauthProxy.openToSignIn' => ({required Object service}) => '${service} openen om aan te melden',
|
||||
'trackers.oauthProxy.urlCopied' => 'URL gekopieerd',
|
||||
'trackers.libraryFilter.title' => 'Bibliotheekfilter',
|
||||
'trackers.libraryFilter.subtitleAllSyncing' => 'Alle bibliotheken synchroniseren',
|
||||
'trackers.libraryFilter.subtitleNoneSyncing' => 'Niets wordt gesynchroniseerd',
|
||||
'trackers.libraryFilter.subtitleBlocked' => ({required Object count}) => '${count} geblokkeerd',
|
||||
'trackers.libraryFilter.subtitleAllowed' => ({required Object count}) => '${count} toegestaan',
|
||||
'trackers.libraryFilter.mode' => 'Filtermodus',
|
||||
'trackers.libraryFilter.modeBlacklist' => 'Zwarte lijst',
|
||||
'trackers.libraryFilter.modeWhitelist' => 'Witte lijst',
|
||||
'trackers.libraryFilter.modeHintBlacklist' => 'Synchroniseer alle bibliotheken behalve die hieronder aangevinkt zijn.',
|
||||
'trackers.libraryFilter.modeHintWhitelist' => 'Synchroniseer alleen de hieronder aangevinkte bibliotheken.',
|
||||
'trackers.libraryFilter.libraries' => 'Bibliotheken',
|
||||
'trackers.libraryFilter.noLibraries' => 'Geen bibliotheken beschikbaar',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1299,6 +1299,7 @@ class _TranslationsTrackersPl implements TranslationsTrackersEn {
|
||||
@override late final _TranslationsTrackersServicesPl services = _TranslationsTrackersServicesPl._(_root);
|
||||
@override late final _TranslationsTrackersDeviceCodePl deviceCode = _TranslationsTrackersDeviceCodePl._(_root);
|
||||
@override late final _TranslationsTrackersOauthProxyPl oauthProxy = _TranslationsTrackersOauthProxyPl._(_root);
|
||||
@override late final _TranslationsTrackersLibraryFilterPl libraryFilter = _TranslationsTrackersLibraryFilterPl._(_root);
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
@@ -1496,6 +1497,27 @@ class _TranslationsTrackersOauthProxyPl implements TranslationsTrackersOauthProx
|
||||
@override String get urlCopied => 'URL skopiowany';
|
||||
}
|
||||
|
||||
// Path: trackers.libraryFilter
|
||||
class _TranslationsTrackersLibraryFilterPl implements TranslationsTrackersLibraryFilterEn {
|
||||
_TranslationsTrackersLibraryFilterPl._(this._root);
|
||||
|
||||
final TranslationsPl _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Filtr bibliotek';
|
||||
@override String get subtitleAllSyncing => 'Synchronizowanie wszystkich bibliotek';
|
||||
@override String get subtitleNoneSyncing => 'Nic nie synchronizuje';
|
||||
@override String subtitleBlocked({required Object count}) => '${count} zablokowanych';
|
||||
@override String subtitleAllowed({required Object count}) => '${count} dozwolonych';
|
||||
@override String get mode => 'Tryb filtra';
|
||||
@override String get modeBlacklist => 'Czarna lista';
|
||||
@override String get modeWhitelist => 'Biała lista';
|
||||
@override String get modeHintBlacklist => 'Synchronizuj wszystkie biblioteki oprócz zaznaczonych poniżej.';
|
||||
@override String get modeHintWhitelist => 'Synchronizuj tylko biblioteki zaznaczone poniżej.';
|
||||
@override String get libraries => 'Biblioteki';
|
||||
@override String get noLibraries => 'Brak dostępnych bibliotek';
|
||||
}
|
||||
|
||||
/// The flat map containing all translations for locale <pl>.
|
||||
/// Only for edge cases! For simple maps, use the map function of this library.
|
||||
///
|
||||
@@ -2453,6 +2475,18 @@ extension on TranslationsPl {
|
||||
'trackers.oauthProxy.body' => 'Zeskanuj ten kod QR telefonem lub otwórz poniższy adres URL na dowolnym urządzeniu z przeglądarką.',
|
||||
'trackers.oauthProxy.openToSignIn' => ({required Object service}) => 'Otwórz ${service}, aby się zalogować',
|
||||
'trackers.oauthProxy.urlCopied' => 'URL skopiowany',
|
||||
'trackers.libraryFilter.title' => 'Filtr bibliotek',
|
||||
'trackers.libraryFilter.subtitleAllSyncing' => 'Synchronizowanie wszystkich bibliotek',
|
||||
'trackers.libraryFilter.subtitleNoneSyncing' => 'Nic nie synchronizuje',
|
||||
'trackers.libraryFilter.subtitleBlocked' => ({required Object count}) => '${count} zablokowanych',
|
||||
'trackers.libraryFilter.subtitleAllowed' => ({required Object count}) => '${count} dozwolonych',
|
||||
'trackers.libraryFilter.mode' => 'Tryb filtra',
|
||||
'trackers.libraryFilter.modeBlacklist' => 'Czarna lista',
|
||||
'trackers.libraryFilter.modeWhitelist' => 'Biała lista',
|
||||
'trackers.libraryFilter.modeHintBlacklist' => 'Synchronizuj wszystkie biblioteki oprócz zaznaczonych poniżej.',
|
||||
'trackers.libraryFilter.modeHintWhitelist' => 'Synchronizuj tylko biblioteki zaznaczone poniżej.',
|
||||
'trackers.libraryFilter.libraries' => 'Biblioteki',
|
||||
'trackers.libraryFilter.noLibraries' => 'Brak dostępnych bibliotek',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1299,6 +1299,7 @@ class _TranslationsTrackersPt implements TranslationsTrackersEn {
|
||||
@override late final _TranslationsTrackersServicesPt services = _TranslationsTrackersServicesPt._(_root);
|
||||
@override late final _TranslationsTrackersDeviceCodePt deviceCode = _TranslationsTrackersDeviceCodePt._(_root);
|
||||
@override late final _TranslationsTrackersOauthProxyPt oauthProxy = _TranslationsTrackersOauthProxyPt._(_root);
|
||||
@override late final _TranslationsTrackersLibraryFilterPt libraryFilter = _TranslationsTrackersLibraryFilterPt._(_root);
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
@@ -1496,6 +1497,27 @@ class _TranslationsTrackersOauthProxyPt implements TranslationsTrackersOauthProx
|
||||
@override String get urlCopied => 'URL copiado';
|
||||
}
|
||||
|
||||
// Path: trackers.libraryFilter
|
||||
class _TranslationsTrackersLibraryFilterPt implements TranslationsTrackersLibraryFilterEn {
|
||||
_TranslationsTrackersLibraryFilterPt._(this._root);
|
||||
|
||||
final TranslationsPt _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Filtro de bibliotecas';
|
||||
@override String get subtitleAllSyncing => 'Sincronizando todas as bibliotecas';
|
||||
@override String get subtitleNoneSyncing => 'Nada a sincronizar';
|
||||
@override String subtitleBlocked({required Object count}) => '${count} bloqueadas';
|
||||
@override String subtitleAllowed({required Object count}) => '${count} permitidas';
|
||||
@override String get mode => 'Modo de filtro';
|
||||
@override String get modeBlacklist => 'Lista negra';
|
||||
@override String get modeWhitelist => 'Lista branca';
|
||||
@override String get modeHintBlacklist => 'Sincronizar todas as bibliotecas exceto as marcadas abaixo.';
|
||||
@override String get modeHintWhitelist => 'Sincronizar apenas as bibliotecas marcadas abaixo.';
|
||||
@override String get libraries => 'Bibliotecas';
|
||||
@override String get noLibraries => 'Nenhuma biblioteca disponível';
|
||||
}
|
||||
|
||||
/// The flat map containing all translations for locale <pt>.
|
||||
/// Only for edge cases! For simple maps, use the map function of this library.
|
||||
///
|
||||
@@ -2453,6 +2475,18 @@ extension on TranslationsPt {
|
||||
'trackers.oauthProxy.body' => 'Escaneie este código QR com o celular, ou abra o URL abaixo em qualquer dispositivo com navegador.',
|
||||
'trackers.oauthProxy.openToSignIn' => ({required Object service}) => 'Abrir ${service} para entrar',
|
||||
'trackers.oauthProxy.urlCopied' => 'URL copiado',
|
||||
'trackers.libraryFilter.title' => 'Filtro de bibliotecas',
|
||||
'trackers.libraryFilter.subtitleAllSyncing' => 'Sincronizando todas as bibliotecas',
|
||||
'trackers.libraryFilter.subtitleNoneSyncing' => 'Nada a sincronizar',
|
||||
'trackers.libraryFilter.subtitleBlocked' => ({required Object count}) => '${count} bloqueadas',
|
||||
'trackers.libraryFilter.subtitleAllowed' => ({required Object count}) => '${count} permitidas',
|
||||
'trackers.libraryFilter.mode' => 'Modo de filtro',
|
||||
'trackers.libraryFilter.modeBlacklist' => 'Lista negra',
|
||||
'trackers.libraryFilter.modeWhitelist' => 'Lista branca',
|
||||
'trackers.libraryFilter.modeHintBlacklist' => 'Sincronizar todas as bibliotecas exceto as marcadas abaixo.',
|
||||
'trackers.libraryFilter.modeHintWhitelist' => 'Sincronizar apenas as bibliotecas marcadas abaixo.',
|
||||
'trackers.libraryFilter.libraries' => 'Bibliotecas',
|
||||
'trackers.libraryFilter.noLibraries' => 'Nenhuma biblioteca disponível',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1299,6 +1299,7 @@ class _TranslationsTrackersRu implements TranslationsTrackersEn {
|
||||
@override late final _TranslationsTrackersServicesRu services = _TranslationsTrackersServicesRu._(_root);
|
||||
@override late final _TranslationsTrackersDeviceCodeRu deviceCode = _TranslationsTrackersDeviceCodeRu._(_root);
|
||||
@override late final _TranslationsTrackersOauthProxyRu oauthProxy = _TranslationsTrackersOauthProxyRu._(_root);
|
||||
@override late final _TranslationsTrackersLibraryFilterRu libraryFilter = _TranslationsTrackersLibraryFilterRu._(_root);
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
@@ -1496,6 +1497,27 @@ class _TranslationsTrackersOauthProxyRu implements TranslationsTrackersOauthProx
|
||||
@override String get urlCopied => 'URL скопирован';
|
||||
}
|
||||
|
||||
// Path: trackers.libraryFilter
|
||||
class _TranslationsTrackersLibraryFilterRu implements TranslationsTrackersLibraryFilterEn {
|
||||
_TranslationsTrackersLibraryFilterRu._(this._root);
|
||||
|
||||
final TranslationsRu _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Фильтр библиотек';
|
||||
@override String get subtitleAllSyncing => 'Синхронизация всех библиотек';
|
||||
@override String get subtitleNoneSyncing => 'Ничего не синхронизируется';
|
||||
@override String subtitleBlocked({required Object count}) => '${count} заблокировано';
|
||||
@override String subtitleAllowed({required Object count}) => '${count} разрешено';
|
||||
@override String get mode => 'Режим фильтра';
|
||||
@override String get modeBlacklist => 'Чёрный список';
|
||||
@override String get modeWhitelist => 'Белый список';
|
||||
@override String get modeHintBlacklist => 'Синхронизировать все библиотеки, кроме отмеченных ниже.';
|
||||
@override String get modeHintWhitelist => 'Синхронизировать только библиотеки, отмеченные ниже.';
|
||||
@override String get libraries => 'Библиотеки';
|
||||
@override String get noLibraries => 'Библиотеки недоступны';
|
||||
}
|
||||
|
||||
/// The flat map containing all translations for locale <ru>.
|
||||
/// Only for edge cases! For simple maps, use the map function of this library.
|
||||
///
|
||||
@@ -2453,6 +2475,18 @@ extension on TranslationsRu {
|
||||
'trackers.oauthProxy.body' => 'Отсканируйте этот QR-код телефоном или откройте ссылку ниже на любом устройстве с браузером.',
|
||||
'trackers.oauthProxy.openToSignIn' => ({required Object service}) => 'Открыть ${service} для входа',
|
||||
'trackers.oauthProxy.urlCopied' => 'URL скопирован',
|
||||
'trackers.libraryFilter.title' => 'Фильтр библиотек',
|
||||
'trackers.libraryFilter.subtitleAllSyncing' => 'Синхронизация всех библиотек',
|
||||
'trackers.libraryFilter.subtitleNoneSyncing' => 'Ничего не синхронизируется',
|
||||
'trackers.libraryFilter.subtitleBlocked' => ({required Object count}) => '${count} заблокировано',
|
||||
'trackers.libraryFilter.subtitleAllowed' => ({required Object count}) => '${count} разрешено',
|
||||
'trackers.libraryFilter.mode' => 'Режим фильтра',
|
||||
'trackers.libraryFilter.modeBlacklist' => 'Чёрный список',
|
||||
'trackers.libraryFilter.modeWhitelist' => 'Белый список',
|
||||
'trackers.libraryFilter.modeHintBlacklist' => 'Синхронизировать все библиотеки, кроме отмеченных ниже.',
|
||||
'trackers.libraryFilter.modeHintWhitelist' => 'Синхронизировать только библиотеки, отмеченные ниже.',
|
||||
'trackers.libraryFilter.libraries' => 'Библиотеки',
|
||||
'trackers.libraryFilter.noLibraries' => 'Библиотеки недоступны',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1299,6 +1299,7 @@ class _TranslationsTrackersSv implements TranslationsTrackersEn {
|
||||
@override late final _TranslationsTrackersServicesSv services = _TranslationsTrackersServicesSv._(_root);
|
||||
@override late final _TranslationsTrackersDeviceCodeSv deviceCode = _TranslationsTrackersDeviceCodeSv._(_root);
|
||||
@override late final _TranslationsTrackersOauthProxySv oauthProxy = _TranslationsTrackersOauthProxySv._(_root);
|
||||
@override late final _TranslationsTrackersLibraryFilterSv libraryFilter = _TranslationsTrackersLibraryFilterSv._(_root);
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
@@ -1496,6 +1497,27 @@ class _TranslationsTrackersOauthProxySv implements TranslationsTrackersOauthProx
|
||||
@override String get urlCopied => 'URL kopierad';
|
||||
}
|
||||
|
||||
// Path: trackers.libraryFilter
|
||||
class _TranslationsTrackersLibraryFilterSv implements TranslationsTrackersLibraryFilterEn {
|
||||
_TranslationsTrackersLibraryFilterSv._(this._root);
|
||||
|
||||
final TranslationsSv _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => 'Biblioteksfilter';
|
||||
@override String get subtitleAllSyncing => 'Synkroniserar alla bibliotek';
|
||||
@override String get subtitleNoneSyncing => 'Ingenting synkroniseras';
|
||||
@override String subtitleBlocked({required Object count}) => '${count} blockerade';
|
||||
@override String subtitleAllowed({required Object count}) => '${count} tillåtna';
|
||||
@override String get mode => 'Filterläge';
|
||||
@override String get modeBlacklist => 'Svartlista';
|
||||
@override String get modeWhitelist => 'Vitlista';
|
||||
@override String get modeHintBlacklist => 'Synkronisera alla bibliotek utom de som markerats nedan.';
|
||||
@override String get modeHintWhitelist => 'Synkronisera endast de bibliotek som markerats nedan.';
|
||||
@override String get libraries => 'Bibliotek';
|
||||
@override String get noLibraries => 'Inga bibliotek tillgängliga';
|
||||
}
|
||||
|
||||
/// The flat map containing all translations for locale <sv>.
|
||||
/// Only for edge cases! For simple maps, use the map function of this library.
|
||||
///
|
||||
@@ -2453,6 +2475,18 @@ extension on TranslationsSv {
|
||||
'trackers.oauthProxy.body' => 'Skanna den här QR-koden med din telefon, eller öppna URL:en nedan på en enhet med webbläsare.',
|
||||
'trackers.oauthProxy.openToSignIn' => ({required Object service}) => 'Öppna ${service} för att logga in',
|
||||
'trackers.oauthProxy.urlCopied' => 'URL kopierad',
|
||||
'trackers.libraryFilter.title' => 'Biblioteksfilter',
|
||||
'trackers.libraryFilter.subtitleAllSyncing' => 'Synkroniserar alla bibliotek',
|
||||
'trackers.libraryFilter.subtitleNoneSyncing' => 'Ingenting synkroniseras',
|
||||
'trackers.libraryFilter.subtitleBlocked' => ({required Object count}) => '${count} blockerade',
|
||||
'trackers.libraryFilter.subtitleAllowed' => ({required Object count}) => '${count} tillåtna',
|
||||
'trackers.libraryFilter.mode' => 'Filterläge',
|
||||
'trackers.libraryFilter.modeBlacklist' => 'Svartlista',
|
||||
'trackers.libraryFilter.modeWhitelist' => 'Vitlista',
|
||||
'trackers.libraryFilter.modeHintBlacklist' => 'Synkronisera alla bibliotek utom de som markerats nedan.',
|
||||
'trackers.libraryFilter.modeHintWhitelist' => 'Synkronisera endast de bibliotek som markerats nedan.',
|
||||
'trackers.libraryFilter.libraries' => 'Bibliotek',
|
||||
'trackers.libraryFilter.noLibraries' => 'Inga bibliotek tillgängliga',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1299,6 +1299,7 @@ class _TranslationsTrackersZh implements TranslationsTrackersEn {
|
||||
@override late final _TranslationsTrackersServicesZh services = _TranslationsTrackersServicesZh._(_root);
|
||||
@override late final _TranslationsTrackersDeviceCodeZh deviceCode = _TranslationsTrackersDeviceCodeZh._(_root);
|
||||
@override late final _TranslationsTrackersOauthProxyZh oauthProxy = _TranslationsTrackersOauthProxyZh._(_root);
|
||||
@override late final _TranslationsTrackersLibraryFilterZh libraryFilter = _TranslationsTrackersLibraryFilterZh._(_root);
|
||||
}
|
||||
|
||||
// Path: hotkeys.actions
|
||||
@@ -1496,6 +1497,27 @@ class _TranslationsTrackersOauthProxyZh implements TranslationsTrackersOauthProx
|
||||
@override String get urlCopied => 'URL 已复制';
|
||||
}
|
||||
|
||||
// Path: trackers.libraryFilter
|
||||
class _TranslationsTrackersLibraryFilterZh implements TranslationsTrackersLibraryFilterEn {
|
||||
_TranslationsTrackersLibraryFilterZh._(this._root);
|
||||
|
||||
final TranslationsZh _root; // ignore: unused_field
|
||||
|
||||
// Translations
|
||||
@override String get title => '媒体库筛选';
|
||||
@override String get subtitleAllSyncing => '同步所有媒体库';
|
||||
@override String get subtitleNoneSyncing => '不同步任何内容';
|
||||
@override String subtitleBlocked({required Object count}) => '已屏蔽 ${count} 个';
|
||||
@override String subtitleAllowed({required Object count}) => '已允许 ${count} 个';
|
||||
@override String get mode => '筛选模式';
|
||||
@override String get modeBlacklist => '黑名单';
|
||||
@override String get modeWhitelist => '白名单';
|
||||
@override String get modeHintBlacklist => '同步下方未勾选的所有媒体库。';
|
||||
@override String get modeHintWhitelist => '仅同步下方勾选的媒体库。';
|
||||
@override String get libraries => '媒体库';
|
||||
@override String get noLibraries => '没有可用的媒体库';
|
||||
}
|
||||
|
||||
/// The flat map containing all translations for locale <zh>.
|
||||
/// Only for edge cases! For simple maps, use the map function of this library.
|
||||
///
|
||||
@@ -2453,6 +2475,18 @@ extension on TranslationsZh {
|
||||
'trackers.oauthProxy.body' => '用手机扫描此二维码,或在任何带浏览器的设备上打开下方 URL。',
|
||||
'trackers.oauthProxy.openToSignIn' => ({required Object service}) => '打开 ${service} 以登录',
|
||||
'trackers.oauthProxy.urlCopied' => 'URL 已复制',
|
||||
'trackers.libraryFilter.title' => '媒体库筛选',
|
||||
'trackers.libraryFilter.subtitleAllSyncing' => '同步所有媒体库',
|
||||
'trackers.libraryFilter.subtitleNoneSyncing' => '不同步任何内容',
|
||||
'trackers.libraryFilter.subtitleBlocked' => ({required Object count}) => '已屏蔽 ${count} 个',
|
||||
'trackers.libraryFilter.subtitleAllowed' => ({required Object count}) => '已允许 ${count} 个',
|
||||
'trackers.libraryFilter.mode' => '筛选模式',
|
||||
'trackers.libraryFilter.modeBlacklist' => '黑名单',
|
||||
'trackers.libraryFilter.modeWhitelist' => '白名单',
|
||||
'trackers.libraryFilter.modeHintBlacklist' => '同步下方未勾选的所有媒体库。',
|
||||
'trackers.libraryFilter.modeHintWhitelist' => '仅同步下方勾选的媒体库。',
|
||||
'trackers.libraryFilter.libraries' => '媒体库',
|
||||
'trackers.libraryFilter.noLibraries' => '没有可用的媒体库',
|
||||
_ => null,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1046,6 +1046,20 @@
|
||||
"body": "Skanna den här QR-koden med din telefon, eller öppna URL:en nedan på en enhet med webbläsare.",
|
||||
"openToSignIn": "Öppna ${service} för att logga in",
|
||||
"urlCopied": "URL kopierad"
|
||||
},
|
||||
"libraryFilter": {
|
||||
"title": "Biblioteksfilter",
|
||||
"subtitleAllSyncing": "Synkroniserar alla bibliotek",
|
||||
"subtitleNoneSyncing": "Ingenting synkroniseras",
|
||||
"subtitleBlocked": "${count} blockerade",
|
||||
"subtitleAllowed": "${count} tillåtna",
|
||||
"mode": "Filterläge",
|
||||
"modeBlacklist": "Svartlista",
|
||||
"modeWhitelist": "Vitlista",
|
||||
"modeHintBlacklist": "Synkronisera alla bibliotek utom de som markerats nedan.",
|
||||
"modeHintWhitelist": "Synkronisera endast de bibliotek som markerats nedan.",
|
||||
"libraries": "Bibliotek",
|
||||
"noLibraries": "Inga bibliotek tillgängliga"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,6 +1046,20 @@
|
||||
"body": "用手机扫描此二维码,或在任何带浏览器的设备上打开下方 URL。",
|
||||
"openToSignIn": "打开 ${service} 以登录",
|
||||
"urlCopied": "URL 已复制"
|
||||
},
|
||||
"libraryFilter": {
|
||||
"title": "媒体库筛选",
|
||||
"subtitleAllSyncing": "同步所有媒体库",
|
||||
"subtitleNoneSyncing": "不同步任何内容",
|
||||
"subtitleBlocked": "已屏蔽 ${count} 个",
|
||||
"subtitleAllowed": "已允许 ${count} 个",
|
||||
"mode": "筛选模式",
|
||||
"modeBlacklist": "黑名单",
|
||||
"modeWhitelist": "白名单",
|
||||
"modeHintBlacklist": "同步下方未勾选的所有媒体库。",
|
||||
"modeHintWhitelist": "仅同步下方勾选的媒体库。",
|
||||
"libraries": "媒体库",
|
||||
"noLibraries": "没有可用的媒体库"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,6 +154,12 @@ class PlexMetadata with MultiServerFields {
|
||||
/// Global unique identifier across all servers (serverId:ratingKey)
|
||||
String get globalKey => serverId != null ? buildGlobalKey(serverId!, ratingKey) : ratingKey;
|
||||
|
||||
/// Global unique identifier of this item's library section, matching
|
||||
/// [PlexLibrary.globalKey]. Null when either [serverId] or [librarySectionID]
|
||||
/// is missing.
|
||||
String? get librarySectionGlobalKey =>
|
||||
serverId != null && librarySectionID != null ? buildGlobalKey(serverId!, librarySectionID!.toString()) : null;
|
||||
|
||||
/// Parent rating keys for hierarchical invalidation.
|
||||
/// For an episode: [seasonRatingKey, showRatingKey]
|
||||
/// For a season: [showRatingKey]
|
||||
|
||||
@@ -20,11 +20,16 @@ class TrackerContext {
|
||||
/// sent to any tracker.
|
||||
final String ratingKey;
|
||||
|
||||
/// Library globalKey the item belongs to, or null when the metadata didn't
|
||||
/// carry library info.
|
||||
final String? libraryGlobalKey;
|
||||
|
||||
const TrackerContext._({
|
||||
required this.external,
|
||||
required this.anime,
|
||||
required this.isMovie,
|
||||
required this.ratingKey,
|
||||
required this.libraryGlobalKey,
|
||||
this.season,
|
||||
this.episodeNumber,
|
||||
});
|
||||
@@ -33,14 +38,22 @@ class TrackerContext {
|
||||
required PlexExternalIds external,
|
||||
required AnimeIds? anime,
|
||||
required String ratingKey,
|
||||
required String? libraryGlobalKey,
|
||||
}) {
|
||||
return TrackerContext._(external: external, anime: anime, isMovie: true, ratingKey: ratingKey);
|
||||
return TrackerContext._(
|
||||
external: external,
|
||||
anime: anime,
|
||||
isMovie: true,
|
||||
ratingKey: ratingKey,
|
||||
libraryGlobalKey: libraryGlobalKey,
|
||||
);
|
||||
}
|
||||
|
||||
factory TrackerContext.episode({
|
||||
required PlexExternalIds external,
|
||||
required AnimeIds? anime,
|
||||
required String ratingKey,
|
||||
required String? libraryGlobalKey,
|
||||
required int season,
|
||||
required int episodeNumber,
|
||||
}) {
|
||||
@@ -49,6 +62,7 @@ class TrackerContext {
|
||||
anime: anime,
|
||||
isMovie: false,
|
||||
ratingKey: ratingKey,
|
||||
libraryGlobalKey: libraryGlobalKey,
|
||||
season: season,
|
||||
episodeNumber: episodeNumber,
|
||||
);
|
||||
|
||||
@@ -20,13 +20,10 @@ import '../services/trackers/simkl/simkl_client.dart';
|
||||
import '../services/trackers/simkl/simkl_session.dart';
|
||||
import '../services/trackers/simkl/simkl_tracker.dart';
|
||||
import '../services/trackers/tracker_account_store.dart';
|
||||
import '../services/trackers/tracker_constants.dart';
|
||||
import '../services/trackers/tracker_coordinator.dart';
|
||||
import '../utils/app_logger.dart';
|
||||
|
||||
/// Identifier used in the settings UI to disambiguate disconnect/connect
|
||||
/// actions without importing the per-service session classes into widgets.
|
||||
enum TrackerService { mal, anilist, simkl }
|
||||
|
||||
/// Owns the active MAL / AniList / Simkl sessions for the currently-selected
|
||||
/// Plex profile. Single rebind seam: [onActiveProfileChanged] loads all three
|
||||
/// sessions from their stores and pushes them to their trackers.
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../i18n/strings.g.dart';
|
||||
import '../../models/plex_library.dart';
|
||||
import '../../providers/libraries_provider.dart';
|
||||
import '../../services/settings_service.dart';
|
||||
import '../../services/trackers/tracker_constants.dart';
|
||||
import '../../widgets/app_icon.dart';
|
||||
import '../../widgets/focusable_list_tile.dart';
|
||||
import '../../widgets/focused_scroll_scaffold.dart';
|
||||
import '../../widgets/settings_section.dart';
|
||||
|
||||
/// Per-provider library whitelist/blacklist screen. Toggling a switch
|
||||
/// adds/removes the library from the filter set; "selected" means "in the
|
||||
/// filter list" in both modes.
|
||||
class TrackerLibraryFilterScreen extends StatefulWidget {
|
||||
final TrackerService service;
|
||||
|
||||
const TrackerLibraryFilterScreen({super.key, required this.service});
|
||||
|
||||
/// Human-readable summary of the current filter state for [service], used as
|
||||
/// the subtitle on the parent settings screen's "Library filter" tile.
|
||||
static String subtitleFor(SettingsService settings, TrackerService service) {
|
||||
final mode = settings.getTrackerLibraryFilterMode(service);
|
||||
final ids = settings.getTrackerLibraryFilterIds(service);
|
||||
if (ids.isEmpty) {
|
||||
return mode == TrackerLibraryFilterMode.blacklist
|
||||
? t.trackers.libraryFilter.subtitleAllSyncing
|
||||
: t.trackers.libraryFilter.subtitleNoneSyncing;
|
||||
}
|
||||
final count = ids.length.toString();
|
||||
return mode == TrackerLibraryFilterMode.blacklist
|
||||
? t.trackers.libraryFilter.subtitleBlocked(count: count)
|
||||
: t.trackers.libraryFilter.subtitleAllowed(count: count);
|
||||
}
|
||||
|
||||
@override
|
||||
State<TrackerLibraryFilterScreen> createState() => _TrackerLibraryFilterScreenState();
|
||||
}
|
||||
|
||||
class _TrackerLibraryFilterScreenState extends State<TrackerLibraryFilterScreen> {
|
||||
late SettingsService _settings;
|
||||
TrackerLibraryFilterMode _mode = TrackerLibraryFilterMode.blacklist;
|
||||
final Set<String> _selectedIds = <String>{};
|
||||
bool _loaded = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_load();
|
||||
}
|
||||
|
||||
Future<void> _load() async {
|
||||
final s = await SettingsService.getInstance();
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
_settings = s;
|
||||
_mode = s.getTrackerLibraryFilterMode(widget.service);
|
||||
_selectedIds
|
||||
..clear()
|
||||
..addAll(s.getTrackerLibraryFilterIds(widget.service));
|
||||
_loaded = true;
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _setMode(TrackerLibraryFilterMode mode) async {
|
||||
if (mode == _mode) return;
|
||||
setState(() => _mode = mode);
|
||||
await _settings.setTrackerLibraryFilterMode(widget.service, mode);
|
||||
}
|
||||
|
||||
Future<void> _toggleLibrary(String globalKey, bool value) async {
|
||||
setState(() {
|
||||
if (value) {
|
||||
_selectedIds.add(globalKey);
|
||||
} else {
|
||||
_selectedIds.remove(globalKey);
|
||||
}
|
||||
});
|
||||
await _settings.setTrackerLibraryFilterIds(widget.service, _selectedIds);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final title = Text(t.trackers.libraryFilter.title);
|
||||
if (!_loaded) {
|
||||
return FocusedScrollScaffold(
|
||||
title: title,
|
||||
slivers: const [SliverFillRemaining(child: Center(child: CircularProgressIndicator()))],
|
||||
);
|
||||
}
|
||||
|
||||
final theme = Theme.of(context);
|
||||
|
||||
return Consumer<LibrariesProvider>(
|
||||
builder: (context, provider, _) {
|
||||
final libraries = provider.libraries;
|
||||
final grouped = _groupByServer(libraries);
|
||||
final showServerHeaders = grouped.length > 1;
|
||||
|
||||
final children = <Widget>[
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 8, 16, 16),
|
||||
child: Text(
|
||||
_mode == TrackerLibraryFilterMode.blacklist
|
||||
? t.trackers.libraryFilter.modeHintBlacklist
|
||||
: t.trackers.libraryFilter.modeHintWhitelist,
|
||||
style: theme.textTheme.bodyMedium?.copyWith(color: theme.colorScheme.onSurfaceVariant),
|
||||
),
|
||||
),
|
||||
SegmentedSetting<TrackerLibraryFilterMode>(
|
||||
icon: Symbols.filter_list_rounded,
|
||||
title: t.trackers.libraryFilter.mode,
|
||||
segments: [
|
||||
ButtonSegment(
|
||||
value: TrackerLibraryFilterMode.blacklist,
|
||||
label: Text(t.trackers.libraryFilter.modeBlacklist),
|
||||
),
|
||||
ButtonSegment(
|
||||
value: TrackerLibraryFilterMode.whitelist,
|
||||
label: Text(t.trackers.libraryFilter.modeWhitelist),
|
||||
),
|
||||
],
|
||||
selected: _mode,
|
||||
onChanged: _setMode,
|
||||
),
|
||||
SettingsSectionHeader(t.trackers.libraryFilter.libraries),
|
||||
];
|
||||
|
||||
if (libraries.isEmpty) {
|
||||
children.add(ListTile(title: Text(t.trackers.libraryFilter.noLibraries)));
|
||||
} else {
|
||||
for (final entry in grouped.entries) {
|
||||
if (showServerHeaders) {
|
||||
children.add(SettingsSectionHeader(entry.value.first.serverName ?? entry.key));
|
||||
}
|
||||
for (final lib in entry.value) {
|
||||
children.add(
|
||||
FocusableSwitchListTile(
|
||||
key: ValueKey('tracker-library-filter-${lib.globalKey}'),
|
||||
secondary: const AppIcon(Symbols.folder_rounded, fill: 1),
|
||||
title: Text(lib.title),
|
||||
value: _selectedIds.contains(lib.globalKey),
|
||||
onChanged: (v) => _toggleLibrary(lib.globalKey, v),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
children.add(const SizedBox(height: 24));
|
||||
|
||||
return FocusedScrollScaffold(
|
||||
title: title,
|
||||
slivers: [
|
||||
SliverList(delegate: SliverChildListDelegate(children)),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
static Map<String, List<PlexLibrary>> _groupByServer(List<PlexLibrary> libs) {
|
||||
final out = <String, List<PlexLibrary>>{};
|
||||
for (final lib in libs) {
|
||||
final serverId = lib.serverId;
|
||||
if (serverId == null) continue;
|
||||
out.putIfAbsent(serverId, () => <PlexLibrary>[]).add(lib);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import '../../services/trackers/anilist/anilist_tracker.dart';
|
||||
import '../../services/trackers/mal/mal_tracker.dart';
|
||||
import '../../services/trackers/oauth_proxy_client.dart';
|
||||
import '../../services/trackers/simkl/simkl_tracker.dart';
|
||||
import '../../services/trackers/tracker_constants.dart';
|
||||
import '../../services/settings_service.dart';
|
||||
import '../../utils/app_logger.dart';
|
||||
import '../../utils/dialogs.dart';
|
||||
@@ -22,6 +23,7 @@ import '../../widgets/device_code_dialog.dart';
|
||||
import '../../widgets/focused_scroll_scaffold.dart';
|
||||
import '../../widgets/oauth_proxy_dialog.dart';
|
||||
import '../../widgets/settings_section.dart';
|
||||
import 'tracker_library_filter_screen.dart';
|
||||
|
||||
/// Shared dialog-driven connect flow used by all three trackers. Handles the
|
||||
/// guard, auto-launch-on-pointer, dialog lifecycle, and failure snackbar —
|
||||
@@ -114,6 +116,7 @@ Future<void> startSimklConnection(BuildContext context) {
|
||||
/// Per-service wiring for [TrackerSettingsScreen]. Keeps tracker-specific
|
||||
/// method names out of the shared screen body.
|
||||
class TrackerConfig {
|
||||
final TrackerService service;
|
||||
final String displayName;
|
||||
final bool Function(TrackersProvider) isConnected;
|
||||
final String? Function(TrackersProvider) username;
|
||||
@@ -122,6 +125,7 @@ class TrackerConfig {
|
||||
final Future<void> Function(TrackersProvider) disconnect;
|
||||
|
||||
const TrackerConfig({
|
||||
required this.service,
|
||||
required this.displayName,
|
||||
required this.isConnected,
|
||||
required this.username,
|
||||
@@ -131,6 +135,7 @@ class TrackerConfig {
|
||||
});
|
||||
|
||||
static TrackerConfig mal() => TrackerConfig(
|
||||
service: TrackerService.mal,
|
||||
displayName: t.trackers.services.mal,
|
||||
isConnected: (a) => a.isMalConnected,
|
||||
username: (a) => a.malUsername,
|
||||
@@ -143,6 +148,7 @@ class TrackerConfig {
|
||||
);
|
||||
|
||||
static TrackerConfig anilist() => TrackerConfig(
|
||||
service: TrackerService.anilist,
|
||||
displayName: t.trackers.services.anilist,
|
||||
isConnected: (a) => a.isAnilistConnected,
|
||||
username: (a) => a.anilistUsername,
|
||||
@@ -155,6 +161,7 @@ class TrackerConfig {
|
||||
);
|
||||
|
||||
static TrackerConfig simkl() => TrackerConfig(
|
||||
service: TrackerService.simkl,
|
||||
displayName: t.trackers.services.simkl,
|
||||
isConnected: (a) => a.isSimklConnected,
|
||||
username: (a) => a.simklUsername,
|
||||
@@ -258,6 +265,20 @@ class _TrackerSettingsScreenState extends State<TrackerSettingsScreen> {
|
||||
await widget.config.setScrobbleEnabled(_settings!, value);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: const AppIcon(Symbols.filter_list_rounded, fill: 1),
|
||||
title: Text(t.trackers.libraryFilter.title),
|
||||
subtitle: Text(TrackerLibraryFilterScreen.subtitleFor(_settings!, widget.config.service)),
|
||||
trailing: const AppIcon(Symbols.chevron_right_rounded, fill: 1),
|
||||
onTap: () async {
|
||||
await Navigator.of(context).push(
|
||||
MaterialPageRoute<void>(
|
||||
builder: (_) => TrackerLibraryFilterScreen(service: widget.config.service),
|
||||
),
|
||||
);
|
||||
if (mounted) setState(() {});
|
||||
},
|
||||
),
|
||||
const Divider(height: 32),
|
||||
ListTile(
|
||||
leading: AppIcon(Symbols.link_off_rounded, fill: 1, color: Theme.of(context).colorScheme.error),
|
||||
|
||||
@@ -9,6 +9,7 @@ import '../../focus/input_mode_tracker.dart';
|
||||
import '../../i18n/strings.g.dart';
|
||||
import '../../providers/trakt_account_provider.dart';
|
||||
import '../../services/settings_service.dart';
|
||||
import '../../services/trackers/tracker_constants.dart';
|
||||
import '../../services/trakt/trakt_scrobble_service.dart';
|
||||
import '../../services/trakt/trakt_sync_service.dart';
|
||||
import '../../utils/app_logger.dart';
|
||||
@@ -18,6 +19,7 @@ import '../../widgets/app_icon.dart';
|
||||
import '../../widgets/device_code_dialog.dart';
|
||||
import '../../widgets/focused_scroll_scaffold.dart';
|
||||
import '../../widgets/settings_section.dart';
|
||||
import 'tracker_library_filter_screen.dart';
|
||||
|
||||
/// Start the Trakt device-code OAuth flow from anywhere in the app.
|
||||
///
|
||||
@@ -174,6 +176,20 @@ class _TraktSettingsScreenState extends State<TraktSettingsScreen> {
|
||||
await TraktSyncService.instance.setEnabled(value);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: const AppIcon(Symbols.filter_list_rounded, fill: 1),
|
||||
title: Text(t.trackers.libraryFilter.title),
|
||||
subtitle: Text(TrackerLibraryFilterScreen.subtitleFor(_settings!, TrackerService.trakt)),
|
||||
trailing: const AppIcon(Symbols.chevron_right_rounded, fill: 1),
|
||||
onTap: () async {
|
||||
await Navigator.of(context).push(
|
||||
MaterialPageRoute<void>(
|
||||
builder: (_) => const TrackerLibraryFilterScreen(service: TrackerService.trakt),
|
||||
),
|
||||
);
|
||||
if (mounted) setState(() {});
|
||||
},
|
||||
),
|
||||
const Divider(height: 32),
|
||||
ListTile(
|
||||
leading: AppIcon(Symbols.link_off_rounded, fill: 1, color: Theme.of(context).colorScheme.error),
|
||||
|
||||
@@ -10,6 +10,7 @@ import '../models/mpv_config_models.dart';
|
||||
import '../models/external_player_models.dart';
|
||||
import 'base_shared_preferences_service.dart';
|
||||
import '../utils/platform_detector.dart';
|
||||
import 'trackers/tracker_constants.dart';
|
||||
|
||||
enum ThemeMode { system, light, dark, oled }
|
||||
|
||||
@@ -98,6 +99,8 @@ class SettingsService extends BaseSharedPreferencesService {
|
||||
static const String _keyEnableMalScrobble = 'enable_mal_scrobble';
|
||||
static const String _keyEnableAnilistScrobble = 'enable_anilist_scrobble';
|
||||
static const String _keyEnableSimklScrobble = 'enable_simkl_scrobble';
|
||||
static const String _prefixTrackerLibraryFilterMode = 'tracker_library_filter_mode_';
|
||||
static const String _prefixTrackerLibraryFilterIds = 'tracker_library_filter_ids_';
|
||||
static const String _keyEnableCompanionRemoteServer = 'enable_companion_remote_server';
|
||||
static const String _keyAutoPip = 'auto_pip';
|
||||
static const String _keyMatchContentFrameRate = 'match_content_frame_rate';
|
||||
@@ -1194,6 +1197,34 @@ class SettingsService extends BaseSharedPreferencesService {
|
||||
return prefs.getBool(_keyEnableSimklScrobble) ?? true;
|
||||
}
|
||||
|
||||
// Per-tracker library filter. Default blacklist+empty = sync every library.
|
||||
TrackerLibraryFilterMode getTrackerLibraryFilterMode(TrackerService service) => _getEnumValue(
|
||||
'$_prefixTrackerLibraryFilterMode${service.name}',
|
||||
TrackerLibraryFilterMode.values,
|
||||
TrackerLibraryFilterMode.blacklist,
|
||||
);
|
||||
|
||||
Future<void> setTrackerLibraryFilterMode(TrackerService service, TrackerLibraryFilterMode mode) async {
|
||||
await prefs.setString('$_prefixTrackerLibraryFilterMode${service.name}', mode.name);
|
||||
}
|
||||
|
||||
Set<String> getTrackerLibraryFilterIds(TrackerService service) {
|
||||
final ids = prefs.getStringList('$_prefixTrackerLibraryFilterIds${service.name}');
|
||||
return ids?.toSet() ?? <String>{};
|
||||
}
|
||||
|
||||
Future<void> setTrackerLibraryFilterIds(TrackerService service, Set<String> ids) async {
|
||||
await prefs.setStringList('$_prefixTrackerLibraryFilterIds${service.name}', ids.toList());
|
||||
}
|
||||
|
||||
/// Whether a scrobble/sync for [libraryGlobalKey] should be sent to [service].
|
||||
/// Null keys bypass the filter so we err on the side of syncing.
|
||||
bool isLibraryAllowedForTracker(TrackerService service, String? libraryGlobalKey) {
|
||||
if (libraryGlobalKey == null) return true;
|
||||
final inList = getTrackerLibraryFilterIds(service).contains(libraryGlobalKey);
|
||||
return getTrackerLibraryFilterMode(service) == TrackerLibraryFilterMode.blacklist ? !inList : inList;
|
||||
}
|
||||
|
||||
// Companion Remote Server
|
||||
Future<void> setEnableCompanionRemoteServer(bool enabled) async {
|
||||
await prefs.setBool(_keyEnableCompanionRemoteServer, enabled);
|
||||
@@ -1536,6 +1567,10 @@ class SettingsService extends BaseSharedPreferencesService {
|
||||
prefs.remove(_keyEnableMalScrobble),
|
||||
prefs.remove(_keyEnableAnilistScrobble),
|
||||
prefs.remove(_keyEnableSimklScrobble),
|
||||
...TrackerService.values.expand((s) => [
|
||||
prefs.remove('$_prefixTrackerLibraryFilterMode${s.name}'),
|
||||
prefs.remove('$_prefixTrackerLibraryFilterIds${s.name}'),
|
||||
]),
|
||||
prefs.remove(_keyAutoPip),
|
||||
prefs.remove(_keyMatchContentFrameRate),
|
||||
prefs.remove(_keyTunneledPlayback),
|
||||
|
||||
@@ -2,6 +2,7 @@ import '../../../models/trackers/tracker_context.dart';
|
||||
import '../../../utils/app_logger.dart';
|
||||
import '../../settings_service.dart';
|
||||
import '../tracker.dart';
|
||||
import '../tracker_constants.dart';
|
||||
import 'anilist_client.dart';
|
||||
import 'anilist_session.dart';
|
||||
|
||||
@@ -17,6 +18,9 @@ class AnilistTracker extends TrackerBase {
|
||||
@override
|
||||
String get name => 'anilist';
|
||||
|
||||
@override
|
||||
TrackerService get service => TrackerService.anilist;
|
||||
|
||||
@override
|
||||
bool get needsFribb => true;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import '../../../models/trackers/tracker_context.dart';
|
||||
import '../../../utils/app_logger.dart';
|
||||
import '../../settings_service.dart';
|
||||
import '../tracker.dart';
|
||||
import '../tracker_constants.dart';
|
||||
import 'mal_client.dart';
|
||||
import 'mal_session.dart';
|
||||
|
||||
@@ -22,6 +23,9 @@ class MalTracker extends TrackerBase {
|
||||
@override
|
||||
String get name => 'mal';
|
||||
|
||||
@override
|
||||
TrackerService get service => TrackerService.mal;
|
||||
|
||||
@override
|
||||
bool get needsFribb => true;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import '../../../models/trackers/tracker_context.dart';
|
||||
import '../../../utils/app_logger.dart';
|
||||
import '../../settings_service.dart';
|
||||
import '../tracker.dart';
|
||||
import '../tracker_constants.dart';
|
||||
import 'simkl_client.dart';
|
||||
import 'simkl_session.dart';
|
||||
|
||||
@@ -20,6 +21,9 @@ class SimklTracker extends TrackerBase {
|
||||
@override
|
||||
String get name => 'simkl';
|
||||
|
||||
@override
|
||||
TrackerService get service => TrackerService.simkl;
|
||||
|
||||
@override
|
||||
bool get needsFribb => false;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import '../../models/trackers/tracker_context.dart';
|
||||
import '../settings_service.dart';
|
||||
import 'tracker_constants.dart';
|
||||
|
||||
/// Abstract tracker contract: the coordinator calls [markWatched] once per
|
||||
/// playback when progress crosses the watched threshold. Enabled/auth gating
|
||||
@@ -7,6 +8,10 @@ import '../settings_service.dart';
|
||||
abstract class Tracker {
|
||||
String get name;
|
||||
|
||||
/// Stable identifier used to persist per-service settings (library filter,
|
||||
/// scrobble enabled, etc.).
|
||||
TrackerService get service;
|
||||
|
||||
bool get canScrobble;
|
||||
|
||||
/// True if this tracker's IDs only come from the Fribb anime mapping
|
||||
@@ -18,6 +23,12 @@ abstract class Tracker {
|
||||
Future<void> initialize();
|
||||
Future<void> setEnabled(bool enabled);
|
||||
|
||||
/// Whether an item in the given library should be scrobbled. Applies the
|
||||
/// per-tracker whitelist/blacklist — callers pass the Plex library
|
||||
/// `serverId:sectionId` globalKey (null when unknown, in which case the
|
||||
/// filter is bypassed so we err on the side of syncing).
|
||||
bool shouldScrobbleForLibrary(String? libraryGlobalKey);
|
||||
|
||||
Future<void> markWatched(TrackerContext ctx);
|
||||
}
|
||||
|
||||
@@ -45,4 +56,8 @@ abstract class TrackerBase implements Tracker {
|
||||
Future<void> setEnabled(bool enabled) async {
|
||||
_isEnabled = enabled;
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldScrobbleForLibrary(String? libraryGlobalKey) =>
|
||||
SettingsService.instanceOrNull?.isLibraryAllowedForTracker(service, libraryGlobalKey) ?? true;
|
||||
}
|
||||
|
||||
@@ -6,3 +6,11 @@ class TrackerConstants {
|
||||
/// pushed to each tracker.
|
||||
static const double watchedThresholdPercent = 80.0;
|
||||
}
|
||||
|
||||
/// Identifier used across the app to disambiguate per-service operations.
|
||||
/// The enum's `.name` forms part of the persistence key — do not rename
|
||||
/// without a migration.
|
||||
enum TrackerService { mal, anilist, simkl, trakt }
|
||||
|
||||
/// Blacklist+[] syncs every library (the default); whitelist+[] syncs nothing.
|
||||
enum TrackerLibraryFilterMode { blacklist, whitelist }
|
||||
|
||||
@@ -113,7 +113,9 @@ class TrackerCoordinator {
|
||||
}
|
||||
|
||||
Future<void> _dispatchMarkWatched(TrackerContext ctx) async {
|
||||
final active = _trackers.where((t) => t.canScrobble);
|
||||
final active = _trackers.where(
|
||||
(t) => t.canScrobble && t.shouldScrobbleForLibrary(ctx.libraryGlobalKey),
|
||||
);
|
||||
await Future.wait(active.map((t) async {
|
||||
try {
|
||||
await t.markWatched(ctx);
|
||||
@@ -127,6 +129,8 @@ class TrackerCoordinator {
|
||||
final resolver = _resolver;
|
||||
if (resolver == null) return null;
|
||||
|
||||
final libraryKey = metadata.librarySectionGlobalKey;
|
||||
|
||||
if (metadata.mediaType == PlexMediaType.movie) {
|
||||
final ids = await resolver.resolveForMovie(metadata.ratingKey);
|
||||
if (ids == null) return null;
|
||||
@@ -134,6 +138,7 @@ class TrackerCoordinator {
|
||||
external: ids.external,
|
||||
anime: ids.anime,
|
||||
ratingKey: metadata.ratingKey,
|
||||
libraryGlobalKey: libraryKey,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -147,6 +152,7 @@ class TrackerCoordinator {
|
||||
external: ids.external,
|
||||
anime: ids.anime,
|
||||
ratingKey: metadata.ratingKey,
|
||||
libraryGlobalKey: libraryKey,
|
||||
season: season,
|
||||
episodeNumber: number,
|
||||
);
|
||||
|
||||
@@ -6,6 +6,7 @@ import '../../models/trakt/trakt_scrobble_request.dart';
|
||||
import '../../utils/app_logger.dart';
|
||||
import '../plex_client.dart';
|
||||
import '../settings_service.dart';
|
||||
import '../trackers/tracker_constants.dart';
|
||||
import '../trackers/tracker_id_resolver.dart';
|
||||
import 'trakt_client.dart';
|
||||
import 'trakt_constants.dart';
|
||||
@@ -91,6 +92,13 @@ class TraktScrobbleService {
|
||||
final type = metadata.mediaType;
|
||||
if (type != PlexMediaType.movie && type != PlexMediaType.episode) return;
|
||||
|
||||
final settings = SettingsService.instanceOrNull;
|
||||
if (settings != null &&
|
||||
!settings.isLibraryAllowedForTracker(TrackerService.trakt, metadata.librarySectionGlobalKey)) {
|
||||
appLogger.d('Trakt: library filtered out for ${metadata.ratingKey}');
|
||||
return;
|
||||
}
|
||||
|
||||
// Seed with the resume offset so the first real position update doesn't
|
||||
// look like a seek when resuming mid-item.
|
||||
_currentPosition = metadata.viewOffset != null ? Duration(milliseconds: metadata.viewOffset!) : Duration.zero;
|
||||
|
||||
@@ -7,6 +7,7 @@ import '../../utils/app_logger.dart';
|
||||
import '../../utils/watch_state_notifier.dart';
|
||||
import '../multi_server_manager.dart';
|
||||
import '../settings_service.dart';
|
||||
import '../trackers/tracker_constants.dart';
|
||||
import '../trackers/tracker_id_resolver.dart';
|
||||
import 'trakt_client.dart';
|
||||
import 'trakt_constants.dart';
|
||||
@@ -109,6 +110,13 @@ class TraktSyncService {
|
||||
final kind = TraktMediaKind.tryFromPlexType(event.mediaType);
|
||||
if (kind == null) return;
|
||||
|
||||
final settings = SettingsService.instanceOrNull;
|
||||
if (settings != null &&
|
||||
!settings.isLibraryAllowedForTracker(TrackerService.trakt, event.librarySectionGlobalKey)) {
|
||||
appLogger.d('Trakt sync: library filtered out for ${event.ratingKey}');
|
||||
return;
|
||||
}
|
||||
|
||||
final op = event.changeType == WatchStateChangeType.watched ? TraktSyncOp.add : TraktSyncOp.remove;
|
||||
await _push(
|
||||
op: op,
|
||||
|
||||
@@ -40,6 +40,10 @@ class WatchStateEvent with HierarchicalEventMixin {
|
||||
/// Whether item is now considered watched (>90% progress or marked)
|
||||
final bool? isNowWatched;
|
||||
|
||||
/// Library section this item belongs to — used for per-tracker library
|
||||
/// filtering. Null when emitted without full metadata.
|
||||
final int? librarySectionID;
|
||||
|
||||
WatchStateEvent({
|
||||
required this.ratingKey,
|
||||
required this.serverId,
|
||||
@@ -48,8 +52,14 @@ class WatchStateEvent with HierarchicalEventMixin {
|
||||
required this.mediaType,
|
||||
this.viewOffset,
|
||||
this.isNowWatched,
|
||||
this.librarySectionID,
|
||||
}) : globalKey = buildGlobalKey(serverId, ratingKey);
|
||||
|
||||
/// `serverId:librarySectionID`, matching [PlexLibrary.globalKey]. Null when
|
||||
/// the library section is unknown.
|
||||
String? get librarySectionGlobalKey =>
|
||||
librarySectionID != null ? buildGlobalKey(serverId, librarySectionID!.toString()) : null;
|
||||
|
||||
@override
|
||||
String toString() => 'WatchStateEvent($changeType, $globalKey, parents: $parentChain)';
|
||||
}
|
||||
@@ -88,6 +98,7 @@ class WatchStateNotifier extends BaseNotifier<WatchStateEvent> {
|
||||
parentChain: metadata.parentChain,
|
||||
mediaType: metadata.type ?? '',
|
||||
isNowWatched: isNowWatched,
|
||||
librarySectionID: metadata.librarySectionID,
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -112,6 +123,7 @@ class WatchStateNotifier extends BaseNotifier<WatchStateEvent> {
|
||||
mediaType: metadata.type ?? '',
|
||||
viewOffset: viewOffset,
|
||||
isNowWatched: isNowWatched,
|
||||
librarySectionID: metadata.librarySectionID,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user