diff --git a/lib/i18n/da.i18n.json b/lib/i18n/da.i18n.json index 8d66b4a8..5b0adfaf 100644 --- a/lib/i18n/da.i18n.json +++ b/lib/i18n/da.i18n.json @@ -53,7 +53,9 @@ "loadingServers": "Indlæser servere...", "connectingToServers": "Forbinder til servere...", "startingOfflineMode": "Starter offlinetilstand...", - "loading": "Indlæser..." + "loading": "Indlæser...", + "fullscreen": "Fuldskærm", + "exitFullscreen": "Forlad fuldskærm" }, "screens": { "licenses": "Licenser", diff --git a/lib/i18n/de.i18n.json b/lib/i18n/de.i18n.json index 1508fce0..95d9173f 100644 --- a/lib/i18n/de.i18n.json +++ b/lib/i18n/de.i18n.json @@ -53,7 +53,9 @@ "loadingServers": "Server werden geladen...", "connectingToServers": "Verbindung zu Servern...", "startingOfflineMode": "Offlinemodus wird gestartet...", - "loading": "Laden..." + "loading": "Laden...", + "fullscreen": "Vollbild", + "exitFullscreen": "Vollbild verlassen" }, "screens": { "licenses": "Lizenzen", diff --git a/lib/i18n/en.i18n.json b/lib/i18n/en.i18n.json index 2041284b..41313817 100644 --- a/lib/i18n/en.i18n.json +++ b/lib/i18n/en.i18n.json @@ -53,7 +53,9 @@ "loadingServers": "Loading servers...", "connectingToServers": "Connecting to servers...", "startingOfflineMode": "Starting offline mode...", - "loading": "Loading..." + "loading": "Loading...", + "fullscreen": "Fullscreen", + "exitFullscreen": "Exit fullscreen" }, "screens": { "licenses": "Licenses", diff --git a/lib/i18n/es.i18n.json b/lib/i18n/es.i18n.json index 9f2f88a8..28bdb699 100644 --- a/lib/i18n/es.i18n.json +++ b/lib/i18n/es.i18n.json @@ -53,7 +53,9 @@ "loadingServers": "Cargando servidores...", "connectingToServers": "Conectando a servidores...", "startingOfflineMode": "Iniciando modo sin conexión...", - "loading": "Cargando..." + "loading": "Cargando...", + "fullscreen": "Pantalla completa", + "exitFullscreen": "Salir de pantalla completa" }, "screens": { "licenses": "Licencias", diff --git a/lib/i18n/fr.i18n.json b/lib/i18n/fr.i18n.json index 170a8bae..b7de2a77 100644 --- a/lib/i18n/fr.i18n.json +++ b/lib/i18n/fr.i18n.json @@ -53,7 +53,9 @@ "loadingServers": "Chargement des serveurs...", "connectingToServers": "Connexion aux serveurs...", "startingOfflineMode": "Démarrage en mode hors-ligne...", - "loading": "Chargement..." + "loading": "Chargement...", + "fullscreen": "Plein écran", + "exitFullscreen": "Quitter le plein écran" }, "screens": { "licenses": "Licenses", diff --git a/lib/i18n/it.i18n.json b/lib/i18n/it.i18n.json index f294ef70..6761d93b 100644 --- a/lib/i18n/it.i18n.json +++ b/lib/i18n/it.i18n.json @@ -53,7 +53,9 @@ "loadingServers": "Caricamento server...", "connectingToServers": "Connessione ai server...", "startingOfflineMode": "Avvio modalità offline...", - "loading": "Caricamento..." + "loading": "Caricamento...", + "fullscreen": "Schermo intero", + "exitFullscreen": "Esci da schermo intero" }, "screens": { "licenses": "Licenze", diff --git a/lib/i18n/ja.i18n.json b/lib/i18n/ja.i18n.json index 90611a84..92c13c3c 100644 --- a/lib/i18n/ja.i18n.json +++ b/lib/i18n/ja.i18n.json @@ -53,7 +53,9 @@ "loadingServers": "サーバーを読み込み中...", "connectingToServers": "サーバーに接続中...", "startingOfflineMode": "オフラインモードを開始中...", - "loading": "読み込み中..." + "loading": "読み込み中...", + "fullscreen": "フルスクリーン", + "exitFullscreen": "フルスクリーンを終了" }, "screens": { "licenses": "ライセンス", diff --git a/lib/i18n/ko.i18n.json b/lib/i18n/ko.i18n.json index 1d670a1b..d59cea3b 100644 --- a/lib/i18n/ko.i18n.json +++ b/lib/i18n/ko.i18n.json @@ -53,7 +53,9 @@ "loadingServers": "서버 로딩 중...", "connectingToServers": "서버 연결 중...", "startingOfflineMode": "오프라인 모드 시작 중...", - "loading": "로딩 중..." + "loading": "로딩 중...", + "fullscreen": "전체화면", + "exitFullscreen": "전체화면 종료" }, "screens": { "licenses": "라이선스", diff --git a/lib/i18n/nb.i18n.json b/lib/i18n/nb.i18n.json index 7669131b..520f0e58 100644 --- a/lib/i18n/nb.i18n.json +++ b/lib/i18n/nb.i18n.json @@ -53,7 +53,9 @@ "loadingServers": "Laster servere...", "connectingToServers": "Kobler til servere...", "startingOfflineMode": "Starter frakoblet modus...", - "loading": "Laster..." + "loading": "Laster...", + "fullscreen": "Fullskjerm", + "exitFullscreen": "Avslutt fullskjerm" }, "screens": { "licenses": "Lisenser", diff --git a/lib/i18n/nl.i18n.json b/lib/i18n/nl.i18n.json index b7a22662..3919618e 100644 --- a/lib/i18n/nl.i18n.json +++ b/lib/i18n/nl.i18n.json @@ -53,7 +53,9 @@ "loadingServers": "Servers laden...", "connectingToServers": "Verbinden met servers...", "startingOfflineMode": "Offlinemodus starten...", - "loading": "Laden..." + "loading": "Laden...", + "fullscreen": "Volledig scherm", + "exitFullscreen": "Volledig scherm verlaten" }, "screens": { "licenses": "Licenties", diff --git a/lib/i18n/pl.i18n.json b/lib/i18n/pl.i18n.json index e2d54d26..1ccca64a 100644 --- a/lib/i18n/pl.i18n.json +++ b/lib/i18n/pl.i18n.json @@ -53,7 +53,9 @@ "loadingServers": "Ładowanie serwerów...", "connectingToServers": "Łączenie z serwerami...", "startingOfflineMode": "Uruchamianie trybu offline...", - "loading": "Ładowanie..." + "loading": "Ładowanie...", + "fullscreen": "Pełny ekran", + "exitFullscreen": "Wyjdź z pełnego ekranu" }, "screens": { "licenses": "Licencje", diff --git a/lib/i18n/pt.i18n.json b/lib/i18n/pt.i18n.json index f0935451..4cfb1f5b 100644 --- a/lib/i18n/pt.i18n.json +++ b/lib/i18n/pt.i18n.json @@ -53,7 +53,9 @@ "loadingServers": "Carregando servidores...", "connectingToServers": "Conectando aos servidores...", "startingOfflineMode": "Iniciando modo offline...", - "loading": "Carregando..." + "loading": "Carregando...", + "fullscreen": "Tela cheia", + "exitFullscreen": "Sair da tela cheia" }, "screens": { "licenses": "Licenças", diff --git a/lib/i18n/ru.i18n.json b/lib/i18n/ru.i18n.json index e9ed2e9e..54967f78 100644 --- a/lib/i18n/ru.i18n.json +++ b/lib/i18n/ru.i18n.json @@ -53,7 +53,9 @@ "loadingServers": "Загрузка серверов...", "connectingToServers": "Подключение к серверам...", "startingOfflineMode": "Запуск автономного режима...", - "loading": "Загрузка..." + "loading": "Загрузка...", + "fullscreen": "Полноэкранный режим", + "exitFullscreen": "Выйти из полноэкранного режима" }, "screens": { "licenses": "Лицензии", diff --git a/lib/i18n/strings.g.dart b/lib/i18n/strings.g.dart index eb4d9cdb..3b0e95d8 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: 13695 (913 per locale) +/// Strings: 13725 (915 per locale) /// -/// Built on 2026-04-22 at 19:30 UTC +/// Built on 2026-04-23 at 02:28 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 be0a6107..8cfafa1a 100644 --- a/lib/i18n/strings_da.g.dart +++ b/lib/i18n/strings_da.g.dart @@ -153,6 +153,8 @@ class _TranslationsCommonDa implements TranslationsCommonEn { @override String get connectingToServers => 'Forbinder til servere...'; @override String get startingOfflineMode => 'Starter offlinetilstand...'; @override String get loading => 'Indlæser...'; + @override String get fullscreen => 'Fuldskærm'; + @override String get exitFullscreen => 'Forlad fuldskærm'; } // Path: screens @@ -1470,6 +1472,8 @@ extension on TranslationsDa { 'common.connectingToServers' => 'Forbinder til servere...', 'common.startingOfflineMode' => 'Starter offlinetilstand...', 'common.loading' => 'Indlæser...', + 'common.fullscreen' => 'Fuldskærm', + 'common.exitFullscreen' => 'Forlad fuldskærm', 'screens.licenses' => 'Licenser', 'screens.switchProfile' => 'Skift profil', 'screens.subtitleStyling' => 'Undertekststil', @@ -1930,10 +1934,10 @@ extension on TranslationsDa { 'libraries.manageLibraries' => 'Administrer biblioteker', 'libraries.sort' => 'Sortér', 'libraries.sortBy' => 'Sortér efter', - 'libraries.filters' => 'Filtre', - 'libraries.confirmActionMessage' => 'Er du sikker på, at du vil udføre denne handling?', _ => null, } ?? switch (path) { + 'libraries.filters' => 'Filtre', + 'libraries.confirmActionMessage' => 'Er du sikker på, at du vil udføre denne handling?', 'libraries.showLibrary' => 'Vis bibliotek', 'libraries.hideLibrary' => 'Skjul bibliotek', 'libraries.libraryOptions' => 'Biblioteksindstillinger', diff --git a/lib/i18n/strings_de.g.dart b/lib/i18n/strings_de.g.dart index 8dae29bc..acf04d1d 100644 --- a/lib/i18n/strings_de.g.dart +++ b/lib/i18n/strings_de.g.dart @@ -153,6 +153,8 @@ class _TranslationsCommonDe implements TranslationsCommonEn { @override String get connectingToServers => 'Verbindung zu Servern...'; @override String get startingOfflineMode => 'Offlinemodus wird gestartet...'; @override String get loading => 'Laden...'; + @override String get fullscreen => 'Vollbild'; + @override String get exitFullscreen => 'Vollbild verlassen'; } // Path: screens @@ -1470,6 +1472,8 @@ extension on TranslationsDe { 'common.connectingToServers' => 'Verbindung zu Servern...', 'common.startingOfflineMode' => 'Offlinemodus wird gestartet...', 'common.loading' => 'Laden...', + 'common.fullscreen' => 'Vollbild', + 'common.exitFullscreen' => 'Vollbild verlassen', 'screens.licenses' => 'Lizenzen', 'screens.switchProfile' => 'Profil wechseln', 'screens.subtitleStyling' => 'Untertitel-Stil', @@ -1930,10 +1934,10 @@ extension on TranslationsDe { 'libraries.manageLibraries' => 'Mediatheken verwalten', 'libraries.sort' => 'Sortieren', 'libraries.sortBy' => 'Sortieren nach', - 'libraries.filters' => 'Filter', - 'libraries.confirmActionMessage' => 'Aktion wirklich durchführen?', _ => null, } ?? switch (path) { + 'libraries.filters' => 'Filter', + 'libraries.confirmActionMessage' => 'Aktion wirklich durchführen?', 'libraries.showLibrary' => 'Mediathek anzeigen', 'libraries.hideLibrary' => 'Mediathek ausblenden', 'libraries.libraryOptions' => 'Mediatheksoptionen', diff --git a/lib/i18n/strings_en.g.dart b/lib/i18n/strings_en.g.dart index 2d45eb78..271531de 100644 --- a/lib/i18n/strings_en.g.dart +++ b/lib/i18n/strings_en.g.dart @@ -256,6 +256,12 @@ class TranslationsCommonEn { /// en: 'Loading...' String get loading => 'Loading...'; + + /// en: 'Fullscreen' + String get fullscreen => 'Fullscreen'; + + /// en: 'Exit fullscreen' + String get exitFullscreen => 'Exit fullscreen'; } // Path: screens @@ -3303,6 +3309,8 @@ extension on Translations { 'common.connectingToServers' => 'Connecting to servers...', 'common.startingOfflineMode' => 'Starting offline mode...', 'common.loading' => 'Loading...', + 'common.fullscreen' => 'Fullscreen', + 'common.exitFullscreen' => 'Exit fullscreen', 'screens.licenses' => 'Licenses', 'screens.switchProfile' => 'Switch Profile', 'screens.subtitleStyling' => 'Subtitle Styling', @@ -3763,10 +3771,10 @@ extension on Translations { 'libraries.manageLibraries' => 'Manage Libraries', 'libraries.sort' => 'Sort', 'libraries.sortBy' => 'Sort By', - 'libraries.filters' => 'Filters', - 'libraries.confirmActionMessage' => 'Are you sure you want to perform this action?', _ => null, } ?? switch (path) { + 'libraries.filters' => 'Filters', + 'libraries.confirmActionMessage' => 'Are you sure you want to perform this action?', 'libraries.showLibrary' => 'Show library', 'libraries.hideLibrary' => 'Hide library', 'libraries.libraryOptions' => 'Library options', diff --git a/lib/i18n/strings_es.g.dart b/lib/i18n/strings_es.g.dart index 61ee6e2d..9e6e6126 100644 --- a/lib/i18n/strings_es.g.dart +++ b/lib/i18n/strings_es.g.dart @@ -153,6 +153,8 @@ class _TranslationsCommonEs implements TranslationsCommonEn { @override String get connectingToServers => 'Conectando a servidores...'; @override String get startingOfflineMode => 'Iniciando modo sin conexión...'; @override String get loading => 'Cargando...'; + @override String get fullscreen => 'Pantalla completa'; + @override String get exitFullscreen => 'Salir de pantalla completa'; } // Path: screens @@ -1470,6 +1472,8 @@ extension on TranslationsEs { 'common.connectingToServers' => 'Conectando a servidores...', 'common.startingOfflineMode' => 'Iniciando modo sin conexión...', 'common.loading' => 'Cargando...', + 'common.fullscreen' => 'Pantalla completa', + 'common.exitFullscreen' => 'Salir de pantalla completa', 'screens.licenses' => 'Licencias', 'screens.switchProfile' => 'Cambiar Perfil', 'screens.subtitleStyling' => 'Estilo de Subtítulos', @@ -1930,10 +1934,10 @@ extension on TranslationsEs { 'libraries.manageLibraries' => 'Gestionar Bibliotecas', 'libraries.sort' => 'Ordenar', 'libraries.sortBy' => 'Ordenar por', - 'libraries.filters' => 'Filtros', - 'libraries.confirmActionMessage' => '¿Estás seguro de que quieres realizar esta acción?', _ => null, } ?? switch (path) { + 'libraries.filters' => 'Filtros', + 'libraries.confirmActionMessage' => '¿Estás seguro de que quieres realizar esta acción?', 'libraries.showLibrary' => 'Mostrar biblioteca', 'libraries.hideLibrary' => 'Ocultar biblioteca', 'libraries.libraryOptions' => 'Opciones de biblioteca', diff --git a/lib/i18n/strings_fr.g.dart b/lib/i18n/strings_fr.g.dart index c96bb352..6906fa06 100644 --- a/lib/i18n/strings_fr.g.dart +++ b/lib/i18n/strings_fr.g.dart @@ -153,6 +153,8 @@ class _TranslationsCommonFr implements TranslationsCommonEn { @override String get connectingToServers => 'Connexion aux serveurs...'; @override String get startingOfflineMode => 'Démarrage en mode hors-ligne...'; @override String get loading => 'Chargement...'; + @override String get fullscreen => 'Plein écran'; + @override String get exitFullscreen => 'Quitter le plein écran'; } // Path: screens @@ -1470,6 +1472,8 @@ extension on TranslationsFr { 'common.connectingToServers' => 'Connexion aux serveurs...', 'common.startingOfflineMode' => 'Démarrage en mode hors-ligne...', 'common.loading' => 'Chargement...', + 'common.fullscreen' => 'Plein écran', + 'common.exitFullscreen' => 'Quitter le plein écran', 'screens.licenses' => 'Licenses', 'screens.switchProfile' => 'Changer de profil', 'screens.subtitleStyling' => 'Configuration des sous-titres', @@ -1930,10 +1934,10 @@ extension on TranslationsFr { 'libraries.manageLibraries' => 'Gérer les bibliothèques', 'libraries.sort' => 'Trier', 'libraries.sortBy' => 'Trier par', - 'libraries.filters' => 'Filtres', - 'libraries.confirmActionMessage' => 'Êtes-vous sûr de vouloir effectuer cette action ?', _ => null, } ?? switch (path) { + 'libraries.filters' => 'Filtres', + 'libraries.confirmActionMessage' => 'Êtes-vous sûr de vouloir effectuer cette action ?', 'libraries.showLibrary' => 'Afficher la bibliothèque', 'libraries.hideLibrary' => 'Masquer la bibliothèque', 'libraries.libraryOptions' => 'Options de bibliothèque', diff --git a/lib/i18n/strings_it.g.dart b/lib/i18n/strings_it.g.dart index df318fb4..3fafa010 100644 --- a/lib/i18n/strings_it.g.dart +++ b/lib/i18n/strings_it.g.dart @@ -153,6 +153,8 @@ class _TranslationsCommonIt implements TranslationsCommonEn { @override String get connectingToServers => 'Connessione ai server...'; @override String get startingOfflineMode => 'Avvio modalità offline...'; @override String get loading => 'Caricamento...'; + @override String get fullscreen => 'Schermo intero'; + @override String get exitFullscreen => 'Esci da schermo intero'; } // Path: screens @@ -1470,6 +1472,8 @@ extension on TranslationsIt { 'common.connectingToServers' => 'Connessione ai server...', 'common.startingOfflineMode' => 'Avvio modalità offline...', 'common.loading' => 'Caricamento...', + 'common.fullscreen' => 'Schermo intero', + 'common.exitFullscreen' => 'Esci da schermo intero', 'screens.licenses' => 'Licenze', 'screens.switchProfile' => 'Cambia profilo', 'screens.subtitleStyling' => 'Stile sottotitoli', @@ -1930,10 +1934,10 @@ extension on TranslationsIt { 'libraries.manageLibraries' => 'Gestisci librerie', 'libraries.sort' => 'Ordina', 'libraries.sortBy' => 'Ordina per', - 'libraries.filters' => 'Filtri', - 'libraries.confirmActionMessage' => 'Sei sicuro di voler eseguire questa azione?', _ => null, } ?? switch (path) { + 'libraries.filters' => 'Filtri', + 'libraries.confirmActionMessage' => 'Sei sicuro di voler eseguire questa azione?', 'libraries.showLibrary' => 'Mostra libreria', 'libraries.hideLibrary' => 'Nascondi libreria', 'libraries.libraryOptions' => 'Opzioni libreria', diff --git a/lib/i18n/strings_ja.g.dart b/lib/i18n/strings_ja.g.dart index 04fb7d7f..531da453 100644 --- a/lib/i18n/strings_ja.g.dart +++ b/lib/i18n/strings_ja.g.dart @@ -153,6 +153,8 @@ class _TranslationsCommonJa implements TranslationsCommonEn { @override String get connectingToServers => 'サーバーに接続中...'; @override String get startingOfflineMode => 'オフラインモードを開始中...'; @override String get loading => '読み込み中...'; + @override String get fullscreen => 'フルスクリーン'; + @override String get exitFullscreen => 'フルスクリーンを終了'; } // Path: screens @@ -1470,6 +1472,8 @@ extension on TranslationsJa { 'common.connectingToServers' => 'サーバーに接続中...', 'common.startingOfflineMode' => 'オフラインモードを開始中...', 'common.loading' => '読み込み中...', + 'common.fullscreen' => 'フルスクリーン', + 'common.exitFullscreen' => 'フルスクリーンを終了', 'screens.licenses' => 'ライセンス', 'screens.switchProfile' => 'プロフィール切替', 'screens.subtitleStyling' => '字幕スタイル', @@ -1930,10 +1934,10 @@ extension on TranslationsJa { 'libraries.manageLibraries' => 'ライブラリを管理', 'libraries.sort' => '並べ替え', 'libraries.sortBy' => '並べ替え順', - 'libraries.filters' => 'フィルター', - 'libraries.confirmActionMessage' => 'この操作を実行してもよろしいですか?', _ => null, } ?? switch (path) { + 'libraries.filters' => 'フィルター', + 'libraries.confirmActionMessage' => 'この操作を実行してもよろしいですか?', 'libraries.showLibrary' => 'ライブラリを表示', 'libraries.hideLibrary' => 'ライブラリを非表示', 'libraries.libraryOptions' => 'ライブラリオプション', diff --git a/lib/i18n/strings_ko.g.dart b/lib/i18n/strings_ko.g.dart index d1324566..e14e0058 100644 --- a/lib/i18n/strings_ko.g.dart +++ b/lib/i18n/strings_ko.g.dart @@ -153,6 +153,8 @@ class _TranslationsCommonKo implements TranslationsCommonEn { @override String get connectingToServers => '서버 연결 중...'; @override String get startingOfflineMode => '오프라인 모드 시작 중...'; @override String get loading => '로딩 중...'; + @override String get fullscreen => '전체화면'; + @override String get exitFullscreen => '전체화면 종료'; } // Path: screens @@ -1470,6 +1472,8 @@ extension on TranslationsKo { 'common.connectingToServers' => '서버 연결 중...', 'common.startingOfflineMode' => '오프라인 모드 시작 중...', 'common.loading' => '로딩 중...', + 'common.fullscreen' => '전체화면', + 'common.exitFullscreen' => '전체화면 종료', 'screens.licenses' => '라이선스', 'screens.switchProfile' => '프로필 전환', 'screens.subtitleStyling' => '자막 스타일 설정', @@ -1930,10 +1934,10 @@ extension on TranslationsKo { 'libraries.manageLibraries' => '미디어 라이브러리 관리', 'libraries.sort' => '정렬', 'libraries.sortBy' => '정렬 기준', - 'libraries.filters' => '필터', - 'libraries.confirmActionMessage' => '이 작업을 실행 하시겠습니까?', _ => null, } ?? switch (path) { + 'libraries.filters' => '필터', + 'libraries.confirmActionMessage' => '이 작업을 실행 하시겠습니까?', 'libraries.showLibrary' => '미디어 라이브러리 표시', 'libraries.hideLibrary' => '미디어 라이브러리 숨기기', 'libraries.libraryOptions' => '미디어 라이브러리 옵션', diff --git a/lib/i18n/strings_nb.g.dart b/lib/i18n/strings_nb.g.dart index 66fa1d20..84cf7722 100644 --- a/lib/i18n/strings_nb.g.dart +++ b/lib/i18n/strings_nb.g.dart @@ -153,6 +153,8 @@ class _TranslationsCommonNb implements TranslationsCommonEn { @override String get connectingToServers => 'Kobler til servere...'; @override String get startingOfflineMode => 'Starter frakoblet modus...'; @override String get loading => 'Laster...'; + @override String get fullscreen => 'Fullskjerm'; + @override String get exitFullscreen => 'Avslutt fullskjerm'; } // Path: screens @@ -1470,6 +1472,8 @@ extension on TranslationsNb { 'common.connectingToServers' => 'Kobler til servere...', 'common.startingOfflineMode' => 'Starter frakoblet modus...', 'common.loading' => 'Laster...', + 'common.fullscreen' => 'Fullskjerm', + 'common.exitFullscreen' => 'Avslutt fullskjerm', 'screens.licenses' => 'Lisenser', 'screens.switchProfile' => 'Bytt profil', 'screens.subtitleStyling' => 'Undertekststil', @@ -1930,10 +1934,10 @@ extension on TranslationsNb { 'libraries.manageLibraries' => 'Administrer biblioteker', 'libraries.sort' => 'Sorter', 'libraries.sortBy' => 'Sorter etter', - 'libraries.filters' => 'Filtre', - 'libraries.confirmActionMessage' => 'Er du sikker på at du vil utføre denne handlingen?', _ => null, } ?? switch (path) { + 'libraries.filters' => 'Filtre', + 'libraries.confirmActionMessage' => 'Er du sikker på at du vil utføre denne handlingen?', 'libraries.showLibrary' => 'Vis bibliotek', 'libraries.hideLibrary' => 'Skjul bibliotek', 'libraries.libraryOptions' => 'Bibliotekalternativer', diff --git a/lib/i18n/strings_nl.g.dart b/lib/i18n/strings_nl.g.dart index 91dcdff0..a1875c6f 100644 --- a/lib/i18n/strings_nl.g.dart +++ b/lib/i18n/strings_nl.g.dart @@ -153,6 +153,8 @@ class _TranslationsCommonNl implements TranslationsCommonEn { @override String get connectingToServers => 'Verbinden met servers...'; @override String get startingOfflineMode => 'Offlinemodus starten...'; @override String get loading => 'Laden...'; + @override String get fullscreen => 'Volledig scherm'; + @override String get exitFullscreen => 'Volledig scherm verlaten'; } // Path: screens @@ -1470,6 +1472,8 @@ extension on TranslationsNl { 'common.connectingToServers' => 'Verbinden met servers...', 'common.startingOfflineMode' => 'Offlinemodus starten...', 'common.loading' => 'Laden...', + 'common.fullscreen' => 'Volledig scherm', + 'common.exitFullscreen' => 'Volledig scherm verlaten', 'screens.licenses' => 'Licenties', 'screens.switchProfile' => 'Wissel van profiel', 'screens.subtitleStyling' => 'Ondertitel opmaak', @@ -1930,10 +1934,10 @@ extension on TranslationsNl { 'libraries.manageLibraries' => 'Beheer bibliotheken', 'libraries.sort' => 'Sorteren', 'libraries.sortBy' => 'Sorteer op', - 'libraries.filters' => 'Filters', - 'libraries.confirmActionMessage' => 'Weet je zeker dat je deze actie wilt uitvoeren?', _ => null, } ?? switch (path) { + 'libraries.filters' => 'Filters', + 'libraries.confirmActionMessage' => 'Weet je zeker dat je deze actie wilt uitvoeren?', 'libraries.showLibrary' => 'Toon bibliotheek', 'libraries.hideLibrary' => 'Verberg bibliotheek', 'libraries.libraryOptions' => 'Bibliotheek opties', diff --git a/lib/i18n/strings_pl.g.dart b/lib/i18n/strings_pl.g.dart index b82fc50e..8d1fb897 100644 --- a/lib/i18n/strings_pl.g.dart +++ b/lib/i18n/strings_pl.g.dart @@ -153,6 +153,8 @@ class _TranslationsCommonPl implements TranslationsCommonEn { @override String get connectingToServers => 'Łączenie z serwerami...'; @override String get startingOfflineMode => 'Uruchamianie trybu offline...'; @override String get loading => 'Ładowanie...'; + @override String get fullscreen => 'Pełny ekran'; + @override String get exitFullscreen => 'Wyjdź z pełnego ekranu'; } // Path: screens @@ -1470,6 +1472,8 @@ extension on TranslationsPl { 'common.connectingToServers' => 'Łączenie z serwerami...', 'common.startingOfflineMode' => 'Uruchamianie trybu offline...', 'common.loading' => 'Ładowanie...', + 'common.fullscreen' => 'Pełny ekran', + 'common.exitFullscreen' => 'Wyjdź z pełnego ekranu', 'screens.licenses' => 'Licencje', 'screens.switchProfile' => 'Zmień profil', 'screens.subtitleStyling' => 'Styl napisów', @@ -1930,10 +1934,10 @@ extension on TranslationsPl { 'libraries.manageLibraries' => 'Zarządzaj bibliotekami', 'libraries.sort' => 'Sortuj', 'libraries.sortBy' => 'Sortuj wg', - 'libraries.filters' => 'Filtry', - 'libraries.confirmActionMessage' => 'Czy na pewno chcesz wykonać tę operację?', _ => null, } ?? switch (path) { + 'libraries.filters' => 'Filtry', + 'libraries.confirmActionMessage' => 'Czy na pewno chcesz wykonać tę operację?', 'libraries.showLibrary' => 'Pokaż bibliotekę', 'libraries.hideLibrary' => 'Ukryj bibliotekę', 'libraries.libraryOptions' => 'Opcje biblioteki', diff --git a/lib/i18n/strings_pt.g.dart b/lib/i18n/strings_pt.g.dart index 3a08a0a9..21c67138 100644 --- a/lib/i18n/strings_pt.g.dart +++ b/lib/i18n/strings_pt.g.dart @@ -153,6 +153,8 @@ class _TranslationsCommonPt implements TranslationsCommonEn { @override String get connectingToServers => 'Conectando aos servidores...'; @override String get startingOfflineMode => 'Iniciando modo offline...'; @override String get loading => 'Carregando...'; + @override String get fullscreen => 'Tela cheia'; + @override String get exitFullscreen => 'Sair da tela cheia'; } // Path: screens @@ -1470,6 +1472,8 @@ extension on TranslationsPt { 'common.connectingToServers' => 'Conectando aos servidores...', 'common.startingOfflineMode' => 'Iniciando modo offline...', 'common.loading' => 'Carregando...', + 'common.fullscreen' => 'Tela cheia', + 'common.exitFullscreen' => 'Sair da tela cheia', 'screens.licenses' => 'Licenças', 'screens.switchProfile' => 'Trocar Perfil', 'screens.subtitleStyling' => 'Estilo de Legendas', @@ -1930,10 +1934,10 @@ extension on TranslationsPt { 'libraries.manageLibraries' => 'Gerenciar Bibliotecas', 'libraries.sort' => 'Ordenar', 'libraries.sortBy' => 'Ordenar Por', - 'libraries.filters' => 'Filtros', - 'libraries.confirmActionMessage' => 'Tem certeza que deseja realizar esta ação?', _ => null, } ?? switch (path) { + 'libraries.filters' => 'Filtros', + 'libraries.confirmActionMessage' => 'Tem certeza que deseja realizar esta ação?', 'libraries.showLibrary' => 'Mostrar biblioteca', 'libraries.hideLibrary' => 'Ocultar biblioteca', 'libraries.libraryOptions' => 'Opções da biblioteca', diff --git a/lib/i18n/strings_ru.g.dart b/lib/i18n/strings_ru.g.dart index 74c3b185..4b7e5564 100644 --- a/lib/i18n/strings_ru.g.dart +++ b/lib/i18n/strings_ru.g.dart @@ -153,6 +153,8 @@ class _TranslationsCommonRu implements TranslationsCommonEn { @override String get connectingToServers => 'Подключение к серверам...'; @override String get startingOfflineMode => 'Запуск автономного режима...'; @override String get loading => 'Загрузка...'; + @override String get fullscreen => 'Полноэкранный режим'; + @override String get exitFullscreen => 'Выйти из полноэкранного режима'; } // Path: screens @@ -1470,6 +1472,8 @@ extension on TranslationsRu { 'common.connectingToServers' => 'Подключение к серверам...', 'common.startingOfflineMode' => 'Запуск автономного режима...', 'common.loading' => 'Загрузка...', + 'common.fullscreen' => 'Полноэкранный режим', + 'common.exitFullscreen' => 'Выйти из полноэкранного режима', 'screens.licenses' => 'Лицензии', 'screens.switchProfile' => 'Сменить профиль', 'screens.subtitleStyling' => 'Стиль субтитров', @@ -1930,10 +1934,10 @@ extension on TranslationsRu { 'libraries.manageLibraries' => 'Управление библиотеками', 'libraries.sort' => 'Сортировка', 'libraries.sortBy' => 'Сортировать по', - 'libraries.filters' => 'Фильтры', - 'libraries.confirmActionMessage' => 'Вы уверены, что хотите выполнить это действие?', _ => null, } ?? switch (path) { + 'libraries.filters' => 'Фильтры', + 'libraries.confirmActionMessage' => 'Вы уверены, что хотите выполнить это действие?', 'libraries.showLibrary' => 'Показать библиотеку', 'libraries.hideLibrary' => 'Скрыть библиотеку', 'libraries.libraryOptions' => 'Параметры библиотеки', diff --git a/lib/i18n/strings_sv.g.dart b/lib/i18n/strings_sv.g.dart index 74daf1b7..dd1d38a9 100644 --- a/lib/i18n/strings_sv.g.dart +++ b/lib/i18n/strings_sv.g.dart @@ -153,6 +153,8 @@ class _TranslationsCommonSv implements TranslationsCommonEn { @override String get connectingToServers => 'Ansluter till servrar...'; @override String get startingOfflineMode => 'Startar offlineläge...'; @override String get loading => 'Laddar...'; + @override String get fullscreen => 'Helskärm'; + @override String get exitFullscreen => 'Avsluta helskärm'; } // Path: screens @@ -1470,6 +1472,8 @@ extension on TranslationsSv { 'common.connectingToServers' => 'Ansluter till servrar...', 'common.startingOfflineMode' => 'Startar offlineläge...', 'common.loading' => 'Laddar...', + 'common.fullscreen' => 'Helskärm', + 'common.exitFullscreen' => 'Avsluta helskärm', 'screens.licenses' => 'Licenser', 'screens.switchProfile' => 'Byt profil', 'screens.subtitleStyling' => 'Undertext-styling', @@ -1930,10 +1934,10 @@ extension on TranslationsSv { 'libraries.manageLibraries' => 'Hantera bibliotek', 'libraries.sort' => 'Sortera', 'libraries.sortBy' => 'Sortera efter', - 'libraries.filters' => 'Filter', - 'libraries.confirmActionMessage' => 'Är du säker på att du vill utföra denna åtgärd?', _ => null, } ?? switch (path) { + 'libraries.filters' => 'Filter', + 'libraries.confirmActionMessage' => 'Är du säker på att du vill utföra denna åtgärd?', 'libraries.showLibrary' => 'Visa bibliotek', 'libraries.hideLibrary' => 'Dölj bibliotek', 'libraries.libraryOptions' => 'Biblioteksalternativ', diff --git a/lib/i18n/strings_zh.g.dart b/lib/i18n/strings_zh.g.dart index 10991f49..efa5da2c 100644 --- a/lib/i18n/strings_zh.g.dart +++ b/lib/i18n/strings_zh.g.dart @@ -153,6 +153,8 @@ class _TranslationsCommonZh implements TranslationsCommonEn { @override String get connectingToServers => '正在连接服务器...'; @override String get startingOfflineMode => '正在启动离线模式...'; @override String get loading => '加载中...'; + @override String get fullscreen => '全屏'; + @override String get exitFullscreen => '退出全屏'; } // Path: screens @@ -1470,6 +1472,8 @@ extension on TranslationsZh { 'common.connectingToServers' => '正在连接服务器...', 'common.startingOfflineMode' => '正在启动离线模式...', 'common.loading' => '加载中...', + 'common.fullscreen' => '全屏', + 'common.exitFullscreen' => '退出全屏', 'screens.licenses' => '许可证', 'screens.switchProfile' => '切换用户', 'screens.subtitleStyling' => '字幕样式', @@ -1930,10 +1934,10 @@ extension on TranslationsZh { 'libraries.manageLibraries' => '管理媒体库', 'libraries.sort' => '排序', 'libraries.sortBy' => '排序依据', - 'libraries.filters' => '筛选器', - 'libraries.confirmActionMessage' => '确定要执行此操作吗?', _ => null, } ?? switch (path) { + 'libraries.filters' => '筛选器', + 'libraries.confirmActionMessage' => '确定要执行此操作吗?', 'libraries.showLibrary' => '显示媒体库', 'libraries.hideLibrary' => '隐藏媒体库', 'libraries.libraryOptions' => '媒体库选项', diff --git a/lib/i18n/sv.i18n.json b/lib/i18n/sv.i18n.json index eab202b4..9cabcd0e 100644 --- a/lib/i18n/sv.i18n.json +++ b/lib/i18n/sv.i18n.json @@ -53,7 +53,9 @@ "loadingServers": "Laddar servrar...", "connectingToServers": "Ansluter till servrar...", "startingOfflineMode": "Startar offlineläge...", - "loading": "Laddar..." + "loading": "Laddar...", + "fullscreen": "Helskärm", + "exitFullscreen": "Avsluta helskärm" }, "screens": { "licenses": "Licenser", diff --git a/lib/i18n/zh.i18n.json b/lib/i18n/zh.i18n.json index d93ce92c..b67911c2 100644 --- a/lib/i18n/zh.i18n.json +++ b/lib/i18n/zh.i18n.json @@ -53,7 +53,9 @@ "loadingServers": "正在加载服务器...", "connectingToServers": "正在连接服务器...", "startingOfflineMode": "正在启动离线模式...", - "loading": "加载中..." + "loading": "加载中...", + "fullscreen": "全屏", + "exitFullscreen": "退出全屏" }, "screens": { "licenses": "许可证", diff --git a/lib/screens/main_screen.dart b/lib/screens/main_screen.dart index 59e1289d..17c5398e 100644 --- a/lib/screens/main_screen.dart +++ b/lib/screens/main_screen.dart @@ -35,6 +35,7 @@ import '../providers/offline_mode_provider.dart'; import '../services/plex_auth_service.dart'; import '../services/storage_service.dart'; import '../services/companion_remote/companion_remote_receiver.dart'; +import '../services/fullscreen_state_manager.dart'; import '../providers/companion_remote_provider.dart'; import '../utils/desktop_window_padding.dart'; import '../widgets/side_navigation_rail.dart'; @@ -699,6 +700,18 @@ class _MainScreenState extends State with RouteAware, WindowListener }); } + /// F11 toggles OS fullscreen from anywhere in the main UI. The in-player + /// hotkey (default `f`) only works while the player is mounted; this is + /// the escape hatch when fullscreen persists after the player closes. + KeyEventResult _handleFullscreenShortcut(KeyEvent event) { + if (event is! KeyDownEvent) return KeyEventResult.ignored; + if (event.logicalKey != LogicalKeyboardKey.f11) return KeyEventResult.ignored; + if (!PlatformDetector.isDesktopOS()) return KeyEventResult.ignored; + + unawaited(FullscreenStateManager().toggleFullscreen()); + return KeyEventResult.handled; + } + /// Handle Cmd+F (macOS) / Ctrl+F (Windows/Linux) to navigate to search. KeyEventResult _handleSearchShortcut(KeyEvent event) { if (event is! KeyDownEvent) return KeyEventResult.ignored; @@ -940,6 +953,8 @@ class _MainScreenState extends State with RouteAware, WindowListener onPopInvokedWithResult: (didPop, result) {}, child: Focus( onKeyEvent: (node, event) { + final fullscreenResult = _handleFullscreenShortcut(event); + if (fullscreenResult == KeyEventResult.handled) return fullscreenResult; final searchResult = _handleSearchShortcut(event); if (searchResult == KeyEventResult.handled) return searchResult; return _handleBackKey(event); diff --git a/lib/screens/video_player_screen.dart b/lib/screens/video_player_screen.dart index 1a890603..4684a987 100644 --- a/lib/screens/video_player_screen.dart +++ b/lib/screens/video_player_screen.dart @@ -12,7 +12,6 @@ import 'package:os_media_controls/os_media_controls.dart'; import 'package:provider/provider.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:wakelock_plus/wakelock_plus.dart'; -import 'package:window_manager/window_manager.dart'; import '../mpv/mpv.dart'; import '../mpv/player/platform/player_android.dart'; @@ -2150,19 +2149,6 @@ class VideoPlayerScreenState extends State with WidgetsBindin await FullscreenStateManager().toggleFullscreen(); } - /// Exit fullscreen before leaving the player (Windows/Linux only). - /// macOS is excluded because we can't distinguish native fullscreen - /// from maximized state, so we leave the window state unchanged. - Future _exitFullscreenIfNeeded() async { - if (Platform.isWindows || Platform.isLinux) { - final isFullscreen = await windowManager.isFullScreen(); - if (isFullscreen) { - await FullscreenStateManager().exitFullscreen(); - await Future.delayed(const Duration(milliseconds: 100)); - } - } - } - /// Handle back button press /// For non-host participants in Watch Together, shows leave session confirmation Future _handleBackButton() async { @@ -2182,8 +2168,6 @@ class VideoPlayerScreenState extends State with WidgetsBindin if (confirmed && mounted) { await _watchTogetherProvider!.leaveSession(); if (mounted) { - await _exitFullscreenIfNeeded(); - if (!mounted) return; final navigator = Navigator.of(context); if (navigator.canPop()) { _isExiting.value = true; @@ -2194,8 +2178,6 @@ class VideoPlayerScreenState extends State with WidgetsBindin return; } - await _exitFullscreenIfNeeded(); - // Default behavior for hosts or non-session users if (!mounted) return; final navigator = Navigator.of(context); diff --git a/lib/services/fullscreen_state_manager.dart b/lib/services/fullscreen_state_manager.dart index 26a1c659..306fb64c 100644 --- a/lib/services/fullscreen_state_manager.dart +++ b/lib/services/fullscreen_state_manager.dart @@ -1,6 +1,7 @@ import 'dart:io' show Platform; import 'package:flutter/foundation.dart'; import 'package:window_manager/window_manager.dart'; +import '../utils/platform_detector.dart'; import 'macos_window_service.dart'; import 'native_window_service.dart'; @@ -96,7 +97,7 @@ class FullscreenStateManager extends ChangeNotifier with WindowListener { } bool _shouldMonitor() { - return Platform.isMacOS || Platform.isWindows || Platform.isLinux; + return PlatformDetector.isDesktopOS(); } // WindowListener callbacks for Windows/Linux diff --git a/lib/services/keyboard_shortcuts_service.dart b/lib/services/keyboard_shortcuts_service.dart index 5cf6b7f0..9c1d5130 100644 --- a/lib/services/keyboard_shortcuts_service.dart +++ b/lib/services/keyboard_shortcuts_service.dart @@ -7,6 +7,7 @@ import '../models/hotkey_model.dart'; import '../i18n/strings.g.dart'; import '../mpv/mpv.dart'; import 'settings_service.dart'; +import '../utils/platform_detector.dart'; import '../utils/player_utils.dart'; class KeyboardShortcutsService { @@ -30,7 +31,7 @@ class KeyboardShortcutsService { /// Keyboard shortcut customization is only supported on desktop platforms. static bool isPlatformSupported() { - return Platform.isWindows || Platform.isLinux || Platform.isMacOS; + return PlatformDetector.isDesktopOS(); } Future _init() async { diff --git a/lib/utils/platform_detector.dart b/lib/utils/platform_detector.dart index 5015f3d8..bfefc65c 100644 --- a/lib/utils/platform_detector.dart +++ b/lib/utils/platform_detector.dart @@ -88,6 +88,13 @@ class PlatformDetector { return !isMobile(context); } + /// True on the desktop OS (Windows / macOS / Linux), without needing a + /// BuildContext. Use for OS-level capability checks (window state, native + /// keyboard, etc.); use [isDesktop] for layout decisions. + static bool isDesktopOS() { + return Platform.isWindows || Platform.isMacOS || Platform.isLinux; + } + /// Detects if the device is likely a tablet based on screen size /// Uses diagonal screen size to determine if device is a tablet static bool isTablet(BuildContext context) { diff --git a/lib/widgets/side_navigation_rail.dart b/lib/widgets/side_navigation_rail.dart index dec4b15d..ab2ed86e 100644 --- a/lib/widgets/side_navigation_rail.dart +++ b/lib/widgets/side_navigation_rail.dart @@ -179,6 +179,7 @@ class SideNavigationRailState extends State { static const _kDownloads = 'downloads'; static const _kSettings = 'settings'; static const _kReconnect = 'reconnect'; + static const _kFullscreen = 'fullscreen'; // Unified focus state tracker for all nav items (main + libraries) late final FocusMemoryTracker _focusTracker; @@ -186,6 +187,9 @@ class SideNavigationRailState extends State { /// Whether the sidebar should be expanded (always, hover, or focus) bool get _shouldExpand => widget.alwaysExpanded || _isHovered || _isTouchExpanded || widget.isSidebarFocused; + /// macOS has the system green button; mobile/TV have no OS fullscreen toggle. + bool get _showFullscreenToggle => Platform.isWindows || Platform.isLinux; + @override void initState() { super.initState(); @@ -257,6 +261,7 @@ class SideNavigationRailState extends State { _kDownloads, _kSettings, _kReconnect, + if (_showFullscreenToggle) _kFullscreen, 'liveTv', ...libraries.map((lib) => lib.globalKey), }; @@ -275,6 +280,7 @@ class SideNavigationRailState extends State { ], _kDownloads, _kSettings, + if (_showFullscreenToggle) _kFullscreen, ]; } @@ -498,6 +504,12 @@ class SideNavigationRailState extends State { ], ), ), + + if (_showFullscreenToggle) + Padding( + padding: const EdgeInsets.fromLTRB(12, 0, 12, 12), + child: _buildFullscreenItem(isCollapsed: isCollapsed), + ), ], ), ), @@ -570,6 +582,28 @@ class SideNavigationRailState extends State { ); } + Widget _buildFullscreenItem({required bool isCollapsed}) { + final t = tokens(context); + final isFullscreen = FullscreenStateManager().isFullscreen; + final isFocused = _focusTracker.isFocused(_kFullscreen); + + return NavigationRailItem( + icon: isFullscreen ? Symbols.fullscreen_exit_rounded : Symbols.fullscreen_rounded, + label: Text( + isFullscreen ? Translations.of(context).common.exitFullscreen : Translations.of(context).common.fullscreen, + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w400, color: t.textMuted), + overflow: TextOverflow.ellipsis, + maxLines: 1, + ), + isSelected: false, + isFocused: isFocused, + isCollapsed: isCollapsed, + onTap: () => unawaited(FullscreenStateManager().toggleFullscreen()), + focusNode: _focusTracker.get(_kFullscreen), + onNavigateRight: widget.onNavigateToContent, + ); + } + Widget _buildLibrariesSection(List visibleLibraries, dynamic t, {bool isCollapsed = false}) { final librariesProvider = context.watch(); final isLoading = librariesProvider.isLoading; diff --git a/slang.yaml b/slang.yaml new file mode 100644 index 00000000..b4014882 --- /dev/null +++ b/slang.yaml @@ -0,0 +1,3 @@ +input_directory: lib/i18n +input_file_pattern: .i18n.json +output_directory: lib/i18n