feat: global fullscreen toggle (F11 + sidebar)

close #907
This commit is contained in:
edde746
2026-04-23 07:43:46 +02:00
parent 1e54344ec3
commit ca5d87143b
38 changed files with 204 additions and 67 deletions
+3 -1
View File
@@ -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",
+3 -1
View File
@@ -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",
+3 -1
View File
@@ -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",
+3 -1
View File
@@ -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",
+3 -1
View File
@@ -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",
+3 -1
View File
@@ -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",
+3 -1
View File
@@ -53,7 +53,9 @@
"loadingServers": "サーバーを読み込み中...",
"connectingToServers": "サーバーに接続中...",
"startingOfflineMode": "オフラインモードを開始中...",
"loading": "読み込み中..."
"loading": "読み込み中...",
"fullscreen": "フルスクリーン",
"exitFullscreen": "フルスクリーンを終了"
},
"screens": {
"licenses": "ライセンス",
+3 -1
View File
@@ -53,7 +53,9 @@
"loadingServers": "서버 로딩 중...",
"connectingToServers": "서버 연결 중...",
"startingOfflineMode": "오프라인 모드 시작 중...",
"loading": "로딩 중..."
"loading": "로딩 중...",
"fullscreen": "전체화면",
"exitFullscreen": "전체화면 종료"
},
"screens": {
"licenses": "라이선스",
+3 -1
View File
@@ -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",
+3 -1
View File
@@ -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",
+3 -1
View File
@@ -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",
+3 -1
View File
@@ -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",
+3 -1
View File
@@ -53,7 +53,9 @@
"loadingServers": "Загрузка серверов...",
"connectingToServers": "Подключение к серверам...",
"startingOfflineMode": "Запуск автономного режима...",
"loading": "Загрузка..."
"loading": "Загрузка...",
"fullscreen": "Полноэкранный режим",
"exitFullscreen": "Выйти из полноэкранного режима"
},
"screens": {
"licenses": "Лицензии",
+2 -2
View File
@@ -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
+6 -2
View File
@@ -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',
+6 -2
View File
@@ -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',
+10 -2
View File
@@ -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',
+6 -2
View File
@@ -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',
+6 -2
View File
@@ -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',
+6 -2
View File
@@ -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',
+6 -2
View File
@@ -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' => 'ライブラリオプション',
+6 -2
View File
@@ -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' => '미디어 라이브러리 옵션',
+6 -2
View File
@@ -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',
+6 -2
View File
@@ -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',
+6 -2
View File
@@ -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',
+6 -2
View File
@@ -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',
+6 -2
View File
@@ -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' => 'Параметры библиотеки',
+6 -2
View File
@@ -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',
+6 -2
View File
@@ -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' => '媒体库选项',
+3 -1
View File
@@ -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",
+3 -1
View File
@@ -53,7 +53,9 @@
"loadingServers": "正在加载服务器...",
"connectingToServers": "正在连接服务器...",
"startingOfflineMode": "正在启动离线模式...",
"loading": "加载中..."
"loading": "加载中...",
"fullscreen": "全屏",
"exitFullscreen": "退出全屏"
},
"screens": {
"licenses": "许可证",
+15
View File
@@ -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<MainScreen> 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<MainScreen> 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);
-18
View File
@@ -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<VideoPlayerScreen> 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<void> _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<void> _handleBackButton() async {
@@ -2182,8 +2168,6 @@ class VideoPlayerScreenState extends State<VideoPlayerScreen> 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<VideoPlayerScreen> with WidgetsBindin
return;
}
await _exitFullscreenIfNeeded();
// Default behavior for hosts or non-session users
if (!mounted) return;
final navigator = Navigator.of(context);
+2 -1
View File
@@ -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
+2 -1
View File
@@ -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<void> _init() async {
+7
View File
@@ -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) {
+34
View File
@@ -179,6 +179,7 @@ class SideNavigationRailState extends State<SideNavigationRail> {
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<SideNavigationRail> {
/// 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<SideNavigationRail> {
_kDownloads,
_kSettings,
_kReconnect,
if (_showFullscreenToggle) _kFullscreen,
'liveTv',
...libraries.map((lib) => lib.globalKey),
};
@@ -275,6 +280,7 @@ class SideNavigationRailState extends State<SideNavigationRail> {
],
_kDownloads,
_kSettings,
if (_showFullscreenToggle) _kFullscreen,
];
}
@@ -498,6 +504,12 @@ class SideNavigationRailState extends State<SideNavigationRail> {
],
),
),
if (_showFullscreenToggle)
Padding(
padding: const EdgeInsets.fromLTRB(12, 0, 12, 12),
child: _buildFullscreenItem(isCollapsed: isCollapsed),
),
],
),
),
@@ -570,6 +582,28 @@ class SideNavigationRailState extends State<SideNavigationRail> {
);
}
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<PlexLibrary> visibleLibraries, dynamic t, {bool isCollapsed = false}) {
final librariesProvider = context.watch<LibrariesProvider>();
final isLoading = librariesProvider.isLoading;
+3
View File
@@ -0,0 +1,3 @@
input_directory: lib/i18n
input_file_pattern: .i18n.json
output_directory: lib/i18n