diff --git a/lib/i18n/da.i18n.json b/lib/i18n/da.i18n.json index 3c001e04..78241441 100644 --- a/lib/i18n/da.i18n.json +++ b/lib/i18n/da.i18n.json @@ -300,7 +300,8 @@ "subSeekNext": "Søg til næste undertekst", "subSeekPrev": "Søg til forrige undertekst", "shaderToggle": "Skift shadere", - "skipMarker": "Spring intro/rulletekster over" + "skipMarker": "Spring intro/rulletekster over", + "screenshot": "Tag skærmbillede" } }, "fileInfo": { @@ -433,6 +434,7 @@ "endsAt": "Slutter kl. ${time}", "pipActive": "Afspiller i billede-i-billede", "pipFailed": "Billede-i-billede kunne ikke starte", + "screenshotSaved": "Skærmbillede gemt", "pipErrors": { "androidVersion": "Kræver Android 8.0 eller nyere", "iosVersion": "Kræver iOS 15.0 eller nyere", diff --git a/lib/i18n/de.i18n.json b/lib/i18n/de.i18n.json index ba180b02..944c658c 100644 --- a/lib/i18n/de.i18n.json +++ b/lib/i18n/de.i18n.json @@ -300,7 +300,8 @@ "subSeekNext": "Zum nächsten Untertitel springen", "subSeekPrev": "Zum vorherigen Untertitel springen", "shaderToggle": "Shader umschalten", - "skipMarker": "Intro/Abspann überspringen" + "skipMarker": "Intro/Abspann überspringen", + "screenshot": "Screenshot aufnehmen" } }, "fileInfo": { @@ -433,6 +434,7 @@ "endsAt": "Endet um ${time}", "pipActive": "Wiedergabe im Bild-in-Bild-Modus", "pipFailed": "Bild-in-Bild konnte nicht gestartet werden", + "screenshotSaved": "Screenshot gespeichert", "pipErrors": { "androidVersion": "Erfordert Android 8.0 oder neuer", "iosVersion": "Erfordert iOS 15.0 oder neuer", diff --git a/lib/i18n/en.i18n.json b/lib/i18n/en.i18n.json index c038fe9f..c70b8fb9 100644 --- a/lib/i18n/en.i18n.json +++ b/lib/i18n/en.i18n.json @@ -300,7 +300,8 @@ "subSeekNext": "Seek to Next Subtitle", "subSeekPrev": "Seek to Previous Subtitle", "shaderToggle": "Toggle Shaders", - "skipMarker": "Skip Intro/Credits" + "skipMarker": "Skip Intro/Credits", + "screenshot": "Take Screenshot" } }, "fileInfo": { @@ -433,6 +434,7 @@ "endsAt": "Ends at ${time}", "pipActive": "Playing in Picture-in-Picture", "pipFailed": "Picture-in-picture failed to start", + "screenshotSaved": "Screenshot saved", "pipErrors": { "androidVersion": "Requires Android 8.0 or newer", "iosVersion": "Requires iOS 15.0 or newer", diff --git a/lib/i18n/es.i18n.json b/lib/i18n/es.i18n.json index f5b4593e..6444aa4a 100644 --- a/lib/i18n/es.i18n.json +++ b/lib/i18n/es.i18n.json @@ -300,7 +300,8 @@ "subSeekNext": "Ir al Siguiente Subtítulo", "subSeekPrev": "Ir al Anterior Subtítulo", "shaderToggle": "Alternar Shaders", - "skipMarker": "Saltar Intro/Créditos" + "skipMarker": "Saltar Intro/Créditos", + "screenshot": "Tomar captura de pantalla" } }, "fileInfo": { @@ -433,6 +434,7 @@ "endsAt": "Termina a las ${time}", "pipActive": "Reproduciendo en Imagen en Imagen", "pipFailed": "Error al iniciar Imagen en Imagen", + "screenshotSaved": "Captura de pantalla guardada", "pipErrors": { "androidVersion": "Requiere Android 8.0 o más reciente", "iosVersion": "Requiere iOS 15.0 o más reciente", diff --git a/lib/i18n/fr.i18n.json b/lib/i18n/fr.i18n.json index a0e36b41..a4f2b115 100644 --- a/lib/i18n/fr.i18n.json +++ b/lib/i18n/fr.i18n.json @@ -300,7 +300,8 @@ "subSeekNext": "Rechercher le sous-titre suivant", "subSeekPrev": "Rechercher le sous-titre précédent", "shaderToggle": "Activer/désactiver les shaders", - "skipMarker": "Passer l'intro/le générique" + "skipMarker": "Passer l'intro/le générique", + "screenshot": "Prendre une capture d'écran" } }, "fileInfo": { @@ -433,6 +434,7 @@ "endsAt": "Fin à ${time}", "pipActive": "Lecture en mode image dans l'image", "pipFailed": "Échec du démarrage du mode image dans l'image", + "screenshotSaved": "Capture d'écran enregistrée", "pipErrors": { "androidVersion": "Nécessite Android 8.0 ou plus récent", "iosVersion": "Nécessite iOS 15.0 ou plus récent", diff --git a/lib/i18n/it.i18n.json b/lib/i18n/it.i18n.json index 515bda73..761f8f5e 100644 --- a/lib/i18n/it.i18n.json +++ b/lib/i18n/it.i18n.json @@ -300,7 +300,8 @@ "subSeekNext": "Vai al sottotitolo successivo", "subSeekPrev": "Vai al sottotitolo precedente", "shaderToggle": "Attiva/disattiva shader", - "skipMarker": "Salta intro/titoli di coda" + "skipMarker": "Salta intro/titoli di coda", + "screenshot": "Cattura schermata" } }, "fileInfo": { @@ -433,6 +434,7 @@ "endsAt": "Finisce alle ${time}", "pipActive": "Riproduzione in Picture-in-Picture", "pipFailed": "Impossibile avviare la modalità Picture-in-Picture", + "screenshotSaved": "Schermata salvata", "pipErrors": { "androidVersion": "Richiede Android 8.0 o versioni successive", "iosVersion": "Richiede iOS 15.0 o versioni successive", diff --git a/lib/i18n/ja.i18n.json b/lib/i18n/ja.i18n.json index 4e87bf7b..a39916c8 100644 --- a/lib/i18n/ja.i18n.json +++ b/lib/i18n/ja.i18n.json @@ -300,7 +300,8 @@ "subSeekNext": "次の字幕にシーク", "subSeekPrev": "前の字幕にシーク", "shaderToggle": "シェーダー切替", - "skipMarker": "イントロ/クレジットをスキップ" + "skipMarker": "イントロ/クレジットをスキップ", + "screenshot": "スクリーンショットを撮る" } }, "fileInfo": { @@ -433,6 +434,7 @@ "endsAt": "${time}に終了", "pipActive": "ピクチャーインピクチャーで再生中", "pipFailed": "ピクチャーインピクチャーの開始に失敗しました", + "screenshotSaved": "スクリーンショットを保存しました", "pipErrors": { "androidVersion": "Android 8.0以降が必要です", "iosVersion": "iOS 15.0以降が必要です", diff --git a/lib/i18n/ko.i18n.json b/lib/i18n/ko.i18n.json index 714be94b..0a905ec8 100644 --- a/lib/i18n/ko.i18n.json +++ b/lib/i18n/ko.i18n.json @@ -300,7 +300,8 @@ "subSeekNext": "다음 자막으로 이동", "subSeekPrev": "이전 자막으로 이동", "shaderToggle": "셰이더 전환", - "skipMarker": "인트로/크레딧 건너뛰기" + "skipMarker": "인트로/크레딧 건너뛰기", + "screenshot": "스크린샷 찍기" } }, "fileInfo": { @@ -433,6 +434,7 @@ "endsAt": "${time}에 종료", "pipActive": "화면 속 화면으로 재생 중", "pipFailed": "화면 속 화면 모드를 시작할 수 없습니다", + "screenshotSaved": "스크린샷 저장됨", "pipErrors": { "androidVersion": "Android 8.0 이상이 필요합니다", "iosVersion": "iOS 15.0 이상이 필요합니다", diff --git a/lib/i18n/nb.i18n.json b/lib/i18n/nb.i18n.json index 17316e08..70e2d163 100644 --- a/lib/i18n/nb.i18n.json +++ b/lib/i18n/nb.i18n.json @@ -300,7 +300,8 @@ "subSeekNext": "Spol til neste undertekst", "subSeekPrev": "Spol til forrige undertekst", "shaderToggle": "Veksle shadere", - "skipMarker": "Hopp over intro/rulletekst" + "skipMarker": "Hopp over intro/rulletekst", + "screenshot": "Ta skjermbilde" } }, "fileInfo": { @@ -433,6 +434,7 @@ "endsAt": "Slutter kl. ${time}", "pipActive": "Spiller i bilde-i-bilde", "pipFailed": "Bilde-i-bilde kunne ikke starte", + "screenshotSaved": "Skjermbilde lagret", "pipErrors": { "androidVersion": "Krever Android 8.0 eller nyere", "iosVersion": "Krever iOS 15.0 eller nyere", diff --git a/lib/i18n/nl.i18n.json b/lib/i18n/nl.i18n.json index d8614864..5244e98c 100644 --- a/lib/i18n/nl.i18n.json +++ b/lib/i18n/nl.i18n.json @@ -300,7 +300,8 @@ "subSeekNext": "Naar volgende ondertitel", "subSeekPrev": "Naar vorige ondertitel", "shaderToggle": "Shaders aan/uit", - "skipMarker": "Intro/aftiteling overslaan" + "skipMarker": "Intro/aftiteling overslaan", + "screenshot": "Schermafbeelding maken" } }, "fileInfo": { @@ -433,6 +434,7 @@ "endsAt": "Eindigt om ${time}", "pipActive": "Afspelen in beeld-in-beeld", "pipFailed": "Beeld-in-beeld kon niet worden gestart", + "screenshotSaved": "Schermafbeelding opgeslagen", "pipErrors": { "androidVersion": "Vereist Android 8.0 of nieuwer", "iosVersion": "Vereist iOS 15.0 of nieuwer", diff --git a/lib/i18n/pl.i18n.json b/lib/i18n/pl.i18n.json index 38640d4d..2345946b 100644 --- a/lib/i18n/pl.i18n.json +++ b/lib/i18n/pl.i18n.json @@ -300,7 +300,8 @@ "subSeekNext": "Przewiń do następnego napisu", "subSeekPrev": "Przewiń do poprzedniego napisu", "shaderToggle": "Przełącz shadery", - "skipMarker": "Pomiń intro/napisy końcowe" + "skipMarker": "Pomiń intro/napisy końcowe", + "screenshot": "Zrób zrzut ekranu" } }, "fileInfo": { @@ -433,6 +434,7 @@ "endsAt": "Kończy się o ${time}", "pipActive": "Odtwarzanie w trybie obraz w obrazie", "pipFailed": "Nie udało się uruchomić trybu obraz w obrazie", + "screenshotSaved": "Zrzut ekranu zapisany", "pipErrors": { "androidVersion": "Wymaga Androida 8.0 lub nowszego", "iosVersion": "Wymaga iOS 15.0 lub nowszego", diff --git a/lib/i18n/pt.i18n.json b/lib/i18n/pt.i18n.json index 561eed68..685bd1b0 100644 --- a/lib/i18n/pt.i18n.json +++ b/lib/i18n/pt.i18n.json @@ -300,7 +300,8 @@ "subSeekNext": "Ir para Próxima Legenda", "subSeekPrev": "Ir para Legenda Anterior", "shaderToggle": "Alternar Shaders", - "skipMarker": "Pular Intro/Créditos" + "skipMarker": "Pular Intro/Créditos", + "screenshot": "Capturar tela" } }, "fileInfo": { @@ -433,6 +434,7 @@ "endsAt": "Termina às ${time}", "pipActive": "Reproduzindo em Picture-in-Picture", "pipFailed": "Falha ao iniciar picture-in-picture", + "screenshotSaved": "Captura de tela salva", "pipErrors": { "androidVersion": "Requer Android 8.0 ou superior", "iosVersion": "Requer iOS 15.0 ou superior", diff --git a/lib/i18n/ru.i18n.json b/lib/i18n/ru.i18n.json index a233ce42..6da19c85 100644 --- a/lib/i18n/ru.i18n.json +++ b/lib/i18n/ru.i18n.json @@ -300,7 +300,8 @@ "subSeekNext": "К следующему субтитру", "subSeekPrev": "К предыдущему субтитру", "shaderToggle": "Вкл./выкл. шейдеры", - "skipMarker": "Пропустить вступление/титры" + "skipMarker": "Пропустить вступление/титры", + "screenshot": "Сделать снимок экрана" } }, "fileInfo": { @@ -433,6 +434,7 @@ "endsAt": "Закончится в ${time}", "pipActive": "Воспроизводится в режиме «картинка в картинке»", "pipFailed": "Не удалось запустить режим «картинка в картинке»", + "screenshotSaved": "Снимок экрана сохранён", "pipErrors": { "androidVersion": "Требуется Android 8.0 или новее", "iosVersion": "Требуется iOS 15.0 или новее", diff --git a/lib/i18n/strings.g.dart b/lib/i18n/strings.g.dart index eb90c825..6a6c45a0 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: 17460 (1164 per locale) +/// Strings: 17490 (1166 per locale) /// -/// Built on 2026-05-16 at 13:41 UTC +/// Built on 2026-05-16 at 21:43 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 43e6ec92..63b831b5 100644 --- a/lib/i18n/strings_da.g.dart +++ b/lib/i18n/strings_da.g.dart @@ -595,6 +595,7 @@ class _TranslationsVideoControlsDa extends TranslationsVideoControlsEn { @override String endsAt({required Object time}) => 'Slutter kl. ${time}'; @override String get pipActive => 'Afspiller i billede-i-billede'; @override String get pipFailed => 'Billede-i-billede kunne ikke starte'; + @override String get screenshotSaved => 'Skærmbillede gemt'; @override late final _TranslationsVideoControlsPipErrorsDa pipErrors = _TranslationsVideoControlsPipErrorsDa._(_root); @override String get chapters => 'Kapitler'; @override String get noChaptersAvailable => 'Ingen kapitler tilgængelige'; @@ -1556,6 +1557,7 @@ class _TranslationsHotkeysActionsDa extends TranslationsHotkeysActionsEn { @override String get subSeekPrev => 'Søg til forrige undertekst'; @override String get shaderToggle => 'Skift shadere'; @override String get skipMarker => 'Spring intro/rulletekster over'; + @override String get screenshot => 'Tag skærmbillede'; } // Path: videoControls.pipErrors @@ -2079,6 +2081,7 @@ extension on TranslationsDa { 'hotkeys.actions.subSeekPrev' => 'Søg til forrige undertekst', 'hotkeys.actions.shaderToggle' => 'Skift shadere', 'hotkeys.actions.skipMarker' => 'Spring intro/rulletekster over', + 'hotkeys.actions.screenshot' => 'Tag skærmbillede', 'fileInfo.title' => 'Filinfo', 'fileInfo.video' => 'Video', 'fileInfo.audio' => 'Lyd', @@ -2198,6 +2201,7 @@ extension on TranslationsDa { 'videoControls.endsAt' => ({required Object time}) => 'Slutter kl. ${time}', 'videoControls.pipActive' => 'Afspiller i billede-i-billede', 'videoControls.pipFailed' => 'Billede-i-billede kunne ikke starte', + 'videoControls.screenshotSaved' => 'Skærmbillede gemt', 'videoControls.pipErrors.androidVersion' => 'Kræver Android 8.0 eller nyere', 'videoControls.pipErrors.iosVersion' => 'Kræver iOS 15.0 eller nyere', 'videoControls.pipErrors.permissionDisabled' => 'Billede-i-billede er deaktiveret. Slå det til i systemindstillinger.', @@ -2303,10 +2307,10 @@ extension on TranslationsDa { 'profiles.summarySingle' => 'Tilføj profiler for at blande administrerede brugere og lokale identiteter', 'profiles.summaryMultipleWithActive' => ({required Object count, required Object activeName}) => '${count} profiler · aktiv: ${activeName}', 'profiles.summaryMultiple' => ({required Object count}) => '${count} profiler', - 'profiles.removeConnectionTitle' => 'Fjern forbindelse?', - 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Fjern ${displayName}s adgang til ${connectionLabel}. Andre profiler beholder den.', _ => null, } ?? switch (path) { + 'profiles.removeConnectionTitle' => 'Fjern forbindelse?', + 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Fjern ${displayName}s adgang til ${connectionLabel}. Andre profiler beholder den.', 'profiles.deleteProfileTitle' => 'Slet profil?', 'profiles.deleteProfileMessage' => ({required Object displayName}) => 'Fjern ${displayName} og forbindelserne. Servere forbliver tilgængelige.', 'profiles.profileNameLabel' => 'Profilnavn', @@ -2817,10 +2821,10 @@ extension on TranslationsDa { 'metadataEdit.selectBackground' => 'Vælg baggrund', 'metadataEdit.selectLogo' => 'Vælg logo', 'metadataEdit.selectSquareArt' => 'Vælg kvadratisk billede', - 'metadataEdit.fromUrl' => 'Fra URL', - 'metadataEdit.uploadFile' => 'Upload fil', _ => null, } ?? switch (path) { + 'metadataEdit.fromUrl' => 'Fra URL', + 'metadataEdit.uploadFile' => 'Upload fil', 'metadataEdit.enterImageUrl' => 'Indtast billed-URL', 'metadataEdit.imageUrl' => 'Billed-URL', 'metadataEdit.metadataUpdated' => 'Metadata opdateret', diff --git a/lib/i18n/strings_de.g.dart b/lib/i18n/strings_de.g.dart index 5ff98aab..99097701 100644 --- a/lib/i18n/strings_de.g.dart +++ b/lib/i18n/strings_de.g.dart @@ -595,6 +595,7 @@ class _TranslationsVideoControlsDe extends TranslationsVideoControlsEn { @override String endsAt({required Object time}) => 'Endet um ${time}'; @override String get pipActive => 'Wiedergabe im Bild-in-Bild-Modus'; @override String get pipFailed => 'Bild-in-Bild konnte nicht gestartet werden'; + @override String get screenshotSaved => 'Screenshot gespeichert'; @override late final _TranslationsVideoControlsPipErrorsDe pipErrors = _TranslationsVideoControlsPipErrorsDe._(_root); @override String get chapters => 'Kapitel'; @override String get noChaptersAvailable => 'Keine Kapitel verfügbar'; @@ -1556,6 +1557,7 @@ class _TranslationsHotkeysActionsDe extends TranslationsHotkeysActionsEn { @override String get subSeekPrev => 'Zum vorherigen Untertitel springen'; @override String get shaderToggle => 'Shader umschalten'; @override String get skipMarker => 'Intro/Abspann überspringen'; + @override String get screenshot => 'Screenshot aufnehmen'; } // Path: videoControls.pipErrors @@ -2079,6 +2081,7 @@ extension on TranslationsDe { 'hotkeys.actions.subSeekPrev' => 'Zum vorherigen Untertitel springen', 'hotkeys.actions.shaderToggle' => 'Shader umschalten', 'hotkeys.actions.skipMarker' => 'Intro/Abspann überspringen', + 'hotkeys.actions.screenshot' => 'Screenshot aufnehmen', 'fileInfo.title' => 'Dateiinfo', 'fileInfo.video' => 'Video', 'fileInfo.audio' => 'Audio', @@ -2198,6 +2201,7 @@ extension on TranslationsDe { 'videoControls.endsAt' => ({required Object time}) => 'Endet um ${time}', 'videoControls.pipActive' => 'Wiedergabe im Bild-in-Bild-Modus', 'videoControls.pipFailed' => 'Bild-in-Bild konnte nicht gestartet werden', + 'videoControls.screenshotSaved' => 'Screenshot gespeichert', 'videoControls.pipErrors.androidVersion' => 'Erfordert Android 8.0 oder neuer', 'videoControls.pipErrors.iosVersion' => 'Erfordert iOS 15.0 oder neuer', 'videoControls.pipErrors.permissionDisabled' => 'Bild-in-Bild ist deaktiviert. Aktiviere es in den Systemeinstellungen.', @@ -2303,10 +2307,10 @@ extension on TranslationsDe { 'profiles.summarySingle' => 'Profile hinzufügen, um verwaltete Benutzer und lokale Identitäten zu mischen', 'profiles.summaryMultipleWithActive' => ({required Object count, required Object activeName}) => '${count} Profile · aktiv: ${activeName}', 'profiles.summaryMultiple' => ({required Object count}) => '${count} Profile', - 'profiles.removeConnectionTitle' => 'Verbindung entfernen?', - 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Zugriff von ${displayName} auf ${connectionLabel} entfernen. Andere Profile behalten ihn.', _ => null, } ?? switch (path) { + 'profiles.removeConnectionTitle' => 'Verbindung entfernen?', + 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Zugriff von ${displayName} auf ${connectionLabel} entfernen. Andere Profile behalten ihn.', 'profiles.deleteProfileTitle' => 'Profil löschen?', 'profiles.deleteProfileMessage' => ({required Object displayName}) => '${displayName} und Verbindungen entfernen. Server bleiben verfügbar.', 'profiles.profileNameLabel' => 'Profilname', @@ -2817,10 +2821,10 @@ extension on TranslationsDe { 'metadataEdit.selectBackground' => 'Hintergrund auswählen', 'metadataEdit.selectLogo' => 'Logo auswählen', 'metadataEdit.selectSquareArt' => 'Quadratisches Bild auswählen', - 'metadataEdit.fromUrl' => 'Von URL', - 'metadataEdit.uploadFile' => 'Datei hochladen', _ => null, } ?? switch (path) { + 'metadataEdit.fromUrl' => 'Von URL', + 'metadataEdit.uploadFile' => 'Datei hochladen', 'metadataEdit.enterImageUrl' => 'Bild-URL eingeben', 'metadataEdit.imageUrl' => 'Bild-URL', 'metadataEdit.metadataUpdated' => 'Metadaten aktualisiert', diff --git a/lib/i18n/strings_en.g.dart b/lib/i18n/strings_en.g.dart index 4bd6de65..b653c78c 100644 --- a/lib/i18n/strings_en.g.dart +++ b/lib/i18n/strings_en.g.dart @@ -1366,6 +1366,9 @@ class TranslationsVideoControlsEn { /// en: 'Picture-in-picture failed to start' String get pipFailed => 'Picture-in-picture failed to start'; + /// en: 'Screenshot saved' + String get screenshotSaved => 'Screenshot saved'; + late final TranslationsVideoControlsPipErrorsEn pipErrors = TranslationsVideoControlsPipErrorsEn.internal(_root); /// en: 'Chapters' @@ -3652,6 +3655,9 @@ class TranslationsHotkeysActionsEn { /// en: 'Skip Intro/Credits' String get skipMarker => 'Skip Intro/Credits'; + + /// en: 'Take Screenshot' + String get screenshot => 'Take Screenshot'; } // Path: videoControls.pipErrors @@ -4413,6 +4419,7 @@ extension on Translations { 'hotkeys.actions.subSeekPrev' => 'Seek to Previous Subtitle', 'hotkeys.actions.shaderToggle' => 'Toggle Shaders', 'hotkeys.actions.skipMarker' => 'Skip Intro/Credits', + 'hotkeys.actions.screenshot' => 'Take Screenshot', 'fileInfo.title' => 'File Info', 'fileInfo.video' => 'Video', 'fileInfo.audio' => 'Audio', @@ -4532,6 +4539,7 @@ extension on Translations { 'videoControls.endsAt' => ({required Object time}) => 'Ends at ${time}', 'videoControls.pipActive' => 'Playing in Picture-in-Picture', 'videoControls.pipFailed' => 'Picture-in-picture failed to start', + 'videoControls.screenshotSaved' => 'Screenshot saved', 'videoControls.pipErrors.androidVersion' => 'Requires Android 8.0 or newer', 'videoControls.pipErrors.iosVersion' => 'Requires iOS 15.0 or newer', 'videoControls.pipErrors.permissionDisabled' => 'Picture-in-picture is disabled. Enable it in system settings.', @@ -4637,10 +4645,10 @@ extension on Translations { 'profiles.summarySingle' => 'Add profiles to mix managed users and local identities', 'profiles.summaryMultipleWithActive' => ({required Object count, required Object activeName}) => '${count} profiles · active: ${activeName}', 'profiles.summaryMultiple' => ({required Object count}) => '${count} profiles', - 'profiles.removeConnectionTitle' => 'Remove connection?', - 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Remove ${displayName}\'s access to ${connectionLabel}. Other profiles keep it.', _ => null, } ?? switch (path) { + 'profiles.removeConnectionTitle' => 'Remove connection?', + 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Remove ${displayName}\'s access to ${connectionLabel}. Other profiles keep it.', 'profiles.deleteProfileTitle' => 'Delete profile?', 'profiles.deleteProfileMessage' => ({required Object displayName}) => 'Remove ${displayName} and its connections. Servers stay available.', 'profiles.profileNameLabel' => 'Profile name', @@ -5151,10 +5159,10 @@ extension on Translations { 'metadataEdit.selectBackground' => 'Select Background', 'metadataEdit.selectLogo' => 'Select Logo', 'metadataEdit.selectSquareArt' => 'Select Square Art', - 'metadataEdit.fromUrl' => 'From URL', - 'metadataEdit.uploadFile' => 'Upload File', _ => null, } ?? switch (path) { + 'metadataEdit.fromUrl' => 'From URL', + 'metadataEdit.uploadFile' => 'Upload File', 'metadataEdit.enterImageUrl' => 'Enter image URL', 'metadataEdit.imageUrl' => 'Image URL', 'metadataEdit.metadataUpdated' => 'Metadata updated', diff --git a/lib/i18n/strings_es.g.dart b/lib/i18n/strings_es.g.dart index 87b1cd97..93d8784e 100644 --- a/lib/i18n/strings_es.g.dart +++ b/lib/i18n/strings_es.g.dart @@ -595,6 +595,7 @@ class _TranslationsVideoControlsEs extends TranslationsVideoControlsEn { @override String endsAt({required Object time}) => 'Termina a las ${time}'; @override String get pipActive => 'Reproduciendo en Imagen en Imagen'; @override String get pipFailed => 'Error al iniciar Imagen en Imagen'; + @override String get screenshotSaved => 'Captura de pantalla guardada'; @override late final _TranslationsVideoControlsPipErrorsEs pipErrors = _TranslationsVideoControlsPipErrorsEs._(_root); @override String get chapters => 'Capítulos'; @override String get noChaptersAvailable => 'No hay capítulos disponibles'; @@ -1556,6 +1557,7 @@ class _TranslationsHotkeysActionsEs extends TranslationsHotkeysActionsEn { @override String get subSeekPrev => 'Ir al Anterior Subtítulo'; @override String get shaderToggle => 'Alternar Shaders'; @override String get skipMarker => 'Saltar Intro/Créditos'; + @override String get screenshot => 'Tomar captura de pantalla'; } // Path: videoControls.pipErrors @@ -2079,6 +2081,7 @@ extension on TranslationsEs { 'hotkeys.actions.subSeekPrev' => 'Ir al Anterior Subtítulo', 'hotkeys.actions.shaderToggle' => 'Alternar Shaders', 'hotkeys.actions.skipMarker' => 'Saltar Intro/Créditos', + 'hotkeys.actions.screenshot' => 'Tomar captura de pantalla', 'fileInfo.title' => 'Información del Archivo', 'fileInfo.video' => 'Video', 'fileInfo.audio' => 'Audio', @@ -2198,6 +2201,7 @@ extension on TranslationsEs { 'videoControls.endsAt' => ({required Object time}) => 'Termina a las ${time}', 'videoControls.pipActive' => 'Reproduciendo en Imagen en Imagen', 'videoControls.pipFailed' => 'Error al iniciar Imagen en Imagen', + 'videoControls.screenshotSaved' => 'Captura de pantalla guardada', 'videoControls.pipErrors.androidVersion' => 'Requiere Android 8.0 o más reciente', 'videoControls.pipErrors.iosVersion' => 'Requiere iOS 15.0 o más reciente', 'videoControls.pipErrors.permissionDisabled' => 'Picture-in-picture está desactivado. Actívalo en los ajustes del sistema.', @@ -2303,10 +2307,10 @@ extension on TranslationsEs { 'profiles.summarySingle' => 'Añade perfiles para mezclar usuarios gestionados e identidades locales', 'profiles.summaryMultipleWithActive' => ({required Object count, required Object activeName}) => '${count} perfiles · activo: ${activeName}', 'profiles.summaryMultiple' => ({required Object count}) => '${count} perfiles', - 'profiles.removeConnectionTitle' => '¿Eliminar conexión?', - 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Eliminar el acceso de ${displayName} a ${connectionLabel}. Los demás perfiles lo conservan.', _ => null, } ?? switch (path) { + 'profiles.removeConnectionTitle' => '¿Eliminar conexión?', + 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Eliminar el acceso de ${displayName} a ${connectionLabel}. Los demás perfiles lo conservan.', 'profiles.deleteProfileTitle' => '¿Eliminar perfil?', 'profiles.deleteProfileMessage' => ({required Object displayName}) => 'Eliminar ${displayName} y sus conexiones. Los servidores seguirán disponibles.', 'profiles.profileNameLabel' => 'Nombre del perfil', @@ -2817,10 +2821,10 @@ extension on TranslationsEs { 'metadataEdit.selectBackground' => 'Seleccionar fondo', 'metadataEdit.selectLogo' => 'Seleccionar logo', 'metadataEdit.selectSquareArt' => 'Seleccionar imagen cuadrada', - 'metadataEdit.fromUrl' => 'Desde URL', - 'metadataEdit.uploadFile' => 'Subir archivo', _ => null, } ?? switch (path) { + 'metadataEdit.fromUrl' => 'Desde URL', + 'metadataEdit.uploadFile' => 'Subir archivo', 'metadataEdit.enterImageUrl' => 'Introducir URL de imagen', 'metadataEdit.imageUrl' => 'URL de imagen', 'metadataEdit.metadataUpdated' => 'Metadatos actualizados', diff --git a/lib/i18n/strings_fr.g.dart b/lib/i18n/strings_fr.g.dart index fcb6eac2..3f4375a6 100644 --- a/lib/i18n/strings_fr.g.dart +++ b/lib/i18n/strings_fr.g.dart @@ -595,6 +595,7 @@ class _TranslationsVideoControlsFr extends TranslationsVideoControlsEn { @override String endsAt({required Object time}) => 'Fin à ${time}'; @override String get pipActive => 'Lecture en mode image dans l\'image'; @override String get pipFailed => 'Échec du démarrage du mode image dans l\'image'; + @override String get screenshotSaved => 'Capture d\'écran enregistrée'; @override late final _TranslationsVideoControlsPipErrorsFr pipErrors = _TranslationsVideoControlsPipErrorsFr._(_root); @override String get chapters => 'Chapitres'; @override String get noChaptersAvailable => 'Aucun chapitre disponible'; @@ -1556,6 +1557,7 @@ class _TranslationsHotkeysActionsFr extends TranslationsHotkeysActionsEn { @override String get subSeekPrev => 'Rechercher le sous-titre précédent'; @override String get shaderToggle => 'Activer/désactiver les shaders'; @override String get skipMarker => 'Passer l\'intro/le générique'; + @override String get screenshot => 'Prendre une capture d\'écran'; } // Path: videoControls.pipErrors @@ -2079,6 +2081,7 @@ extension on TranslationsFr { 'hotkeys.actions.subSeekPrev' => 'Rechercher le sous-titre précédent', 'hotkeys.actions.shaderToggle' => 'Activer/désactiver les shaders', 'hotkeys.actions.skipMarker' => 'Passer l\'intro/le générique', + 'hotkeys.actions.screenshot' => 'Prendre une capture d\'écran', 'fileInfo.title' => 'Informations sur le fichier', 'fileInfo.video' => 'Vidéo', 'fileInfo.audio' => 'Audio', @@ -2198,6 +2201,7 @@ extension on TranslationsFr { 'videoControls.endsAt' => ({required Object time}) => 'Fin à ${time}', 'videoControls.pipActive' => 'Lecture en mode image dans l\'image', 'videoControls.pipFailed' => 'Échec du démarrage du mode image dans l\'image', + 'videoControls.screenshotSaved' => 'Capture d\'écran enregistrée', 'videoControls.pipErrors.androidVersion' => 'Nécessite Android 8.0 ou plus récent', 'videoControls.pipErrors.iosVersion' => 'Nécessite iOS 15.0 ou plus récent', 'videoControls.pipErrors.permissionDisabled' => 'Picture-in-picture est désactivé. Activez-le dans les paramètres système.', @@ -2303,10 +2307,10 @@ extension on TranslationsFr { 'profiles.summarySingle' => 'Ajoutez des profils pour mélanger utilisateurs gérés et identités locales', 'profiles.summaryMultipleWithActive' => ({required Object count, required Object activeName}) => '${count} profils · actif : ${activeName}', 'profiles.summaryMultiple' => ({required Object count}) => '${count} profils', - 'profiles.removeConnectionTitle' => 'Retirer la connexion ?', - 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Supprimer l\'accès de ${displayName} à ${connectionLabel}. Les autres profils le conservent.', _ => null, } ?? switch (path) { + 'profiles.removeConnectionTitle' => 'Retirer la connexion ?', + 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Supprimer l\'accès de ${displayName} à ${connectionLabel}. Les autres profils le conservent.', 'profiles.deleteProfileTitle' => 'Supprimer le profil ?', 'profiles.deleteProfileMessage' => ({required Object displayName}) => 'Supprimer ${displayName} et ses connexions. Les serveurs restent disponibles.', 'profiles.profileNameLabel' => 'Nom du profil', @@ -2817,10 +2821,10 @@ extension on TranslationsFr { 'metadataEdit.selectBackground' => 'Sélectionner l\'arrière-plan', 'metadataEdit.selectLogo' => 'Sélectionner le logo', 'metadataEdit.selectSquareArt' => 'Sélectionner l\'image carrée', - 'metadataEdit.fromUrl' => 'Depuis une URL', - 'metadataEdit.uploadFile' => 'Importer un fichier', _ => null, } ?? switch (path) { + 'metadataEdit.fromUrl' => 'Depuis une URL', + 'metadataEdit.uploadFile' => 'Importer un fichier', 'metadataEdit.enterImageUrl' => 'Entrer l\'URL de l\'image', 'metadataEdit.imageUrl' => 'URL de l\'image', 'metadataEdit.metadataUpdated' => 'Métadonnées mises à jour', diff --git a/lib/i18n/strings_it.g.dart b/lib/i18n/strings_it.g.dart index d238a547..fe6fc06d 100644 --- a/lib/i18n/strings_it.g.dart +++ b/lib/i18n/strings_it.g.dart @@ -595,6 +595,7 @@ class _TranslationsVideoControlsIt extends TranslationsVideoControlsEn { @override String endsAt({required Object time}) => 'Finisce alle ${time}'; @override String get pipActive => 'Riproduzione in Picture-in-Picture'; @override String get pipFailed => 'Impossibile avviare la modalità Picture-in-Picture'; + @override String get screenshotSaved => 'Schermata salvata'; @override late final _TranslationsVideoControlsPipErrorsIt pipErrors = _TranslationsVideoControlsPipErrorsIt._(_root); @override String get chapters => 'Capitoli'; @override String get noChaptersAvailable => 'Nessun capitolo disponibile'; @@ -1556,6 +1557,7 @@ class _TranslationsHotkeysActionsIt extends TranslationsHotkeysActionsEn { @override String get subSeekPrev => 'Vai al sottotitolo precedente'; @override String get shaderToggle => 'Attiva/disattiva shader'; @override String get skipMarker => 'Salta intro/titoli di coda'; + @override String get screenshot => 'Cattura schermata'; } // Path: videoControls.pipErrors @@ -2079,6 +2081,7 @@ extension on TranslationsIt { 'hotkeys.actions.subSeekPrev' => 'Vai al sottotitolo precedente', 'hotkeys.actions.shaderToggle' => 'Attiva/disattiva shader', 'hotkeys.actions.skipMarker' => 'Salta intro/titoli di coda', + 'hotkeys.actions.screenshot' => 'Cattura schermata', 'fileInfo.title' => 'Info sul file', 'fileInfo.video' => 'Video', 'fileInfo.audio' => 'Audio', @@ -2198,6 +2201,7 @@ extension on TranslationsIt { 'videoControls.endsAt' => ({required Object time}) => 'Finisce alle ${time}', 'videoControls.pipActive' => 'Riproduzione in Picture-in-Picture', 'videoControls.pipFailed' => 'Impossibile avviare la modalità Picture-in-Picture', + 'videoControls.screenshotSaved' => 'Schermata salvata', 'videoControls.pipErrors.androidVersion' => 'Richiede Android 8.0 o versioni successive', 'videoControls.pipErrors.iosVersion' => 'Richiede iOS 15.0 o versioni successive', 'videoControls.pipErrors.permissionDisabled' => 'Picture-in-picture è disattivato. Attivalo nelle impostazioni di sistema.', @@ -2303,10 +2307,10 @@ extension on TranslationsIt { 'profiles.summarySingle' => 'Aggiungi profili per combinare utenti gestiti e identità locali', 'profiles.summaryMultipleWithActive' => ({required Object count, required Object activeName}) => '${count} profili · attivo: ${activeName}', 'profiles.summaryMultiple' => ({required Object count}) => '${count} profili', - 'profiles.removeConnectionTitle' => 'Rimuovere la connessione?', - 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Rimuovi l\'accesso di ${displayName} a ${connectionLabel}. Gli altri profili lo mantengono.', _ => null, } ?? switch (path) { + 'profiles.removeConnectionTitle' => 'Rimuovere la connessione?', + 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Rimuovi l\'accesso di ${displayName} a ${connectionLabel}. Gli altri profili lo mantengono.', 'profiles.deleteProfileTitle' => 'Eliminare il profilo?', 'profiles.deleteProfileMessage' => ({required Object displayName}) => 'Rimuovi ${displayName} e le sue connessioni. I server restano disponibili.', 'profiles.profileNameLabel' => 'Nome profilo', @@ -2817,10 +2821,10 @@ extension on TranslationsIt { 'metadataEdit.selectBackground' => 'Seleziona sfondo', 'metadataEdit.selectLogo' => 'Seleziona logo', 'metadataEdit.selectSquareArt' => 'Seleziona immagine quadrata', - 'metadataEdit.fromUrl' => 'Da URL', - 'metadataEdit.uploadFile' => 'Carica file', _ => null, } ?? switch (path) { + 'metadataEdit.fromUrl' => 'Da URL', + 'metadataEdit.uploadFile' => 'Carica file', 'metadataEdit.enterImageUrl' => 'Inserisci URL immagine', 'metadataEdit.imageUrl' => 'URL immagine', 'metadataEdit.metadataUpdated' => 'Metadati aggiornati', diff --git a/lib/i18n/strings_ja.g.dart b/lib/i18n/strings_ja.g.dart index c18bb06e..4df7d160 100644 --- a/lib/i18n/strings_ja.g.dart +++ b/lib/i18n/strings_ja.g.dart @@ -595,6 +595,7 @@ class _TranslationsVideoControlsJa extends TranslationsVideoControlsEn { @override String endsAt({required Object time}) => '${time}に終了'; @override String get pipActive => 'ピクチャーインピクチャーで再生中'; @override String get pipFailed => 'ピクチャーインピクチャーの開始に失敗しました'; + @override String get screenshotSaved => 'スクリーンショットを保存しました'; @override late final _TranslationsVideoControlsPipErrorsJa pipErrors = _TranslationsVideoControlsPipErrorsJa._(_root); @override String get chapters => 'チャプター'; @override String get noChaptersAvailable => 'チャプターがありません'; @@ -1556,6 +1557,7 @@ class _TranslationsHotkeysActionsJa extends TranslationsHotkeysActionsEn { @override String get subSeekPrev => '前の字幕にシーク'; @override String get shaderToggle => 'シェーダー切替'; @override String get skipMarker => 'イントロ/クレジットをスキップ'; + @override String get screenshot => 'スクリーンショットを撮る'; } // Path: videoControls.pipErrors @@ -2079,6 +2081,7 @@ extension on TranslationsJa { 'hotkeys.actions.subSeekPrev' => '前の字幕にシーク', 'hotkeys.actions.shaderToggle' => 'シェーダー切替', 'hotkeys.actions.skipMarker' => 'イントロ/クレジットをスキップ', + 'hotkeys.actions.screenshot' => 'スクリーンショットを撮る', 'fileInfo.title' => 'ファイル情報', 'fileInfo.video' => '映像', 'fileInfo.audio' => '音声', @@ -2198,6 +2201,7 @@ extension on TranslationsJa { 'videoControls.endsAt' => ({required Object time}) => '${time}に終了', 'videoControls.pipActive' => 'ピクチャーインピクチャーで再生中', 'videoControls.pipFailed' => 'ピクチャーインピクチャーの開始に失敗しました', + 'videoControls.screenshotSaved' => 'スクリーンショットを保存しました', 'videoControls.pipErrors.androidVersion' => 'Android 8.0以降が必要です', 'videoControls.pipErrors.iosVersion' => 'iOS 15.0以降が必要です', 'videoControls.pipErrors.permissionDisabled' => 'ピクチャーインピクチャーが無効です。システム設定で有効にしてください。', @@ -2303,10 +2307,10 @@ extension on TranslationsJa { 'profiles.summarySingle' => 'プロファイルを追加して、管理対象ユーザーとローカルIDを混在させます', 'profiles.summaryMultipleWithActive' => ({required Object count, required Object activeName}) => '${count}個のプロファイル · アクティブ: ${activeName}', 'profiles.summaryMultiple' => ({required Object count}) => '${count}個のプロファイル', - 'profiles.removeConnectionTitle' => '接続を削除しますか?', - 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => '${displayName}の${connectionLabel}へのアクセスを削除します。他のプロフィールには残ります。', _ => null, } ?? switch (path) { + 'profiles.removeConnectionTitle' => '接続を削除しますか?', + 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => '${displayName}の${connectionLabel}へのアクセスを削除します。他のプロフィールには残ります。', 'profiles.deleteProfileTitle' => 'プロファイルを削除しますか?', 'profiles.deleteProfileMessage' => ({required Object displayName}) => '${displayName}とその接続を削除します。サーバーは引き続き利用できます。', 'profiles.profileNameLabel' => 'プロファイル名', @@ -2817,10 +2821,10 @@ extension on TranslationsJa { 'metadataEdit.selectBackground' => '背景を選択', 'metadataEdit.selectLogo' => 'ロゴを選択', 'metadataEdit.selectSquareArt' => '正方形アートを選択', - 'metadataEdit.fromUrl' => 'URLから', - 'metadataEdit.uploadFile' => 'ファイルをアップロード', _ => null, } ?? switch (path) { + 'metadataEdit.fromUrl' => 'URLから', + 'metadataEdit.uploadFile' => 'ファイルをアップロード', 'metadataEdit.enterImageUrl' => '画像URLを入力', 'metadataEdit.imageUrl' => '画像URL', 'metadataEdit.metadataUpdated' => 'メタデータを更新しました', diff --git a/lib/i18n/strings_ko.g.dart b/lib/i18n/strings_ko.g.dart index b82bc251..f36e3fc1 100644 --- a/lib/i18n/strings_ko.g.dart +++ b/lib/i18n/strings_ko.g.dart @@ -595,6 +595,7 @@ class _TranslationsVideoControlsKo extends TranslationsVideoControlsEn { @override String endsAt({required Object time}) => '${time}에 종료'; @override String get pipActive => '화면 속 화면으로 재생 중'; @override String get pipFailed => '화면 속 화면 모드를 시작할 수 없습니다'; + @override String get screenshotSaved => '스크린샷 저장됨'; @override late final _TranslationsVideoControlsPipErrorsKo pipErrors = _TranslationsVideoControlsPipErrorsKo._(_root); @override String get chapters => '챕터'; @override String get noChaptersAvailable => '사용 가능한 챕터가 없습니다'; @@ -1556,6 +1557,7 @@ class _TranslationsHotkeysActionsKo extends TranslationsHotkeysActionsEn { @override String get subSeekPrev => '이전 자막으로 이동'; @override String get shaderToggle => '셰이더 전환'; @override String get skipMarker => '인트로/크레딧 건너뛰기'; + @override String get screenshot => '스크린샷 찍기'; } // Path: videoControls.pipErrors @@ -2079,6 +2081,7 @@ extension on TranslationsKo { 'hotkeys.actions.subSeekPrev' => '이전 자막으로 이동', 'hotkeys.actions.shaderToggle' => '셰이더 전환', 'hotkeys.actions.skipMarker' => '인트로/크레딧 건너뛰기', + 'hotkeys.actions.screenshot' => '스크린샷 찍기', 'fileInfo.title' => '파일 정보', 'fileInfo.video' => '비디오', 'fileInfo.audio' => '오디오', @@ -2198,6 +2201,7 @@ extension on TranslationsKo { 'videoControls.endsAt' => ({required Object time}) => '${time}에 종료', 'videoControls.pipActive' => '화면 속 화면으로 재생 중', 'videoControls.pipFailed' => '화면 속 화면 모드를 시작할 수 없습니다', + 'videoControls.screenshotSaved' => '스크린샷 저장됨', 'videoControls.pipErrors.androidVersion' => 'Android 8.0 이상이 필요합니다', 'videoControls.pipErrors.iosVersion' => 'iOS 15.0 이상이 필요합니다', 'videoControls.pipErrors.permissionDisabled' => '화면 속 화면이 비활성화되어 있습니다. 시스템 설정에서 활성화하세요.', @@ -2303,10 +2307,10 @@ extension on TranslationsKo { 'profiles.summarySingle' => '관리되는 사용자와 로컬 ID를 혼합하려면 프로필을 추가하세요', 'profiles.summaryMultipleWithActive' => ({required Object count, required Object activeName}) => '${count}개 프로필 · 활성: ${activeName}', 'profiles.summaryMultiple' => ({required Object count}) => '${count}개 프로필', - 'profiles.removeConnectionTitle' => '연결을 제거하시겠습니까?', - 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => '${displayName}의 ${connectionLabel} 접근 권한을 제거합니다. 다른 프로필에는 유지됩니다.', _ => null, } ?? switch (path) { + 'profiles.removeConnectionTitle' => '연결을 제거하시겠습니까?', + 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => '${displayName}의 ${connectionLabel} 접근 권한을 제거합니다. 다른 프로필에는 유지됩니다.', 'profiles.deleteProfileTitle' => '프로필을 삭제하시겠습니까?', 'profiles.deleteProfileMessage' => ({required Object displayName}) => '${displayName} 및 해당 연결을 제거합니다. 서버는 계속 사용할 수 있습니다.', 'profiles.profileNameLabel' => '프로필 이름', @@ -2817,10 +2821,10 @@ extension on TranslationsKo { 'metadataEdit.selectBackground' => '배경 선택', 'metadataEdit.selectLogo' => '로고 선택', 'metadataEdit.selectSquareArt' => '정사각형 아트 선택', - 'metadataEdit.fromUrl' => 'URL에서', - 'metadataEdit.uploadFile' => '파일 업로드', _ => null, } ?? switch (path) { + 'metadataEdit.fromUrl' => 'URL에서', + 'metadataEdit.uploadFile' => '파일 업로드', 'metadataEdit.enterImageUrl' => '이미지 URL 입력', 'metadataEdit.imageUrl' => '이미지 URL', 'metadataEdit.metadataUpdated' => '메타데이터가 업데이트되었습니다', diff --git a/lib/i18n/strings_nb.g.dart b/lib/i18n/strings_nb.g.dart index ebb98f2b..a8c80fbf 100644 --- a/lib/i18n/strings_nb.g.dart +++ b/lib/i18n/strings_nb.g.dart @@ -595,6 +595,7 @@ class _TranslationsVideoControlsNb extends TranslationsVideoControlsEn { @override String endsAt({required Object time}) => 'Slutter kl. ${time}'; @override String get pipActive => 'Spiller i bilde-i-bilde'; @override String get pipFailed => 'Bilde-i-bilde kunne ikke starte'; + @override String get screenshotSaved => 'Skjermbilde lagret'; @override late final _TranslationsVideoControlsPipErrorsNb pipErrors = _TranslationsVideoControlsPipErrorsNb._(_root); @override String get chapters => 'Kapitler'; @override String get noChaptersAvailable => 'Ingen kapitler tilgjengelig'; @@ -1556,6 +1557,7 @@ class _TranslationsHotkeysActionsNb extends TranslationsHotkeysActionsEn { @override String get subSeekPrev => 'Spol til forrige undertekst'; @override String get shaderToggle => 'Veksle shadere'; @override String get skipMarker => 'Hopp over intro/rulletekst'; + @override String get screenshot => 'Ta skjermbilde'; } // Path: videoControls.pipErrors @@ -2079,6 +2081,7 @@ extension on TranslationsNb { 'hotkeys.actions.subSeekPrev' => 'Spol til forrige undertekst', 'hotkeys.actions.shaderToggle' => 'Veksle shadere', 'hotkeys.actions.skipMarker' => 'Hopp over intro/rulletekst', + 'hotkeys.actions.screenshot' => 'Ta skjermbilde', 'fileInfo.title' => 'Filinformasjon', 'fileInfo.video' => 'Video', 'fileInfo.audio' => 'Lyd', @@ -2198,6 +2201,7 @@ extension on TranslationsNb { 'videoControls.endsAt' => ({required Object time}) => 'Slutter kl. ${time}', 'videoControls.pipActive' => 'Spiller i bilde-i-bilde', 'videoControls.pipFailed' => 'Bilde-i-bilde kunne ikke starte', + 'videoControls.screenshotSaved' => 'Skjermbilde lagret', 'videoControls.pipErrors.androidVersion' => 'Krever Android 8.0 eller nyere', 'videoControls.pipErrors.iosVersion' => 'Krever iOS 15.0 eller nyere', 'videoControls.pipErrors.permissionDisabled' => 'Bilde-i-bilde er deaktivert. Slå det på i systeminnstillinger.', @@ -2303,10 +2307,10 @@ extension on TranslationsNb { 'profiles.summarySingle' => 'Legg til profiler for å blande administrerte brukere og lokale identiteter', 'profiles.summaryMultipleWithActive' => ({required Object count, required Object activeName}) => '${count} profiler · aktiv: ${activeName}', 'profiles.summaryMultiple' => ({required Object count}) => '${count} profiler', - 'profiles.removeConnectionTitle' => 'Fjerne tilkobling?', - 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Fjern ${displayName}s tilgang til ${connectionLabel}. Andre profiler beholder den.', _ => null, } ?? switch (path) { + 'profiles.removeConnectionTitle' => 'Fjerne tilkobling?', + 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Fjern ${displayName}s tilgang til ${connectionLabel}. Andre profiler beholder den.', 'profiles.deleteProfileTitle' => 'Slette profil?', 'profiles.deleteProfileMessage' => ({required Object displayName}) => 'Fjern ${displayName} og tilkoblingene. Servere forblir tilgjengelige.', 'profiles.profileNameLabel' => 'Profilnavn', @@ -2817,10 +2821,10 @@ extension on TranslationsNb { 'metadataEdit.selectBackground' => 'Velg bakgrunn', 'metadataEdit.selectLogo' => 'Velg logo', 'metadataEdit.selectSquareArt' => 'Velg kvadratisk bilde', - 'metadataEdit.fromUrl' => 'Fra URL', - 'metadataEdit.uploadFile' => 'Last opp fil', _ => null, } ?? switch (path) { + 'metadataEdit.fromUrl' => 'Fra URL', + 'metadataEdit.uploadFile' => 'Last opp fil', 'metadataEdit.enterImageUrl' => 'Skriv inn bilde-URL', 'metadataEdit.imageUrl' => 'Bilde-URL', 'metadataEdit.metadataUpdated' => 'Metadata oppdatert', diff --git a/lib/i18n/strings_nl.g.dart b/lib/i18n/strings_nl.g.dart index 068b20ef..6d4e2a76 100644 --- a/lib/i18n/strings_nl.g.dart +++ b/lib/i18n/strings_nl.g.dart @@ -595,6 +595,7 @@ class _TranslationsVideoControlsNl extends TranslationsVideoControlsEn { @override String endsAt({required Object time}) => 'Eindigt om ${time}'; @override String get pipActive => 'Afspelen in beeld-in-beeld'; @override String get pipFailed => 'Beeld-in-beeld kon niet worden gestart'; + @override String get screenshotSaved => 'Schermafbeelding opgeslagen'; @override late final _TranslationsVideoControlsPipErrorsNl pipErrors = _TranslationsVideoControlsPipErrorsNl._(_root); @override String get chapters => 'Hoofdstukken'; @override String get noChaptersAvailable => 'Geen hoofdstukken beschikbaar'; @@ -1556,6 +1557,7 @@ class _TranslationsHotkeysActionsNl extends TranslationsHotkeysActionsEn { @override String get subSeekPrev => 'Naar vorige ondertitel'; @override String get shaderToggle => 'Shaders aan/uit'; @override String get skipMarker => 'Intro/aftiteling overslaan'; + @override String get screenshot => 'Schermafbeelding maken'; } // Path: videoControls.pipErrors @@ -2079,6 +2081,7 @@ extension on TranslationsNl { 'hotkeys.actions.subSeekPrev' => 'Naar vorige ondertitel', 'hotkeys.actions.shaderToggle' => 'Shaders aan/uit', 'hotkeys.actions.skipMarker' => 'Intro/aftiteling overslaan', + 'hotkeys.actions.screenshot' => 'Schermafbeelding maken', 'fileInfo.title' => 'Bestand info', 'fileInfo.video' => 'Video', 'fileInfo.audio' => 'Audio', @@ -2198,6 +2201,7 @@ extension on TranslationsNl { 'videoControls.endsAt' => ({required Object time}) => 'Eindigt om ${time}', 'videoControls.pipActive' => 'Afspelen in beeld-in-beeld', 'videoControls.pipFailed' => 'Beeld-in-beeld kon niet worden gestart', + 'videoControls.screenshotSaved' => 'Schermafbeelding opgeslagen', 'videoControls.pipErrors.androidVersion' => 'Vereist Android 8.0 of nieuwer', 'videoControls.pipErrors.iosVersion' => 'Vereist iOS 15.0 of nieuwer', 'videoControls.pipErrors.permissionDisabled' => 'Picture-in-picture is uitgeschakeld. Schakel het in via systeeminstellingen.', @@ -2303,10 +2307,10 @@ extension on TranslationsNl { 'profiles.summarySingle' => 'Voeg profielen toe om beheerde gebruikers en lokale identiteiten te combineren', 'profiles.summaryMultipleWithActive' => ({required Object count, required Object activeName}) => '${count} profielen · actief: ${activeName}', 'profiles.summaryMultiple' => ({required Object count}) => '${count} profielen', - 'profiles.removeConnectionTitle' => 'Verbinding verwijderen?', - 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Verwijder ${displayName}s toegang tot ${connectionLabel}. Andere profielen behouden die.', _ => null, } ?? switch (path) { + 'profiles.removeConnectionTitle' => 'Verbinding verwijderen?', + 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Verwijder ${displayName}s toegang tot ${connectionLabel}. Andere profielen behouden die.', 'profiles.deleteProfileTitle' => 'Profiel verwijderen?', 'profiles.deleteProfileMessage' => ({required Object displayName}) => 'Verwijder ${displayName} en de verbindingen. Servers blijven beschikbaar.', 'profiles.profileNameLabel' => 'Profielnaam', @@ -2817,10 +2821,10 @@ extension on TranslationsNl { 'metadataEdit.selectBackground' => 'Achtergrond selecteren', 'metadataEdit.selectLogo' => 'Logo selecteren', 'metadataEdit.selectSquareArt' => 'Vierkante afbeelding selecteren', - 'metadataEdit.fromUrl' => 'Vanaf URL', - 'metadataEdit.uploadFile' => 'Bestand uploaden', _ => null, } ?? switch (path) { + 'metadataEdit.fromUrl' => 'Vanaf URL', + 'metadataEdit.uploadFile' => 'Bestand uploaden', 'metadataEdit.enterImageUrl' => 'Voer afbeeldings-URL in', 'metadataEdit.imageUrl' => 'Afbeeldings-URL', 'metadataEdit.metadataUpdated' => 'Metadata bijgewerkt', diff --git a/lib/i18n/strings_pl.g.dart b/lib/i18n/strings_pl.g.dart index f369bc84..19bb7f53 100644 --- a/lib/i18n/strings_pl.g.dart +++ b/lib/i18n/strings_pl.g.dart @@ -595,6 +595,7 @@ class _TranslationsVideoControlsPl extends TranslationsVideoControlsEn { @override String endsAt({required Object time}) => 'Kończy się o ${time}'; @override String get pipActive => 'Odtwarzanie w trybie obraz w obrazie'; @override String get pipFailed => 'Nie udało się uruchomić trybu obraz w obrazie'; + @override String get screenshotSaved => 'Zrzut ekranu zapisany'; @override late final _TranslationsVideoControlsPipErrorsPl pipErrors = _TranslationsVideoControlsPipErrorsPl._(_root); @override String get chapters => 'Rozdziały'; @override String get noChaptersAvailable => 'Brak dostępnych rozdziałów'; @@ -1556,6 +1557,7 @@ class _TranslationsHotkeysActionsPl extends TranslationsHotkeysActionsEn { @override String get subSeekPrev => 'Przewiń do poprzedniego napisu'; @override String get shaderToggle => 'Przełącz shadery'; @override String get skipMarker => 'Pomiń intro/napisy końcowe'; + @override String get screenshot => 'Zrób zrzut ekranu'; } // Path: videoControls.pipErrors @@ -2079,6 +2081,7 @@ extension on TranslationsPl { 'hotkeys.actions.subSeekPrev' => 'Przewiń do poprzedniego napisu', 'hotkeys.actions.shaderToggle' => 'Przełącz shadery', 'hotkeys.actions.skipMarker' => 'Pomiń intro/napisy końcowe', + 'hotkeys.actions.screenshot' => 'Zrób zrzut ekranu', 'fileInfo.title' => 'Informacje o pliku', 'fileInfo.video' => 'Wideo', 'fileInfo.audio' => 'Audio', @@ -2198,6 +2201,7 @@ extension on TranslationsPl { 'videoControls.endsAt' => ({required Object time}) => 'Kończy się o ${time}', 'videoControls.pipActive' => 'Odtwarzanie w trybie obraz w obrazie', 'videoControls.pipFailed' => 'Nie udało się uruchomić trybu obraz w obrazie', + 'videoControls.screenshotSaved' => 'Zrzut ekranu zapisany', 'videoControls.pipErrors.androidVersion' => 'Wymaga Androida 8.0 lub nowszego', 'videoControls.pipErrors.iosVersion' => 'Wymaga iOS 15.0 lub nowszego', 'videoControls.pipErrors.permissionDisabled' => 'Obraz w obrazie jest wyłączony. Włącz go w ustawieniach systemu.', @@ -2303,10 +2307,10 @@ extension on TranslationsPl { 'profiles.summarySingle' => 'Dodaj profile, aby łączyć zarządzanych użytkowników i tożsamości lokalne', 'profiles.summaryMultipleWithActive' => ({required Object count, required Object activeName}) => '${count} profili · aktywny: ${activeName}', 'profiles.summaryMultiple' => ({required Object count}) => '${count} profili', - 'profiles.removeConnectionTitle' => 'Usunąć połączenie?', - 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Usuń dostęp ${displayName} do ${connectionLabel}. Inne profile go zachowają.', _ => null, } ?? switch (path) { + 'profiles.removeConnectionTitle' => 'Usunąć połączenie?', + 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Usuń dostęp ${displayName} do ${connectionLabel}. Inne profile go zachowają.', 'profiles.deleteProfileTitle' => 'Usunąć profil?', 'profiles.deleteProfileMessage' => ({required Object displayName}) => 'Usuń ${displayName} i jego połączenia. Serwery pozostaną dostępne.', 'profiles.profileNameLabel' => 'Nazwa profilu', @@ -2817,10 +2821,10 @@ extension on TranslationsPl { 'metadataEdit.selectBackground' => 'Wybierz tło', 'metadataEdit.selectLogo' => 'Wybierz logo', 'metadataEdit.selectSquareArt' => 'Wybierz kwadratowy obraz', - 'metadataEdit.fromUrl' => 'Z URL', - 'metadataEdit.uploadFile' => 'Prześlij plik', _ => null, } ?? switch (path) { + 'metadataEdit.fromUrl' => 'Z URL', + 'metadataEdit.uploadFile' => 'Prześlij plik', 'metadataEdit.enterImageUrl' => 'Wprowadź URL obrazu', 'metadataEdit.imageUrl' => 'URL obrazu', 'metadataEdit.metadataUpdated' => 'Metadane zaktualizowane', diff --git a/lib/i18n/strings_pt.g.dart b/lib/i18n/strings_pt.g.dart index 1b01573a..8de947b1 100644 --- a/lib/i18n/strings_pt.g.dart +++ b/lib/i18n/strings_pt.g.dart @@ -595,6 +595,7 @@ class _TranslationsVideoControlsPt extends TranslationsVideoControlsEn { @override String endsAt({required Object time}) => 'Termina às ${time}'; @override String get pipActive => 'Reproduzindo em Picture-in-Picture'; @override String get pipFailed => 'Falha ao iniciar picture-in-picture'; + @override String get screenshotSaved => 'Captura de tela salva'; @override late final _TranslationsVideoControlsPipErrorsPt pipErrors = _TranslationsVideoControlsPipErrorsPt._(_root); @override String get chapters => 'Capítulos'; @override String get noChaptersAvailable => 'Nenhum capítulo disponível'; @@ -1556,6 +1557,7 @@ class _TranslationsHotkeysActionsPt extends TranslationsHotkeysActionsEn { @override String get subSeekPrev => 'Ir para Legenda Anterior'; @override String get shaderToggle => 'Alternar Shaders'; @override String get skipMarker => 'Pular Intro/Créditos'; + @override String get screenshot => 'Capturar tela'; } // Path: videoControls.pipErrors @@ -2079,6 +2081,7 @@ extension on TranslationsPt { 'hotkeys.actions.subSeekPrev' => 'Ir para Legenda Anterior', 'hotkeys.actions.shaderToggle' => 'Alternar Shaders', 'hotkeys.actions.skipMarker' => 'Pular Intro/Créditos', + 'hotkeys.actions.screenshot' => 'Capturar tela', 'fileInfo.title' => 'Info do Arquivo', 'fileInfo.video' => 'Vídeo', 'fileInfo.audio' => 'Áudio', @@ -2198,6 +2201,7 @@ extension on TranslationsPt { 'videoControls.endsAt' => ({required Object time}) => 'Termina às ${time}', 'videoControls.pipActive' => 'Reproduzindo em Picture-in-Picture', 'videoControls.pipFailed' => 'Falha ao iniciar picture-in-picture', + 'videoControls.screenshotSaved' => 'Captura de tela salva', 'videoControls.pipErrors.androidVersion' => 'Requer Android 8.0 ou superior', 'videoControls.pipErrors.iosVersion' => 'Requer iOS 15.0 ou superior', 'videoControls.pipErrors.permissionDisabled' => 'Picture-in-picture está desativado. Ative nas configurações do sistema.', @@ -2303,10 +2307,10 @@ extension on TranslationsPt { 'profiles.summarySingle' => 'Adicione perfis para mesclar usuários gerenciados e identidades locais', 'profiles.summaryMultipleWithActive' => ({required Object count, required Object activeName}) => '${count} perfis · ativo: ${activeName}', 'profiles.summaryMultiple' => ({required Object count}) => '${count} perfis', - 'profiles.removeConnectionTitle' => 'Remover conexão?', - 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Remover acesso de ${displayName} a ${connectionLabel}. Outros perfis mantêm o acesso.', _ => null, } ?? switch (path) { + 'profiles.removeConnectionTitle' => 'Remover conexão?', + 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Remover acesso de ${displayName} a ${connectionLabel}. Outros perfis mantêm o acesso.', 'profiles.deleteProfileTitle' => 'Excluir perfil?', 'profiles.deleteProfileMessage' => ({required Object displayName}) => 'Remover ${displayName} e suas conexões. Servidores continuam disponíveis.', 'profiles.profileNameLabel' => 'Nome do perfil', @@ -2817,10 +2821,10 @@ extension on TranslationsPt { 'metadataEdit.selectBackground' => 'Selecionar Plano de Fundo', 'metadataEdit.selectLogo' => 'Selecionar Logo', 'metadataEdit.selectSquareArt' => 'Selecionar Imagem Quadrada', - 'metadataEdit.fromUrl' => 'Da URL', - 'metadataEdit.uploadFile' => 'Enviar Arquivo', _ => null, } ?? switch (path) { + 'metadataEdit.fromUrl' => 'Da URL', + 'metadataEdit.uploadFile' => 'Enviar Arquivo', 'metadataEdit.enterImageUrl' => 'Insira a URL da imagem', 'metadataEdit.imageUrl' => 'URL da Imagem', 'metadataEdit.metadataUpdated' => 'Metadados atualizados', diff --git a/lib/i18n/strings_ru.g.dart b/lib/i18n/strings_ru.g.dart index 037b7f95..8dcc1777 100644 --- a/lib/i18n/strings_ru.g.dart +++ b/lib/i18n/strings_ru.g.dart @@ -595,6 +595,7 @@ class _TranslationsVideoControlsRu extends TranslationsVideoControlsEn { @override String endsAt({required Object time}) => 'Закончится в ${time}'; @override String get pipActive => 'Воспроизводится в режиме «картинка в картинке»'; @override String get pipFailed => 'Не удалось запустить режим «картинка в картинке»'; + @override String get screenshotSaved => 'Снимок экрана сохранён'; @override late final _TranslationsVideoControlsPipErrorsRu pipErrors = _TranslationsVideoControlsPipErrorsRu._(_root); @override String get chapters => 'Главы'; @override String get noChaptersAvailable => 'Главы недоступны'; @@ -1556,6 +1557,7 @@ class _TranslationsHotkeysActionsRu extends TranslationsHotkeysActionsEn { @override String get subSeekPrev => 'К предыдущему субтитру'; @override String get shaderToggle => 'Вкл./выкл. шейдеры'; @override String get skipMarker => 'Пропустить вступление/титры'; + @override String get screenshot => 'Сделать снимок экрана'; } // Path: videoControls.pipErrors @@ -2079,6 +2081,7 @@ extension on TranslationsRu { 'hotkeys.actions.subSeekPrev' => 'К предыдущему субтитру', 'hotkeys.actions.shaderToggle' => 'Вкл./выкл. шейдеры', 'hotkeys.actions.skipMarker' => 'Пропустить вступление/титры', + 'hotkeys.actions.screenshot' => 'Сделать снимок экрана', 'fileInfo.title' => 'Информация о файле', 'fileInfo.video' => 'Видео', 'fileInfo.audio' => 'Аудио', @@ -2198,6 +2201,7 @@ extension on TranslationsRu { 'videoControls.endsAt' => ({required Object time}) => 'Закончится в ${time}', 'videoControls.pipActive' => 'Воспроизводится в режиме «картинка в картинке»', 'videoControls.pipFailed' => 'Не удалось запустить режим «картинка в картинке»', + 'videoControls.screenshotSaved' => 'Снимок экрана сохранён', 'videoControls.pipErrors.androidVersion' => 'Требуется Android 8.0 или новее', 'videoControls.pipErrors.iosVersion' => 'Требуется iOS 15.0 или новее', 'videoControls.pipErrors.permissionDisabled' => 'Картинка-в-картинке отключена. Включите ее в системных настройках.', @@ -2303,10 +2307,10 @@ extension on TranslationsRu { 'profiles.summarySingle' => 'Добавьте профили, чтобы смешать управляемых пользователей и локальные идентификаторы', 'profiles.summaryMultipleWithActive' => ({required Object count, required Object activeName}) => '${count} профилей · активный: ${activeName}', 'profiles.summaryMultiple' => ({required Object count}) => '${count} профилей', - 'profiles.removeConnectionTitle' => 'Удалить соединение?', - 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Удалить доступ ${displayName} к ${connectionLabel}. У других профилей он останется.', _ => null, } ?? switch (path) { + 'profiles.removeConnectionTitle' => 'Удалить соединение?', + 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Удалить доступ ${displayName} к ${connectionLabel}. У других профилей он останется.', 'profiles.deleteProfileTitle' => 'Удалить профиль?', 'profiles.deleteProfileMessage' => ({required Object displayName}) => 'Удалить ${displayName} и его подключения. Серверы останутся доступны.', 'profiles.profileNameLabel' => 'Имя профиля', @@ -2817,10 +2821,10 @@ extension on TranslationsRu { 'metadataEdit.selectBackground' => 'Выбрать фон', 'metadataEdit.selectLogo' => 'Выбрать логотип', 'metadataEdit.selectSquareArt' => 'Выбрать квадратное изображение', - 'metadataEdit.fromUrl' => 'По URL', - 'metadataEdit.uploadFile' => 'Загрузить файл', _ => null, } ?? switch (path) { + 'metadataEdit.fromUrl' => 'По URL', + 'metadataEdit.uploadFile' => 'Загрузить файл', 'metadataEdit.enterImageUrl' => 'Введите URL изображения', 'metadataEdit.imageUrl' => 'URL изображения', 'metadataEdit.metadataUpdated' => 'Метаданные обновлены', diff --git a/lib/i18n/strings_sv.g.dart b/lib/i18n/strings_sv.g.dart index 768e148d..be687bf1 100644 --- a/lib/i18n/strings_sv.g.dart +++ b/lib/i18n/strings_sv.g.dart @@ -595,6 +595,7 @@ class _TranslationsVideoControlsSv extends TranslationsVideoControlsEn { @override String endsAt({required Object time}) => 'Slutar ${time}'; @override String get pipActive => 'Spelar i bild-i-bild'; @override String get pipFailed => 'Bild-i-bild kunde inte starta'; + @override String get screenshotSaved => 'Skärmbild sparad'; @override late final _TranslationsVideoControlsPipErrorsSv pipErrors = _TranslationsVideoControlsPipErrorsSv._(_root); @override String get chapters => 'Kapitel'; @override String get noChaptersAvailable => 'Inga kapitel tillgängliga'; @@ -1556,6 +1557,7 @@ class _TranslationsHotkeysActionsSv extends TranslationsHotkeysActionsEn { @override String get subSeekPrev => 'Hoppa till föregående undertext'; @override String get shaderToggle => 'Växla shaders'; @override String get skipMarker => 'Hoppa över intro/eftertexter'; + @override String get screenshot => 'Ta skärmbild'; } // Path: videoControls.pipErrors @@ -2079,6 +2081,7 @@ extension on TranslationsSv { 'hotkeys.actions.subSeekPrev' => 'Hoppa till föregående undertext', 'hotkeys.actions.shaderToggle' => 'Växla shaders', 'hotkeys.actions.skipMarker' => 'Hoppa över intro/eftertexter', + 'hotkeys.actions.screenshot' => 'Ta skärmbild', 'fileInfo.title' => 'Filinformation', 'fileInfo.video' => 'Video', 'fileInfo.audio' => 'Ljud', @@ -2198,6 +2201,7 @@ extension on TranslationsSv { 'videoControls.endsAt' => ({required Object time}) => 'Slutar ${time}', 'videoControls.pipActive' => 'Spelar i bild-i-bild', 'videoControls.pipFailed' => 'Bild-i-bild kunde inte starta', + 'videoControls.screenshotSaved' => 'Skärmbild sparad', 'videoControls.pipErrors.androidVersion' => 'Kräver Android 8.0 eller nyare', 'videoControls.pipErrors.iosVersion' => 'Kräver iOS 15.0 eller nyare', 'videoControls.pipErrors.permissionDisabled' => 'Bild-i-bild är inaktiverat. Aktivera det i systeminställningarna.', @@ -2303,10 +2307,10 @@ extension on TranslationsSv { 'profiles.summarySingle' => 'Lägg till profiler för att blanda hanterade användare och lokala identiteter', 'profiles.summaryMultipleWithActive' => ({required Object count, required Object activeName}) => '${count} profiler · aktiv: ${activeName}', 'profiles.summaryMultiple' => ({required Object count}) => '${count} profiler', - 'profiles.removeConnectionTitle' => 'Ta bort anslutning?', - 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Ta bort ${displayName}s åtkomst till ${connectionLabel}. Andra profiler behåller den.', _ => null, } ?? switch (path) { + 'profiles.removeConnectionTitle' => 'Ta bort anslutning?', + 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => 'Ta bort ${displayName}s åtkomst till ${connectionLabel}. Andra profiler behåller den.', 'profiles.deleteProfileTitle' => 'Ta bort profil?', 'profiles.deleteProfileMessage' => ({required Object displayName}) => 'Ta bort ${displayName} och dess anslutningar. Servrar förblir tillgängliga.', 'profiles.profileNameLabel' => 'Profilnamn', @@ -2817,10 +2821,10 @@ extension on TranslationsSv { 'metadataEdit.selectBackground' => 'Välj bakgrund', 'metadataEdit.selectLogo' => 'Välj logotyp', 'metadataEdit.selectSquareArt' => 'Välj kvadratisk bild', - 'metadataEdit.fromUrl' => 'Från URL', - 'metadataEdit.uploadFile' => 'Ladda upp fil', _ => null, } ?? switch (path) { + 'metadataEdit.fromUrl' => 'Från URL', + 'metadataEdit.uploadFile' => 'Ladda upp fil', 'metadataEdit.enterImageUrl' => 'Ange bild-URL', 'metadataEdit.imageUrl' => 'Bild-URL', 'metadataEdit.metadataUpdated' => 'Metadata uppdaterad', diff --git a/lib/i18n/strings_zh.g.dart b/lib/i18n/strings_zh.g.dart index 44a8fd16..48ea386d 100644 --- a/lib/i18n/strings_zh.g.dart +++ b/lib/i18n/strings_zh.g.dart @@ -595,6 +595,7 @@ class _TranslationsVideoControlsZh extends TranslationsVideoControlsEn { @override String endsAt({required Object time}) => '${time} 结束'; @override String get pipActive => '正在画中画模式中播放'; @override String get pipFailed => '画中画启动失败'; + @override String get screenshotSaved => '截图已保存'; @override late final _TranslationsVideoControlsPipErrorsZh pipErrors = _TranslationsVideoControlsPipErrorsZh._(_root); @override String get chapters => '章节'; @override String get noChaptersAvailable => '没有可用的章节'; @@ -1556,6 +1557,7 @@ class _TranslationsHotkeysActionsZh extends TranslationsHotkeysActionsEn { @override String get subSeekPrev => '跳转到上一字幕'; @override String get shaderToggle => '切换着色器'; @override String get skipMarker => '跳过片头/片尾'; + @override String get screenshot => '截图'; } // Path: videoControls.pipErrors @@ -2079,6 +2081,7 @@ extension on TranslationsZh { 'hotkeys.actions.subSeekPrev' => '跳转到上一字幕', 'hotkeys.actions.shaderToggle' => '切换着色器', 'hotkeys.actions.skipMarker' => '跳过片头/片尾', + 'hotkeys.actions.screenshot' => '截图', 'fileInfo.title' => '文件信息', 'fileInfo.video' => '视频', 'fileInfo.audio' => '音频', @@ -2198,6 +2201,7 @@ extension on TranslationsZh { 'videoControls.endsAt' => ({required Object time}) => '${time} 结束', 'videoControls.pipActive' => '正在画中画模式中播放', 'videoControls.pipFailed' => '画中画启动失败', + 'videoControls.screenshotSaved' => '截图已保存', 'videoControls.pipErrors.androidVersion' => '需要 Android 8.0 或更高版本', 'videoControls.pipErrors.iosVersion' => '需要 iOS 15.0 或更高版本', 'videoControls.pipErrors.permissionDisabled' => '画中画已禁用。请在系统设置中启用。', @@ -2303,10 +2307,10 @@ extension on TranslationsZh { 'profiles.summarySingle' => '添加配置文件以混合托管用户和本地身份', 'profiles.summaryMultipleWithActive' => ({required Object count, required Object activeName}) => '${count} 个配置文件 · 活跃:${activeName}', 'profiles.summaryMultiple' => ({required Object count}) => '${count} 个配置文件', - 'profiles.removeConnectionTitle' => '移除连接?', - 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => '移除 ${displayName} 对 ${connectionLabel} 的访问。其他个人资料仍保留。', _ => null, } ?? switch (path) { + 'profiles.removeConnectionTitle' => '移除连接?', + 'profiles.removeConnectionMessage' => ({required Object displayName, required Object connectionLabel}) => '移除 ${displayName} 对 ${connectionLabel} 的访问。其他个人资料仍保留。', 'profiles.deleteProfileTitle' => '删除配置文件?', 'profiles.deleteProfileMessage' => ({required Object displayName}) => '移除 ${displayName} 及其连接。服务器仍可用。', 'profiles.profileNameLabel' => '配置文件名称', @@ -2817,10 +2821,10 @@ extension on TranslationsZh { 'metadataEdit.selectBackground' => '选择背景', 'metadataEdit.selectLogo' => '选择标志', 'metadataEdit.selectSquareArt' => '选择方形图片', - 'metadataEdit.fromUrl' => '从 URL', - 'metadataEdit.uploadFile' => '上传文件', _ => null, } ?? switch (path) { + 'metadataEdit.fromUrl' => '从 URL', + 'metadataEdit.uploadFile' => '上传文件', 'metadataEdit.enterImageUrl' => '输入图片 URL', 'metadataEdit.imageUrl' => '图片 URL', 'metadataEdit.metadataUpdated' => '元数据已更新', diff --git a/lib/i18n/sv.i18n.json b/lib/i18n/sv.i18n.json index 7531dc6b..bb725c6b 100644 --- a/lib/i18n/sv.i18n.json +++ b/lib/i18n/sv.i18n.json @@ -300,7 +300,8 @@ "subSeekNext": "Hoppa till nästa undertext", "subSeekPrev": "Hoppa till föregående undertext", "shaderToggle": "Växla shaders", - "skipMarker": "Hoppa över intro/eftertexter" + "skipMarker": "Hoppa över intro/eftertexter", + "screenshot": "Ta skärmbild" } }, "fileInfo": { @@ -433,6 +434,7 @@ "endsAt": "Slutar ${time}", "pipActive": "Spelar i bild-i-bild", "pipFailed": "Bild-i-bild kunde inte starta", + "screenshotSaved": "Skärmbild sparad", "pipErrors": { "androidVersion": "Kräver Android 8.0 eller nyare", "iosVersion": "Kräver iOS 15.0 eller nyare", diff --git a/lib/i18n/zh.i18n.json b/lib/i18n/zh.i18n.json index 921e98c5..bfd41a7f 100644 --- a/lib/i18n/zh.i18n.json +++ b/lib/i18n/zh.i18n.json @@ -300,7 +300,8 @@ "subSeekNext": "跳转到下一字幕", "subSeekPrev": "跳转到上一字幕", "shaderToggle": "切换着色器", - "skipMarker": "跳过片头/片尾" + "skipMarker": "跳过片头/片尾", + "screenshot": "截图" } }, "fileInfo": { @@ -433,6 +434,7 @@ "endsAt": "${time} 结束", "pipActive": "正在画中画模式中播放", "pipFailed": "画中画启动失败", + "screenshotSaved": "截图已保存", "pipErrors": { "androidVersion": "需要 Android 8.0 或更高版本", "iosVersion": "需要 iOS 15.0 或更高版本", diff --git a/lib/screens/video_player_screen.dart b/lib/screens/video_player_screen.dart index 7fa1e5ca..94acfd47 100644 --- a/lib/screens/video_player_screen.dart +++ b/lib/screens/video_player_screen.dart @@ -733,6 +733,10 @@ class VideoPlayerScreenState extends State with WidgetsBindin await currentPlayer.setProperty('af', 'loudnorm=I=-14:TP=-3:LRA=4'); } + if (PlatformDetector.isDesktopOS()) { + await currentPlayer.setProperty('screenshot-directory', '~/Pictures'); + } + final customMpvConfig = SettingsService.parseMpvConfigText(settingsService.read(SettingsService.mpvConfigText)); for (final entry in customMpvConfig.entries) { try { diff --git a/lib/services/keyboard_shortcuts_service.dart b/lib/services/keyboard_shortcuts_service.dart index a0e62226..c4db0b87 100644 --- a/lib/services/keyboard_shortcuts_service.dart +++ b/lib/services/keyboard_shortcuts_service.dart @@ -182,6 +182,7 @@ class KeyboardShortcutsService extends ChangeNotifier { VoidCallback? onSkipMarker, VoidCallback? onNextEpisode, VoidCallback? onPreviousEpisode, + VoidCallback? onScreenshot, int? currentPositionEpoch, ValueChanged? onLiveSeek, }) { @@ -258,6 +259,7 @@ class KeyboardShortcutsService extends ChangeNotifier { onSkipMarker: onSkipMarker, onNextEpisode: onNextEpisode, onPreviousEpisode: onPreviousEpisode, + onScreenshot: onScreenshot, currentPositionEpoch: currentPositionEpoch, onLiveSeek: onLiveSeek, ); @@ -281,6 +283,7 @@ class KeyboardShortcutsService extends ChangeNotifier { VoidCallback? onSkipMarker, VoidCallback? onNextEpisode, VoidCallback? onPreviousEpisode, + VoidCallback? onScreenshot, int? currentPositionEpoch, ValueChanged? onLiveSeek, }) { @@ -374,6 +377,9 @@ class KeyboardShortcutsService extends ChangeNotifier { case 'skip_marker': onSkipMarker?.call(); break; + case 'screenshot': + unawaited(player.command(['screenshot', 'window']).then((_) => onScreenshot?.call())); + break; } } @@ -425,6 +431,8 @@ class KeyboardShortcutsService extends ChangeNotifier { return t.hotkeys.actions.shaderToggle; case 'skip_marker': return t.hotkeys.actions.skipMarker; + case 'screenshot': + return t.hotkeys.actions.screenshot; default: return action; } diff --git a/lib/services/settings_service.dart b/lib/services/settings_service.dart index 5c62d945..55e628db 100644 --- a/lib/services/settings_service.dart +++ b/lib/services/settings_service.dart @@ -207,6 +207,7 @@ Map _defaultKeyboardShortcuts() => { 'speed_reset': 'R', 'sub_seek_next': 'Ctrl+Right', 'sub_seek_prev': 'Ctrl+Left', + 'screenshot': 'Ctrl+S', }; Map _defaultKeyboardHotkeys() => { @@ -233,6 +234,7 @@ Map _defaultKeyboardHotkeys() => { 'sub_seek_prev': const HotKey(key: PhysicalKeyboardKey.arrowLeft, modifiers: [HotKeyModifier.control]), 'shader_toggle': const HotKey(key: PhysicalKeyboardKey.keyG), 'skip_marker': const HotKey(key: PhysicalKeyboardKey.enter), + 'screenshot': const HotKey(key: PhysicalKeyboardKey.keyS, modifiers: [HotKeyModifier.control]), }; Map _decodeKeyboardShortcuts(dynamic raw) { diff --git a/lib/widgets/video_controls/parts/key_events.dart b/lib/widgets/video_controls/parts/key_events.dart index 35f9ded0..8c5b7c9f 100644 --- a/lib/widgets/video_controls/parts/key_events.dart +++ b/lib/widgets/video_controls/parts/key_events.dart @@ -5,6 +5,10 @@ extension _PlexVideoControlsKeyEventMethods on _PlexVideoControlsState { _keyboardService = await KeyboardShortcutsService.getInstance(); } + void _showScreenshotToast() { + widget.toastController.show(Symbols.photo_camera_rounded, t.videoControls.screenshotSaved); + } + bool _isDirectionalKey(LogicalKeyboardKey key) { return key == LogicalKeyboardKey.arrowUp || key == LogicalKeyboardKey.arrowDown || @@ -151,6 +155,7 @@ extension _PlexVideoControlsKeyEventMethods on _PlexVideoControlsState { onToggleShader: _toggleShader, onNextEpisode: widget.onNext, onPreviousEpisode: widget.onPrevious, + onScreenshot: _showScreenshotToast, currentPositionEpoch: widget.currentPositionEpoch, onLiveSeek: widget.onLiveSeek, ); @@ -298,6 +303,7 @@ extension _PlexVideoControlsKeyEventMethods on _PlexVideoControlsState { onSkipMarker: _performAutoSkip, onNextEpisode: widget.onNext, onPreviousEpisode: widget.onPrevious, + onScreenshot: _showScreenshotToast, currentPositionEpoch: widget.currentPositionEpoch, onLiveSeek: widget.onLiveSeek, ); diff --git a/test/services/keyboard_shortcuts_service_test.dart b/test/services/keyboard_shortcuts_service_test.dart new file mode 100644 index 00000000..9627f7e9 --- /dev/null +++ b/test/services/keyboard_shortcuts_service_test.dart @@ -0,0 +1,62 @@ +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:plezy/mpv/mpv.dart'; +import 'package:plezy/services/keyboard_shortcuts_service.dart'; +import 'package:plezy/services/settings_service.dart'; + +import '../test_helpers/prefs.dart'; + +void main() { + setUp(() { + resetSharedPreferencesForTest(); + SettingsService.resetForTesting(); + }); + + testWidgets('Ctrl+S takes a screenshot and shows feedback', (tester) async { + final service = await KeyboardShortcutsService.getInstance(); + addTearDown(service.dispose); + final player = _FakePlayer(); + var feedbackCount = 0; + + await tester.sendKeyDownEvent(LogicalKeyboardKey.controlLeft); + final result = service.handleVideoPlayerKeyEvent( + const KeyDownEvent( + physicalKey: PhysicalKeyboardKey.keyS, + logicalKey: LogicalKeyboardKey.keyS, + timeStamp: Duration.zero, + ), + player, + null, + null, + null, + null, + null, + null, + onScreenshot: () => feedbackCount++, + ); + await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft); + await tester.pump(); + + expect(result, KeyEventResult.handled); + expect(player.commands, [ + ['screenshot', 'window'], + ]); + expect(feedbackCount, 1); + }); +} + +class _FakePlayer implements Player { + final commands = >[]; + + @override + Future command(List args) async { + commands.add(args); + } + + @override + PlayerState get state => PlayerState(); + + @override + dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); +} diff --git a/test/services/settings_service_test.dart b/test/services/settings_service_test.dart index 92eddfc3..23915c78 100644 --- a/test/services/settings_service_test.dart +++ b/test/services/settings_service_test.dart @@ -1,4 +1,6 @@ +import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:plezy/models/hotkey_model.dart'; import 'package:plezy/services/settings_service.dart'; import 'package:plezy/services/trackers/tracker_constants.dart'; @@ -61,6 +63,17 @@ void main() { }); }); + group('SettingsService keyboard shortcut defaults', () { + test('includes Ctrl+S screenshot shortcut', () { + expect(SettingsService.defaultKeyboardShortcuts()['screenshot'], 'Ctrl+S'); + + final hotkey = SettingsService.defaultKeyboardHotkeys()['screenshot']; + expect(hotkey, isNotNull); + expect(hotkey!.key, PhysicalKeyboardKey.keyS); + expect(hotkey.modifiers, [HotKeyModifier.control]); + }); + }); + group('SettingsService listenables', () { test('refreshListenables updates active prefs outside the resettable surface', () async { final settings = await SettingsService.getInstance();