feat: live TV channel favorites

close #663
This commit is contained in:
edde746
2026-03-15 07:44:44 +01:00
parent 79888168ae
commit 5f18efcfb3
39 changed files with 603 additions and 71 deletions
+5 -1
View File
@@ -13,6 +13,9 @@ class FocusableAction {
/// Icon color. Ignored when [child] is provided.
final Color? iconColor;
/// Icon fill weight (0.01.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<FocusableActionBar> {
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,
),
+8 -2
View File
@@ -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",
+8 -2
View File
@@ -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",
+8 -2
View File
@@ -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",
+8 -2
View File
@@ -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",
+8 -2
View File
@@ -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",
+8 -2
View File
@@ -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",
+8 -2
View File
@@ -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": "コレクション",
+8 -2
View File
@@ -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": "컬렉션",
+8 -2
View File
@@ -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",
+8 -2
View File
@@ -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",
+8 -2
View File
@@ -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",
+8 -2
View File
@@ -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",
+8 -2
View File
@@ -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": "Коллекции",
+2 -2
View File
@@ -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
+14 -2
View File
@@ -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',
+14 -2
View File
@@ -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',
+26 -2
View File
@@ -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',
+14 -2
View File
@@ -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',
+14 -2
View File
@@ -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',
+14 -2
View File
@@ -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',
+14 -2
View File
@@ -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' => 'コレクションは空です',
+14 -2
View File
@@ -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' => '컬렉션이 비어 있습니다',
+14 -2
View File
@@ -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',
+14 -2
View File
@@ -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',
+14 -2
View File
@@ -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',
+14 -2
View File
@@ -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',
+14 -2
View File
@@ -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' => 'Коллекция пуста',
+14 -2
View File
@@ -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',
+14 -2
View File
@@ -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' => '电视剧',
+8 -2
View File
@@ -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",
+8 -2
View File
@@ -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": "下载",
+47
View File
@@ -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<String, dynamic> 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<String, dynamic> 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,
);
}
}
+10
View File
@@ -14,6 +14,7 @@ class SettingsProvider extends ChangeNotifier {
bool _showUnwatchedCount = true;
bool _hideSpoilers = false;
bool _showNavBarLabels = true;
bool _liveTvDefaultFavorites = false;
bool _isInitialized = false;
Future<void>? _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<void> _updateSetting<T>({
required T current,
@@ -142,6 +146,12 @@ class SettingsProvider extends ChangeNotifier {
persist: _settingsService!.setShowNavBarLabels,
);
Future<void> setLiveTvDefaultFavorites(bool value) => _updateSetting(
current: _liveTvDefaultFavorites, value: value,
setLocal: (v) => _liveTvDefaultFavorites = v,
persist: _settingsService!.setLiveTvDefaultFavorites,
);
String get libraryDensityDisplayName {
switch (_libraryDensity) {
case LibraryDensity.compact:
+90 -1
View File
@@ -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<LiveTvScreen>
bool _isLoading = true;
String? _error;
// Favorites
bool _showFavoritesOnly = false;
Set<String> _favoriteChannelIds = {};
List<FavoriteChannel> _favoriteChannels = [];
/// Source URI per server, built from machineIdentifier + EPG provider identifier.
final Map<String, String> _favoriteSourceByServer = {};
List<LiveTvChannel> get _filteredChannels {
if (!_showFavoritesOnly || _favoriteChannelIds.isEmpty) return _channels;
return _channels.where((c) => _favoriteChannelIds.contains(c.key)).toList();
}
@override
List<FocusNode> get tabChipFocusNodes => [_guideTabFocusNode, _whatsOnTabFocusNode];
@@ -46,6 +59,7 @@ class _LiveTvScreenState extends State<LiveTvScreen>
void initState() {
super.initState();
suppressAutoFocus = true;
_showFavoritesOnly = context.read<SettingsProvider>().liveTvDefaultFavorites;
initTabNavigation();
_loadChannels();
}
@@ -172,6 +186,9 @@ class _LiveTvScreenState extends State<LiveTvScreen>
_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<LiveTvScreen>
}
}
Future<void> _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<MultiServerProvider>();
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<LiveTvScreen>
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<LiveTvScreen>
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<LiveTvScreen>
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),
],
),
+39 -7
View File
@@ -25,10 +25,19 @@ import '../program_details_sheet.dart';
class GuideTab extends StatefulWidget {
final List<LiveTvChannel> channels;
final Set<String> 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<GuideTab> createState() => GuideTabState();
@@ -410,6 +419,13 @@ class GuideTabState extends State<GuideTab> {
}
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<GuideTab> {
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),
),
],
),
),
),
),
),
);
}
}
+15
View File
@@ -77,6 +77,7 @@ class _SettingsScreenState extends State<SettingsScreen> 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<SettingsScreen> with FocusableTab {
);
},
),
Consumer<SettingsProvider>(
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<SettingsProvider>(
builder: (context, settingsProvider, child) {
return SwitchListTile(
+44
View File
@@ -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<String> 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<List<FavoriteChannel>> 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<String, dynamic>))
.toList();
}
return [];
} catch (e) {
appLogger.e('Failed to get favorite channels', error: e);
return [];
}
}
/// Update favorite channels on the Plex cloud.
Future<void> setFavoriteChannels(List<FavoriteChannel> 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<void> _handleEndpointSwitch(String newBaseUrl) async {
if (config.baseUrl == newBaseUrl) {
return;
+9
View File
@@ -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<void> setLiveTvDefaultFavorites(bool enabled) async {
await prefs.setBool(_keyLiveTvDefaultFavorites, enabled);
}
bool getLiveTvDefaultFavorites() {
return prefs.getBool(_keyLiveTvDefaultFavorites) ?? false;
}
// Global Shader Preset (for MPV video enhancement)
Future<void> setGlobalShaderPreset(String presetId) async {
await prefs.setString(_keyGlobalShaderPreset, presetId);