From 5f18efcfb3daf3c0a3b92e754a47f74b6ce6a3cf Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Sun, 15 Mar 2026 07:41:41 +0100 Subject: [PATCH] feat: live TV channel favorites close #663 --- lib/focus/focusable_action_bar.dart | 6 +- lib/i18n/da.i18n.json | 10 ++- lib/i18n/de.i18n.json | 10 ++- lib/i18n/en.i18n.json | 10 ++- lib/i18n/es.i18n.json | 10 ++- lib/i18n/fr.i18n.json | 10 ++- lib/i18n/it.i18n.json | 10 ++- lib/i18n/ja.i18n.json | 10 ++- lib/i18n/ko.i18n.json | 10 ++- lib/i18n/nb.i18n.json | 10 ++- lib/i18n/nl.i18n.json | 10 ++- lib/i18n/pl.i18n.json | 10 ++- lib/i18n/pt.i18n.json | 10 ++- lib/i18n/ru.i18n.json | 10 ++- lib/i18n/strings.g.dart | 4 +- lib/i18n/strings_da.g.dart | 16 +++- lib/i18n/strings_de.g.dart | 16 +++- lib/i18n/strings_en.g.dart | 28 ++++++- lib/i18n/strings_es.g.dart | 16 +++- lib/i18n/strings_fr.g.dart | 16 +++- lib/i18n/strings_it.g.dart | 16 +++- lib/i18n/strings_ja.g.dart | 16 +++- lib/i18n/strings_ko.g.dart | 16 +++- lib/i18n/strings_nb.g.dart | 16 +++- lib/i18n/strings_nl.g.dart | 16 +++- lib/i18n/strings_pl.g.dart | 16 +++- lib/i18n/strings_pt.g.dart | 16 +++- lib/i18n/strings_ru.g.dart | 16 +++- lib/i18n/strings_sv.g.dart | 16 +++- lib/i18n/strings_zh.g.dart | 16 +++- lib/i18n/sv.i18n.json | 10 ++- lib/i18n/zh.i18n.json | 10 ++- lib/models/livetv_channel.dart | 47 ++++++++++++ lib/providers/settings_provider.dart | 10 +++ lib/screens/livetv/live_tv_screen.dart | 91 ++++++++++++++++++++++- lib/screens/livetv/tabs/guide_tab.dart | 46 ++++++++++-- lib/screens/settings/settings_screen.dart | 15 ++++ lib/services/plex_client.dart | 44 +++++++++++ lib/services/settings_service.dart | 9 +++ 39 files changed, 603 insertions(+), 71 deletions(-) diff --git a/lib/focus/focusable_action_bar.dart b/lib/focus/focusable_action_bar.dart index 89f9c551..4bf63ab4 100644 --- a/lib/focus/focusable_action_bar.dart +++ b/lib/focus/focusable_action_bar.dart @@ -13,6 +13,9 @@ class FocusableAction { /// Icon color. Ignored when [child] is provided. final Color? iconColor; + /// Icon fill weight (0.0–1.0). Defaults to 1.0. Ignored when [child] is provided. + final double iconFill; + final String? tooltip; final VoidCallback? onPressed; @@ -23,6 +26,7 @@ class FocusableAction { const FocusableAction({ this.icon = Icons.circle, this.iconColor, + this.iconFill = 1.0, this.tooltip, this.onPressed, this.child, @@ -173,7 +177,7 @@ class FocusableActionBarState extends State { decoration: FocusTheme.focusBackgroundDecoration(isFocused: showFocus, borderRadius: 20), child: action.child ?? IconButton( - icon: AppIcon(action.icon, fill: 1, color: action.iconColor), + icon: AppIcon(action.icon, fill: action.iconFill, color: action.iconColor), tooltip: action.tooltip, onPressed: action.onPressed, ), diff --git a/lib/i18n/da.i18n.json b/lib/i18n/da.i18n.json index ddff2551..a031b152 100644 --- a/lib/i18n/da.i18n.json +++ b/lib/i18n/da.i18n.json @@ -128,7 +128,9 @@ "confirmExitOnBack": "Bekræft før lukning", "confirmExitOnBackDescription": "Vis bekræftelsesdialog ved tryk på tilbage for at lukke appen", "showNavBarLabels": "Vis navigationsbarlabels", - "showNavBarLabelsDescription": "Vis tekstlabels under navigationsbarikoner" + "showNavBarLabelsDescription": "Vis tekstlabels under navigationsbarikoner", + "liveTvDefaultFavorites": "Standard til favoritkanaler", + "liveTvDefaultFavoritesDescription": "Vis kun favoritkanaler ved åbning af Live TV" }, "search": { "hint": "Søg film, serier, musik...", "tryDifferentTerm": "Prøv en anden søgning", @@ -323,7 +325,11 @@ "channelNumber": "Kn. ${number}", "live": "LIVE", "hd": "HD", "premiere": "NY", "reloadGuide": "Genindlæs guide", "allChannels": "Alle kanaler", "now": "Nu", "today": "I dag", "midnight": "Midnat", "overnight": "Nat", "morning": "Morgen", "daytime": "Dagtid", - "evening": "Aften", "lateNight": "Sen aften", "whatsOn": "Hvad der kører", "watchChannel": "Se kanal" + "evening": "Aften", "lateNight": "Sen aften", "whatsOn": "Hvad der kører", "watchChannel": "Se kanal", + "favorites": "Favoritter", + "addToFavorites": "Føj til favoritter", + "removeFromFavorites": "Fjern fra favoritter", + "noFavorites": "Ingen favoritkanaler. Tryk længe på en kanal for at tilføje den." }, "collections": { "title": "Samlinger", "collection": "Samling", "empty": "Samlingen er tom", diff --git a/lib/i18n/de.i18n.json b/lib/i18n/de.i18n.json index 60dd3908..3b125528 100644 --- a/lib/i18n/de.i18n.json +++ b/lib/i18n/de.i18n.json @@ -213,7 +213,9 @@ "confirmExitOnBack": "Vor dem Beenden bestätigen", "confirmExitOnBackDescription": "Bestätigungsdialog anzeigen, wenn Zurück zum Beenden der App gedrückt wird", "showNavBarLabels": "Navigationsleisten-Beschriftungen anzeigen", - "showNavBarLabelsDescription": "Textbeschriftungen unter den Symbolen der Navigationsleiste anzeigen" + "showNavBarLabelsDescription": "Textbeschriftungen unter den Symbolen der Navigationsleiste anzeigen", + "liveTvDefaultFavorites": "Standardmäßig Favoritenkanäle", + "liveTvDefaultFavoritesDescription": "Beim Öffnen von Live TV nur Favoritenkanäle anzeigen" }, "search": { "hint": "Filme, Serien, Musik suchen...", @@ -590,7 +592,11 @@ "evening": "Abend", "lateNight": "Spätnacht", "whatsOn": "Jetzt im TV", - "watchChannel": "Kanal ansehen" + "watchChannel": "Kanal ansehen", + "favorites": "Favoriten", + "addToFavorites": "Zu Favoriten hinzufügen", + "removeFromFavorites": "Aus Favoriten entfernen", + "noFavorites": "Keine Favoritenkanäle. Kanal lange drücken, um ihn hinzuzufügen." }, "downloads": { "title": "Downloads", diff --git a/lib/i18n/en.i18n.json b/lib/i18n/en.i18n.json index c31ffbaf..433a12fd 100644 --- a/lib/i18n/en.i18n.json +++ b/lib/i18n/en.i18n.json @@ -213,7 +213,9 @@ "confirmExitOnBack": "Confirm before exiting", "confirmExitOnBackDescription": "Show a confirmation dialog when pressing back to exit the app", "showNavBarLabels": "Show Navigation Bar Labels", - "showNavBarLabelsDescription": "Display text labels under navigation bar icons" + "showNavBarLabelsDescription": "Display text labels under navigation bar icons", + "liveTvDefaultFavorites": "Default to Favorite Channels", + "liveTvDefaultFavoritesDescription": "Show only favorite channels when opening Live TV" }, "search": { "hint": "Search movies, shows, music...", @@ -590,7 +592,11 @@ "evening": "Evening", "lateNight": "Late Night", "whatsOn": "What's On", - "watchChannel": "Watch Channel" + "watchChannel": "Watch Channel", + "favorites": "Favorites", + "addToFavorites": "Add to Favorites", + "removeFromFavorites": "Remove from Favorites", + "noFavorites": "No favorite channels. Long-press a channel to add it." }, "collections": { "title": "Collections", diff --git a/lib/i18n/es.i18n.json b/lib/i18n/es.i18n.json index b3dfe151..1b39f726 100644 --- a/lib/i18n/es.i18n.json +++ b/lib/i18n/es.i18n.json @@ -213,7 +213,9 @@ "confirmExitOnBack": "Confirmar antes de salir", "confirmExitOnBackDescription": "Mostrar un diálogo de confirmación al presionar atrás para salir de la app", "showNavBarLabels": "Mostrar etiquetas de la barra de navegación", - "showNavBarLabelsDescription": "Mostrar etiquetas de texto bajo los iconos de la barra de navegación" + "showNavBarLabelsDescription": "Mostrar etiquetas de texto bajo los iconos de la barra de navegación", + "liveTvDefaultFavorites": "Canales favoritos por defecto", + "liveTvDefaultFavoritesDescription": "Mostrar solo canales favoritos al abrir TV en vivo" }, "search": { "hint": "Buscar películas, series, música...", @@ -590,7 +592,11 @@ "evening": "Noche", "lateNight": "Trasnoche", "whatsOn": "En emisión", - "watchChannel": "Ver canal" + "watchChannel": "Ver canal", + "favorites": "Favoritos", + "addToFavorites": "Añadir a favoritos", + "removeFromFavorites": "Eliminar de favoritos", + "noFavorites": "No hay canales favoritos. Mantén pulsado un canal para añadirlo." }, "collections": { "title": "Colecciones", diff --git a/lib/i18n/fr.i18n.json b/lib/i18n/fr.i18n.json index f0d438cd..d07b5ab2 100644 --- a/lib/i18n/fr.i18n.json +++ b/lib/i18n/fr.i18n.json @@ -213,7 +213,9 @@ "confirmExitOnBack": "Confirmer avant de quitter", "confirmExitOnBackDescription": "Afficher une boîte de dialogue de confirmation en appuyant sur retour pour quitter", "showNavBarLabels": "Afficher les libellés de la barre de navigation", - "showNavBarLabelsDescription": "Afficher les libellés sous les icônes de la barre de navigation" + "showNavBarLabelsDescription": "Afficher les libellés sous les icônes de la barre de navigation", + "liveTvDefaultFavorites": "Chaînes favorites par défaut", + "liveTvDefaultFavoritesDescription": "Afficher uniquement les chaînes favorites à l'ouverture de la TV en direct" }, "search": { "hint": "Rechercher des films, des séries, de la musique...", @@ -590,7 +592,11 @@ "evening": "Soirée", "lateNight": "Nuit tardive", "whatsOn": "En ce moment", - "watchChannel": "Regarder la chaîne" + "watchChannel": "Regarder la chaîne", + "favorites": "Favoris", + "addToFavorites": "Ajouter aux favoris", + "removeFromFavorites": "Retirer des favoris", + "noFavorites": "Aucune chaîne favorite. Appuyez longuement sur une chaîne pour l'ajouter." }, "collections": { "title": "Collections", diff --git a/lib/i18n/it.i18n.json b/lib/i18n/it.i18n.json index 36991ad8..d703c87c 100644 --- a/lib/i18n/it.i18n.json +++ b/lib/i18n/it.i18n.json @@ -213,7 +213,9 @@ "confirmExitOnBack": "Conferma prima di uscire", "confirmExitOnBackDescription": "Mostra una finestra di conferma quando si preme indietro per uscire dall'app", "showNavBarLabels": "Mostra etichette barra di navigazione", - "showNavBarLabelsDescription": "Mostra le etichette sotto le icone della barra di navigazione" + "showNavBarLabelsDescription": "Mostra le etichette sotto le icone della barra di navigazione", + "liveTvDefaultFavorites": "Canali preferiti predefiniti", + "liveTvDefaultFavoritesDescription": "Mostra solo i canali preferiti all'apertura della TV dal vivo" }, "search": { "hint": "Cerca film. spettacoli, musica...", @@ -590,7 +592,11 @@ "evening": "Sera", "lateNight": "Notte tarda", "whatsOn": "In onda ora", - "watchChannel": "Guarda canale" + "watchChannel": "Guarda canale", + "favorites": "Preferiti", + "addToFavorites": "Aggiungi ai preferiti", + "removeFromFavorites": "Rimuovi dai preferiti", + "noFavorites": "Nessun canale preferito. Tieni premuto un canale per aggiungerlo." }, "downloads": { "title": "Download", diff --git a/lib/i18n/ja.i18n.json b/lib/i18n/ja.i18n.json index 4cd2b147..8360a963 100644 --- a/lib/i18n/ja.i18n.json +++ b/lib/i18n/ja.i18n.json @@ -213,7 +213,9 @@ "confirmExitOnBack": "終了前に確認", "confirmExitOnBackDescription": "戻るボタンでアプリを終了する際に確認ダイアログを表示", "showNavBarLabels": "ナビゲーションバーラベルを表示", - "showNavBarLabelsDescription": "ナビゲーションバーアイコンの下にテキストラベルを表示" + "showNavBarLabelsDescription": "ナビゲーションバーアイコンの下にテキストラベルを表示", + "liveTvDefaultFavorites": "お気に入りチャンネルをデフォルトに", + "liveTvDefaultFavoritesDescription": "ライブTV を開いたときにお気に入りチャンネルのみ表示" }, "search": { "hint": "映画、番組、音楽を検索...", @@ -590,7 +592,11 @@ "evening": "夕方", "lateNight": "深夜", "whatsOn": "放送中", - "watchChannel": "チャンネルを視聴" + "watchChannel": "チャンネルを視聴", + "favorites": "お気に入り", + "addToFavorites": "お気に入りに追加", + "removeFromFavorites": "お気に入りから削除", + "noFavorites": "お気に入りチャンネルがありません。チャンネルを長押しして追加してください。" }, "collections": { "title": "コレクション", diff --git a/lib/i18n/ko.i18n.json b/lib/i18n/ko.i18n.json index 79e4e684..c425e167 100644 --- a/lib/i18n/ko.i18n.json +++ b/lib/i18n/ko.i18n.json @@ -213,7 +213,9 @@ "confirmExitOnBack": "종료 전 확인", "confirmExitOnBackDescription": "뒤로 버튼을 눌러 앱을 종료할 때 확인 대화상자를 표시합니다", "showNavBarLabels": "내비게이션 바 라벨 표시", - "showNavBarLabelsDescription": "내비게이션 바 아이콘 아래에 텍스트 라벨을 표시합니다" + "showNavBarLabelsDescription": "내비게이션 바 아이콘 아래에 텍스트 라벨을 표시합니다", + "liveTvDefaultFavorites": "즐겨찾기 채널 기본 설정", + "liveTvDefaultFavoritesDescription": "라이브 TV를 열 때 즐겨찾기 채널만 표시" }, "search": { "hint": "영화, 시리즈, 음악 등을 검색하세요...", @@ -590,7 +592,11 @@ "evening": "저녁", "lateNight": "심야 방송", "whatsOn": "지금 방송 중", - "watchChannel": "채널 시청" + "watchChannel": "채널 시청", + "favorites": "즐겨찾기", + "addToFavorites": "즐겨찾기에 추가", + "removeFromFavorites": "즐겨찾기에서 제거", + "noFavorites": "즐겨찾기 채널이 없습니다. 채널을 길게 눌러 추가하세요." }, "collections": { "title": "컬렉션", diff --git a/lib/i18n/nb.i18n.json b/lib/i18n/nb.i18n.json index 79e22553..76f9bfc6 100644 --- a/lib/i18n/nb.i18n.json +++ b/lib/i18n/nb.i18n.json @@ -213,7 +213,9 @@ "confirmExitOnBack": "Bekreft før avslutning", "confirmExitOnBackDescription": "Vis en bekreftelsesdialog når du trykker tilbake for å avslutte appen", "showNavBarLabels": "Vis navigasjonsfeltlabeler", - "showNavBarLabelsDescription": "Vis tekstlabeler under navigasjonsfeltikoner" + "showNavBarLabelsDescription": "Vis tekstlabeler under navigasjonsfeltikoner", + "liveTvDefaultFavorites": "Standard til favorittkanaler", + "liveTvDefaultFavoritesDescription": "Vis kun favorittkanaler når du åpner Live TV" }, "search": { "hint": "Søk i filmer, serier, musikk...", @@ -590,7 +592,11 @@ "evening": "Kveld", "lateNight": "Sen kveld", "whatsOn": "Hva går nå", - "watchChannel": "Se kanal" + "watchChannel": "Se kanal", + "favorites": "Favoritter", + "addToFavorites": "Legg til i favoritter", + "removeFromFavorites": "Fjern fra favoritter", + "noFavorites": "Ingen favorittkanaler. Trykk lenge på en kanal for å legge den til." }, "collections": { "title": "Samlinger", diff --git a/lib/i18n/nl.i18n.json b/lib/i18n/nl.i18n.json index 79461978..7b7f0e8d 100644 --- a/lib/i18n/nl.i18n.json +++ b/lib/i18n/nl.i18n.json @@ -213,7 +213,9 @@ "confirmExitOnBack": "Bevestigen voor afsluiten", "confirmExitOnBackDescription": "Toon een bevestigingsvenster bij het drukken op terug om de app af te sluiten", "showNavBarLabels": "Navigatiebalk labels tonen", - "showNavBarLabelsDescription": "Tekstlabels onder de pictogrammen van de navigatiebalk weergeven" + "showNavBarLabelsDescription": "Tekstlabels onder de pictogrammen van de navigatiebalk weergeven", + "liveTvDefaultFavorites": "Standaard favoriete zenders", + "liveTvDefaultFavoritesDescription": "Toon alleen favoriete zenders bij het openen van Live TV" }, "search": { "hint": "Zoek films, series, muziek...", @@ -590,7 +592,11 @@ "evening": "Avond", "lateNight": "Late avond", "whatsOn": "Nu op TV", - "watchChannel": "Kanaal bekijken" + "watchChannel": "Kanaal bekijken", + "favorites": "Favorieten", + "addToFavorites": "Toevoegen aan favorieten", + "removeFromFavorites": "Verwijderen uit favorieten", + "noFavorites": "Geen favoriete zenders. Houd een zender ingedrukt om toe te voegen." }, "downloads": { "title": "Downloads", diff --git a/lib/i18n/pl.i18n.json b/lib/i18n/pl.i18n.json index d99b2c6f..dac5a0b9 100644 --- a/lib/i18n/pl.i18n.json +++ b/lib/i18n/pl.i18n.json @@ -213,7 +213,9 @@ "confirmExitOnBack": "Potwierdź przed wyjściem", "confirmExitOnBackDescription": "Pokaż dialog potwierdzenia przy naciśnięciu wstecz, aby wyjść z aplikacji", "showNavBarLabels": "Pokaż etykiety paska nawigacji", - "showNavBarLabelsDescription": "Wyświetl tekstowe etykiety pod ikonami paska nawigacji" + "showNavBarLabelsDescription": "Wyświetl tekstowe etykiety pod ikonami paska nawigacji", + "liveTvDefaultFavorites": "Domyślnie ulubione kanały", + "liveTvDefaultFavoritesDescription": "Pokaż tylko ulubione kanały po otwarciu telewizji na żywo" }, "search": { "hint": "Szukaj filmów, seriali, muzyki...", @@ -590,7 +592,11 @@ "evening": "Wieczorem", "lateNight": "Późna noc", "whatsOn": "Co leci", - "watchChannel": "Oglądaj kanał" + "watchChannel": "Oglądaj kanał", + "favorites": "Ulubione", + "addToFavorites": "Dodaj do ulubionych", + "removeFromFavorites": "Usuń z ulubionych", + "noFavorites": "Brak ulubionych kanałów. Przytrzymaj kanał, aby go dodać." }, "collections": { "title": "Kolekcje", diff --git a/lib/i18n/pt.i18n.json b/lib/i18n/pt.i18n.json index 36d55730..a5127330 100644 --- a/lib/i18n/pt.i18n.json +++ b/lib/i18n/pt.i18n.json @@ -213,7 +213,9 @@ "confirmExitOnBack": "Confirmar antes de sair", "confirmExitOnBackDescription": "Mostrar diálogo de confirmação ao pressionar voltar para sair do app", "showNavBarLabels": "Mostrar Rótulos da Barra de Navegação", - "showNavBarLabelsDescription": "Exibir rótulos de texto sob os ícones da barra de navegação" + "showNavBarLabelsDescription": "Exibir rótulos de texto sob os ícones da barra de navegação", + "liveTvDefaultFavorites": "Canais favoritos por padrão", + "liveTvDefaultFavoritesDescription": "Mostrar apenas canais favoritos ao abrir TV ao vivo" }, "search": { "hint": "Buscar filmes, séries, músicas...", @@ -590,7 +592,11 @@ "evening": "Noite", "lateNight": "Madrugada", "whatsOn": "O que Está Passando", - "watchChannel": "Assistir Canal" + "watchChannel": "Assistir Canal", + "favorites": "Favoritos", + "addToFavorites": "Adicionar aos favoritos", + "removeFromFavorites": "Remover dos favoritos", + "noFavorites": "Nenhum canal favorito. Pressione e segure um canal para adicioná-lo." }, "collections": { "title": "Coleções", diff --git a/lib/i18n/ru.i18n.json b/lib/i18n/ru.i18n.json index 67310895..e8f66ac9 100644 --- a/lib/i18n/ru.i18n.json +++ b/lib/i18n/ru.i18n.json @@ -213,7 +213,9 @@ "confirmExitOnBack": "Подтверждать выход", "confirmExitOnBackDescription": "Показывать диалог подтверждения при нажатии «назад» для выхода из приложения", "showNavBarLabels": "Показывать подписи панели навигации", - "showNavBarLabelsDescription": "Отображать текстовые подписи под иконками панели навигации" + "showNavBarLabelsDescription": "Отображать текстовые подписи под иконками панели навигации", + "liveTvDefaultFavorites": "Избранные каналы по умолчанию", + "liveTvDefaultFavoritesDescription": "Показывать только избранные каналы при открытии ТВ" }, "search": { "hint": "Поиск фильмов, сериалов, музыки...", @@ -590,7 +592,11 @@ "evening": "Вечер", "lateNight": "Поздний вечер", "whatsOn": "Что идёт", - "watchChannel": "Смотреть канал" + "watchChannel": "Смотреть канал", + "favorites": "Избранное", + "addToFavorites": "Добавить в избранное", + "removeFromFavorites": "Удалить из избранного", + "noFavorites": "Нет избранных каналов. Удерживайте канал, чтобы добавить его." }, "collections": { "title": "Коллекции", diff --git a/lib/i18n/strings.g.dart b/lib/i18n/strings.g.dart index 82d4e1ee..40283d7c 100644 --- a/lib/i18n/strings.g.dart +++ b/lib/i18n/strings.g.dart @@ -4,9 +4,9 @@ /// To regenerate, run: `dart run slang` /// /// Locales: 15 -/// Strings: 12195 (813 per locale) +/// Strings: 12285 (819 per locale) /// -/// Built on 2026-03-13 at 05:11 UTC +/// Built on 2026-03-15 at 06:44 UTC // coverage:ignore-file // ignore_for_file: type=lint, unused_import diff --git a/lib/i18n/strings_da.g.dart b/lib/i18n/strings_da.g.dart index e8bc1955..226b99c1 100644 --- a/lib/i18n/strings_da.g.dart +++ b/lib/i18n/strings_da.g.dart @@ -333,6 +333,8 @@ class _TranslationsSettingsDa implements TranslationsSettingsEn { @override String get confirmExitOnBackDescription => 'Vis bekræftelsesdialog ved tryk på tilbage for at lukke appen'; @override String get showNavBarLabels => 'Vis navigationsbarlabels'; @override String get showNavBarLabelsDescription => 'Vis tekstlabels under navigationsbarikoner'; + @override String get liveTvDefaultFavorites => 'Standard til favoritkanaler'; + @override String get liveTvDefaultFavoritesDescription => 'Vis kun favoritkanaler ved åbning af Live TV'; } // Path: search @@ -830,6 +832,10 @@ class _TranslationsLiveTvDa implements TranslationsLiveTvEn { @override String get lateNight => 'Sen aften'; @override String get whatsOn => 'Hvad der kører'; @override String get watchChannel => 'Se kanal'; + @override String get favorites => 'Favoritter'; + @override String get addToFavorites => 'Føj til favoritter'; + @override String get removeFromFavorites => 'Fjern fra favoritter'; + @override String get noFavorites => 'Ingen favoritkanaler. Tryk længe på en kanal for at tilføje den.'; } // Path: collections @@ -1514,6 +1520,8 @@ extension on TranslationsDa { 'settings.confirmExitOnBackDescription' => 'Vis bekræftelsesdialog ved tryk på tilbage for at lukke appen', 'settings.showNavBarLabels' => 'Vis navigationsbarlabels', 'settings.showNavBarLabelsDescription' => 'Vis tekstlabels under navigationsbarikoner', + 'settings.liveTvDefaultFavorites' => 'Standard til favoritkanaler', + 'settings.liveTvDefaultFavoritesDescription' => 'Vis kun favoritkanaler ved åbning af Live TV', 'search.hint' => 'Søg film, serier, musik...', 'search.tryDifferentTerm' => 'Prøv en anden søgning', 'search.searchYourMedia' => 'Søg i dine medier', @@ -1820,10 +1828,10 @@ extension on TranslationsDa { 'liveTv.tuneFailed' => 'Kunne ikke tune kanal', 'liveTv.loading' => 'Indlæser kanaler...', 'liveTv.nowPlaying' => 'Afspiller nu', - 'liveTv.noPrograms' => 'Ingen programdata tilgængelig', - 'liveTv.channelNumber' => ({required Object number}) => 'Kn. ${number}', _ => null, } ?? switch (path) { + 'liveTv.noPrograms' => 'Ingen programdata tilgængelig', + 'liveTv.channelNumber' => ({required Object number}) => 'Kn. ${number}', 'liveTv.live' => 'LIVE', 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'NY', @@ -1839,6 +1847,10 @@ extension on TranslationsDa { 'liveTv.lateNight' => 'Sen aften', 'liveTv.whatsOn' => 'Hvad der kører', 'liveTv.watchChannel' => 'Se kanal', + 'liveTv.favorites' => 'Favoritter', + 'liveTv.addToFavorites' => 'Føj til favoritter', + 'liveTv.removeFromFavorites' => 'Fjern fra favoritter', + 'liveTv.noFavorites' => 'Ingen favoritkanaler. Tryk længe på en kanal for at tilføje den.', 'collections.title' => 'Samlinger', 'collections.collection' => 'Samling', 'collections.empty' => 'Samlingen er tom', diff --git a/lib/i18n/strings_de.g.dart b/lib/i18n/strings_de.g.dart index 349cd4c0..fc47a53a 100644 --- a/lib/i18n/strings_de.g.dart +++ b/lib/i18n/strings_de.g.dart @@ -333,6 +333,8 @@ class _TranslationsSettingsDe implements TranslationsSettingsEn { @override String get confirmExitOnBackDescription => 'Bestätigungsdialog anzeigen, wenn Zurück zum Beenden der App gedrückt wird'; @override String get showNavBarLabels => 'Navigationsleisten-Beschriftungen anzeigen'; @override String get showNavBarLabelsDescription => 'Textbeschriftungen unter den Symbolen der Navigationsleiste anzeigen'; + @override String get liveTvDefaultFavorites => 'Standardmäßig Favoritenkanäle'; + @override String get liveTvDefaultFavoritesDescription => 'Beim Öffnen von Live TV nur Favoritenkanäle anzeigen'; } // Path: search @@ -830,6 +832,10 @@ class _TranslationsLiveTvDe implements TranslationsLiveTvEn { @override String get lateNight => 'Spätnacht'; @override String get whatsOn => 'Jetzt im TV'; @override String get watchChannel => 'Kanal ansehen'; + @override String get favorites => 'Favoriten'; + @override String get addToFavorites => 'Zu Favoriten hinzufügen'; + @override String get removeFromFavorites => 'Aus Favoriten entfernen'; + @override String get noFavorites => 'Keine Favoritenkanäle. Kanal lange drücken, um ihn hinzuzufügen.'; } // Path: downloads @@ -1514,6 +1520,8 @@ extension on TranslationsDe { 'settings.confirmExitOnBackDescription' => 'Bestätigungsdialog anzeigen, wenn Zurück zum Beenden der App gedrückt wird', 'settings.showNavBarLabels' => 'Navigationsleisten-Beschriftungen anzeigen', 'settings.showNavBarLabelsDescription' => 'Textbeschriftungen unter den Symbolen der Navigationsleiste anzeigen', + 'settings.liveTvDefaultFavorites' => 'Standardmäßig Favoritenkanäle', + 'settings.liveTvDefaultFavoritesDescription' => 'Beim Öffnen von Live TV nur Favoritenkanäle anzeigen', 'search.hint' => 'Filme, Serien, Musik suchen...', 'search.tryDifferentTerm' => 'Anderen Suchbegriff versuchen', 'search.searchYourMedia' => 'In den eigenen Medien suchen', @@ -1820,10 +1828,10 @@ extension on TranslationsDe { 'liveTv.tuneFailed' => 'Kanal konnte nicht eingestellt werden', 'liveTv.loading' => 'Kanäle werden geladen...', 'liveTv.nowPlaying' => 'Läuft gerade', - 'liveTv.noPrograms' => 'Keine Programmdaten verfügbar', - 'liveTv.channelNumber' => ({required Object number}) => 'Kanal ${number}', _ => null, } ?? switch (path) { + 'liveTv.noPrograms' => 'Keine Programmdaten verfügbar', + 'liveTv.channelNumber' => ({required Object number}) => 'Kanal ${number}', 'liveTv.live' => 'LIVE', 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'NEU', @@ -1839,6 +1847,10 @@ extension on TranslationsDe { 'liveTv.lateNight' => 'Spätnacht', 'liveTv.whatsOn' => 'Jetzt im TV', 'liveTv.watchChannel' => 'Kanal ansehen', + 'liveTv.favorites' => 'Favoriten', + 'liveTv.addToFavorites' => 'Zu Favoriten hinzufügen', + 'liveTv.removeFromFavorites' => 'Aus Favoriten entfernen', + 'liveTv.noFavorites' => 'Keine Favoritenkanäle. Kanal lange drücken, um ihn hinzuzufügen.', 'downloads.title' => 'Downloads', 'downloads.manage' => 'Verwalten', 'downloads.tvShows' => 'Serien', diff --git a/lib/i18n/strings_en.g.dart b/lib/i18n/strings_en.g.dart index e12fa967..95708fb7 100644 --- a/lib/i18n/strings_en.g.dart +++ b/lib/i18n/strings_en.g.dart @@ -744,6 +744,12 @@ class TranslationsSettingsEn { /// en: 'Display text labels under navigation bar icons' String get showNavBarLabelsDescription => 'Display text labels under navigation bar icons'; + + /// en: 'Default to Favorite Channels' + String get liveTvDefaultFavorites => 'Default to Favorite Channels'; + + /// en: 'Show only favorite channels when opening Live TV' + String get liveTvDefaultFavoritesDescription => 'Show only favorite channels when opening Live TV'; } // Path: search @@ -1816,6 +1822,18 @@ class TranslationsLiveTvEn { /// en: 'Watch Channel' String get watchChannel => 'Watch Channel'; + + /// en: 'Favorites' + String get favorites => 'Favorites'; + + /// en: 'Add to Favorites' + String get addToFavorites => 'Add to Favorites'; + + /// en: 'Remove from Favorites' + String get removeFromFavorites => 'Remove from Favorites'; + + /// en: 'No favorite channels. Long-press a channel to add it.' + String get noFavorites => 'No favorite channels. Long-press a channel to add it.'; } // Path: collections @@ -3147,6 +3165,8 @@ extension on Translations { 'settings.confirmExitOnBackDescription' => 'Show a confirmation dialog when pressing back to exit the app', 'settings.showNavBarLabels' => 'Show Navigation Bar Labels', 'settings.showNavBarLabelsDescription' => 'Display text labels under navigation bar icons', + 'settings.liveTvDefaultFavorites' => 'Default to Favorite Channels', + 'settings.liveTvDefaultFavoritesDescription' => 'Show only favorite channels when opening Live TV', 'search.hint' => 'Search movies, shows, music...', 'search.tryDifferentTerm' => 'Try a different search term', 'search.searchYourMedia' => 'Search your media', @@ -3453,10 +3473,10 @@ extension on Translations { 'liveTv.tuneFailed' => 'Failed to tune channel', 'liveTv.loading' => 'Loading channels...', 'liveTv.nowPlaying' => 'Now Playing', - 'liveTv.noPrograms' => 'No program data available', - 'liveTv.channelNumber' => ({required Object number}) => 'Ch. ${number}', _ => null, } ?? switch (path) { + 'liveTv.noPrograms' => 'No program data available', + 'liveTv.channelNumber' => ({required Object number}) => 'Ch. ${number}', 'liveTv.live' => 'LIVE', 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'NEW', @@ -3472,6 +3492,10 @@ extension on Translations { 'liveTv.lateNight' => 'Late Night', 'liveTv.whatsOn' => 'What\'s On', 'liveTv.watchChannel' => 'Watch Channel', + 'liveTv.favorites' => 'Favorites', + 'liveTv.addToFavorites' => 'Add to Favorites', + 'liveTv.removeFromFavorites' => 'Remove from Favorites', + 'liveTv.noFavorites' => 'No favorite channels. Long-press a channel to add it.', 'collections.title' => 'Collections', 'collections.collection' => 'Collection', 'collections.empty' => 'Collection is empty', diff --git a/lib/i18n/strings_es.g.dart b/lib/i18n/strings_es.g.dart index 10a685b6..1e1f7903 100644 --- a/lib/i18n/strings_es.g.dart +++ b/lib/i18n/strings_es.g.dart @@ -333,6 +333,8 @@ class _TranslationsSettingsEs implements TranslationsSettingsEn { @override String get confirmExitOnBackDescription => 'Mostrar un diálogo de confirmación al presionar atrás para salir de la app'; @override String get showNavBarLabels => 'Mostrar etiquetas de la barra de navegación'; @override String get showNavBarLabelsDescription => 'Mostrar etiquetas de texto bajo los iconos de la barra de navegación'; + @override String get liveTvDefaultFavorites => 'Canales favoritos por defecto'; + @override String get liveTvDefaultFavoritesDescription => 'Mostrar solo canales favoritos al abrir TV en vivo'; } // Path: search @@ -830,6 +832,10 @@ class _TranslationsLiveTvEs implements TranslationsLiveTvEn { @override String get lateNight => 'Trasnoche'; @override String get whatsOn => 'En emisión'; @override String get watchChannel => 'Ver canal'; + @override String get favorites => 'Favoritos'; + @override String get addToFavorites => 'Añadir a favoritos'; + @override String get removeFromFavorites => 'Eliminar de favoritos'; + @override String get noFavorites => 'No hay canales favoritos. Mantén pulsado un canal para añadirlo.'; } // Path: collections @@ -1514,6 +1520,8 @@ extension on TranslationsEs { 'settings.confirmExitOnBackDescription' => 'Mostrar un diálogo de confirmación al presionar atrás para salir de la app', 'settings.showNavBarLabels' => 'Mostrar etiquetas de la barra de navegación', 'settings.showNavBarLabelsDescription' => 'Mostrar etiquetas de texto bajo los iconos de la barra de navegación', + 'settings.liveTvDefaultFavorites' => 'Canales favoritos por defecto', + 'settings.liveTvDefaultFavoritesDescription' => 'Mostrar solo canales favoritos al abrir TV en vivo', 'search.hint' => 'Buscar películas, series, música...', 'search.tryDifferentTerm' => 'Prueba con un término de búsqueda diferente', 'search.searchYourMedia' => 'Busca en tu contenido', @@ -1820,10 +1828,10 @@ extension on TranslationsEs { 'liveTv.tuneFailed' => 'Error al sintonizar el canal', 'liveTv.loading' => 'Cargando canales...', 'liveTv.nowPlaying' => 'Reproduciendo ahora', - 'liveTv.noPrograms' => 'No hay datos de programación disponibles', - 'liveTv.channelNumber' => ({required Object number}) => 'Canal ${number}', _ => null, } ?? switch (path) { + 'liveTv.noPrograms' => 'No hay datos de programación disponibles', + 'liveTv.channelNumber' => ({required Object number}) => 'Canal ${number}', 'liveTv.live' => 'EN VIVO', 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'NUEVO', @@ -1839,6 +1847,10 @@ extension on TranslationsEs { 'liveTv.lateNight' => 'Trasnoche', 'liveTv.whatsOn' => 'En emisión', 'liveTv.watchChannel' => 'Ver canal', + 'liveTv.favorites' => 'Favoritos', + 'liveTv.addToFavorites' => 'Añadir a favoritos', + 'liveTv.removeFromFavorites' => 'Eliminar de favoritos', + 'liveTv.noFavorites' => 'No hay canales favoritos. Mantén pulsado un canal para añadirlo.', 'collections.title' => 'Colecciones', 'collections.collection' => 'Colección', 'collections.empty' => 'La colección está vacía', diff --git a/lib/i18n/strings_fr.g.dart b/lib/i18n/strings_fr.g.dart index 9aab6c73..64c9263d 100644 --- a/lib/i18n/strings_fr.g.dart +++ b/lib/i18n/strings_fr.g.dart @@ -333,6 +333,8 @@ class _TranslationsSettingsFr implements TranslationsSettingsEn { @override String get confirmExitOnBackDescription => 'Afficher une boîte de dialogue de confirmation en appuyant sur retour pour quitter'; @override String get showNavBarLabels => 'Afficher les libellés de la barre de navigation'; @override String get showNavBarLabelsDescription => 'Afficher les libellés sous les icônes de la barre de navigation'; + @override String get liveTvDefaultFavorites => 'Chaînes favorites par défaut'; + @override String get liveTvDefaultFavoritesDescription => 'Afficher uniquement les chaînes favorites à l\'ouverture de la TV en direct'; } // Path: search @@ -830,6 +832,10 @@ class _TranslationsLiveTvFr implements TranslationsLiveTvEn { @override String get lateNight => 'Nuit tardive'; @override String get whatsOn => 'En ce moment'; @override String get watchChannel => 'Regarder la chaîne'; + @override String get favorites => 'Favoris'; + @override String get addToFavorites => 'Ajouter aux favoris'; + @override String get removeFromFavorites => 'Retirer des favoris'; + @override String get noFavorites => 'Aucune chaîne favorite. Appuyez longuement sur une chaîne pour l\'ajouter.'; } // Path: collections @@ -1514,6 +1520,8 @@ extension on TranslationsFr { 'settings.confirmExitOnBackDescription' => 'Afficher une boîte de dialogue de confirmation en appuyant sur retour pour quitter', 'settings.showNavBarLabels' => 'Afficher les libellés de la barre de navigation', 'settings.showNavBarLabelsDescription' => 'Afficher les libellés sous les icônes de la barre de navigation', + 'settings.liveTvDefaultFavorites' => 'Chaînes favorites par défaut', + 'settings.liveTvDefaultFavoritesDescription' => 'Afficher uniquement les chaînes favorites à l\'ouverture de la TV en direct', 'search.hint' => 'Rechercher des films, des séries, de la musique...', 'search.tryDifferentTerm' => 'Essayez un autre terme de recherche', 'search.searchYourMedia' => 'Rechercher dans vos médias', @@ -1820,10 +1828,10 @@ extension on TranslationsFr { 'liveTv.tuneFailed' => 'Impossible de syntoniser la chaîne', 'liveTv.loading' => 'Chargement des chaînes...', 'liveTv.nowPlaying' => 'En cours de lecture', - 'liveTv.noPrograms' => 'Aucune donnée de programme disponible', - 'liveTv.channelNumber' => ({required Object number}) => 'Ch. ${number}', _ => null, } ?? switch (path) { + 'liveTv.noPrograms' => 'Aucune donnée de programme disponible', + 'liveTv.channelNumber' => ({required Object number}) => 'Ch. ${number}', 'liveTv.live' => 'EN DIRECT', 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'NOUVEAU', @@ -1839,6 +1847,10 @@ extension on TranslationsFr { 'liveTv.lateNight' => 'Nuit tardive', 'liveTv.whatsOn' => 'En ce moment', 'liveTv.watchChannel' => 'Regarder la chaîne', + 'liveTv.favorites' => 'Favoris', + 'liveTv.addToFavorites' => 'Ajouter aux favoris', + 'liveTv.removeFromFavorites' => 'Retirer des favoris', + 'liveTv.noFavorites' => 'Aucune chaîne favorite. Appuyez longuement sur une chaîne pour l\'ajouter.', 'collections.title' => 'Collections', 'collections.collection' => 'Collection', 'collections.empty' => 'La collection est vide', diff --git a/lib/i18n/strings_it.g.dart b/lib/i18n/strings_it.g.dart index 9e7eb4e7..85ebb577 100644 --- a/lib/i18n/strings_it.g.dart +++ b/lib/i18n/strings_it.g.dart @@ -333,6 +333,8 @@ class _TranslationsSettingsIt implements TranslationsSettingsEn { @override String get confirmExitOnBackDescription => 'Mostra una finestra di conferma quando si preme indietro per uscire dall\'app'; @override String get showNavBarLabels => 'Mostra etichette barra di navigazione'; @override String get showNavBarLabelsDescription => 'Mostra le etichette sotto le icone della barra di navigazione'; + @override String get liveTvDefaultFavorites => 'Canali preferiti predefiniti'; + @override String get liveTvDefaultFavoritesDescription => 'Mostra solo i canali preferiti all\'apertura della TV dal vivo'; } // Path: search @@ -830,6 +832,10 @@ class _TranslationsLiveTvIt implements TranslationsLiveTvEn { @override String get lateNight => 'Notte tarda'; @override String get whatsOn => 'In onda ora'; @override String get watchChannel => 'Guarda canale'; + @override String get favorites => 'Preferiti'; + @override String get addToFavorites => 'Aggiungi ai preferiti'; + @override String get removeFromFavorites => 'Rimuovi dai preferiti'; + @override String get noFavorites => 'Nessun canale preferito. Tieni premuto un canale per aggiungerlo.'; } // Path: downloads @@ -1514,6 +1520,8 @@ extension on TranslationsIt { 'settings.confirmExitOnBackDescription' => 'Mostra una finestra di conferma quando si preme indietro per uscire dall\'app', 'settings.showNavBarLabels' => 'Mostra etichette barra di navigazione', 'settings.showNavBarLabelsDescription' => 'Mostra le etichette sotto le icone della barra di navigazione', + 'settings.liveTvDefaultFavorites' => 'Canali preferiti predefiniti', + 'settings.liveTvDefaultFavoritesDescription' => 'Mostra solo i canali preferiti all\'apertura della TV dal vivo', 'search.hint' => 'Cerca film. spettacoli, musica...', 'search.tryDifferentTerm' => 'Prova altri termini di ricerca', 'search.searchYourMedia' => 'Cerca nei tuoi media', @@ -1820,10 +1828,10 @@ extension on TranslationsIt { 'liveTv.tuneFailed' => 'Impossibile sintonizzare il canale', 'liveTv.loading' => 'Caricamento canali...', 'liveTv.nowPlaying' => 'In riproduzione', - 'liveTv.noPrograms' => 'Nessun dato di programma disponibile', - 'liveTv.channelNumber' => ({required Object number}) => 'Canale ${number}', _ => null, } ?? switch (path) { + 'liveTv.noPrograms' => 'Nessun dato di programma disponibile', + 'liveTv.channelNumber' => ({required Object number}) => 'Canale ${number}', 'liveTv.live' => 'IN DIRETTA', 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'NUOVO', @@ -1839,6 +1847,10 @@ extension on TranslationsIt { 'liveTv.lateNight' => 'Notte tarda', 'liveTv.whatsOn' => 'In onda ora', 'liveTv.watchChannel' => 'Guarda canale', + 'liveTv.favorites' => 'Preferiti', + 'liveTv.addToFavorites' => 'Aggiungi ai preferiti', + 'liveTv.removeFromFavorites' => 'Rimuovi dai preferiti', + 'liveTv.noFavorites' => 'Nessun canale preferito. Tieni premuto un canale per aggiungerlo.', 'downloads.title' => 'Download', 'downloads.manage' => 'Gestisci', 'downloads.tvShows' => 'Serie TV', diff --git a/lib/i18n/strings_ja.g.dart b/lib/i18n/strings_ja.g.dart index 69e54b26..f4406417 100644 --- a/lib/i18n/strings_ja.g.dart +++ b/lib/i18n/strings_ja.g.dart @@ -333,6 +333,8 @@ class _TranslationsSettingsJa implements TranslationsSettingsEn { @override String get confirmExitOnBackDescription => '戻るボタンでアプリを終了する際に確認ダイアログを表示'; @override String get showNavBarLabels => 'ナビゲーションバーラベルを表示'; @override String get showNavBarLabelsDescription => 'ナビゲーションバーアイコンの下にテキストラベルを表示'; + @override String get liveTvDefaultFavorites => 'お気に入りチャンネルをデフォルトに'; + @override String get liveTvDefaultFavoritesDescription => 'ライブTV を開いたときにお気に入りチャンネルのみ表示'; } // Path: search @@ -830,6 +832,10 @@ class _TranslationsLiveTvJa implements TranslationsLiveTvEn { @override String get lateNight => '深夜'; @override String get whatsOn => '放送中'; @override String get watchChannel => 'チャンネルを視聴'; + @override String get favorites => 'お気に入り'; + @override String get addToFavorites => 'お気に入りに追加'; + @override String get removeFromFavorites => 'お気に入りから削除'; + @override String get noFavorites => 'お気に入りチャンネルがありません。チャンネルを長押しして追加してください。'; } // Path: collections @@ -1514,6 +1520,8 @@ extension on TranslationsJa { 'settings.confirmExitOnBackDescription' => '戻るボタンでアプリを終了する際に確認ダイアログを表示', 'settings.showNavBarLabels' => 'ナビゲーションバーラベルを表示', 'settings.showNavBarLabelsDescription' => 'ナビゲーションバーアイコンの下にテキストラベルを表示', + 'settings.liveTvDefaultFavorites' => 'お気に入りチャンネルをデフォルトに', + 'settings.liveTvDefaultFavoritesDescription' => 'ライブTV を開いたときにお気に入りチャンネルのみ表示', 'search.hint' => '映画、番組、音楽を検索...', 'search.tryDifferentTerm' => '別の検索語をお試しください', 'search.searchYourMedia' => 'メディアを検索', @@ -1820,10 +1828,10 @@ extension on TranslationsJa { 'liveTv.tuneFailed' => 'チャンネルのチューニングに失敗しました', 'liveTv.loading' => 'チャンネルを読み込み中...', 'liveTv.nowPlaying' => '現在放送中', - 'liveTv.noPrograms' => '番組データがありません', - 'liveTv.channelNumber' => ({required Object number}) => 'Ch. ${number}', _ => null, } ?? switch (path) { + 'liveTv.noPrograms' => '番組データがありません', + 'liveTv.channelNumber' => ({required Object number}) => 'Ch. ${number}', 'liveTv.live' => 'ライブ', 'liveTv.hd' => 'HD', 'liveTv.premiere' => '新着', @@ -1839,6 +1847,10 @@ extension on TranslationsJa { 'liveTv.lateNight' => '深夜', 'liveTv.whatsOn' => '放送中', 'liveTv.watchChannel' => 'チャンネルを視聴', + 'liveTv.favorites' => 'お気に入り', + 'liveTv.addToFavorites' => 'お気に入りに追加', + 'liveTv.removeFromFavorites' => 'お気に入りから削除', + 'liveTv.noFavorites' => 'お気に入りチャンネルがありません。チャンネルを長押しして追加してください。', 'collections.title' => 'コレクション', 'collections.collection' => 'コレクション', 'collections.empty' => 'コレクションは空です', diff --git a/lib/i18n/strings_ko.g.dart b/lib/i18n/strings_ko.g.dart index d9c61f9a..bd29e03e 100644 --- a/lib/i18n/strings_ko.g.dart +++ b/lib/i18n/strings_ko.g.dart @@ -333,6 +333,8 @@ class _TranslationsSettingsKo implements TranslationsSettingsEn { @override String get confirmExitOnBackDescription => '뒤로 버튼을 눌러 앱을 종료할 때 확인 대화상자를 표시합니다'; @override String get showNavBarLabels => '내비게이션 바 라벨 표시'; @override String get showNavBarLabelsDescription => '내비게이션 바 아이콘 아래에 텍스트 라벨을 표시합니다'; + @override String get liveTvDefaultFavorites => '즐겨찾기 채널 기본 설정'; + @override String get liveTvDefaultFavoritesDescription => '라이브 TV를 열 때 즐겨찾기 채널만 표시'; } // Path: search @@ -830,6 +832,10 @@ class _TranslationsLiveTvKo implements TranslationsLiveTvEn { @override String get lateNight => '심야 방송'; @override String get whatsOn => '지금 방송 중'; @override String get watchChannel => '채널 시청'; + @override String get favorites => '즐겨찾기'; + @override String get addToFavorites => '즐겨찾기에 추가'; + @override String get removeFromFavorites => '즐겨찾기에서 제거'; + @override String get noFavorites => '즐겨찾기 채널이 없습니다. 채널을 길게 눌러 추가하세요.'; } // Path: collections @@ -1514,6 +1520,8 @@ extension on TranslationsKo { 'settings.confirmExitOnBackDescription' => '뒤로 버튼을 눌러 앱을 종료할 때 확인 대화상자를 표시합니다', 'settings.showNavBarLabels' => '내비게이션 바 라벨 표시', 'settings.showNavBarLabelsDescription' => '내비게이션 바 아이콘 아래에 텍스트 라벨을 표시합니다', + 'settings.liveTvDefaultFavorites' => '즐겨찾기 채널 기본 설정', + 'settings.liveTvDefaultFavoritesDescription' => '라이브 TV를 열 때 즐겨찾기 채널만 표시', 'search.hint' => '영화, 시리즈, 음악 등을 검색하세요...', 'search.tryDifferentTerm' => '다른 검색어를 시도해 보세요', 'search.searchYourMedia' => '미디어 검색', @@ -1820,10 +1828,10 @@ extension on TranslationsKo { 'liveTv.tuneFailed' => '채널 튜닝에 실패했습니다', 'liveTv.loading' => '채널 로딩 중...', 'liveTv.nowPlaying' => '현재 재생 중', - 'liveTv.noPrograms' => '프로그램 데이터가 없습니다', - 'liveTv.channelNumber' => ({required Object number}) => '채널 ${number}', _ => null, } ?? switch (path) { + 'liveTv.noPrograms' => '프로그램 데이터가 없습니다', + 'liveTv.channelNumber' => ({required Object number}) => '채널 ${number}', 'liveTv.live' => '실시간', 'liveTv.hd' => 'HD', 'liveTv.premiere' => '신규', @@ -1839,6 +1847,10 @@ extension on TranslationsKo { 'liveTv.lateNight' => '심야 방송', 'liveTv.whatsOn' => '지금 방송 중', 'liveTv.watchChannel' => '채널 시청', + 'liveTv.favorites' => '즐겨찾기', + 'liveTv.addToFavorites' => '즐겨찾기에 추가', + 'liveTv.removeFromFavorites' => '즐겨찾기에서 제거', + 'liveTv.noFavorites' => '즐겨찾기 채널이 없습니다. 채널을 길게 눌러 추가하세요.', 'collections.title' => '컬렉션', 'collections.collection' => '컬렉션', 'collections.empty' => '컬렉션이 비어 있습니다', diff --git a/lib/i18n/strings_nb.g.dart b/lib/i18n/strings_nb.g.dart index e059929f..13e446d9 100644 --- a/lib/i18n/strings_nb.g.dart +++ b/lib/i18n/strings_nb.g.dart @@ -333,6 +333,8 @@ class _TranslationsSettingsNb implements TranslationsSettingsEn { @override String get confirmExitOnBackDescription => 'Vis en bekreftelsesdialog når du trykker tilbake for å avslutte appen'; @override String get showNavBarLabels => 'Vis navigasjonsfeltlabeler'; @override String get showNavBarLabelsDescription => 'Vis tekstlabeler under navigasjonsfeltikoner'; + @override String get liveTvDefaultFavorites => 'Standard til favorittkanaler'; + @override String get liveTvDefaultFavoritesDescription => 'Vis kun favorittkanaler når du åpner Live TV'; } // Path: search @@ -830,6 +832,10 @@ class _TranslationsLiveTvNb implements TranslationsLiveTvEn { @override String get lateNight => 'Sen kveld'; @override String get whatsOn => 'Hva går nå'; @override String get watchChannel => 'Se kanal'; + @override String get favorites => 'Favoritter'; + @override String get addToFavorites => 'Legg til i favoritter'; + @override String get removeFromFavorites => 'Fjern fra favoritter'; + @override String get noFavorites => 'Ingen favorittkanaler. Trykk lenge på en kanal for å legge den til.'; } // Path: collections @@ -1514,6 +1520,8 @@ extension on TranslationsNb { 'settings.confirmExitOnBackDescription' => 'Vis en bekreftelsesdialog når du trykker tilbake for å avslutte appen', 'settings.showNavBarLabels' => 'Vis navigasjonsfeltlabeler', 'settings.showNavBarLabelsDescription' => 'Vis tekstlabeler under navigasjonsfeltikoner', + 'settings.liveTvDefaultFavorites' => 'Standard til favorittkanaler', + 'settings.liveTvDefaultFavoritesDescription' => 'Vis kun favorittkanaler når du åpner Live TV', 'search.hint' => 'Søk i filmer, serier, musikk...', 'search.tryDifferentTerm' => 'Prøv et annet søkeord', 'search.searchYourMedia' => 'Søk i mediene dine', @@ -1820,10 +1828,10 @@ extension on TranslationsNb { 'liveTv.tuneFailed' => 'Kunne ikke stille inn kanal', 'liveTv.loading' => 'Laster kanaler...', 'liveTv.nowPlaying' => 'Spilles nå', - 'liveTv.noPrograms' => 'Ingen programdata tilgjengelig', - 'liveTv.channelNumber' => ({required Object number}) => 'Kanal ${number}', _ => null, } ?? switch (path) { + 'liveTv.noPrograms' => 'Ingen programdata tilgjengelig', + 'liveTv.channelNumber' => ({required Object number}) => 'Kanal ${number}', 'liveTv.live' => 'DIREKTE', 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'NY', @@ -1839,6 +1847,10 @@ extension on TranslationsNb { 'liveTv.lateNight' => 'Sen kveld', 'liveTv.whatsOn' => 'Hva går nå', 'liveTv.watchChannel' => 'Se kanal', + 'liveTv.favorites' => 'Favoritter', + 'liveTv.addToFavorites' => 'Legg til i favoritter', + 'liveTv.removeFromFavorites' => 'Fjern fra favoritter', + 'liveTv.noFavorites' => 'Ingen favorittkanaler. Trykk lenge på en kanal for å legge den til.', 'collections.title' => 'Samlinger', 'collections.collection' => 'Samling', 'collections.empty' => 'Samlingen er tom', diff --git a/lib/i18n/strings_nl.g.dart b/lib/i18n/strings_nl.g.dart index 3eae83a0..60c8ea4d 100644 --- a/lib/i18n/strings_nl.g.dart +++ b/lib/i18n/strings_nl.g.dart @@ -333,6 +333,8 @@ class _TranslationsSettingsNl implements TranslationsSettingsEn { @override String get confirmExitOnBackDescription => 'Toon een bevestigingsvenster bij het drukken op terug om de app af te sluiten'; @override String get showNavBarLabels => 'Navigatiebalk labels tonen'; @override String get showNavBarLabelsDescription => 'Tekstlabels onder de pictogrammen van de navigatiebalk weergeven'; + @override String get liveTvDefaultFavorites => 'Standaard favoriete zenders'; + @override String get liveTvDefaultFavoritesDescription => 'Toon alleen favoriete zenders bij het openen van Live TV'; } // Path: search @@ -830,6 +832,10 @@ class _TranslationsLiveTvNl implements TranslationsLiveTvEn { @override String get lateNight => 'Late avond'; @override String get whatsOn => 'Nu op TV'; @override String get watchChannel => 'Kanaal bekijken'; + @override String get favorites => 'Favorieten'; + @override String get addToFavorites => 'Toevoegen aan favorieten'; + @override String get removeFromFavorites => 'Verwijderen uit favorieten'; + @override String get noFavorites => 'Geen favoriete zenders. Houd een zender ingedrukt om toe te voegen.'; } // Path: downloads @@ -1514,6 +1520,8 @@ extension on TranslationsNl { 'settings.confirmExitOnBackDescription' => 'Toon een bevestigingsvenster bij het drukken op terug om de app af te sluiten', 'settings.showNavBarLabels' => 'Navigatiebalk labels tonen', 'settings.showNavBarLabelsDescription' => 'Tekstlabels onder de pictogrammen van de navigatiebalk weergeven', + 'settings.liveTvDefaultFavorites' => 'Standaard favoriete zenders', + 'settings.liveTvDefaultFavoritesDescription' => 'Toon alleen favoriete zenders bij het openen van Live TV', 'search.hint' => 'Zoek films, series, muziek...', 'search.tryDifferentTerm' => 'Probeer een andere zoekterm', 'search.searchYourMedia' => 'Zoek in je media', @@ -1820,10 +1828,10 @@ extension on TranslationsNl { 'liveTv.tuneFailed' => 'Kan zender niet afstemmen', 'liveTv.loading' => 'Zenders laden...', 'liveTv.nowPlaying' => 'Nu aan het afspelen', - 'liveTv.noPrograms' => 'Geen programmagegevens beschikbaar', - 'liveTv.channelNumber' => ({required Object number}) => 'Kanaal ${number}', _ => null, } ?? switch (path) { + 'liveTv.noPrograms' => 'Geen programmagegevens beschikbaar', + 'liveTv.channelNumber' => ({required Object number}) => 'Kanaal ${number}', 'liveTv.live' => 'LIVE', 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'NIEUW', @@ -1839,6 +1847,10 @@ extension on TranslationsNl { 'liveTv.lateNight' => 'Late avond', 'liveTv.whatsOn' => 'Nu op TV', 'liveTv.watchChannel' => 'Kanaal bekijken', + 'liveTv.favorites' => 'Favorieten', + 'liveTv.addToFavorites' => 'Toevoegen aan favorieten', + 'liveTv.removeFromFavorites' => 'Verwijderen uit favorieten', + 'liveTv.noFavorites' => 'Geen favoriete zenders. Houd een zender ingedrukt om toe te voegen.', 'downloads.title' => 'Downloads', 'downloads.manage' => 'Beheren', 'downloads.tvShows' => 'Series', diff --git a/lib/i18n/strings_pl.g.dart b/lib/i18n/strings_pl.g.dart index 083f2f50..8a49c66d 100644 --- a/lib/i18n/strings_pl.g.dart +++ b/lib/i18n/strings_pl.g.dart @@ -333,6 +333,8 @@ class _TranslationsSettingsPl implements TranslationsSettingsEn { @override String get confirmExitOnBackDescription => 'Pokaż dialog potwierdzenia przy naciśnięciu wstecz, aby wyjść z aplikacji'; @override String get showNavBarLabels => 'Pokaż etykiety paska nawigacji'; @override String get showNavBarLabelsDescription => 'Wyświetl tekstowe etykiety pod ikonami paska nawigacji'; + @override String get liveTvDefaultFavorites => 'Domyślnie ulubione kanały'; + @override String get liveTvDefaultFavoritesDescription => 'Pokaż tylko ulubione kanały po otwarciu telewizji na żywo'; } // Path: search @@ -830,6 +832,10 @@ class _TranslationsLiveTvPl implements TranslationsLiveTvEn { @override String get lateNight => 'Późna noc'; @override String get whatsOn => 'Co leci'; @override String get watchChannel => 'Oglądaj kanał'; + @override String get favorites => 'Ulubione'; + @override String get addToFavorites => 'Dodaj do ulubionych'; + @override String get removeFromFavorites => 'Usuń z ulubionych'; + @override String get noFavorites => 'Brak ulubionych kanałów. Przytrzymaj kanał, aby go dodać.'; } // Path: collections @@ -1514,6 +1520,8 @@ extension on TranslationsPl { 'settings.confirmExitOnBackDescription' => 'Pokaż dialog potwierdzenia przy naciśnięciu wstecz, aby wyjść z aplikacji', 'settings.showNavBarLabels' => 'Pokaż etykiety paska nawigacji', 'settings.showNavBarLabelsDescription' => 'Wyświetl tekstowe etykiety pod ikonami paska nawigacji', + 'settings.liveTvDefaultFavorites' => 'Domyślnie ulubione kanały', + 'settings.liveTvDefaultFavoritesDescription' => 'Pokaż tylko ulubione kanały po otwarciu telewizji na żywo', 'search.hint' => 'Szukaj filmów, seriali, muzyki...', 'search.tryDifferentTerm' => 'Spróbuj innego wyszukiwania', 'search.searchYourMedia' => 'Przeszukaj swoje media', @@ -1820,10 +1828,10 @@ extension on TranslationsPl { 'liveTv.tuneFailed' => 'Nie udało się dostroić kanału', 'liveTv.loading' => 'Ładowanie kanałów...', 'liveTv.nowPlaying' => 'Teraz odtwarzane', - 'liveTv.noPrograms' => 'Brak danych o programach', - 'liveTv.channelNumber' => ({required Object number}) => 'Kn. ${number}', _ => null, } ?? switch (path) { + 'liveTv.noPrograms' => 'Brak danych o programach', + 'liveTv.channelNumber' => ({required Object number}) => 'Kn. ${number}', 'liveTv.live' => 'NA ŻYWO', 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'NOWE', @@ -1839,6 +1847,10 @@ extension on TranslationsPl { 'liveTv.lateNight' => 'Późna noc', 'liveTv.whatsOn' => 'Co leci', 'liveTv.watchChannel' => 'Oglądaj kanał', + 'liveTv.favorites' => 'Ulubione', + 'liveTv.addToFavorites' => 'Dodaj do ulubionych', + 'liveTv.removeFromFavorites' => 'Usuń z ulubionych', + 'liveTv.noFavorites' => 'Brak ulubionych kanałów. Przytrzymaj kanał, aby go dodać.', 'collections.title' => 'Kolekcje', 'collections.collection' => 'Kolekcja', 'collections.empty' => 'Kolekcja jest pusta', diff --git a/lib/i18n/strings_pt.g.dart b/lib/i18n/strings_pt.g.dart index d4756a88..b38bf5bc 100644 --- a/lib/i18n/strings_pt.g.dart +++ b/lib/i18n/strings_pt.g.dart @@ -333,6 +333,8 @@ class _TranslationsSettingsPt implements TranslationsSettingsEn { @override String get confirmExitOnBackDescription => 'Mostrar diálogo de confirmação ao pressionar voltar para sair do app'; @override String get showNavBarLabels => 'Mostrar Rótulos da Barra de Navegação'; @override String get showNavBarLabelsDescription => 'Exibir rótulos de texto sob os ícones da barra de navegação'; + @override String get liveTvDefaultFavorites => 'Canais favoritos por padrão'; + @override String get liveTvDefaultFavoritesDescription => 'Mostrar apenas canais favoritos ao abrir TV ao vivo'; } // Path: search @@ -830,6 +832,10 @@ class _TranslationsLiveTvPt implements TranslationsLiveTvEn { @override String get lateNight => 'Madrugada'; @override String get whatsOn => 'O que Está Passando'; @override String get watchChannel => 'Assistir Canal'; + @override String get favorites => 'Favoritos'; + @override String get addToFavorites => 'Adicionar aos favoritos'; + @override String get removeFromFavorites => 'Remover dos favoritos'; + @override String get noFavorites => 'Nenhum canal favorito. Pressione e segure um canal para adicioná-lo.'; } // Path: collections @@ -1514,6 +1520,8 @@ extension on TranslationsPt { 'settings.confirmExitOnBackDescription' => 'Mostrar diálogo de confirmação ao pressionar voltar para sair do app', 'settings.showNavBarLabels' => 'Mostrar Rótulos da Barra de Navegação', 'settings.showNavBarLabelsDescription' => 'Exibir rótulos de texto sob os ícones da barra de navegação', + 'settings.liveTvDefaultFavorites' => 'Canais favoritos por padrão', + 'settings.liveTvDefaultFavoritesDescription' => 'Mostrar apenas canais favoritos ao abrir TV ao vivo', 'search.hint' => 'Buscar filmes, séries, músicas...', 'search.tryDifferentTerm' => 'Tente um termo de busca diferente', 'search.searchYourMedia' => 'Buscar suas mídias', @@ -1820,10 +1828,10 @@ extension on TranslationsPt { 'liveTv.tuneFailed' => 'Falha ao sintonizar canal', 'liveTv.loading' => 'Carregando canais...', 'liveTv.nowPlaying' => 'Reproduzindo Agora', - 'liveTv.noPrograms' => 'Nenhum dado de programação disponível', - 'liveTv.channelNumber' => ({required Object number}) => 'Ch. ${number}', _ => null, } ?? switch (path) { + 'liveTv.noPrograms' => 'Nenhum dado de programação disponível', + 'liveTv.channelNumber' => ({required Object number}) => 'Ch. ${number}', 'liveTv.live' => 'AO VIVO', 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'NOVO', @@ -1839,6 +1847,10 @@ extension on TranslationsPt { 'liveTv.lateNight' => 'Madrugada', 'liveTv.whatsOn' => 'O que Está Passando', 'liveTv.watchChannel' => 'Assistir Canal', + 'liveTv.favorites' => 'Favoritos', + 'liveTv.addToFavorites' => 'Adicionar aos favoritos', + 'liveTv.removeFromFavorites' => 'Remover dos favoritos', + 'liveTv.noFavorites' => 'Nenhum canal favorito. Pressione e segure um canal para adicioná-lo.', 'collections.title' => 'Coleções', 'collections.collection' => 'Coleção', 'collections.empty' => 'A coleção está vazia', diff --git a/lib/i18n/strings_ru.g.dart b/lib/i18n/strings_ru.g.dart index 9bb54f00..9976037e 100644 --- a/lib/i18n/strings_ru.g.dart +++ b/lib/i18n/strings_ru.g.dart @@ -333,6 +333,8 @@ class _TranslationsSettingsRu implements TranslationsSettingsEn { @override String get confirmExitOnBackDescription => 'Показывать диалог подтверждения при нажатии «назад» для выхода из приложения'; @override String get showNavBarLabels => 'Показывать подписи панели навигации'; @override String get showNavBarLabelsDescription => 'Отображать текстовые подписи под иконками панели навигации'; + @override String get liveTvDefaultFavorites => 'Избранные каналы по умолчанию'; + @override String get liveTvDefaultFavoritesDescription => 'Показывать только избранные каналы при открытии ТВ'; } // Path: search @@ -830,6 +832,10 @@ class _TranslationsLiveTvRu implements TranslationsLiveTvEn { @override String get lateNight => 'Поздний вечер'; @override String get whatsOn => 'Что идёт'; @override String get watchChannel => 'Смотреть канал'; + @override String get favorites => 'Избранное'; + @override String get addToFavorites => 'Добавить в избранное'; + @override String get removeFromFavorites => 'Удалить из избранного'; + @override String get noFavorites => 'Нет избранных каналов. Удерживайте канал, чтобы добавить его.'; } // Path: collections @@ -1514,6 +1520,8 @@ extension on TranslationsRu { 'settings.confirmExitOnBackDescription' => 'Показывать диалог подтверждения при нажатии «назад» для выхода из приложения', 'settings.showNavBarLabels' => 'Показывать подписи панели навигации', 'settings.showNavBarLabelsDescription' => 'Отображать текстовые подписи под иконками панели навигации', + 'settings.liveTvDefaultFavorites' => 'Избранные каналы по умолчанию', + 'settings.liveTvDefaultFavoritesDescription' => 'Показывать только избранные каналы при открытии ТВ', 'search.hint' => 'Поиск фильмов, сериалов, музыки...', 'search.tryDifferentTerm' => 'Попробуйте другой запрос', 'search.searchYourMedia' => 'Поиск в вашей медиатеке', @@ -1820,10 +1828,10 @@ extension on TranslationsRu { 'liveTv.tuneFailed' => 'Не удалось настроить канал', 'liveTv.loading' => 'Загрузка каналов...', 'liveTv.nowPlaying' => 'Сейчас воспроизводится', - 'liveTv.noPrograms' => 'Нет данных о программах', - 'liveTv.channelNumber' => ({required Object number}) => 'Кн. ${number}', _ => null, } ?? switch (path) { + 'liveTv.noPrograms' => 'Нет данных о программах', + 'liveTv.channelNumber' => ({required Object number}) => 'Кн. ${number}', 'liveTv.live' => 'ЭФИР', 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'НОВОЕ', @@ -1839,6 +1847,10 @@ extension on TranslationsRu { 'liveTv.lateNight' => 'Поздний вечер', 'liveTv.whatsOn' => 'Что идёт', 'liveTv.watchChannel' => 'Смотреть канал', + 'liveTv.favorites' => 'Избранное', + 'liveTv.addToFavorites' => 'Добавить в избранное', + 'liveTv.removeFromFavorites' => 'Удалить из избранного', + 'liveTv.noFavorites' => 'Нет избранных каналов. Удерживайте канал, чтобы добавить его.', 'collections.title' => 'Коллекции', 'collections.collection' => 'Коллекция', 'collections.empty' => 'Коллекция пуста', diff --git a/lib/i18n/strings_sv.g.dart b/lib/i18n/strings_sv.g.dart index 5cad5e50..f486bcec 100644 --- a/lib/i18n/strings_sv.g.dart +++ b/lib/i18n/strings_sv.g.dart @@ -333,6 +333,8 @@ class _TranslationsSettingsSv implements TranslationsSettingsEn { @override String get confirmExitOnBackDescription => 'Visa en bekräftelsedialog när du trycker tillbaka för att avsluta appen'; @override String get showNavBarLabels => 'Visa navigeringsfältets etiketter'; @override String get showNavBarLabelsDescription => 'Visa textetiketter under navigeringsfältets ikoner'; + @override String get liveTvDefaultFavorites => 'Standard till favoritkanaler'; + @override String get liveTvDefaultFavoritesDescription => 'Visa bara favoritkanaler när du öppnar Live TV'; } // Path: search @@ -830,6 +832,10 @@ class _TranslationsLiveTvSv implements TranslationsLiveTvEn { @override String get lateNight => 'Sen kväll'; @override String get whatsOn => 'På TV nu'; @override String get watchChannel => 'Titta på kanal'; + @override String get favorites => 'Favoriter'; + @override String get addToFavorites => 'Lägg till i favoriter'; + @override String get removeFromFavorites => 'Ta bort från favoriter'; + @override String get noFavorites => 'Inga favoritkanaler. Tryck länge på en kanal för att lägga till den.'; } // Path: downloads @@ -1514,6 +1520,8 @@ extension on TranslationsSv { 'settings.confirmExitOnBackDescription' => 'Visa en bekräftelsedialog när du trycker tillbaka för att avsluta appen', 'settings.showNavBarLabels' => 'Visa navigeringsfältets etiketter', 'settings.showNavBarLabelsDescription' => 'Visa textetiketter under navigeringsfältets ikoner', + 'settings.liveTvDefaultFavorites' => 'Standard till favoritkanaler', + 'settings.liveTvDefaultFavoritesDescription' => 'Visa bara favoritkanaler när du öppnar Live TV', 'search.hint' => 'Sök filmer, serier, musik...', 'search.tryDifferentTerm' => 'Prova en annan sökterm', 'search.searchYourMedia' => 'Sök i dina media', @@ -1820,10 +1828,10 @@ extension on TranslationsSv { 'liveTv.tuneFailed' => 'Kunde inte ställa in kanalen', 'liveTv.loading' => 'Laddar kanaler...', 'liveTv.nowPlaying' => 'Spelas nu', - 'liveTv.noPrograms' => 'Ingen programdata tillgänglig', - 'liveTv.channelNumber' => ({required Object number}) => 'Kanal ${number}', _ => null, } ?? switch (path) { + 'liveTv.noPrograms' => 'Ingen programdata tillgänglig', + 'liveTv.channelNumber' => ({required Object number}) => 'Kanal ${number}', 'liveTv.live' => 'LIVE', 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'NY', @@ -1839,6 +1847,10 @@ extension on TranslationsSv { 'liveTv.lateNight' => 'Sen kväll', 'liveTv.whatsOn' => 'På TV nu', 'liveTv.watchChannel' => 'Titta på kanal', + 'liveTv.favorites' => 'Favoriter', + 'liveTv.addToFavorites' => 'Lägg till i favoriter', + 'liveTv.removeFromFavorites' => 'Ta bort från favoriter', + 'liveTv.noFavorites' => 'Inga favoritkanaler. Tryck länge på en kanal för att lägga till den.', 'downloads.title' => 'Nedladdningar', 'downloads.manage' => 'Hantera', 'downloads.tvShows' => 'TV-serier', diff --git a/lib/i18n/strings_zh.g.dart b/lib/i18n/strings_zh.g.dart index e99a9bc8..b9d3ba37 100644 --- a/lib/i18n/strings_zh.g.dart +++ b/lib/i18n/strings_zh.g.dart @@ -333,6 +333,8 @@ class _TranslationsSettingsZh implements TranslationsSettingsEn { @override String get confirmExitOnBackDescription => '按返回键退出应用时显示确认对话框'; @override String get showNavBarLabels => '显示导航栏标签'; @override String get showNavBarLabelsDescription => '在导航栏图标下方显示文字标签'; + @override String get liveTvDefaultFavorites => '默认显示收藏频道'; + @override String get liveTvDefaultFavoritesDescription => '打开直播电视时仅显示收藏频道'; } // Path: search @@ -830,6 +832,10 @@ class _TranslationsLiveTvZh implements TranslationsLiveTvEn { @override String get lateNight => '深夜'; @override String get whatsOn => '正在播出'; @override String get watchChannel => '观看频道'; + @override String get favorites => '收藏'; + @override String get addToFavorites => '添加到收藏'; + @override String get removeFromFavorites => '从收藏中移除'; + @override String get noFavorites => '没有收藏频道。长按频道即可添加。'; } // Path: downloads @@ -1514,6 +1520,8 @@ extension on TranslationsZh { 'settings.confirmExitOnBackDescription' => '按返回键退出应用时显示确认对话框', 'settings.showNavBarLabels' => '显示导航栏标签', 'settings.showNavBarLabelsDescription' => '在导航栏图标下方显示文字标签', + 'settings.liveTvDefaultFavorites' => '默认显示收藏频道', + 'settings.liveTvDefaultFavoritesDescription' => '打开直播电视时仅显示收藏频道', 'search.hint' => '搜索电影、系列、音乐...', 'search.tryDifferentTerm' => '尝试不同的搜索词', 'search.searchYourMedia' => '搜索媒体', @@ -1820,10 +1828,10 @@ extension on TranslationsZh { 'liveTv.tuneFailed' => '无法调谐频道', 'liveTv.loading' => '正在加载频道...', 'liveTv.nowPlaying' => '正在播放', - 'liveTv.noPrograms' => '没有可用的节目数据', - 'liveTv.channelNumber' => ({required Object number}) => '频道 ${number}', _ => null, } ?? switch (path) { + 'liveTv.noPrograms' => '没有可用的节目数据', + 'liveTv.channelNumber' => ({required Object number}) => '频道 ${number}', 'liveTv.live' => '直播', 'liveTv.hd' => '高清', 'liveTv.premiere' => '新', @@ -1839,6 +1847,10 @@ extension on TranslationsZh { 'liveTv.lateNight' => '深夜', 'liveTv.whatsOn' => '正在播出', 'liveTv.watchChannel' => '观看频道', + 'liveTv.favorites' => '收藏', + 'liveTv.addToFavorites' => '添加到收藏', + 'liveTv.removeFromFavorites' => '从收藏中移除', + 'liveTv.noFavorites' => '没有收藏频道。长按频道即可添加。', 'downloads.title' => '下载', 'downloads.manage' => '管理', 'downloads.tvShows' => '电视剧', diff --git a/lib/i18n/sv.i18n.json b/lib/i18n/sv.i18n.json index 841970ae..55da6d67 100644 --- a/lib/i18n/sv.i18n.json +++ b/lib/i18n/sv.i18n.json @@ -213,7 +213,9 @@ "confirmExitOnBack": "Bekräfta innan avslut", "confirmExitOnBackDescription": "Visa en bekräftelsedialog när du trycker tillbaka för att avsluta appen", "showNavBarLabels": "Visa navigeringsfältets etiketter", - "showNavBarLabelsDescription": "Visa textetiketter under navigeringsfältets ikoner" + "showNavBarLabelsDescription": "Visa textetiketter under navigeringsfältets ikoner", + "liveTvDefaultFavorites": "Standard till favoritkanaler", + "liveTvDefaultFavoritesDescription": "Visa bara favoritkanaler när du öppnar Live TV" }, "search": { "hint": "Sök filmer, serier, musik...", @@ -590,7 +592,11 @@ "evening": "Kväll", "lateNight": "Sen kväll", "whatsOn": "På TV nu", - "watchChannel": "Titta på kanal" + "watchChannel": "Titta på kanal", + "favorites": "Favoriter", + "addToFavorites": "Lägg till i favoriter", + "removeFromFavorites": "Ta bort från favoriter", + "noFavorites": "Inga favoritkanaler. Tryck länge på en kanal för att lägga till den." }, "downloads": { "title": "Nedladdningar", diff --git a/lib/i18n/zh.i18n.json b/lib/i18n/zh.i18n.json index 54816f3e..68678fa7 100644 --- a/lib/i18n/zh.i18n.json +++ b/lib/i18n/zh.i18n.json @@ -213,7 +213,9 @@ "confirmExitOnBack": "退出前确认", "confirmExitOnBackDescription": "按返回键退出应用时显示确认对话框", "showNavBarLabels": "显示导航栏标签", - "showNavBarLabelsDescription": "在导航栏图标下方显示文字标签" + "showNavBarLabelsDescription": "在导航栏图标下方显示文字标签", + "liveTvDefaultFavorites": "默认显示收藏频道", + "liveTvDefaultFavoritesDescription": "打开直播电视时仅显示收藏频道" }, "search": { "hint": "搜索电影、系列、音乐...", @@ -590,7 +592,11 @@ "evening": "晚上", "lateNight": "深夜", "whatsOn": "正在播出", - "watchChannel": "观看频道" + "watchChannel": "观看频道", + "favorites": "收藏", + "addToFavorites": "添加到收藏", + "removeFromFavorites": "从收藏中移除", + "noFavorites": "没有收藏频道。长按频道即可添加。" }, "downloads": { "title": "下载", diff --git a/lib/models/livetv_channel.dart b/lib/models/livetv_channel.dart index dfbc5fa8..c54e7183 100644 --- a/lib/models/livetv_channel.dart +++ b/lib/models/livetv_channel.dart @@ -69,3 +69,50 @@ class LiveTvChannel { /// Display name: prefer callSign, fallback to title String get displayName => callSign ?? title ?? 'Channel $number'; } + +/// A channel entry in the Plex cloud favorites list. +/// Stored at `https://epg.provider.plex.tv/settings/favoriteChannels`. +class FavoriteChannel { + final String source; + final String id; + final String? title; + final String? thumb; + final String? vcn; + + FavoriteChannel({ + required this.source, + required this.id, + this.title, + this.thumb, + this.vcn, + }); + + factory FavoriteChannel.fromJson(Map json) { + return FavoriteChannel( + source: json['source'] as String? ?? '', + id: json['id'] as String? ?? json['key'] as String? ?? '', + title: json['title'] as String?, + thumb: json['thumb'] as String?, + vcn: json['vcn'] as String?, + ); + } + + Map toJson() => { + 'source': source, + 'id': id, + if (title != null) 'title': title, + if (thumb != null) 'thumb': thumb, + if (vcn != null) 'vcn': vcn, + }; + + /// Create from a [LiveTvChannel] and a source URI. + factory FavoriteChannel.fromLiveTvChannel(LiveTvChannel channel, String source) { + return FavoriteChannel( + source: source, + id: channel.key, + title: channel.title ?? channel.callSign, + thumb: channel.thumb, + vcn: channel.number, + ); + } +} diff --git a/lib/providers/settings_provider.dart b/lib/providers/settings_provider.dart index 47da2528..c03f57eb 100644 --- a/lib/providers/settings_provider.dart +++ b/lib/providers/settings_provider.dart @@ -14,6 +14,7 @@ class SettingsProvider extends ChangeNotifier { bool _showUnwatchedCount = true; bool _hideSpoilers = false; bool _showNavBarLabels = true; + bool _liveTvDefaultFavorites = false; bool _isInitialized = false; Future? _initFuture; @@ -40,6 +41,7 @@ class SettingsProvider extends ChangeNotifier { _showUnwatchedCount = _settingsService!.getShowUnwatchedCount(); _hideSpoilers = _settingsService!.getHideSpoilers(); _showNavBarLabels = _settingsService!.getShowNavBarLabels(); + _liveTvDefaultFavorites = _settingsService!.getLiveTvDefaultFavorites(); _isInitialized = true; notifyListeners(); } @@ -67,6 +69,8 @@ class SettingsProvider extends ChangeNotifier { bool get showNavBarLabels => _showNavBarLabels; + bool get liveTvDefaultFavorites => _liveTvDefaultFavorites; + /// Helper to update a setting: ensures init, deduplicates, persists, notifies. Future _updateSetting({ required T current, @@ -142,6 +146,12 @@ class SettingsProvider extends ChangeNotifier { persist: _settingsService!.setShowNavBarLabels, ); + Future setLiveTvDefaultFavorites(bool value) => _updateSetting( + current: _liveTvDefaultFavorites, value: value, + setLocal: (v) => _liveTvDefaultFavorites = v, + persist: _settingsService!.setLiveTvDefaultFavorites, + ); + String get libraryDensityDisplayName { switch (_libraryDensity) { case LibraryDensity.compact: diff --git a/lib/screens/livetv/live_tv_screen.dart b/lib/screens/livetv/live_tv_screen.dart index 2274240d..e6963267 100644 --- a/lib/screens/livetv/live_tv_screen.dart +++ b/lib/screens/livetv/live_tv_screen.dart @@ -9,6 +9,7 @@ import '../../models/livetv_dvr.dart'; import '../../mixins/refreshable.dart'; import '../../mixins/tab_navigation_mixin.dart'; import '../../providers/multi_server_provider.dart'; +import '../../providers/settings_provider.dart'; import '../../utils/app_logger.dart'; import '../../utils/desktop_window_padding.dart'; import '../../utils/platform_detector.dart'; @@ -39,6 +40,18 @@ class _LiveTvScreenState extends State bool _isLoading = true; String? _error; + // Favorites + bool _showFavoritesOnly = false; + Set _favoriteChannelIds = {}; + List _favoriteChannels = []; + /// Source URI per server, built from machineIdentifier + EPG provider identifier. + final Map _favoriteSourceByServer = {}; + + List get _filteredChannels { + if (!_showFavoritesOnly || _favoriteChannelIds.isEmpty) return _channels; + return _channels.where((c) => _favoriteChannelIds.contains(c.key)).toList(); + } + @override List get tabChipFocusNodes => [_guideTabFocusNode, _whatsOnTabFocusNode]; @@ -46,6 +59,7 @@ class _LiveTvScreenState extends State void initState() { super.initState(); suppressAutoFocus = true; + _showFavoritesOnly = context.read().liveTvDefaultFavorites; initTabNavigation(); _loadChannels(); } @@ -172,6 +186,9 @@ class _LiveTvScreenState extends State _isLoading = false; }); + // Load favorites from the first available server (favorites are cloud-synced) + _loadFavorites(multiServer); + if (allChannels.isNotEmpty && PlatformDetector.shouldUseSideNavigation(context)) { WidgetsBinding.instance.addPostFrameCallback((_) { if (mounted) _focusCurrentTab(); @@ -188,6 +205,62 @@ class _LiveTvScreenState extends State } } + Future _loadFavorites(MultiServerProvider multiServer) async { + try { + // Use the first available server's client to fetch favorites + for (final serverInfo in multiServer.liveTvServers) { + final client = multiServer.getClientForServer(serverInfo.serverId); + if (client == null) continue; + + // Build and cache the source URI for this server + final source = await client.buildFavoriteChannelSource(); + _favoriteSourceByServer[serverInfo.serverId] = source; + + final favorites = await client.getFavoriteChannels(); + if (!mounted) return; + + setState(() { + _favoriteChannels = favorites; + _favoriteChannelIds = favorites.map((f) => f.id).toSet(); + }); + appLogger.d('Live TV: loaded ${favorites.length} favorite channels'); + break; // Favorites are cloud-synced, only need to fetch once + } + } catch (e) { + appLogger.e('Failed to load favorite channels', error: e); + } + } + + void _toggleFavoritesFilter() { + setState(() { + _showFavoritesOnly = !_showFavoritesOnly; + }); + } + + void _toggleFavorite(LiveTvChannel channel) { + final multiServer = context.read(); + final source = _favoriteSourceByServer[channel.serverId] ?? ''; + + setState(() { + if (_favoriteChannelIds.contains(channel.key)) { + _favoriteChannelIds = Set.from(_favoriteChannelIds)..remove(channel.key); + _favoriteChannels = _favoriteChannels.where((f) => f.id != channel.key).toList(); + } else { + _favoriteChannelIds = Set.from(_favoriteChannelIds)..add(channel.key); + _favoriteChannels = [..._favoriteChannels, FavoriteChannel.fromLiveTvChannel(channel, source)]; + } + }); + + // Persist to server (fire-and-forget, optimistic UI) + for (final serverInfo in multiServer.liveTvServers) { + final client = multiServer.getClientForServer(serverInfo.serverId); + if (client != null) { + client.setFavoriteChannels(_favoriteChannels); + break; + } + } + } + void _focusCurrentTab() { if (tabController.index == 0) { _guideTabKey.currentState?.focusContent(); @@ -274,6 +347,12 @@ class _LiveTvScreenState extends State onNavigateLeft: () => getTabChipFocusNode(tabCount - 1).requestFocus(), onNavigateDown: _focusCurrentTab, actions: [ + FocusableAction( + icon: _showFavoritesOnly ? Symbols.star_rounded : Symbols.star_outline_rounded, + iconFill: _showFavoritesOnly ? 1.0 : 0.0, + tooltip: t.liveTv.favorites, + onPressed: _toggleFavoritesFilter, + ), FocusableAction( icon: Symbols.refresh_rounded, tooltip: t.liveTv.reloadGuide, @@ -312,6 +391,9 @@ class _LiveTvScreenState extends State if (_channels.isEmpty) { return Center(child: Text(t.liveTv.noChannels)); } + + final guideChannels = _filteredChannels; + return Column( children: [ if (!useSideNav) @@ -333,7 +415,14 @@ class _LiveTvScreenState extends State child: TabBarView( controller: tabController, children: [ - GuideTab(key: _guideTabKey, channels: _channels, onNavigateUp: focusTabBar, onBack: onTabBarBack), + GuideTab( + key: _guideTabKey, + channels: guideChannels, + favoriteChannelIds: _favoriteChannelIds, + onToggleFavorite: _toggleFavorite, + onNavigateUp: focusTabBar, + onBack: onTabBarBack, + ), WhatsOnTab(key: _whatsOnTabKey, channels: _channels, onNavigateUp: focusTabBar, onBack: onTabBarBack), ], ), diff --git a/lib/screens/livetv/tabs/guide_tab.dart b/lib/screens/livetv/tabs/guide_tab.dart index 6afef551..5f7774b6 100644 --- a/lib/screens/livetv/tabs/guide_tab.dart +++ b/lib/screens/livetv/tabs/guide_tab.dart @@ -25,10 +25,19 @@ import '../program_details_sheet.dart'; class GuideTab extends StatefulWidget { final List channels; + final Set favoriteChannelIds; + final void Function(LiveTvChannel)? onToggleFavorite; final VoidCallback? onNavigateUp; final VoidCallback? onBack; - const GuideTab({super.key, required this.channels, this.onNavigateUp, this.onBack}); + const GuideTab({ + super.key, + required this.channels, + this.favoriteChannelIds = const {}, + this.onToggleFavorite, + this.onNavigateUp, + this.onBack, + }); @override State createState() => GuideTabState(); @@ -410,6 +419,13 @@ class GuideTabState extends State { } return KeyEventResult.handled; } + // 'F' key toggles favorite on focused channel + if (key == LogicalKeyboardKey.keyF && _gridColumn == 0) { + if (_gridChannelIndex >= 0 && _gridChannelIndex < widget.channels.length) { + widget.onToggleFavorite?.call(widget.channels[_gridChannelIndex]); + } + return KeyEventResult.handled; + } return KeyEventResult.ignored; } @@ -888,7 +904,9 @@ class GuideTabState extends State { channel: channel, theme: theme, onTap: () => _tuneChannel(channel), + onLongPress: widget.onToggleFavorite != null ? () => widget.onToggleFavorite!(channel) : null, isFocused: isFocused, + isFavorite: widget.favoriteChannelIds.contains(channel.key), fallbackBuilder: () => _buildChannelNameFallback(channel, theme), ); } @@ -1113,7 +1131,9 @@ class _ChannelCell extends StatefulWidget { final LiveTvChannel channel; final ThemeData theme; final VoidCallback onTap; + final VoidCallback? onLongPress; final bool isFocused; + final bool isFavorite; final Widget Function() fallbackBuilder; const _ChannelCell({ @@ -1124,7 +1144,9 @@ class _ChannelCell extends StatefulWidget { required this.channel, required this.theme, required this.onTap, + this.onLongPress, required this.isFocused, + this.isFavorite = false, required this.fallbackBuilder, }); @@ -1143,12 +1165,15 @@ class _ChannelCellState extends State<_ChannelCell> { return MouseRegion( onEnter: (_) => setState(() => _hovered = true), onExit: (_) => setState(() => _hovered = false), - child: Material( - color: widget.isFocused ? theme.colorScheme.primary.withValues(alpha: 0.15) : Colors.transparent, - child: InkWell( - canRequestFocus: false, - onTap: widget.onTap, - child: Container( + child: GestureDetector( + onSecondaryTap: widget.onLongPress, + child: Material( + color: widget.isFocused ? theme.colorScheme.primary.withValues(alpha: 0.15) : Colors.transparent, + child: InkWell( + canRequestFocus: false, + onTap: widget.onTap, + onLongPress: widget.onLongPress, + child: Container( height: widget.rowHeight, padding: const EdgeInsets.symmetric(horizontal: 8), decoration: BoxDecoration( @@ -1174,11 +1199,18 @@ class _ChannelCellState extends State<_ChannelCell> { : widget.fallbackBuilder(), ), if (showAction) AppIcon(Symbols.play_arrow_rounded, size: 32, color: theme.colorScheme.onSurface), + if (widget.isFavorite) + Positioned( + top: 2, + right: 0, + child: AppIcon(Symbols.star_rounded, size: 14, color: theme.colorScheme.primary), + ), ], ), ), ), ), + ), ); } } diff --git a/lib/screens/settings/settings_screen.dart b/lib/screens/settings/settings_screen.dart index 90cf398f..0231350a 100644 --- a/lib/screens/settings/settings_screen.dart +++ b/lib/screens/settings/settings_screen.dart @@ -77,6 +77,7 @@ class _SettingsScreenState extends State with FocusableTab { static const _kShowUnwatchedCount = 'show_unwatched_count'; static const _kHideSpoilers = 'hide_spoilers'; static const _kShowNavBarLabels = 'show_nav_bar_labels'; + static const _kLiveTvDefaultFavorites = 'live_tv_default_favorites'; static const _kRequireProfileSelectionOnOpen = 'require_profile_selection_on_open'; static const _kConfirmExitOnBack = 'confirm_exit_on_back'; static const _kPlayerBackend = 'player_backend'; @@ -525,6 +526,20 @@ class _SettingsScreenState extends State with FocusableTab { ); }, ), + Consumer( + builder: (context, settingsProvider, child) { + return SwitchListTile( + focusNode: _focusTracker.get(_kLiveTvDefaultFavorites), + secondary: const AppIcon(Symbols.star_rounded, fill: 1), + title: Text(t.settings.liveTvDefaultFavorites), + subtitle: Text(t.settings.liveTvDefaultFavoritesDescription), + value: settingsProvider.liveTvDefaultFavorites, + onChanged: (value) async { + await settingsProvider.setLiveTvDefaultFavorites(value); + }, + ); + }, + ), Consumer( builder: (context, settingsProvider, child) { return SwitchListTile( diff --git a/lib/services/plex_client.dart b/lib/services/plex_client.dart index 661a537f..a797eb9e 100644 --- a/lib/services/plex_client.dart +++ b/lib/services/plex_client.dart @@ -2475,6 +2475,50 @@ class PlexClient { ); } + static const _favoriteChannelsUrl = 'https://epg.provider.plex.tv/settings/favoriteChannels'; + static const _providerVersionHeader = {'X-Plex-Provider-Version': '5.1'}; + + /// Build the source URI for favorite channels: `server://{machineIdentifier}/{providerIdentifier}` + Future buildFavoriteChannelSource() async { + final providers = await _discoverEpgProviders(); + final providerIdentifier = providers.isNotEmpty ? providers.first.identifier : 'tv.plex.provider.epg'; + final machineId = config.machineIdentifier ?? serverId; + return 'server://$machineId/$providerIdentifier'; + } + + /// Get favorite channels from the Plex cloud. + Future> getFavoriteChannels() async { + try { + final response = await _dio.get( + _favoriteChannelsUrl, + options: Options(headers: _providerVersionHeader), + ); + final container = _getMediaContainer(response); + if (container != null && container['FavoriteChannel'] != null) { + return (container['FavoriteChannel'] as List) + .map((json) => FavoriteChannel.fromJson(json as Map)) + .toList(); + } + return []; + } catch (e) { + appLogger.e('Failed to get favorite channels', error: e); + return []; + } + } + + /// Update favorite channels on the Plex cloud. + Future setFavoriteChannels(List channels) async { + try { + await _dio.put( + _favoriteChannelsUrl, + data: channels.map((c) => c.toJson()).toList(), + options: Options(headers: _providerVersionHeader), + ); + } catch (e) { + appLogger.e('Failed to update favorite channels', error: e); + } + } + Future _handleEndpointSwitch(String newBaseUrl) async { if (config.baseUrl == newBaseUrl) { return; diff --git a/lib/services/settings_service.dart b/lib/services/settings_service.dart index 2869f4c0..d75cff9e 100644 --- a/lib/services/settings_service.dart +++ b/lib/services/settings_service.dart @@ -95,6 +95,7 @@ class SettingsService extends BaseSharedPreferencesService { static const String _keyAudioPassthrough = 'audio_passthrough'; static const String _keyAudioNormalization = 'audio_normalization'; static const String _keyCustomShaderPresets = 'custom_shader_presets'; + static const String _keyLiveTvDefaultFavorites = 'live_tv_default_favorites'; SettingsService._(); @@ -1180,6 +1181,14 @@ class SettingsService extends BaseSharedPreferencesService { return prefs.getBool(_keyShowNavBarLabels) ?? true; // Default: show labels } + Future setLiveTvDefaultFavorites(bool enabled) async { + await prefs.setBool(_keyLiveTvDefaultFavorites, enabled); + } + + bool getLiveTvDefaultFavorites() { + return prefs.getBool(_keyLiveTvDefaultFavorites) ?? false; + } + // Global Shader Preset (for MPV video enhancement) Future setGlobalShaderPreset(String presetId) async { await prefs.setString(_keyGlobalShaderPreset, presetId);