From dcd97dda30576ad7cedac4b596000ab02a0c1ff8 Mon Sep 17 00:00:00 2001 From: Micah Morrison Date: Mon, 2 Feb 2026 20:07:06 -0500 Subject: [PATCH] Add option to show/hide unwatched counts --- lib/i18n/de.i18n.json | 2 ++ lib/i18n/en.i18n.json | 2 ++ lib/i18n/es.i18n.json | 2 ++ lib/i18n/fr.i18n.json | 2 ++ lib/i18n/it.i18n.json | 2 ++ lib/i18n/ko.i18n.json | 2 ++ lib/i18n/nl.i18n.json | 2 ++ lib/i18n/strings.g.dart | 4 ++-- lib/i18n/strings_de.g.dart | 8 ++++++-- lib/i18n/strings_en.g.dart | 12 ++++++++++-- lib/i18n/strings_es.g.dart | 8 ++++++-- lib/i18n/strings_fr.g.dart | 8 ++++++-- lib/i18n/strings_it.g.dart | 8 ++++++-- lib/i18n/strings_ko.g.dart | 8 ++++++-- lib/i18n/strings_nl.g.dart | 8 ++++++-- lib/i18n/strings_sv.g.dart | 8 ++++++-- lib/i18n/strings_zh.g.dart | 8 ++++++-- lib/i18n/sv.i18n.json | 2 ++ lib/i18n/zh.i18n.json | 2 ++ lib/providers/settings_provider.dart | 13 +++++++++++++ lib/screens/settings/settings_screen.dart | 15 +++++++++++++++ lib/services/settings_service.dart | 11 +++++++++++ lib/widgets/media_card.dart | 5 ++++- 23 files changed, 121 insertions(+), 21 deletions(-) diff --git a/lib/i18n/de.i18n.json b/lib/i18n/de.i18n.json index 788f53b3..b036b6dd 100644 --- a/lib/i18n/de.i18n.json +++ b/lib/i18n/de.i18n.json @@ -99,6 +99,8 @@ "showServerNameOnHubsDescription": "Zeigt immer den Servernamen in Hub-Titeln an. Wenn deaktiviert, nur bei doppelten Hub-Namen.", "alwaysKeepSidebarOpen": "Seitenleiste immer geöffnet halten", "alwaysKeepSidebarOpenDescription": "Seitenleiste bleibt erweitert und Inhaltsbereich passt sich an", + "showUnwatchedCount": "Anzahl nicht gesehener Folgen anzeigen", + "showUnwatchedCountDescription": "Zeigt die Anzahl nicht gesehener Episoden bei Serien und Staffeln an", "playerBackend": "Player-Backend", "exoPlayer": "ExoPlayer (Empfohlen)", "exoPlayerDescription": "Android-nativer Player mit besserer Hardware-Unterstützung", diff --git a/lib/i18n/en.i18n.json b/lib/i18n/en.i18n.json index c2ac4fac..52da572c 100644 --- a/lib/i18n/en.i18n.json +++ b/lib/i18n/en.i18n.json @@ -98,6 +98,8 @@ "showServerNameOnHubsDescription": "Always display the server name in hub titles. When off, only shows for duplicate hub names.", "alwaysKeepSidebarOpen": "Always Keep Sidebar Open", "alwaysKeepSidebarOpenDescription": "Sidebar stays expanded and content area adjusts to fit", + "showUnwatchedCount": "Show Unwatched Count", + "showUnwatchedCountDescription": "Display unwatched episode count on shows and seasons", "playerBackend": "Player Backend", "exoPlayer": "ExoPlayer (Recommended)", "exoPlayerDescription": "Android native player with better hardware support", diff --git a/lib/i18n/es.i18n.json b/lib/i18n/es.i18n.json index 4be3af53..2ea13e86 100644 --- a/lib/i18n/es.i18n.json +++ b/lib/i18n/es.i18n.json @@ -98,6 +98,8 @@ "showServerNameOnHubsDescription": "Mostrar siempre el nombre del servidor en los títulos de los hubs. Cuando está desactivado, solo se muestra para nombres de hubs duplicados.", "alwaysKeepSidebarOpen": "Mantener siempre la barra lateral abierta", "alwaysKeepSidebarOpenDescription": "La barra lateral permanece expandida y el área de contenido se ajusta para adaptarse", + "showUnwatchedCount": "Mostrar conteo de no vistos", + "showUnwatchedCountDescription": "Mostrar el conteo de episodios no vistos en series y temporadas", "playerBackend": "Reproductor", "exoPlayer": "ExoPlayer (Recomendado)", "exoPlayerDescription": "Reproductor nativo de Android con mejor soporte de hardware", diff --git a/lib/i18n/fr.i18n.json b/lib/i18n/fr.i18n.json index a4c80009..acdf3120 100644 --- a/lib/i18n/fr.i18n.json +++ b/lib/i18n/fr.i18n.json @@ -98,6 +98,8 @@ "showServerNameOnHubsDescription": "Toujours afficher le nom du serveur dans les titres des hubs. Lorsque cette option est désactivée, seuls les noms de hubs en double s'affichent.", "alwaysKeepSidebarOpen": "Toujours garder la barre latérale ouverte", "alwaysKeepSidebarOpenDescription": "La barre latérale reste étendue et la zone de contenu s'adapte", + "showUnwatchedCount": "Afficher le nombre non visionné", + "showUnwatchedCountDescription": "Afficher le nombre d'épisodes non visionnés pour les séries et saisons", "playerBackend": "Moteur de lecture", "exoPlayer": "ExoPlayer (Recommandé)", "exoPlayerDescription": "Lecteur natif Android avec meilleur support matériel", diff --git a/lib/i18n/it.i18n.json b/lib/i18n/it.i18n.json index 21be8373..3fdbc969 100644 --- a/lib/i18n/it.i18n.json +++ b/lib/i18n/it.i18n.json @@ -99,6 +99,8 @@ "showServerNameOnHubsDescription": "Mostra sempre il nome del server nei titoli degli hub. Se disattivato, solo per nomi hub duplicati.", "alwaysKeepSidebarOpen": "Mantieni sempre aperta la barra laterale", "alwaysKeepSidebarOpenDescription": "La barra laterale rimane espansa e l'area del contenuto si adatta", + "showUnwatchedCount": "Mostra conteggio non visti", + "showUnwatchedCountDescription": "Mostra il numero di episodi non visti per serie e stagioni", "playerBackend": "Motore di riproduzione", "exoPlayer": "ExoPlayer (Consigliato)", "exoPlayerDescription": "Lettore nativo Android con migliore supporto hardware", diff --git a/lib/i18n/ko.i18n.json b/lib/i18n/ko.i18n.json index a0e5be3a..0e487096 100644 --- a/lib/i18n/ko.i18n.json +++ b/lib/i18n/ko.i18n.json @@ -99,6 +99,8 @@ "showServerNameOnHubsDescription": "허브 제목에 항상 서버 이름을 표시합니다. 끄면 중복된 허브 이름에만 표시됩니다.", "alwaysKeepSidebarOpen": "사이드바 항상 열어두기", "alwaysKeepSidebarOpenDescription": "사이드바가 확장된 상태로 유지되고 콘텐츠 영역이 맞춰집니다", + "showUnwatchedCount": "미시청 수 표시", + "showUnwatchedCountDescription": "시리즈 및 시즌에 미시청 에피소드 수 표시", "playerBackend": "플레이어 백엔드", "exoPlayer": "ExoPlayer (권장)", "exoPlayerDescription": "더 나은 하드웨어 지원을 제공하는 Android 네이티브 플레이어", diff --git a/lib/i18n/nl.i18n.json b/lib/i18n/nl.i18n.json index 48ed20dd..8055b195 100644 --- a/lib/i18n/nl.i18n.json +++ b/lib/i18n/nl.i18n.json @@ -99,6 +99,8 @@ "showServerNameOnHubsDescription": "Toon altijd de servernaam in hub-titels. Indien uitgeschakeld, alleen bij dubbele hub-namen.", "alwaysKeepSidebarOpen": "Zijbalk altijd open houden", "alwaysKeepSidebarOpenDescription": "Zijbalk blijft uitgevouwen en inhoudsgebied past zich aan", + "showUnwatchedCount": "Aantal ongekeken tonen", + "showUnwatchedCountDescription": "Toon aantal ongekeken afleveringen bij series en seizoenen", "playerBackend": "Speler backend", "exoPlayer": "ExoPlayer (Aanbevolen)", "exoPlayerDescription": "Android-native speler met betere hardware-ondersteuning", diff --git a/lib/i18n/strings.g.dart b/lib/i18n/strings.g.dart index 47a82d93..5adf79ad 100644 --- a/lib/i18n/strings.g.dart +++ b/lib/i18n/strings.g.dart @@ -4,9 +4,9 @@ /// To regenerate, run: `dart run slang` /// /// Locales: 9 -/// Strings: 5151 (572 per locale) +/// Strings: 5169 (574 per locale) /// -/// Built on 2026-02-02 at 21:40 UTC +/// Built on 2026-02-03 at 01:03 UTC // coverage:ignore-file // ignore_for_file: type=lint, unused_import diff --git a/lib/i18n/strings_de.g.dart b/lib/i18n/strings_de.g.dart index 2de1bbbc..88f229c9 100644 --- a/lib/i18n/strings_de.g.dart +++ b/lib/i18n/strings_de.g.dart @@ -213,6 +213,8 @@ class _TranslationsSettingsDe implements TranslationsSettingsEn { @override String get showServerNameOnHubsDescription => 'Zeigt immer den Servernamen in Hub-Titeln an. Wenn deaktiviert, nur bei doppelten Hub-Namen.'; @override String get alwaysKeepSidebarOpen => 'Seitenleiste immer geöffnet halten'; @override String get alwaysKeepSidebarOpenDescription => 'Seitenleiste bleibt erweitert und Inhaltsbereich passt sich an'; + @override String get showUnwatchedCount => 'Anzahl nicht gesehener Folgen anzeigen'; + @override String get showUnwatchedCountDescription => 'Zeigt die Anzahl nicht gesehener Episoden bei Serien und Staffeln an'; @override String get playerBackend => 'Player-Backend'; @override String get exoPlayer => 'ExoPlayer (Empfohlen)'; @override String get exoPlayerDescription => 'Android-nativer Player mit besserer Hardware-Unterstützung'; @@ -1079,6 +1081,8 @@ extension on TranslationsDe { 'settings.showServerNameOnHubsDescription' => 'Zeigt immer den Servernamen in Hub-Titeln an. Wenn deaktiviert, nur bei doppelten Hub-Namen.', 'settings.alwaysKeepSidebarOpen' => 'Seitenleiste immer geöffnet halten', 'settings.alwaysKeepSidebarOpenDescription' => 'Seitenleiste bleibt erweitert und Inhaltsbereich passt sich an', + 'settings.showUnwatchedCount' => 'Anzahl nicht gesehener Folgen anzeigen', + 'settings.showUnwatchedCountDescription' => 'Zeigt die Anzahl nicht gesehener Episoden bei Serien und Staffeln an', 'settings.playerBackend' => 'Player-Backend', 'settings.exoPlayer' => 'ExoPlayer (Empfohlen)', 'settings.exoPlayerDescription' => 'Android-nativer Player mit besserer Hardware-Unterstützung', @@ -1500,10 +1504,10 @@ extension on TranslationsDe { 'collections.deleteFailedWithError' => ({required Object error}) => 'Sammlung konnte nicht gelöscht werden: ${error}', 'collections.failedToLoadItems' => ({required Object error}) => 'Sammlungselemente konnten nicht geladen werden: ${error}', 'collections.selectCollection' => 'Sammlung auswählen', - 'collections.createNewCollection' => 'Neue Sammlung erstellen', - 'collections.collectionName' => 'Sammlungsname', _ => null, } ?? switch (path) { + 'collections.createNewCollection' => 'Neue Sammlung erstellen', + 'collections.collectionName' => 'Sammlungsname', 'collections.enterCollectionName' => 'Sammlungsnamen eingeben', 'collections.addedToCollection' => 'Zur Sammlung hinzugefügt', 'collections.errorAddingToCollection' => 'Fehler beim Hinzufügen zur Sammlung', diff --git a/lib/i18n/strings_en.g.dart b/lib/i18n/strings_en.g.dart index e6126eac..b9e5f771 100644 --- a/lib/i18n/strings_en.g.dart +++ b/lib/i18n/strings_en.g.dart @@ -392,6 +392,12 @@ class TranslationsSettingsEn { /// en: 'Sidebar stays expanded and content area adjusts to fit' String get alwaysKeepSidebarOpenDescription => 'Sidebar stays expanded and content area adjusts to fit'; + /// en: 'Show Unwatched Count' + String get showUnwatchedCount => 'Show Unwatched Count'; + + /// en: 'Display unwatched episode count on shows and seasons' + String get showUnwatchedCountDescription => 'Display unwatched episode count on shows and seasons'; + /// en: 'Player Backend' String get playerBackend => 'Player Backend'; @@ -2224,6 +2230,8 @@ extension on Translations { 'settings.showServerNameOnHubsDescription' => 'Always display the server name in hub titles. When off, only shows for duplicate hub names.', 'settings.alwaysKeepSidebarOpen' => 'Always Keep Sidebar Open', 'settings.alwaysKeepSidebarOpenDescription' => 'Sidebar stays expanded and content area adjusts to fit', + 'settings.showUnwatchedCount' => 'Show Unwatched Count', + 'settings.showUnwatchedCountDescription' => 'Display unwatched episode count on shows and seasons', 'settings.playerBackend' => 'Player Backend', 'settings.exoPlayer' => 'ExoPlayer (Recommended)', 'settings.exoPlayerDescription' => 'Android native player with better hardware support', @@ -2646,10 +2654,10 @@ extension on Translations { 'watchTogether.createSession' => 'Create Session', 'watchTogether.creating' => 'Creating...', 'watchTogether.joinSession' => 'Join Session', - 'watchTogether.joining' => 'Joining...', - 'watchTogether.controlMode' => 'Control Mode', _ => null, } ?? switch (path) { + 'watchTogether.joining' => 'Joining...', + 'watchTogether.controlMode' => 'Control Mode', 'watchTogether.controlModeQuestion' => 'Who can control playback?', 'watchTogether.hostOnly' => 'Host Only', 'watchTogether.anyone' => 'Anyone', diff --git a/lib/i18n/strings_es.g.dart b/lib/i18n/strings_es.g.dart index 164fddd7..905767cb 100644 --- a/lib/i18n/strings_es.g.dart +++ b/lib/i18n/strings_es.g.dart @@ -212,6 +212,8 @@ class _TranslationsSettingsEs implements TranslationsSettingsEn { @override String get showServerNameOnHubsDescription => 'Mostrar siempre el nombre del servidor en los títulos de los hubs. Cuando está desactivado, solo se muestra para nombres de hubs duplicados.'; @override String get alwaysKeepSidebarOpen => 'Mantener siempre la barra lateral abierta'; @override String get alwaysKeepSidebarOpenDescription => 'La barra lateral permanece expandida y el área de contenido se ajusta para adaptarse'; + @override String get showUnwatchedCount => 'Mostrar conteo de no vistos'; + @override String get showUnwatchedCountDescription => 'Mostrar el conteo de episodios no vistos en series y temporadas'; @override String get playerBackend => 'Reproductor'; @override String get exoPlayer => 'ExoPlayer (Recomendado)'; @override String get exoPlayerDescription => 'Reproductor nativo de Android con mejor soporte de hardware'; @@ -1076,6 +1078,8 @@ extension on TranslationsEs { 'settings.showServerNameOnHubsDescription' => 'Mostrar siempre el nombre del servidor en los títulos de los hubs. Cuando está desactivado, solo se muestra para nombres de hubs duplicados.', 'settings.alwaysKeepSidebarOpen' => 'Mantener siempre la barra lateral abierta', 'settings.alwaysKeepSidebarOpenDescription' => 'La barra lateral permanece expandida y el área de contenido se ajusta para adaptarse', + 'settings.showUnwatchedCount' => 'Mostrar conteo de no vistos', + 'settings.showUnwatchedCountDescription' => 'Mostrar el conteo de episodios no vistos en series y temporadas', 'settings.playerBackend' => 'Reproductor', 'settings.exoPlayer' => 'ExoPlayer (Recomendado)', 'settings.exoPlayerDescription' => 'Reproductor nativo de Android con mejor soporte de hardware', @@ -1498,10 +1502,10 @@ extension on TranslationsEs { 'watchTogether.createSession' => 'Crear Sesión', 'watchTogether.creating' => 'Creando...', 'watchTogether.joinSession' => 'Unirse a Sesión', - 'watchTogether.joining' => 'Uniendo...', - 'watchTogether.controlMode' => 'Modo de Control', _ => null, } ?? switch (path) { + 'watchTogether.joining' => 'Uniendo...', + 'watchTogether.controlMode' => 'Modo de Control', 'watchTogether.controlModeQuestion' => '¿Quién puede controlar la reproducción?', 'watchTogether.hostOnly' => 'Solo el Anfitrión', 'watchTogether.anyone' => 'Cualquiera', diff --git a/lib/i18n/strings_fr.g.dart b/lib/i18n/strings_fr.g.dart index 59f7c299..5062e4f3 100644 --- a/lib/i18n/strings_fr.g.dart +++ b/lib/i18n/strings_fr.g.dart @@ -212,6 +212,8 @@ class _TranslationsSettingsFr implements TranslationsSettingsEn { @override String get showServerNameOnHubsDescription => 'Toujours afficher le nom du serveur dans les titres des hubs. Lorsque cette option est désactivée, seuls les noms de hubs en double s\'affichent.'; @override String get alwaysKeepSidebarOpen => 'Toujours garder la barre latérale ouverte'; @override String get alwaysKeepSidebarOpenDescription => 'La barre latérale reste étendue et la zone de contenu s\'adapte'; + @override String get showUnwatchedCount => 'Afficher le nombre non visionné'; + @override String get showUnwatchedCountDescription => 'Afficher le nombre d\'épisodes non visionnés pour les séries et saisons'; @override String get playerBackend => 'Moteur de lecture'; @override String get exoPlayer => 'ExoPlayer (Recommandé)'; @override String get exoPlayerDescription => 'Lecteur natif Android avec meilleur support matériel'; @@ -1076,6 +1078,8 @@ extension on TranslationsFr { 'settings.showServerNameOnHubsDescription' => 'Toujours afficher le nom du serveur dans les titres des hubs. Lorsque cette option est désactivée, seuls les noms de hubs en double s\'affichent.', 'settings.alwaysKeepSidebarOpen' => 'Toujours garder la barre latérale ouverte', 'settings.alwaysKeepSidebarOpenDescription' => 'La barre latérale reste étendue et la zone de contenu s\'adapte', + 'settings.showUnwatchedCount' => 'Afficher le nombre non visionné', + 'settings.showUnwatchedCountDescription' => 'Afficher le nombre d\'épisodes non visionnés pour les séries et saisons', 'settings.playerBackend' => 'Moteur de lecture', 'settings.exoPlayer' => 'ExoPlayer (Recommandé)', 'settings.exoPlayerDescription' => 'Lecteur natif Android avec meilleur support matériel', @@ -1498,10 +1502,10 @@ extension on TranslationsFr { 'watchTogether.createSession' => 'Créer une session', 'watchTogether.creating' => 'Création...', 'watchTogether.joinSession' => 'Rejoindre la session', - 'watchTogether.joining' => 'Rejoindre...', - 'watchTogether.controlMode' => 'Mode de contrôle', _ => null, } ?? switch (path) { + 'watchTogether.joining' => 'Rejoindre...', + 'watchTogether.controlMode' => 'Mode de contrôle', 'watchTogether.controlModeQuestion' => 'Qui peut contrôler la lecture ?', 'watchTogether.hostOnly' => 'Hôte uniquement', 'watchTogether.anyone' => 'N\'importe qui', diff --git a/lib/i18n/strings_it.g.dart b/lib/i18n/strings_it.g.dart index 04123adc..895f47c3 100644 --- a/lib/i18n/strings_it.g.dart +++ b/lib/i18n/strings_it.g.dart @@ -213,6 +213,8 @@ class _TranslationsSettingsIt implements TranslationsSettingsEn { @override String get showServerNameOnHubsDescription => 'Mostra sempre il nome del server nei titoli degli hub. Se disattivato, solo per nomi hub duplicati.'; @override String get alwaysKeepSidebarOpen => 'Mantieni sempre aperta la barra laterale'; @override String get alwaysKeepSidebarOpenDescription => 'La barra laterale rimane espansa e l\'area del contenuto si adatta'; + @override String get showUnwatchedCount => 'Mostra conteggio non visti'; + @override String get showUnwatchedCountDescription => 'Mostra il numero di episodi non visti per serie e stagioni'; @override String get playerBackend => 'Motore di riproduzione'; @override String get exoPlayer => 'ExoPlayer (Consigliato)'; @override String get exoPlayerDescription => 'Lettore nativo Android con migliore supporto hardware'; @@ -1079,6 +1081,8 @@ extension on TranslationsIt { 'settings.showServerNameOnHubsDescription' => 'Mostra sempre il nome del server nei titoli degli hub. Se disattivato, solo per nomi hub duplicati.', 'settings.alwaysKeepSidebarOpen' => 'Mantieni sempre aperta la barra laterale', 'settings.alwaysKeepSidebarOpenDescription' => 'La barra laterale rimane espansa e l\'area del contenuto si adatta', + 'settings.showUnwatchedCount' => 'Mostra conteggio non visti', + 'settings.showUnwatchedCountDescription' => 'Mostra il numero di episodi non visti per serie e stagioni', 'settings.playerBackend' => 'Motore di riproduzione', 'settings.exoPlayer' => 'ExoPlayer (Consigliato)', 'settings.exoPlayerDescription' => 'Lettore nativo Android con migliore supporto hardware', @@ -1500,10 +1504,10 @@ extension on TranslationsIt { 'collections.deleteFailedWithError' => ({required Object error}) => 'Impossibile eliminare la raccolta: ${error}', 'collections.failedToLoadItems' => ({required Object error}) => 'Impossibile caricare gli elementi della raccolta: ${error}', 'collections.selectCollection' => 'Seleziona raccolta', - 'collections.createNewCollection' => 'Crea nuova raccolta', - 'collections.collectionName' => 'Nome raccolta', _ => null, } ?? switch (path) { + 'collections.createNewCollection' => 'Crea nuova raccolta', + 'collections.collectionName' => 'Nome raccolta', 'collections.enterCollectionName' => 'Inserisci nome raccolta', 'collections.addedToCollection' => 'Aggiunto alla raccolta', 'collections.errorAddingToCollection' => 'Errore nell\'aggiunta alla raccolta', diff --git a/lib/i18n/strings_ko.g.dart b/lib/i18n/strings_ko.g.dart index 51f1d14e..de1b1b79 100644 --- a/lib/i18n/strings_ko.g.dart +++ b/lib/i18n/strings_ko.g.dart @@ -213,6 +213,8 @@ class _TranslationsSettingsKo implements TranslationsSettingsEn { @override String get showServerNameOnHubsDescription => '허브 제목에 항상 서버 이름을 표시합니다. 끄면 중복된 허브 이름에만 표시됩니다.'; @override String get alwaysKeepSidebarOpen => '사이드바 항상 열어두기'; @override String get alwaysKeepSidebarOpenDescription => '사이드바가 확장된 상태로 유지되고 콘텐츠 영역이 맞춰집니다'; + @override String get showUnwatchedCount => '미시청 수 표시'; + @override String get showUnwatchedCountDescription => '시리즈 및 시즌에 미시청 에피소드 수 표시'; @override String get playerBackend => '플레이어 백엔드'; @override String get exoPlayer => 'ExoPlayer (권장)'; @override String get exoPlayerDescription => '더 나은 하드웨어 지원을 제공하는 Android 네이티브 플레이어'; @@ -1079,6 +1081,8 @@ extension on TranslationsKo { 'settings.showServerNameOnHubsDescription' => '허브 제목에 항상 서버 이름을 표시합니다. 끄면 중복된 허브 이름에만 표시됩니다.', 'settings.alwaysKeepSidebarOpen' => '사이드바 항상 열어두기', 'settings.alwaysKeepSidebarOpenDescription' => '사이드바가 확장된 상태로 유지되고 콘텐츠 영역이 맞춰집니다', + 'settings.showUnwatchedCount' => '미시청 수 표시', + 'settings.showUnwatchedCountDescription' => '시리즈 및 시즌에 미시청 에피소드 수 표시', 'settings.playerBackend' => '플레이어 백엔드', 'settings.exoPlayer' => 'ExoPlayer (권장)', 'settings.exoPlayerDescription' => '더 나은 하드웨어 지원을 제공하는 Android 네이티브 플레이어', @@ -1500,10 +1504,10 @@ extension on TranslationsKo { 'watchTogether.title' => '함께 보기', 'watchTogether.description' => '친구 및 가족과 콘텐츠를 동시에 시청하세요', 'watchTogether.createSession' => '세션 생성', - 'watchTogether.creating' => '생성 중...', - 'watchTogether.joinSession' => '세션 참여', _ => null, } ?? switch (path) { + 'watchTogether.creating' => '생성 중...', + 'watchTogether.joinSession' => '세션 참여', 'watchTogether.joining' => '참가 중...', 'watchTogether.controlMode' => '제어 모드', 'watchTogether.controlModeQuestion' => '누가 재생을 제어할 수 있나요?', diff --git a/lib/i18n/strings_nl.g.dart b/lib/i18n/strings_nl.g.dart index b1d0658e..33947129 100644 --- a/lib/i18n/strings_nl.g.dart +++ b/lib/i18n/strings_nl.g.dart @@ -213,6 +213,8 @@ class _TranslationsSettingsNl implements TranslationsSettingsEn { @override String get showServerNameOnHubsDescription => 'Toon altijd de servernaam in hub-titels. Indien uitgeschakeld, alleen bij dubbele hub-namen.'; @override String get alwaysKeepSidebarOpen => 'Zijbalk altijd open houden'; @override String get alwaysKeepSidebarOpenDescription => 'Zijbalk blijft uitgevouwen en inhoudsgebied past zich aan'; + @override String get showUnwatchedCount => 'Aantal ongekeken tonen'; + @override String get showUnwatchedCountDescription => 'Toon aantal ongekeken afleveringen bij series en seizoenen'; @override String get playerBackend => 'Speler backend'; @override String get exoPlayer => 'ExoPlayer (Aanbevolen)'; @override String get exoPlayerDescription => 'Android-native speler met betere hardware-ondersteuning'; @@ -1079,6 +1081,8 @@ extension on TranslationsNl { 'settings.showServerNameOnHubsDescription' => 'Toon altijd de servernaam in hub-titels. Indien uitgeschakeld, alleen bij dubbele hub-namen.', 'settings.alwaysKeepSidebarOpen' => 'Zijbalk altijd open houden', 'settings.alwaysKeepSidebarOpenDescription' => 'Zijbalk blijft uitgevouwen en inhoudsgebied past zich aan', + 'settings.showUnwatchedCount' => 'Aantal ongekeken tonen', + 'settings.showUnwatchedCountDescription' => 'Toon aantal ongekeken afleveringen bij series en seizoenen', 'settings.playerBackend' => 'Speler backend', 'settings.exoPlayer' => 'ExoPlayer (Aanbevolen)', 'settings.exoPlayerDescription' => 'Android-native speler met betere hardware-ondersteuning', @@ -1500,10 +1504,10 @@ extension on TranslationsNl { 'collections.deleteFailedWithError' => ({required Object error}) => 'Collectie verwijderen mislukt: ${error}', 'collections.failedToLoadItems' => ({required Object error}) => 'Collectie-items laden mislukt: ${error}', 'collections.selectCollection' => 'Selecteer collectie', - 'collections.createNewCollection' => 'Nieuwe collectie maken', - 'collections.collectionName' => 'Collectienaam', _ => null, } ?? switch (path) { + 'collections.createNewCollection' => 'Nieuwe collectie maken', + 'collections.collectionName' => 'Collectienaam', 'collections.enterCollectionName' => 'Voer collectienaam in', 'collections.addedToCollection' => 'Toegevoegd aan collectie', 'collections.errorAddingToCollection' => 'Fout bij toevoegen aan collectie', diff --git a/lib/i18n/strings_sv.g.dart b/lib/i18n/strings_sv.g.dart index 55b8f3f3..9f420c73 100644 --- a/lib/i18n/strings_sv.g.dart +++ b/lib/i18n/strings_sv.g.dart @@ -213,6 +213,8 @@ class _TranslationsSettingsSv implements TranslationsSettingsEn { @override String get showServerNameOnHubsDescription => 'Visa alltid servernamnet i hubbtitlar. När av visas endast för duplicerade hubbnamn.'; @override String get alwaysKeepSidebarOpen => 'Håll sidofältet alltid öppet'; @override String get alwaysKeepSidebarOpenDescription => 'Sidofältet förblir expanderat och innehållsytan anpassas'; + @override String get showUnwatchedCount => 'Visa antal osedda'; + @override String get showUnwatchedCountDescription => 'Visa antal osedda avsnitt för serier och säsonger'; @override String get playerBackend => 'Spelarmotor'; @override String get exoPlayer => 'ExoPlayer (Rekommenderad)'; @override String get exoPlayerDescription => 'Android-nativ spelare med bättre hårdvarustöd'; @@ -1079,6 +1081,8 @@ extension on TranslationsSv { 'settings.showServerNameOnHubsDescription' => 'Visa alltid servernamnet i hubbtitlar. När av visas endast för duplicerade hubbnamn.', 'settings.alwaysKeepSidebarOpen' => 'Håll sidofältet alltid öppet', 'settings.alwaysKeepSidebarOpenDescription' => 'Sidofältet förblir expanderat och innehållsytan anpassas', + 'settings.showUnwatchedCount' => 'Visa antal osedda', + 'settings.showUnwatchedCountDescription' => 'Visa antal osedda avsnitt för serier och säsonger', 'settings.playerBackend' => 'Spelarmotor', 'settings.exoPlayer' => 'ExoPlayer (Rekommenderad)', 'settings.exoPlayerDescription' => 'Android-nativ spelare med bättre hårdvarustöd', @@ -1500,10 +1504,10 @@ extension on TranslationsSv { 'collections.deleteFailedWithError' => ({required Object error}) => 'Det gick inte att ta bort samlingen: ${error}', 'collections.failedToLoadItems' => ({required Object error}) => 'Det gick inte att läsa in samlingsobjekt: ${error}', 'collections.selectCollection' => 'Välj samling', - 'collections.createNewCollection' => 'Skapa ny samling', - 'collections.collectionName' => 'Samlingsnamn', _ => null, } ?? switch (path) { + 'collections.createNewCollection' => 'Skapa ny samling', + 'collections.collectionName' => 'Samlingsnamn', 'collections.enterCollectionName' => 'Ange samlingsnamn', 'collections.addedToCollection' => 'Tillagd i samling', 'collections.errorAddingToCollection' => 'Fel vid tillägg i samling', diff --git a/lib/i18n/strings_zh.g.dart b/lib/i18n/strings_zh.g.dart index 7d13299d..bf258372 100644 --- a/lib/i18n/strings_zh.g.dart +++ b/lib/i18n/strings_zh.g.dart @@ -213,6 +213,8 @@ class _TranslationsSettingsZh implements TranslationsSettingsEn { @override String get showServerNameOnHubsDescription => '始终在推荐栏标题中显示服务器名称。关闭时仅在推荐栏名称重复时显示。'; @override String get alwaysKeepSidebarOpen => '始终保持侧边栏展开'; @override String get alwaysKeepSidebarOpenDescription => '侧边栏保持展开状态,内容区域自动调整'; + @override String get showUnwatchedCount => '显示未观看数量'; + @override String get showUnwatchedCountDescription => '在剧集和季上显示未观看的集数'; @override String get playerBackend => '播放器引擎'; @override String get exoPlayer => 'ExoPlayer(推荐)'; @override String get exoPlayerDescription => 'Android 原生播放器,硬件支持更好'; @@ -1079,6 +1081,8 @@ extension on TranslationsZh { 'settings.showServerNameOnHubsDescription' => '始终在推荐栏标题中显示服务器名称。关闭时仅在推荐栏名称重复时显示。', 'settings.alwaysKeepSidebarOpen' => '始终保持侧边栏展开', 'settings.alwaysKeepSidebarOpenDescription' => '侧边栏保持展开状态,内容区域自动调整', + 'settings.showUnwatchedCount' => '显示未观看数量', + 'settings.showUnwatchedCountDescription' => '在剧集和季上显示未观看的集数', 'settings.playerBackend' => '播放器引擎', 'settings.exoPlayer' => 'ExoPlayer(推荐)', 'settings.exoPlayerDescription' => 'Android 原生播放器,硬件支持更好', @@ -1500,10 +1504,10 @@ extension on TranslationsZh { 'collections.deleteFailedWithError' => ({required Object error}) => '删除合集失败:${error}', 'collections.failedToLoadItems' => ({required Object error}) => '加载合集项目失败:${error}', 'collections.selectCollection' => '选择合集', - 'collections.createNewCollection' => '创建新合集', - 'collections.collectionName' => '合集名称', _ => null, } ?? switch (path) { + 'collections.createNewCollection' => '创建新合集', + 'collections.collectionName' => '合集名称', 'collections.enterCollectionName' => '输入合集名称', 'collections.addedToCollection' => '已添加到合集', 'collections.errorAddingToCollection' => '添加到合集失败', diff --git a/lib/i18n/sv.i18n.json b/lib/i18n/sv.i18n.json index ceac5b88..69257ae1 100644 --- a/lib/i18n/sv.i18n.json +++ b/lib/i18n/sv.i18n.json @@ -99,6 +99,8 @@ "showServerNameOnHubsDescription": "Visa alltid servernamnet i hubbtitlar. När av visas endast för duplicerade hubbnamn.", "alwaysKeepSidebarOpen": "Håll sidofältet alltid öppet", "alwaysKeepSidebarOpenDescription": "Sidofältet förblir expanderat och innehållsytan anpassas", + "showUnwatchedCount": "Visa antal osedda", + "showUnwatchedCountDescription": "Visa antal osedda avsnitt för serier och säsonger", "playerBackend": "Spelarmotor", "exoPlayer": "ExoPlayer (Rekommenderad)", "exoPlayerDescription": "Android-nativ spelare med bättre hårdvarustöd", diff --git a/lib/i18n/zh.i18n.json b/lib/i18n/zh.i18n.json index fd0ac85f..e1cfcd3b 100644 --- a/lib/i18n/zh.i18n.json +++ b/lib/i18n/zh.i18n.json @@ -99,6 +99,8 @@ "showServerNameOnHubsDescription": "始终在推荐栏标题中显示服务器名称。关闭时仅在推荐栏名称重复时显示。", "alwaysKeepSidebarOpen": "始终保持侧边栏展开", "alwaysKeepSidebarOpenDescription": "侧边栏保持展开状态,内容区域自动调整", + "showUnwatchedCount": "显示未观看数量", + "showUnwatchedCountDescription": "在剧集和季上显示未观看的集数", "playerBackend": "播放器引擎", "exoPlayer": "ExoPlayer(推荐)", "exoPlayerDescription": "Android 原生播放器,硬件支持更好", diff --git a/lib/providers/settings_provider.dart b/lib/providers/settings_provider.dart index 7152df8e..16fb09da 100644 --- a/lib/providers/settings_provider.dart +++ b/lib/providers/settings_provider.dart @@ -11,6 +11,7 @@ class SettingsProvider extends ChangeNotifier { bool _useGlobalHubs = true; bool _showServerNameOnHubs = false; bool _alwaysKeepSidebarOpen = false; + bool _showUnwatchedCount = true; bool _isInitialized = false; Future? _initFuture; @@ -34,6 +35,7 @@ class SettingsProvider extends ChangeNotifier { _useGlobalHubs = _settingsService!.getUseGlobalHubs(); _showServerNameOnHubs = _settingsService!.getShowServerNameOnHubs(); _alwaysKeepSidebarOpen = _settingsService!.getAlwaysKeepSidebarOpen(); + _showUnwatchedCount = _settingsService!.getShowUnwatchedCount(); _isInitialized = true; notifyListeners(); } @@ -55,6 +57,8 @@ class SettingsProvider extends ChangeNotifier { bool get alwaysKeepSidebarOpen => _alwaysKeepSidebarOpen; + bool get showUnwatchedCount => _showUnwatchedCount; + Future setLibraryDensity(LibraryDensity density) async { if (!_isInitialized) await _initializeSettings(); if (_libraryDensity != density) { @@ -118,6 +122,15 @@ class SettingsProvider extends ChangeNotifier { } } + Future setShowUnwatchedCount(bool value) async { + if (!_isInitialized) await _initializeSettings(); + if (_showUnwatchedCount != value) { + _showUnwatchedCount = value; + await _settingsService!.setShowUnwatchedCount(value); + notifyListeners(); + } + } + String get libraryDensityDisplayName { switch (_libraryDensity) { case LibraryDensity.compact: diff --git a/lib/screens/settings/settings_screen.dart b/lib/screens/settings/settings_screen.dart index 030b5b8f..be812d7c 100644 --- a/lib/screens/settings/settings_screen.dart +++ b/lib/screens/settings/settings_screen.dart @@ -61,6 +61,7 @@ class _SettingsScreenState extends State with FocusableTab { static const _kUseGlobalHubs = 'use_global_hubs'; static const _kShowServerNameOnHubs = 'show_server_name_on_hubs'; static const _kAlwaysKeepSidebarOpen = 'always_keep_sidebar_open'; + static const _kShowUnwatchedCount = 'show_unwatched_count'; static const _kPlayerBackend = 'player_backend'; static const _kHardwareDecoding = 'hardware_decoding'; static const _kMatchContentFrameRate = 'match_content_frame_rate'; @@ -342,6 +343,20 @@ class _SettingsScreenState extends State with FocusableTab { ); }, ), + Consumer( + builder: (context, settingsProvider, child) { + return SwitchListTile( + focusNode: _focusTracker.get(_kShowUnwatchedCount), + secondary: const AppIcon(Symbols.counter_1_rounded, fill: 1), + title: Text(t.settings.showUnwatchedCount), + subtitle: Text(t.settings.showUnwatchedCountDescription), + value: settingsProvider.showUnwatchedCount, + onChanged: (value) async { + await settingsProvider.setShowUnwatchedCount(value); + }, + ); + }, + ), ], ), ); diff --git a/lib/services/settings_service.dart b/lib/services/settings_service.dart index 1bf1ad8d..82ac07d0 100644 --- a/lib/services/settings_service.dart +++ b/lib/services/settings_service.dart @@ -66,6 +66,7 @@ class SettingsService extends BaseSharedPreferencesService { static const String _keyAutoPlayNextEpisode = 'auto_play_next_episode'; static const String _keyUseExoPlayer = 'use_exoplayer'; static const String _keyAlwaysKeepSidebarOpen = 'always_keep_sidebar_open'; + static const String _keyShowUnwatchedCount = 'show_unwatched_count'; static const String _keyGlobalShaderPreset = 'global_shader_preset'; SettingsService._(); @@ -1008,6 +1009,15 @@ class SettingsService extends BaseSharedPreferencesService { return prefs.getBool(_keyAlwaysKeepSidebarOpen) ?? false; // Default: collapsed } + // Show Unwatched Count (show unwatched episode count on shows/seasons) + Future setShowUnwatchedCount(bool enabled) async { + await prefs.setBool(_keyShowUnwatchedCount, enabled); + } + + bool getShowUnwatchedCount() { + return prefs.getBool(_keyShowUnwatchedCount) ?? true; // Default: enabled (show counts) + } + // Global Shader Preset (for MPV video enhancement) Future setGlobalShaderPreset(String presetId) async { await prefs.setString(_keyGlobalShaderPreset, presetId); @@ -1063,6 +1073,7 @@ class SettingsService extends BaseSharedPreferencesService { prefs.remove(_keyAutoPlayNextEpisode), prefs.remove(_keyUseExoPlayer), prefs.remove(_keyAlwaysKeepSidebarOpen), + prefs.remove(_keyShowUnwatchedCount), prefs.remove(_keyGlobalShaderPreset), ]); } diff --git a/lib/widgets/media_card.dart b/lib/widgets/media_card.dart index cb58698a..5a88da2f 100644 --- a/lib/widgets/media_card.dart +++ b/lib/widgets/media_card.dart @@ -714,6 +714,8 @@ class _MediaCardHelpers { /// Builds watch progress overlay (checkmark for watched, progress bar for in-progress) static Widget buildWatchProgress(BuildContext context, PlexMetadata metadata) { + final showUnwatchedCount = context.watch().showUnwatchedCount; + return Stack( children: [ // Watched indicator (checkmark) @@ -731,7 +733,8 @@ class _MediaCardHelpers { child: AppIcon(Symbols.check_rounded, fill: 1, color: tokens(context).bg, size: 16), ), ), - if (!metadata.isWatched && + if (showUnwatchedCount && + !metadata.isWatched && (metadata.mediaType == PlexMediaType.show || metadata.mediaType == PlexMediaType.season) && (metadata.leafCount != null && metadata.leafCount! > 0 && metadata.viewedLeafCount != null)) Positioned(