diff --git a/lib/i18n/da.i18n.json b/lib/i18n/da.i18n.json index 3337b244..17deb54d 100644 --- a/lib/i18n/da.i18n.json +++ b/lib/i18n/da.i18n.json @@ -97,6 +97,11 @@ "autoSkipCreditsDescription": "Spring automatisk rulletekster over og afspil næste episode", "autoSkipDelay": "Auto-spring forsinkelse", "autoSkipDelayDescription": "Vent ${seconds} sekunder før automatisk spring", + "introPattern": "Intromarkørmønster", + "introPatternDescription": "Regulært udtryk til at genkende intromarkører i kapiteltitler", + "creditsPattern": "Rulletekstmarkørmønster", + "creditsPatternDescription": "Regulært udtryk til at genkende rulletekstmarkører i kapiteltitler", + "invalidRegex": "Ugyldigt regulært udtryk", "downloads": "Downloads", "downloadLocationDescription": "Vælg hvor downloadet indhold skal gemmes", "downloadLocationDefault": "Standard (App-lagring)", "downloadLocationCustom": "Brugerdefineret placering", "selectFolder": "Vælg mappe", "resetToDefault": "Nulstil til standard", diff --git a/lib/i18n/de.i18n.json b/lib/i18n/de.i18n.json index d1ca2b5e..6e38bfca 100644 --- a/lib/i18n/de.i18n.json +++ b/lib/i18n/de.i18n.json @@ -178,6 +178,11 @@ "autoSkipCreditsDescription": "Abspann automatisch überspringen und nächste Episode abspielen", "autoSkipDelay": "Verzögerung für automatisches Überspringen", "autoSkipDelayDescription": "${seconds} Sekunden vor dem automatischen Überspringen warten", + "introPattern": "Intro-Markierungsmuster", + "introPatternDescription": "Regulärer Ausdruck zum Erkennen von Intro-Markierungen in Kapiteltiteln", + "creditsPattern": "Abspann-Markierungsmuster", + "creditsPatternDescription": "Regulärer Ausdruck zum Erkennen von Abspann-Markierungen in Kapiteltiteln", + "invalidRegex": "Ungültiger regulärer Ausdruck", "downloads": "Downloads", "downloadLocationDescription": "Speicherort für heruntergeladene Inhalte wählen", "downloadLocationDefault": "Standard (App-Speicher)", diff --git a/lib/i18n/en.i18n.json b/lib/i18n/en.i18n.json index 9d1a0053..cff9fb08 100644 --- a/lib/i18n/en.i18n.json +++ b/lib/i18n/en.i18n.json @@ -178,6 +178,11 @@ "autoSkipCreditsDescription": "Automatically skip credits and play next episode", "autoSkipDelay": "Auto Skip Delay", "autoSkipDelayDescription": "Wait ${seconds} seconds before auto-skipping", + "introPattern": "Intro Marker Pattern", + "introPatternDescription": "Regex pattern to match intro markers in chapter titles", + "creditsPattern": "Credits Marker Pattern", + "creditsPatternDescription": "Regex pattern to match credits markers in chapter titles", + "invalidRegex": "Invalid regular expression", "downloads": "Downloads", "downloadLocationDescription": "Choose where to store downloaded content", "downloadLocationDefault": "Default (App Storage)", diff --git a/lib/i18n/es.i18n.json b/lib/i18n/es.i18n.json index 992c7b27..32887324 100644 --- a/lib/i18n/es.i18n.json +++ b/lib/i18n/es.i18n.json @@ -178,6 +178,11 @@ "autoSkipCreditsDescription": "Saltar automáticamente los créditos y reproducir el siguiente episodio", "autoSkipDelay": "Retraso de Salto automático", "autoSkipDelayDescription": "Esperar ${seconds} segundos antes de saltar automáticamente", + "introPattern": "Patrón de marcador de intro", + "introPatternDescription": "Expresión regular para reconocer marcadores de intro en los títulos de capítulos", + "creditsPattern": "Patrón de marcador de créditos", + "creditsPatternDescription": "Expresión regular para reconocer marcadores de créditos en los títulos de capítulos", + "invalidRegex": "Expresión regular no válida", "downloads": "Descargas", "downloadLocationDescription": "Elegir dónde almacenar el contenido descargado", "downloadLocationDefault": "Predeterminado (Almacenamiento de la App)", diff --git a/lib/i18n/fr.i18n.json b/lib/i18n/fr.i18n.json index b626282f..eac0d86e 100644 --- a/lib/i18n/fr.i18n.json +++ b/lib/i18n/fr.i18n.json @@ -178,6 +178,11 @@ "autoSkipCreditsDescription": "Passer les crédits et passer à l'épisode suivant automatiquement", "autoSkipDelay": "Délai avant skip automatique", "autoSkipDelayDescription": "Attendre ${seconds} secondes avant l'auto-skip", + "introPattern": "Modèle de marqueur d'intro", + "introPatternDescription": "Expression régulière pour reconnaître les marqueurs d'intro dans les titres de chapitres", + "creditsPattern": "Modèle de marqueur de générique", + "creditsPatternDescription": "Expression régulière pour reconnaître les marqueurs de générique dans les titres de chapitres", + "invalidRegex": "Expression régulière invalide", "downloads": "Téléchargement", "downloadLocationDescription": "Choisissez où stocker le contenu téléchargé", "downloadLocationDefault": "Par défaut (stockage de l'application)", diff --git a/lib/i18n/it.i18n.json b/lib/i18n/it.i18n.json index 3c4f9096..072a16f3 100644 --- a/lib/i18n/it.i18n.json +++ b/lib/i18n/it.i18n.json @@ -178,6 +178,11 @@ "autoSkipCreditsDescription": "Salta automaticamente i crediti e riproduci l'episodio successivo", "autoSkipDelay": "Ritardo Salto Automatico", "autoSkipDelayDescription": "Aspetta ${seconds} secondi prima del salto automatico", + "introPattern": "Pattern marcatore intro", + "introPatternDescription": "Espressione regolare per riconoscere i marcatori intro nei titoli dei capitoli", + "creditsPattern": "Pattern marcatore titoli di coda", + "creditsPatternDescription": "Espressione regolare per riconoscere i marcatori dei titoli di coda nei capitoli", + "invalidRegex": "Espressione regolare non valida", "downloads": "Download", "downloadLocationDescription": "Scegli dove salvare i contenuti scaricati", "downloadLocationDefault": "Predefinita (Archiviazione App)", diff --git a/lib/i18n/ja.i18n.json b/lib/i18n/ja.i18n.json index 7ed55db0..e3ee2b14 100644 --- a/lib/i18n/ja.i18n.json +++ b/lib/i18n/ja.i18n.json @@ -178,6 +178,11 @@ "autoSkipCreditsDescription": "クレジットを自動的にスキップして次のエピソードを再生", "autoSkipDelay": "自動スキップの遅延", "autoSkipDelayDescription": "自動スキップまで${seconds}秒待機", + "introPattern": "イントロマーカーパターン", + "introPatternDescription": "チャプタータイトルのイントロマーカーに一致する正規表現パターン", + "creditsPattern": "クレジットマーカーパターン", + "creditsPatternDescription": "チャプタータイトルのクレジットマーカーに一致する正規表現パターン", + "invalidRegex": "無効な正規表現", "downloads": "ダウンロード", "downloadLocationDescription": "ダウンロードコンテンツの保存場所を選択", "downloadLocationDefault": "デフォルト(アプリストレージ)", diff --git a/lib/i18n/ko.i18n.json b/lib/i18n/ko.i18n.json index 93271406..b6ef8420 100644 --- a/lib/i18n/ko.i18n.json +++ b/lib/i18n/ko.i18n.json @@ -178,6 +178,11 @@ "autoSkipCreditsDescription": "엔딩 크레딧 자동 건너뛰기 후 다음 에피소드 재생", "autoSkipDelay": "자동 건너뛰기 지연", "autoSkipDelayDescription": "자동 건너뛰기 전 ${seconds} 초 대기", + "introPattern": "인트로 마커 패턴", + "introPatternDescription": "챕터 제목에서 인트로 마커를 인식하는 정규식 패턴", + "creditsPattern": "크레딧 마커 패턴", + "creditsPatternDescription": "챕터 제목에서 크레딧 마커를 인식하는 정규식 패턴", + "invalidRegex": "잘못된 정규식", "downloads": "다운로드", "downloadLocationDescription": "다운로드 콘텐츠 저장 위치 선택", "downloadLocationDefault": "기본값 (앱 저장소)", diff --git a/lib/i18n/nb.i18n.json b/lib/i18n/nb.i18n.json index 1fb18134..3dc1d46a 100644 --- a/lib/i18n/nb.i18n.json +++ b/lib/i18n/nb.i18n.json @@ -178,6 +178,11 @@ "autoSkipCreditsDescription": "Hopp automatisk over rulletekst og spill neste episode", "autoSkipDelay": "Forsinkelse for automatisk hopp", "autoSkipDelayDescription": "Vent ${seconds} sekunder før automatisk hopping", + "introPattern": "Intromarkørmønster", + "introPatternDescription": "Regulært uttrykk for å gjenkjenne intromarkører i kapitteltitler", + "creditsPattern": "Rulletekstmarkørmønster", + "creditsPatternDescription": "Regulært uttrykk for å gjenkjenne rulletekstmarkører i kapitteltitler", + "invalidRegex": "Ugyldig regulært uttrykk", "downloads": "Nedlastinger", "downloadLocationDescription": "Velg hvor nedlastet innhold skal lagres", "downloadLocationDefault": "Standard (App-lagring)", diff --git a/lib/i18n/nl.i18n.json b/lib/i18n/nl.i18n.json index dc312e12..54f4ec95 100644 --- a/lib/i18n/nl.i18n.json +++ b/lib/i18n/nl.i18n.json @@ -178,6 +178,11 @@ "autoSkipCreditsDescription": "Credits automatisch overslaan en volgende aflevering afspelen", "autoSkipDelay": "Vertraging Automatisch Overslaan", "autoSkipDelayDescription": "${seconds} seconden wachten voor automatisch overslaan", + "introPattern": "Intromarkeringspatroon", + "introPatternDescription": "Reguliere expressie om intromarkeringen in hoofdstuktitels te herkennen", + "creditsPattern": "Aftitelingmarkeringspatroon", + "creditsPatternDescription": "Reguliere expressie om aftitelingmarkeringen in hoofdstuktitels te herkennen", + "invalidRegex": "Ongeldige reguliere expressie", "downloads": "Downloads", "downloadLocationDescription": "Kies waar gedownloade content wordt opgeslagen", "downloadLocationDefault": "Standaard (App-opslag)", diff --git a/lib/i18n/pl.i18n.json b/lib/i18n/pl.i18n.json index ccf74d2e..789107fb 100644 --- a/lib/i18n/pl.i18n.json +++ b/lib/i18n/pl.i18n.json @@ -178,6 +178,11 @@ "autoSkipCreditsDescription": "Automatycznie pomijaj napisy końcowe i odtwórz następny odcinek", "autoSkipDelay": "Opóźnienie automatycznego pomijania", "autoSkipDelayDescription": "Czekaj ${seconds} sekund przed automatycznym pominięciem", + "introPattern": "Wzorzec znacznika intro", + "introPatternDescription": "Wyrażenie regularne do rozpoznawania znaczników intro w tytułach rozdziałów", + "creditsPattern": "Wzorzec znacznika napisów końcowych", + "creditsPatternDescription": "Wyrażenie regularne do rozpoznawania znaczników napisów końcowych w tytułach rozdziałów", + "invalidRegex": "Nieprawidłowe wyrażenie regularne", "downloads": "Pobrania", "downloadLocationDescription": "Wybierz miejsce przechowywania pobranych treści", "downloadLocationDefault": "Domyślne (Pamięć aplikacji)", diff --git a/lib/i18n/pt.i18n.json b/lib/i18n/pt.i18n.json index a4ed5eae..944d3bc2 100644 --- a/lib/i18n/pt.i18n.json +++ b/lib/i18n/pt.i18n.json @@ -178,6 +178,11 @@ "autoSkipCreditsDescription": "Pular créditos automaticamente e reproduzir próximo episódio", "autoSkipDelay": "Atraso do Pulo Automático", "autoSkipDelayDescription": "Aguardar ${seconds} segundos antes de pular automaticamente", + "introPattern": "Padrão de marcador de intro", + "introPatternDescription": "Expressão regular para corresponder marcadores de intro nos títulos dos capítulos", + "creditsPattern": "Padrão de marcador de créditos", + "creditsPatternDescription": "Expressão regular para corresponder marcadores de créditos nos títulos dos capítulos", + "invalidRegex": "Expressão regular inválida", "downloads": "Downloads", "downloadLocationDescription": "Escolha onde armazenar conteúdo baixado", "downloadLocationDefault": "Padrão (Armazenamento do App)", diff --git a/lib/i18n/ru.i18n.json b/lib/i18n/ru.i18n.json index 20c723fe..66227d33 100644 --- a/lib/i18n/ru.i18n.json +++ b/lib/i18n/ru.i18n.json @@ -178,6 +178,11 @@ "autoSkipCreditsDescription": "Автоматически пропускать титры и воспроизводить следующий эпизод", "autoSkipDelay": "Задержка автопропуска", "autoSkipDelayDescription": "Подождать ${seconds} секунд перед автопропуском", + "introPattern": "Шаблон маркера вступления", + "introPatternDescription": "Регулярное выражение для распознавания маркеров вступления в заголовках глав", + "creditsPattern": "Шаблон маркера титров", + "creditsPatternDescription": "Регулярное выражение для распознавания маркеров титров в заголовках глав", + "invalidRegex": "Недопустимое регулярное выражение", "downloads": "Загрузки", "downloadLocationDescription": "Выберите место для хранения загруженного контента", "downloadLocationDefault": "По умолчанию (Хранилище приложения)", diff --git a/lib/i18n/strings.g.dart b/lib/i18n/strings.g.dart index 0e4eb171..b46f1599 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: 12105 (807 per locale) +/// Strings: 12180 (812 per locale) /// -/// Built on 2026-03-11 at 02:00 UTC +/// Built on 2026-03-11 at 13:56 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 507b5002..902ffb44 100644 --- a/lib/i18n/strings_da.g.dart +++ b/lib/i18n/strings_da.g.dart @@ -297,6 +297,11 @@ class _TranslationsSettingsDa implements TranslationsSettingsEn { @override String get autoSkipCreditsDescription => 'Spring automatisk rulletekster over og afspil næste episode'; @override String get autoSkipDelay => 'Auto-spring forsinkelse'; @override String autoSkipDelayDescription({required Object seconds}) => 'Vent ${seconds} sekunder før automatisk spring'; + @override String get introPattern => 'Intromarkørmønster'; + @override String get introPatternDescription => 'Regulært udtryk til at genkende intromarkører i kapiteltitler'; + @override String get creditsPattern => 'Rulletekstmarkørmønster'; + @override String get creditsPatternDescription => 'Regulært udtryk til at genkende rulletekstmarkører i kapiteltitler'; + @override String get invalidRegex => 'Ugyldigt regulært udtryk'; @override String get downloads => 'Downloads'; @override String get downloadLocationDescription => 'Vælg hvor downloadet indhold skal gemmes'; @override String get downloadLocationDefault => 'Standard (App-lagring)'; @@ -1472,6 +1477,11 @@ extension on TranslationsDa { 'settings.autoSkipCreditsDescription' => 'Spring automatisk rulletekster over og afspil næste episode', 'settings.autoSkipDelay' => 'Auto-spring forsinkelse', 'settings.autoSkipDelayDescription' => ({required Object seconds}) => 'Vent ${seconds} sekunder før automatisk spring', + 'settings.introPattern' => 'Intromarkørmønster', + 'settings.introPatternDescription' => 'Regulært udtryk til at genkende intromarkører i kapiteltitler', + 'settings.creditsPattern' => 'Rulletekstmarkørmønster', + 'settings.creditsPatternDescription' => 'Regulært udtryk til at genkende rulletekstmarkører i kapiteltitler', + 'settings.invalidRegex' => 'Ugyldigt regulært udtryk', 'settings.downloads' => 'Downloads', 'settings.downloadLocationDescription' => 'Vælg hvor downloadet indhold skal gemmes', 'settings.downloadLocationDefault' => 'Standard (App-lagring)', @@ -1811,13 +1821,13 @@ extension on TranslationsDa { 'liveTv.noPrograms' => 'Ingen programdata tilgængelig', 'liveTv.channelNumber' => ({required Object number}) => 'Kn. ${number}', 'liveTv.live' => 'LIVE', + _ => null, + } ?? switch (path) { 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'NY', 'liveTv.reloadGuide' => 'Genindlæs guide', 'liveTv.allChannels' => 'Alle kanaler', 'liveTv.now' => 'Nu', - _ => null, - } ?? switch (path) { 'liveTv.today' => 'I dag', 'liveTv.midnight' => 'Midnat', 'liveTv.overnight' => 'Nat', diff --git a/lib/i18n/strings_de.g.dart b/lib/i18n/strings_de.g.dart index dfd6ee22..11dc3daa 100644 --- a/lib/i18n/strings_de.g.dart +++ b/lib/i18n/strings_de.g.dart @@ -297,6 +297,11 @@ class _TranslationsSettingsDe implements TranslationsSettingsEn { @override String get autoSkipCreditsDescription => 'Abspann automatisch überspringen und nächste Episode abspielen'; @override String get autoSkipDelay => 'Verzögerung für automatisches Überspringen'; @override String autoSkipDelayDescription({required Object seconds}) => '${seconds} Sekunden vor dem automatischen Überspringen warten'; + @override String get introPattern => 'Intro-Markierungsmuster'; + @override String get introPatternDescription => 'Regulärer Ausdruck zum Erkennen von Intro-Markierungen in Kapiteltiteln'; + @override String get creditsPattern => 'Abspann-Markierungsmuster'; + @override String get creditsPatternDescription => 'Regulärer Ausdruck zum Erkennen von Abspann-Markierungen in Kapiteltiteln'; + @override String get invalidRegex => 'Ungültiger regulärer Ausdruck'; @override String get downloads => 'Downloads'; @override String get downloadLocationDescription => 'Speicherort für heruntergeladene Inhalte wählen'; @override String get downloadLocationDefault => 'Standard (App-Speicher)'; @@ -1472,6 +1477,11 @@ extension on TranslationsDe { 'settings.autoSkipCreditsDescription' => 'Abspann automatisch überspringen und nächste Episode abspielen', 'settings.autoSkipDelay' => 'Verzögerung für automatisches Überspringen', 'settings.autoSkipDelayDescription' => ({required Object seconds}) => '${seconds} Sekunden vor dem automatischen Überspringen warten', + 'settings.introPattern' => 'Intro-Markierungsmuster', + 'settings.introPatternDescription' => 'Regulärer Ausdruck zum Erkennen von Intro-Markierungen in Kapiteltiteln', + 'settings.creditsPattern' => 'Abspann-Markierungsmuster', + 'settings.creditsPatternDescription' => 'Regulärer Ausdruck zum Erkennen von Abspann-Markierungen in Kapiteltiteln', + 'settings.invalidRegex' => 'Ungültiger regulärer Ausdruck', 'settings.downloads' => 'Downloads', 'settings.downloadLocationDescription' => 'Speicherort für heruntergeladene Inhalte wählen', 'settings.downloadLocationDefault' => 'Standard (App-Speicher)', @@ -1811,13 +1821,13 @@ extension on TranslationsDe { 'liveTv.noPrograms' => 'Keine Programmdaten verfügbar', 'liveTv.channelNumber' => ({required Object number}) => 'Kanal ${number}', 'liveTv.live' => 'LIVE', + _ => null, + } ?? switch (path) { 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'NEU', 'liveTv.reloadGuide' => 'Programmführer neu laden', 'liveTv.allChannels' => 'Alle Kanäle', 'liveTv.now' => 'Jetzt', - _ => null, - } ?? switch (path) { 'liveTv.today' => 'Heute', 'liveTv.midnight' => 'Mitternacht', 'liveTv.overnight' => 'Nacht', diff --git a/lib/i18n/strings_en.g.dart b/lib/i18n/strings_en.g.dart index a344660f..ceb115aa 100644 --- a/lib/i18n/strings_en.g.dart +++ b/lib/i18n/strings_en.g.dart @@ -637,6 +637,21 @@ class TranslationsSettingsEn { /// en: 'Wait ${seconds} seconds before auto-skipping' String autoSkipDelayDescription({required Object seconds}) => 'Wait ${seconds} seconds before auto-skipping'; + /// en: 'Intro Marker Pattern' + String get introPattern => 'Intro Marker Pattern'; + + /// en: 'Regex pattern to match intro markers in chapter titles' + String get introPatternDescription => 'Regex pattern to match intro markers in chapter titles'; + + /// en: 'Credits Marker Pattern' + String get creditsPattern => 'Credits Marker Pattern'; + + /// en: 'Regex pattern to match credits markers in chapter titles' + String get creditsPatternDescription => 'Regex pattern to match credits markers in chapter titles'; + + /// en: 'Invalid regular expression' + String get invalidRegex => 'Invalid regular expression'; + /// en: 'Downloads' String get downloads => 'Downloads'; @@ -3093,6 +3108,11 @@ extension on Translations { 'settings.autoSkipCreditsDescription' => 'Automatically skip credits and play next episode', 'settings.autoSkipDelay' => 'Auto Skip Delay', 'settings.autoSkipDelayDescription' => ({required Object seconds}) => 'Wait ${seconds} seconds before auto-skipping', + 'settings.introPattern' => 'Intro Marker Pattern', + 'settings.introPatternDescription' => 'Regex pattern to match intro markers in chapter titles', + 'settings.creditsPattern' => 'Credits Marker Pattern', + 'settings.creditsPatternDescription' => 'Regex pattern to match credits markers in chapter titles', + 'settings.invalidRegex' => 'Invalid regular expression', 'settings.downloads' => 'Downloads', 'settings.downloadLocationDescription' => 'Choose where to store downloaded content', 'settings.downloadLocationDefault' => 'Default (App Storage)', @@ -3432,13 +3452,13 @@ extension on Translations { 'liveTv.noPrograms' => 'No program data available', 'liveTv.channelNumber' => ({required Object number}) => 'Ch. ${number}', 'liveTv.live' => 'LIVE', + _ => null, + } ?? switch (path) { 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'NEW', 'liveTv.reloadGuide' => 'Reload Guide', 'liveTv.allChannels' => 'All Channels', 'liveTv.now' => 'Now', - _ => null, - } ?? switch (path) { 'liveTv.today' => 'Today', 'liveTv.midnight' => 'Midnight', 'liveTv.overnight' => 'Overnight', diff --git a/lib/i18n/strings_es.g.dart b/lib/i18n/strings_es.g.dart index c54aed9a..af0fa9d0 100644 --- a/lib/i18n/strings_es.g.dart +++ b/lib/i18n/strings_es.g.dart @@ -297,6 +297,11 @@ class _TranslationsSettingsEs implements TranslationsSettingsEn { @override String get autoSkipCreditsDescription => 'Saltar automáticamente los créditos y reproducir el siguiente episodio'; @override String get autoSkipDelay => 'Retraso de Salto automático'; @override String autoSkipDelayDescription({required Object seconds}) => 'Esperar ${seconds} segundos antes de saltar automáticamente'; + @override String get introPattern => 'Patrón de marcador de intro'; + @override String get introPatternDescription => 'Expresión regular para reconocer marcadores de intro en los títulos de capítulos'; + @override String get creditsPattern => 'Patrón de marcador de créditos'; + @override String get creditsPatternDescription => 'Expresión regular para reconocer marcadores de créditos en los títulos de capítulos'; + @override String get invalidRegex => 'Expresión regular no válida'; @override String get downloads => 'Descargas'; @override String get downloadLocationDescription => 'Elegir dónde almacenar el contenido descargado'; @override String get downloadLocationDefault => 'Predeterminado (Almacenamiento de la App)'; @@ -1472,6 +1477,11 @@ extension on TranslationsEs { 'settings.autoSkipCreditsDescription' => 'Saltar automáticamente los créditos y reproducir el siguiente episodio', 'settings.autoSkipDelay' => 'Retraso de Salto automático', 'settings.autoSkipDelayDescription' => ({required Object seconds}) => 'Esperar ${seconds} segundos antes de saltar automáticamente', + 'settings.introPattern' => 'Patrón de marcador de intro', + 'settings.introPatternDescription' => 'Expresión regular para reconocer marcadores de intro en los títulos de capítulos', + 'settings.creditsPattern' => 'Patrón de marcador de créditos', + 'settings.creditsPatternDescription' => 'Expresión regular para reconocer marcadores de créditos en los títulos de capítulos', + 'settings.invalidRegex' => 'Expresión regular no válida', 'settings.downloads' => 'Descargas', 'settings.downloadLocationDescription' => 'Elegir dónde almacenar el contenido descargado', 'settings.downloadLocationDefault' => 'Predeterminado (Almacenamiento de la App)', @@ -1811,13 +1821,13 @@ extension on TranslationsEs { 'liveTv.noPrograms' => 'No hay datos de programación disponibles', 'liveTv.channelNumber' => ({required Object number}) => 'Canal ${number}', 'liveTv.live' => 'EN VIVO', + _ => null, + } ?? switch (path) { 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'NUEVO', 'liveTv.reloadGuide' => 'Recargar guía', 'liveTv.allChannels' => 'Todos los canales', 'liveTv.now' => 'Ahora', - _ => null, - } ?? switch (path) { 'liveTv.today' => 'Hoy', 'liveTv.midnight' => 'Medianoche', 'liveTv.overnight' => 'Madrugada', diff --git a/lib/i18n/strings_fr.g.dart b/lib/i18n/strings_fr.g.dart index bd0f0955..9c58044b 100644 --- a/lib/i18n/strings_fr.g.dart +++ b/lib/i18n/strings_fr.g.dart @@ -297,6 +297,11 @@ class _TranslationsSettingsFr implements TranslationsSettingsEn { @override String get autoSkipCreditsDescription => 'Passer les crédits et passer à l\'épisode suivant automatiquement'; @override String get autoSkipDelay => 'Délai avant skip automatique'; @override String autoSkipDelayDescription({required Object seconds}) => 'Attendre ${seconds} secondes avant l\'auto-skip'; + @override String get introPattern => 'Modèle de marqueur d\'intro'; + @override String get introPatternDescription => 'Expression régulière pour reconnaître les marqueurs d\'intro dans les titres de chapitres'; + @override String get creditsPattern => 'Modèle de marqueur de générique'; + @override String get creditsPatternDescription => 'Expression régulière pour reconnaître les marqueurs de générique dans les titres de chapitres'; + @override String get invalidRegex => 'Expression régulière invalide'; @override String get downloads => 'Téléchargement'; @override String get downloadLocationDescription => 'Choisissez où stocker le contenu téléchargé'; @override String get downloadLocationDefault => 'Par défaut (stockage de l\'application)'; @@ -1472,6 +1477,11 @@ extension on TranslationsFr { 'settings.autoSkipCreditsDescription' => 'Passer les crédits et passer à l\'épisode suivant automatiquement', 'settings.autoSkipDelay' => 'Délai avant skip automatique', 'settings.autoSkipDelayDescription' => ({required Object seconds}) => 'Attendre ${seconds} secondes avant l\'auto-skip', + 'settings.introPattern' => 'Modèle de marqueur d\'intro', + 'settings.introPatternDescription' => 'Expression régulière pour reconnaître les marqueurs d\'intro dans les titres de chapitres', + 'settings.creditsPattern' => 'Modèle de marqueur de générique', + 'settings.creditsPatternDescription' => 'Expression régulière pour reconnaître les marqueurs de générique dans les titres de chapitres', + 'settings.invalidRegex' => 'Expression régulière invalide', 'settings.downloads' => 'Téléchargement', 'settings.downloadLocationDescription' => 'Choisissez où stocker le contenu téléchargé', 'settings.downloadLocationDefault' => 'Par défaut (stockage de l\'application)', @@ -1811,13 +1821,13 @@ extension on TranslationsFr { 'liveTv.noPrograms' => 'Aucune donnée de programme disponible', 'liveTv.channelNumber' => ({required Object number}) => 'Ch. ${number}', 'liveTv.live' => 'EN DIRECT', + _ => null, + } ?? switch (path) { 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'NOUVEAU', 'liveTv.reloadGuide' => 'Recharger le guide', 'liveTv.allChannels' => 'Toutes les chaînes', 'liveTv.now' => 'Maintenant', - _ => null, - } ?? switch (path) { 'liveTv.today' => 'Aujourd\'hui', 'liveTv.midnight' => 'Minuit', 'liveTv.overnight' => 'Nuit', diff --git a/lib/i18n/strings_it.g.dart b/lib/i18n/strings_it.g.dart index 982a93dc..8c8417e0 100644 --- a/lib/i18n/strings_it.g.dart +++ b/lib/i18n/strings_it.g.dart @@ -297,6 +297,11 @@ class _TranslationsSettingsIt implements TranslationsSettingsEn { @override String get autoSkipCreditsDescription => 'Salta automaticamente i crediti e riproduci l\'episodio successivo'; @override String get autoSkipDelay => 'Ritardo Salto Automatico'; @override String autoSkipDelayDescription({required Object seconds}) => 'Aspetta ${seconds} secondi prima del salto automatico'; + @override String get introPattern => 'Pattern marcatore intro'; + @override String get introPatternDescription => 'Espressione regolare per riconoscere i marcatori intro nei titoli dei capitoli'; + @override String get creditsPattern => 'Pattern marcatore titoli di coda'; + @override String get creditsPatternDescription => 'Espressione regolare per riconoscere i marcatori dei titoli di coda nei capitoli'; + @override String get invalidRegex => 'Espressione regolare non valida'; @override String get downloads => 'Download'; @override String get downloadLocationDescription => 'Scegli dove salvare i contenuti scaricati'; @override String get downloadLocationDefault => 'Predefinita (Archiviazione App)'; @@ -1472,6 +1477,11 @@ extension on TranslationsIt { 'settings.autoSkipCreditsDescription' => 'Salta automaticamente i crediti e riproduci l\'episodio successivo', 'settings.autoSkipDelay' => 'Ritardo Salto Automatico', 'settings.autoSkipDelayDescription' => ({required Object seconds}) => 'Aspetta ${seconds} secondi prima del salto automatico', + 'settings.introPattern' => 'Pattern marcatore intro', + 'settings.introPatternDescription' => 'Espressione regolare per riconoscere i marcatori intro nei titoli dei capitoli', + 'settings.creditsPattern' => 'Pattern marcatore titoli di coda', + 'settings.creditsPatternDescription' => 'Espressione regolare per riconoscere i marcatori dei titoli di coda nei capitoli', + 'settings.invalidRegex' => 'Espressione regolare non valida', 'settings.downloads' => 'Download', 'settings.downloadLocationDescription' => 'Scegli dove salvare i contenuti scaricati', 'settings.downloadLocationDefault' => 'Predefinita (Archiviazione App)', @@ -1811,13 +1821,13 @@ extension on TranslationsIt { 'liveTv.noPrograms' => 'Nessun dato di programma disponibile', 'liveTv.channelNumber' => ({required Object number}) => 'Canale ${number}', 'liveTv.live' => 'IN DIRETTA', + _ => null, + } ?? switch (path) { 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'NUOVO', 'liveTv.reloadGuide' => 'Ricarica guida', 'liveTv.allChannels' => 'Tutti i canali', 'liveTv.now' => 'Ora', - _ => null, - } ?? switch (path) { 'liveTv.today' => 'Oggi', 'liveTv.midnight' => 'Mezzanotte', 'liveTv.overnight' => 'Notte', diff --git a/lib/i18n/strings_ja.g.dart b/lib/i18n/strings_ja.g.dart index eadc4784..bfdaf02c 100644 --- a/lib/i18n/strings_ja.g.dart +++ b/lib/i18n/strings_ja.g.dart @@ -297,6 +297,11 @@ class _TranslationsSettingsJa implements TranslationsSettingsEn { @override String get autoSkipCreditsDescription => 'クレジットを自動的にスキップして次のエピソードを再生'; @override String get autoSkipDelay => '自動スキップの遅延'; @override String autoSkipDelayDescription({required Object seconds}) => '自動スキップまで${seconds}秒待機'; + @override String get introPattern => 'イントロマーカーパターン'; + @override String get introPatternDescription => 'チャプタータイトルのイントロマーカーに一致する正規表現パターン'; + @override String get creditsPattern => 'クレジットマーカーパターン'; + @override String get creditsPatternDescription => 'チャプタータイトルのクレジットマーカーに一致する正規表現パターン'; + @override String get invalidRegex => '無効な正規表現'; @override String get downloads => 'ダウンロード'; @override String get downloadLocationDescription => 'ダウンロードコンテンツの保存場所を選択'; @override String get downloadLocationDefault => 'デフォルト(アプリストレージ)'; @@ -1472,6 +1477,11 @@ extension on TranslationsJa { 'settings.autoSkipCreditsDescription' => 'クレジットを自動的にスキップして次のエピソードを再生', 'settings.autoSkipDelay' => '自動スキップの遅延', 'settings.autoSkipDelayDescription' => ({required Object seconds}) => '自動スキップまで${seconds}秒待機', + 'settings.introPattern' => 'イントロマーカーパターン', + 'settings.introPatternDescription' => 'チャプタータイトルのイントロマーカーに一致する正規表現パターン', + 'settings.creditsPattern' => 'クレジットマーカーパターン', + 'settings.creditsPatternDescription' => 'チャプタータイトルのクレジットマーカーに一致する正規表現パターン', + 'settings.invalidRegex' => '無効な正規表現', 'settings.downloads' => 'ダウンロード', 'settings.downloadLocationDescription' => 'ダウンロードコンテンツの保存場所を選択', 'settings.downloadLocationDefault' => 'デフォルト(アプリストレージ)', @@ -1811,13 +1821,13 @@ extension on TranslationsJa { 'liveTv.noPrograms' => '番組データがありません', 'liveTv.channelNumber' => ({required Object number}) => 'Ch. ${number}', 'liveTv.live' => 'ライブ', + _ => null, + } ?? switch (path) { 'liveTv.hd' => 'HD', 'liveTv.premiere' => '新着', 'liveTv.reloadGuide' => '番組表を再読込', 'liveTv.allChannels' => 'すべてのチャンネル', 'liveTv.now' => '現在', - _ => null, - } ?? switch (path) { 'liveTv.today' => '今日', 'liveTv.midnight' => '深夜', 'liveTv.overnight' => '深夜', diff --git a/lib/i18n/strings_ko.g.dart b/lib/i18n/strings_ko.g.dart index 6f417631..c861990e 100644 --- a/lib/i18n/strings_ko.g.dart +++ b/lib/i18n/strings_ko.g.dart @@ -297,6 +297,11 @@ class _TranslationsSettingsKo implements TranslationsSettingsEn { @override String get autoSkipCreditsDescription => '엔딩 크레딧 자동 건너뛰기 후 다음 에피소드 재생'; @override String get autoSkipDelay => '자동 건너뛰기 지연'; @override String autoSkipDelayDescription({required Object seconds}) => '자동 건너뛰기 전 ${seconds} 초 대기'; + @override String get introPattern => '인트로 마커 패턴'; + @override String get introPatternDescription => '챕터 제목에서 인트로 마커를 인식하는 정규식 패턴'; + @override String get creditsPattern => '크레딧 마커 패턴'; + @override String get creditsPatternDescription => '챕터 제목에서 크레딧 마커를 인식하는 정규식 패턴'; + @override String get invalidRegex => '잘못된 정규식'; @override String get downloads => '다운로드'; @override String get downloadLocationDescription => '다운로드 콘텐츠 저장 위치 선택'; @override String get downloadLocationDefault => '기본값 (앱 저장소)'; @@ -1472,6 +1477,11 @@ extension on TranslationsKo { 'settings.autoSkipCreditsDescription' => '엔딩 크레딧 자동 건너뛰기 후 다음 에피소드 재생', 'settings.autoSkipDelay' => '자동 건너뛰기 지연', 'settings.autoSkipDelayDescription' => ({required Object seconds}) => '자동 건너뛰기 전 ${seconds} 초 대기', + 'settings.introPattern' => '인트로 마커 패턴', + 'settings.introPatternDescription' => '챕터 제목에서 인트로 마커를 인식하는 정규식 패턴', + 'settings.creditsPattern' => '크레딧 마커 패턴', + 'settings.creditsPatternDescription' => '챕터 제목에서 크레딧 마커를 인식하는 정규식 패턴', + 'settings.invalidRegex' => '잘못된 정규식', 'settings.downloads' => '다운로드', 'settings.downloadLocationDescription' => '다운로드 콘텐츠 저장 위치 선택', 'settings.downloadLocationDefault' => '기본값 (앱 저장소)', @@ -1811,13 +1821,13 @@ extension on TranslationsKo { 'liveTv.noPrograms' => '프로그램 데이터가 없습니다', 'liveTv.channelNumber' => ({required Object number}) => '채널 ${number}', 'liveTv.live' => '실시간', + _ => null, + } ?? switch (path) { 'liveTv.hd' => 'HD', 'liveTv.premiere' => '신규', 'liveTv.reloadGuide' => '편성표 새로고침', 'liveTv.allChannels' => '전체 채널', 'liveTv.now' => '지금', - _ => null, - } ?? switch (path) { 'liveTv.today' => '오늘', 'liveTv.midnight' => '자정', 'liveTv.overnight' => '심야', diff --git a/lib/i18n/strings_nb.g.dart b/lib/i18n/strings_nb.g.dart index 0b28524a..86eb60f9 100644 --- a/lib/i18n/strings_nb.g.dart +++ b/lib/i18n/strings_nb.g.dart @@ -297,6 +297,11 @@ class _TranslationsSettingsNb implements TranslationsSettingsEn { @override String get autoSkipCreditsDescription => 'Hopp automatisk over rulletekst og spill neste episode'; @override String get autoSkipDelay => 'Forsinkelse for automatisk hopp'; @override String autoSkipDelayDescription({required Object seconds}) => 'Vent ${seconds} sekunder før automatisk hopping'; + @override String get introPattern => 'Intromarkørmønster'; + @override String get introPatternDescription => 'Regulært uttrykk for å gjenkjenne intromarkører i kapitteltitler'; + @override String get creditsPattern => 'Rulletekstmarkørmønster'; + @override String get creditsPatternDescription => 'Regulært uttrykk for å gjenkjenne rulletekstmarkører i kapitteltitler'; + @override String get invalidRegex => 'Ugyldig regulært uttrykk'; @override String get downloads => 'Nedlastinger'; @override String get downloadLocationDescription => 'Velg hvor nedlastet innhold skal lagres'; @override String get downloadLocationDefault => 'Standard (App-lagring)'; @@ -1472,6 +1477,11 @@ extension on TranslationsNb { 'settings.autoSkipCreditsDescription' => 'Hopp automatisk over rulletekst og spill neste episode', 'settings.autoSkipDelay' => 'Forsinkelse for automatisk hopp', 'settings.autoSkipDelayDescription' => ({required Object seconds}) => 'Vent ${seconds} sekunder før automatisk hopping', + 'settings.introPattern' => 'Intromarkørmønster', + 'settings.introPatternDescription' => 'Regulært uttrykk for å gjenkjenne intromarkører i kapitteltitler', + 'settings.creditsPattern' => 'Rulletekstmarkørmønster', + 'settings.creditsPatternDescription' => 'Regulært uttrykk for å gjenkjenne rulletekstmarkører i kapitteltitler', + 'settings.invalidRegex' => 'Ugyldig regulært uttrykk', 'settings.downloads' => 'Nedlastinger', 'settings.downloadLocationDescription' => 'Velg hvor nedlastet innhold skal lagres', 'settings.downloadLocationDefault' => 'Standard (App-lagring)', @@ -1811,13 +1821,13 @@ extension on TranslationsNb { 'liveTv.noPrograms' => 'Ingen programdata tilgjengelig', 'liveTv.channelNumber' => ({required Object number}) => 'Kanal ${number}', 'liveTv.live' => 'DIREKTE', + _ => null, + } ?? switch (path) { 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'NY', 'liveTv.reloadGuide' => 'Last inn programguide på nytt', 'liveTv.allChannels' => 'Alle kanaler', 'liveTv.now' => 'Nå', - _ => null, - } ?? switch (path) { 'liveTv.today' => 'I dag', 'liveTv.midnight' => 'Midnatt', 'liveTv.overnight' => 'Natt', diff --git a/lib/i18n/strings_nl.g.dart b/lib/i18n/strings_nl.g.dart index 1df5c236..f7ec08ba 100644 --- a/lib/i18n/strings_nl.g.dart +++ b/lib/i18n/strings_nl.g.dart @@ -297,6 +297,11 @@ class _TranslationsSettingsNl implements TranslationsSettingsEn { @override String get autoSkipCreditsDescription => 'Credits automatisch overslaan en volgende aflevering afspelen'; @override String get autoSkipDelay => 'Vertraging Automatisch Overslaan'; @override String autoSkipDelayDescription({required Object seconds}) => '${seconds} seconden wachten voor automatisch overslaan'; + @override String get introPattern => 'Intromarkeringspatroon'; + @override String get introPatternDescription => 'Reguliere expressie om intromarkeringen in hoofdstuktitels te herkennen'; + @override String get creditsPattern => 'Aftitelingmarkeringspatroon'; + @override String get creditsPatternDescription => 'Reguliere expressie om aftitelingmarkeringen in hoofdstuktitels te herkennen'; + @override String get invalidRegex => 'Ongeldige reguliere expressie'; @override String get downloads => 'Downloads'; @override String get downloadLocationDescription => 'Kies waar gedownloade content wordt opgeslagen'; @override String get downloadLocationDefault => 'Standaard (App-opslag)'; @@ -1472,6 +1477,11 @@ extension on TranslationsNl { 'settings.autoSkipCreditsDescription' => 'Credits automatisch overslaan en volgende aflevering afspelen', 'settings.autoSkipDelay' => 'Vertraging Automatisch Overslaan', 'settings.autoSkipDelayDescription' => ({required Object seconds}) => '${seconds} seconden wachten voor automatisch overslaan', + 'settings.introPattern' => 'Intromarkeringspatroon', + 'settings.introPatternDescription' => 'Reguliere expressie om intromarkeringen in hoofdstuktitels te herkennen', + 'settings.creditsPattern' => 'Aftitelingmarkeringspatroon', + 'settings.creditsPatternDescription' => 'Reguliere expressie om aftitelingmarkeringen in hoofdstuktitels te herkennen', + 'settings.invalidRegex' => 'Ongeldige reguliere expressie', 'settings.downloads' => 'Downloads', 'settings.downloadLocationDescription' => 'Kies waar gedownloade content wordt opgeslagen', 'settings.downloadLocationDefault' => 'Standaard (App-opslag)', @@ -1811,13 +1821,13 @@ extension on TranslationsNl { 'liveTv.noPrograms' => 'Geen programmagegevens beschikbaar', 'liveTv.channelNumber' => ({required Object number}) => 'Kanaal ${number}', 'liveTv.live' => 'LIVE', + _ => null, + } ?? switch (path) { 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'NIEUW', 'liveTv.reloadGuide' => 'Gids herladen', 'liveTv.allChannels' => 'Alle zenders', 'liveTv.now' => 'Nu', - _ => null, - } ?? switch (path) { 'liveTv.today' => 'Vandaag', 'liveTv.midnight' => 'Middernacht', 'liveTv.overnight' => 'Nacht', diff --git a/lib/i18n/strings_pl.g.dart b/lib/i18n/strings_pl.g.dart index 2fa2a690..9788d4ed 100644 --- a/lib/i18n/strings_pl.g.dart +++ b/lib/i18n/strings_pl.g.dart @@ -297,6 +297,11 @@ class _TranslationsSettingsPl implements TranslationsSettingsEn { @override String get autoSkipCreditsDescription => 'Automatycznie pomijaj napisy końcowe i odtwórz następny odcinek'; @override String get autoSkipDelay => 'Opóźnienie automatycznego pomijania'; @override String autoSkipDelayDescription({required Object seconds}) => 'Czekaj ${seconds} sekund przed automatycznym pominięciem'; + @override String get introPattern => 'Wzorzec znacznika intro'; + @override String get introPatternDescription => 'Wyrażenie regularne do rozpoznawania znaczników intro w tytułach rozdziałów'; + @override String get creditsPattern => 'Wzorzec znacznika napisów końcowych'; + @override String get creditsPatternDescription => 'Wyrażenie regularne do rozpoznawania znaczników napisów końcowych w tytułach rozdziałów'; + @override String get invalidRegex => 'Nieprawidłowe wyrażenie regularne'; @override String get downloads => 'Pobrania'; @override String get downloadLocationDescription => 'Wybierz miejsce przechowywania pobranych treści'; @override String get downloadLocationDefault => 'Domyślne (Pamięć aplikacji)'; @@ -1472,6 +1477,11 @@ extension on TranslationsPl { 'settings.autoSkipCreditsDescription' => 'Automatycznie pomijaj napisy końcowe i odtwórz następny odcinek', 'settings.autoSkipDelay' => 'Opóźnienie automatycznego pomijania', 'settings.autoSkipDelayDescription' => ({required Object seconds}) => 'Czekaj ${seconds} sekund przed automatycznym pominięciem', + 'settings.introPattern' => 'Wzorzec znacznika intro', + 'settings.introPatternDescription' => 'Wyrażenie regularne do rozpoznawania znaczników intro w tytułach rozdziałów', + 'settings.creditsPattern' => 'Wzorzec znacznika napisów końcowych', + 'settings.creditsPatternDescription' => 'Wyrażenie regularne do rozpoznawania znaczników napisów końcowych w tytułach rozdziałów', + 'settings.invalidRegex' => 'Nieprawidłowe wyrażenie regularne', 'settings.downloads' => 'Pobrania', 'settings.downloadLocationDescription' => 'Wybierz miejsce przechowywania pobranych treści', 'settings.downloadLocationDefault' => 'Domyślne (Pamięć aplikacji)', @@ -1811,13 +1821,13 @@ extension on TranslationsPl { 'liveTv.noPrograms' => 'Brak danych o programach', 'liveTv.channelNumber' => ({required Object number}) => 'Kn. ${number}', 'liveTv.live' => 'NA ŻYWO', + _ => null, + } ?? switch (path) { 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'NOWE', 'liveTv.reloadGuide' => 'Odśwież przewodnik', 'liveTv.allChannels' => 'Wszystkie kanały', 'liveTv.now' => 'Teraz', - _ => null, - } ?? switch (path) { 'liveTv.today' => 'Dzisiaj', 'liveTv.midnight' => 'Północ', 'liveTv.overnight' => 'Nocą', diff --git a/lib/i18n/strings_pt.g.dart b/lib/i18n/strings_pt.g.dart index 311be130..42a0255f 100644 --- a/lib/i18n/strings_pt.g.dart +++ b/lib/i18n/strings_pt.g.dart @@ -297,6 +297,11 @@ class _TranslationsSettingsPt implements TranslationsSettingsEn { @override String get autoSkipCreditsDescription => 'Pular créditos automaticamente e reproduzir próximo episódio'; @override String get autoSkipDelay => 'Atraso do Pulo Automático'; @override String autoSkipDelayDescription({required Object seconds}) => 'Aguardar ${seconds} segundos antes de pular automaticamente'; + @override String get introPattern => 'Padrão de marcador de intro'; + @override String get introPatternDescription => 'Expressão regular para corresponder marcadores de intro nos títulos dos capítulos'; + @override String get creditsPattern => 'Padrão de marcador de créditos'; + @override String get creditsPatternDescription => 'Expressão regular para corresponder marcadores de créditos nos títulos dos capítulos'; + @override String get invalidRegex => 'Expressão regular inválida'; @override String get downloads => 'Downloads'; @override String get downloadLocationDescription => 'Escolha onde armazenar conteúdo baixado'; @override String get downloadLocationDefault => 'Padrão (Armazenamento do App)'; @@ -1472,6 +1477,11 @@ extension on TranslationsPt { 'settings.autoSkipCreditsDescription' => 'Pular créditos automaticamente e reproduzir próximo episódio', 'settings.autoSkipDelay' => 'Atraso do Pulo Automático', 'settings.autoSkipDelayDescription' => ({required Object seconds}) => 'Aguardar ${seconds} segundos antes de pular automaticamente', + 'settings.introPattern' => 'Padrão de marcador de intro', + 'settings.introPatternDescription' => 'Expressão regular para corresponder marcadores de intro nos títulos dos capítulos', + 'settings.creditsPattern' => 'Padrão de marcador de créditos', + 'settings.creditsPatternDescription' => 'Expressão regular para corresponder marcadores de créditos nos títulos dos capítulos', + 'settings.invalidRegex' => 'Expressão regular inválida', 'settings.downloads' => 'Downloads', 'settings.downloadLocationDescription' => 'Escolha onde armazenar conteúdo baixado', 'settings.downloadLocationDefault' => 'Padrão (Armazenamento do App)', @@ -1811,13 +1821,13 @@ extension on TranslationsPt { 'liveTv.noPrograms' => 'Nenhum dado de programação disponível', 'liveTv.channelNumber' => ({required Object number}) => 'Ch. ${number}', 'liveTv.live' => 'AO VIVO', + _ => null, + } ?? switch (path) { 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'NOVO', 'liveTv.reloadGuide' => 'Recarregar Guia', 'liveTv.allChannels' => 'Todos os Canais', 'liveTv.now' => 'Agora', - _ => null, - } ?? switch (path) { 'liveTv.today' => 'Hoje', 'liveTv.midnight' => 'Meia-noite', 'liveTv.overnight' => 'Madrugada', diff --git a/lib/i18n/strings_ru.g.dart b/lib/i18n/strings_ru.g.dart index 057d93be..96446052 100644 --- a/lib/i18n/strings_ru.g.dart +++ b/lib/i18n/strings_ru.g.dart @@ -297,6 +297,11 @@ class _TranslationsSettingsRu implements TranslationsSettingsEn { @override String get autoSkipCreditsDescription => 'Автоматически пропускать титры и воспроизводить следующий эпизод'; @override String get autoSkipDelay => 'Задержка автопропуска'; @override String autoSkipDelayDescription({required Object seconds}) => 'Подождать ${seconds} секунд перед автопропуском'; + @override String get introPattern => 'Шаблон маркера вступления'; + @override String get introPatternDescription => 'Регулярное выражение для распознавания маркеров вступления в заголовках глав'; + @override String get creditsPattern => 'Шаблон маркера титров'; + @override String get creditsPatternDescription => 'Регулярное выражение для распознавания маркеров титров в заголовках глав'; + @override String get invalidRegex => 'Недопустимое регулярное выражение'; @override String get downloads => 'Загрузки'; @override String get downloadLocationDescription => 'Выберите место для хранения загруженного контента'; @override String get downloadLocationDefault => 'По умолчанию (Хранилище приложения)'; @@ -1472,6 +1477,11 @@ extension on TranslationsRu { 'settings.autoSkipCreditsDescription' => 'Автоматически пропускать титры и воспроизводить следующий эпизод', 'settings.autoSkipDelay' => 'Задержка автопропуска', 'settings.autoSkipDelayDescription' => ({required Object seconds}) => 'Подождать ${seconds} секунд перед автопропуском', + 'settings.introPattern' => 'Шаблон маркера вступления', + 'settings.introPatternDescription' => 'Регулярное выражение для распознавания маркеров вступления в заголовках глав', + 'settings.creditsPattern' => 'Шаблон маркера титров', + 'settings.creditsPatternDescription' => 'Регулярное выражение для распознавания маркеров титров в заголовках глав', + 'settings.invalidRegex' => 'Недопустимое регулярное выражение', 'settings.downloads' => 'Загрузки', 'settings.downloadLocationDescription' => 'Выберите место для хранения загруженного контента', 'settings.downloadLocationDefault' => 'По умолчанию (Хранилище приложения)', @@ -1811,13 +1821,13 @@ extension on TranslationsRu { 'liveTv.noPrograms' => 'Нет данных о программах', 'liveTv.channelNumber' => ({required Object number}) => 'Кн. ${number}', 'liveTv.live' => 'ЭФИР', + _ => null, + } ?? switch (path) { 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'НОВОЕ', 'liveTv.reloadGuide' => 'Перезагрузить программу', 'liveTv.allChannels' => 'Все каналы', 'liveTv.now' => 'Сейчас', - _ => null, - } ?? switch (path) { 'liveTv.today' => 'Сегодня', 'liveTv.midnight' => 'Полночь', 'liveTv.overnight' => 'Ночь', diff --git a/lib/i18n/strings_sv.g.dart b/lib/i18n/strings_sv.g.dart index 50cf358e..af1d1876 100644 --- a/lib/i18n/strings_sv.g.dart +++ b/lib/i18n/strings_sv.g.dart @@ -297,6 +297,11 @@ class _TranslationsSettingsSv implements TranslationsSettingsEn { @override String get autoSkipCreditsDescription => 'Hoppa automatiskt över credits och spela nästa avsnitt'; @override String get autoSkipDelay => 'Fördröjning Auto Hoppa Över'; @override String autoSkipDelayDescription({required Object seconds}) => 'Vänta ${seconds} sekunder innan automatisk överhoppning'; + @override String get introPattern => 'Intromarkörsmönster'; + @override String get introPatternDescription => 'Reguljärt uttryck för att matcha intromarkörer i kapiteltitlar'; + @override String get creditsPattern => 'Eftertextmarkörsmönster'; + @override String get creditsPatternDescription => 'Reguljärt uttryck för att matcha eftertextmarkörer i kapiteltitlar'; + @override String get invalidRegex => 'Ogiltigt reguljärt uttryck'; @override String get downloads => 'Nedladdningar'; @override String get downloadLocationDescription => 'Välj var nedladdat innehåll ska lagras'; @override String get downloadLocationDefault => 'Standard (App-lagring)'; @@ -1472,6 +1477,11 @@ extension on TranslationsSv { 'settings.autoSkipCreditsDescription' => 'Hoppa automatiskt över credits och spela nästa avsnitt', 'settings.autoSkipDelay' => 'Fördröjning Auto Hoppa Över', 'settings.autoSkipDelayDescription' => ({required Object seconds}) => 'Vänta ${seconds} sekunder innan automatisk överhoppning', + 'settings.introPattern' => 'Intromarkörsmönster', + 'settings.introPatternDescription' => 'Reguljärt uttryck för att matcha intromarkörer i kapiteltitlar', + 'settings.creditsPattern' => 'Eftertextmarkörsmönster', + 'settings.creditsPatternDescription' => 'Reguljärt uttryck för att matcha eftertextmarkörer i kapiteltitlar', + 'settings.invalidRegex' => 'Ogiltigt reguljärt uttryck', 'settings.downloads' => 'Nedladdningar', 'settings.downloadLocationDescription' => 'Välj var nedladdat innehåll ska lagras', 'settings.downloadLocationDefault' => 'Standard (App-lagring)', @@ -1811,13 +1821,13 @@ extension on TranslationsSv { 'liveTv.noPrograms' => 'Ingen programdata tillgänglig', 'liveTv.channelNumber' => ({required Object number}) => 'Kanal ${number}', 'liveTv.live' => 'LIVE', + _ => null, + } ?? switch (path) { 'liveTv.hd' => 'HD', 'liveTv.premiere' => 'NY', 'liveTv.reloadGuide' => 'Ladda om programguide', 'liveTv.allChannels' => 'Alla kanaler', 'liveTv.now' => 'Nu', - _ => null, - } ?? switch (path) { 'liveTv.today' => 'Idag', 'liveTv.midnight' => 'Midnatt', 'liveTv.overnight' => 'Natt', diff --git a/lib/i18n/strings_zh.g.dart b/lib/i18n/strings_zh.g.dart index aee19408..6467c72a 100644 --- a/lib/i18n/strings_zh.g.dart +++ b/lib/i18n/strings_zh.g.dart @@ -297,6 +297,11 @@ class _TranslationsSettingsZh implements TranslationsSettingsEn { @override String get autoSkipCreditsDescription => '自动跳过片尾并播放下一集'; @override String get autoSkipDelay => '自动跳过延迟'; @override String autoSkipDelayDescription({required Object seconds}) => '自动跳过前等待 ${seconds} 秒'; + @override String get introPattern => '片头标记模式'; + @override String get introPatternDescription => '用于匹配章节标题中片头标记的正则表达式'; + @override String get creditsPattern => '片尾标记模式'; + @override String get creditsPatternDescription => '用于匹配章节标题中片尾标记的正则表达式'; + @override String get invalidRegex => '无效的正则表达式'; @override String get downloads => '下载'; @override String get downloadLocationDescription => '选择下载内容的存储位置'; @override String get downloadLocationDefault => '默认(应用存储)'; @@ -1472,6 +1477,11 @@ extension on TranslationsZh { 'settings.autoSkipCreditsDescription' => '自动跳过片尾并播放下一集', 'settings.autoSkipDelay' => '自动跳过延迟', 'settings.autoSkipDelayDescription' => ({required Object seconds}) => '自动跳过前等待 ${seconds} 秒', + 'settings.introPattern' => '片头标记模式', + 'settings.introPatternDescription' => '用于匹配章节标题中片头标记的正则表达式', + 'settings.creditsPattern' => '片尾标记模式', + 'settings.creditsPatternDescription' => '用于匹配章节标题中片尾标记的正则表达式', + 'settings.invalidRegex' => '无效的正则表达式', 'settings.downloads' => '下载', 'settings.downloadLocationDescription' => '选择下载内容的存储位置', 'settings.downloadLocationDefault' => '默认(应用存储)', @@ -1811,13 +1821,13 @@ extension on TranslationsZh { 'liveTv.noPrograms' => '没有可用的节目数据', 'liveTv.channelNumber' => ({required Object number}) => '频道 ${number}', 'liveTv.live' => '直播', + _ => null, + } ?? switch (path) { 'liveTv.hd' => '高清', 'liveTv.premiere' => '新', 'liveTv.reloadGuide' => '重新加载节目指南', 'liveTv.allChannels' => '所有频道', 'liveTv.now' => '现在', - _ => null, - } ?? switch (path) { 'liveTv.today' => '今天', 'liveTv.midnight' => '午夜', 'liveTv.overnight' => '凌晨', diff --git a/lib/i18n/sv.i18n.json b/lib/i18n/sv.i18n.json index 28dce681..c8453603 100644 --- a/lib/i18n/sv.i18n.json +++ b/lib/i18n/sv.i18n.json @@ -178,6 +178,11 @@ "autoSkipCreditsDescription": "Hoppa automatiskt över credits och spela nästa avsnitt", "autoSkipDelay": "Fördröjning Auto Hoppa Över", "autoSkipDelayDescription": "Vänta ${seconds} sekunder innan automatisk överhoppning", + "introPattern": "Intromarkörsmönster", + "introPatternDescription": "Reguljärt uttryck för att matcha intromarkörer i kapiteltitlar", + "creditsPattern": "Eftertextmarkörsmönster", + "creditsPatternDescription": "Reguljärt uttryck för att matcha eftertextmarkörer i kapiteltitlar", + "invalidRegex": "Ogiltigt reguljärt uttryck", "downloads": "Nedladdningar", "downloadLocationDescription": "Välj var nedladdat innehåll ska lagras", "downloadLocationDefault": "Standard (App-lagring)", diff --git a/lib/i18n/zh.i18n.json b/lib/i18n/zh.i18n.json index b224c676..11ca1113 100644 --- a/lib/i18n/zh.i18n.json +++ b/lib/i18n/zh.i18n.json @@ -178,6 +178,11 @@ "autoSkipCreditsDescription": "自动跳过片尾并播放下一集", "autoSkipDelay": "自动跳过延迟", "autoSkipDelayDescription": "自动跳过前等待 ${seconds} 秒", + "introPattern": "片头标记模式", + "introPatternDescription": "用于匹配章节标题中片头标记的正则表达式", + "creditsPattern": "片尾标记模式", + "creditsPatternDescription": "用于匹配章节标题中片尾标记的正则表达式", + "invalidRegex": "无效的正则表达式", "downloads": "下载", "downloadLocationDescription": "选择下载内容的存储位置", "downloadLocationDefault": "默认(应用存储)", diff --git a/lib/models/plex_media_info.dart b/lib/models/plex_media_info.dart index 701e713d..2ea29e49 100644 --- a/lib/models/plex_media_info.dart +++ b/lib/models/plex_media_info.dart @@ -227,29 +227,42 @@ class PlaybackExtras { PlaybackExtras({required this.chapters, required this.markers}); - static final _introPattern = RegExp( - r'(?:^|\b)(?:intro(?:duction)?|opening)(?:\b|$)|^op(?:\s?\d+)?$', - caseSensitive: false, - ); - static final _creditsPattern = RegExp( - r'(?:^|\b)(?:outro|closing|credits?|ending)(?:\b|$)|^ed(?:\s?\d+)?$', - caseSensitive: false, - ); - - static String? _classifyChapterTitle(String title) { - if (_introPattern.hasMatch(title)) return 'intro'; - if (_creditsPattern.hasMatch(title)) return 'credits'; + static String? _classifyChapterTitle(String title, RegExp introPattern, RegExp creditsPattern) { + if (introPattern.hasMatch(title)) return 'intro'; + if (creditsPattern.hasMatch(title)) return 'credits'; return null; } /// Returns [PlaybackExtras] using real markers when available, otherwise /// synthesises markers from chapter titles matching intro/credits patterns. + /// When real markers exist, reclassifies markers with unknown types against + /// the patterns so non-standard type strings (e.g. "OP-Song") get recognized. factory PlaybackExtras.withChapterFallback({ required List chapters, required List markers, + String? introPatternStr, + String? creditsPatternStr, }) { + final introPattern = RegExp( + introPatternStr ?? r'(?:^|\b)(?:intro(?:duction)?|opening)(?:\b|$)|^op(?:\s?\d+)?$', + caseSensitive: false, + ); + final creditsPattern = RegExp( + creditsPatternStr ?? r'(?:^|\b)(?:outro|closing|credits?|ending)(?:\b|$)|^ed(?:\s?\d+)?$', + caseSensitive: false, + ); + if (markers.isNotEmpty) { - return PlaybackExtras(chapters: chapters, markers: markers); + // Reclassify markers with non-standard types against the patterns + final reclassified = markers.map((m) { + if (m.type == 'intro' || m.type == 'credits') return m; + final newType = _classifyChapterTitle(m.type, introPattern, creditsPattern); + if (newType != null) { + return PlexMarker(id: m.id, type: newType, startTimeOffset: m.startTimeOffset, endTimeOffset: m.endTimeOffset); + } + return m; + }).toList(); + return PlaybackExtras(chapters: chapters, markers: reclassified); } final synthetic = []; @@ -258,7 +271,7 @@ class PlaybackExtras { final title = ch.title; if (title == null || title.isEmpty) continue; - final type = _classifyChapterTitle(title); + final type = _classifyChapterTitle(title, introPattern, creditsPattern); if (type == null) continue; final start = ch.startTimeOffset; diff --git a/lib/screens/settings/settings_screen.dart b/lib/screens/settings/settings_screen.dart index acc15144..90cf398f 100644 --- a/lib/screens/settings/settings_screen.dart +++ b/lib/screens/settings/settings_screen.dart @@ -98,6 +98,8 @@ class _SettingsScreenState extends State with FocusableTab { static const _kAutoSkipIntro = 'auto_skip_intro'; static const _kAutoSkipCredits = 'auto_skip_credits'; static const _kAutoSkipDelay = 'auto_skip_delay'; + static const _kIntroPattern = 'intro_pattern'; + static const _kCreditsPattern = 'credits_pattern'; static const _kDownloadLocation = 'download_location'; static const _kDownloadOnWifiOnly = 'download_on_wifi_only'; static const _kVideoPlayerControls = 'video_player_controls'; @@ -125,6 +127,8 @@ class _SettingsScreenState extends State with FocusableTab { bool _autoSkipIntro = false; bool _autoSkipCredits = false; int _autoSkipDelay = 5; + String _introPattern = settings.SettingsService.defaultIntroPattern; + String _creditsPattern = settings.SettingsService.defaultCreditsPattern; bool _downloadOnWifiOnly = false; bool _videoPlayerNavigationEnabled = false; int _maxVolume = 100; @@ -202,6 +206,8 @@ class _SettingsScreenState extends State with FocusableTab { _autoSkipIntro = _settingsService.getAutoSkipIntro(); _autoSkipCredits = _settingsService.getAutoSkipCredits(); _autoSkipDelay = _settingsService.getAutoSkipDelay(); + _introPattern = _settingsService.getIntroPattern(); + _creditsPattern = _settingsService.getCreditsPattern(); _downloadOnWifiOnly = _settingsService.getDownloadOnWifiOnly(); _videoPlayerNavigationEnabled = _settingsService.getVideoPlayerNavigationEnabled(); _maxVolume = _settingsService.getMaxVolume(); @@ -874,6 +880,38 @@ class _SettingsScreenState extends State with FocusableTab { trailing: const AppIcon(Symbols.chevron_right_rounded, fill: 1), onTap: () => _showAutoSkipDelayDialog(), ), + ListTile( + focusNode: _focusTracker.get(_kIntroPattern), + leading: const AppIcon(Symbols.match_case_rounded, fill: 1), + title: Text(t.settings.introPattern), + subtitle: Text(t.settings.introPatternDescription), + trailing: const AppIcon(Symbols.chevron_right_rounded, fill: 1), + onTap: () => _showTextInputDialog( + title: t.settings.introPattern, + currentValue: _introPattern, + defaultValue: settings.SettingsService.defaultIntroPattern, + onSave: (value) async { + setState(() => _introPattern = value); + await _settingsService.setIntroPattern(value); + }, + ), + ), + ListTile( + focusNode: _focusTracker.get(_kCreditsPattern), + leading: const AppIcon(Symbols.match_case_rounded, fill: 1), + title: Text(t.settings.creditsPattern), + subtitle: Text(t.settings.creditsPatternDescription), + trailing: const AppIcon(Symbols.chevron_right_rounded, fill: 1), + onTap: () => _showTextInputDialog( + title: t.settings.creditsPattern, + currentValue: _creditsPattern, + defaultValue: settings.SettingsService.defaultCreditsPattern, + onSave: (value) async { + setState(() => _creditsPattern = value); + await _settingsService.setCreditsPattern(value); + }, + ), + ), ], ), ); @@ -1602,6 +1640,69 @@ class _SettingsScreenState extends State with FocusableTab { ); } + void _showTextInputDialog({ + required String title, + required String currentValue, + required String defaultValue, + required Future Function(String value) onSave, + }) { + final controller = TextEditingController(text: currentValue); + String? errorText; + final saveFocusNode = FocusNode(); + + showDialog( + context: context, + builder: (BuildContext dialogContext) { + return StatefulBuilder( + builder: (context, setDialogState) { + return AlertDialog( + title: Text(title), + content: TextField( + controller: controller, + decoration: InputDecoration( + labelText: 'Regex', + errorText: errorText, + ), + autofocus: true, + textInputAction: TextInputAction.done, + onEditingComplete: () => saveFocusNode.requestFocus(), + onChanged: (value) { + setDialogState(() { + try { + RegExp(value, caseSensitive: false); + errorText = null; + } catch (_) { + errorText = t.settings.invalidRegex; + } + }); + }, + ), + actions: [ + TextButton( + onPressed: () { + controller.text = defaultValue; + setDialogState(() => errorText = null); + }, + child: Text(t.settings.resetToDefault), + ), + TextButton(onPressed: () => Navigator.pop(dialogContext), child: Text(t.common.cancel)), + TextButton( + focusNode: saveFocusNode, + onPressed: () async { + if (errorText != null) return; + await onSave(controller.text); + if (dialogContext.mounted) Navigator.pop(dialogContext); + }, + child: Text(t.common.save), + ), + ], + ); + }, + ); + }, + ).then((_) => saveFocusNode.dispose()); + } + void _showMaxVolumeDialog() { _showNumericInputDialog( title: t.settings.maxVolume, diff --git a/lib/services/plex_client.dart b/lib/services/plex_client.dart index 86ce8913..730333be 100644 --- a/lib/services/plex_client.dart +++ b/lib/services/plex_client.dart @@ -954,7 +954,7 @@ class PlexClient { /// Get chapters and markers from cached metadata or fetch if needed /// Uses same cache key as other metadata methods for consistency - Future getPlaybackExtras(String ratingKey) async { + Future getPlaybackExtras(String ratingKey, {String? introPattern, String? creditsPattern}) async { try { final data = await _fetchWithCacheFirst>( cacheKey: '/library/metadata/$ratingKey', @@ -964,7 +964,7 @@ class PlexClient { parseResponse: (response) => response.data as Map?, ); final metadataJson = _getFirstMetadataJsonFromData(data); - return _parsePlaybackExtrasFromMetadataJson(metadataJson); + return _parsePlaybackExtrasFromMetadataJson(metadataJson, introPattern: introPattern, creditsPattern: creditsPattern); } catch (e) { appLogger.w('Failed to get playback extras', error: e); return PlaybackExtras(chapters: [], markers: []); @@ -972,10 +972,12 @@ class PlexClient { } /// Parse PlaybackExtras from metadata JSON - PlaybackExtras _parsePlaybackExtrasFromMetadataJson(Map? metadataJson) { + PlaybackExtras _parsePlaybackExtrasFromMetadataJson(Map? metadataJson, {String? introPattern, String? creditsPattern}) { return PlaybackExtras.withChapterFallback( chapters: _parseChapters(metadataJson), markers: _parseMarkers(metadataJson), + introPatternStr: introPattern, + creditsPatternStr: creditsPattern, ); } diff --git a/lib/services/settings_service.dart b/lib/services/settings_service.dart index 8c48cec3..2869f4c0 100644 --- a/lib/services/settings_service.dart +++ b/lib/services/settings_service.dart @@ -57,6 +57,13 @@ class SettingsService extends BaseSharedPreferencesService { static const String _keyAutoSkipIntro = 'auto_skip_intro'; static const String _keyAutoSkipCredits = 'auto_skip_credits'; static const String _keyAutoSkipDelay = 'auto_skip_delay'; + static const String _keyIntroPattern = 'intro_pattern'; + static const String _keyCreditsPattern = 'credits_pattern'; + + static const String defaultIntroPattern = + r'(?:^|\b)(?:intro(?:duction)?|opening)(?:\b|$)|^op(?:\s?\d+)?$'; + static const String defaultCreditsPattern = + r'(?:^|\b)(?:outro|closing|credits?|ending)(?:\b|$)|^ed(?:\s?\d+)?$'; static const String _keyCustomDownloadPath = 'custom_download_path'; static const String _keyCustomDownloadPathType = 'custom_download_path_type'; static const String _keyDownloadOnWifiOnly = 'download_on_wifi_only'; @@ -894,6 +901,24 @@ class SettingsService extends BaseSharedPreferencesService { return prefs.getInt(_keyAutoSkipDelay) ?? 5; // Default: 5 seconds } + // Intro Pattern + Future setIntroPattern(String value) async { + await prefs.setString(_keyIntroPattern, value); + } + + String getIntroPattern() { + return prefs.getString(_keyIntroPattern) ?? defaultIntroPattern; + } + + // Credits Pattern + Future setCreditsPattern(String value) async { + await prefs.setString(_keyCreditsPattern, value); + } + + String getCreditsPattern() { + return prefs.getString(_keyCreditsPattern) ?? defaultCreditsPattern; + } + // Custom Download Path Future setCustomDownloadPath(String? path, {String type = 'file'}) async { if (path == null) { @@ -1381,6 +1406,8 @@ class SettingsService extends BaseSharedPreferencesService { 'autoSkipIntro': getAutoSkipIntro(), 'autoSkipCredits': getAutoSkipCredits(), 'autoSkipDelay': getAutoSkipDelay(), + 'introPattern': getIntroPattern(), + 'creditsPattern': getCreditsPattern(), }; } } diff --git a/lib/widgets/video_controls/video_controls.dart b/lib/widgets/video_controls/video_controls.dart index 3a275981..f24012b5 100644 --- a/lib/widgets/video_controls/video_controls.dart +++ b/lib/widgets/video_controls/video_controls.dart @@ -929,7 +929,10 @@ class _PlexVideoControlsState extends State with WindowListen final client = _getClientForMetadata(); appLogger.d('_loadPlaybackExtras: got client with serverId=${client.serverId}'); - final extras = await client.getPlaybackExtras(widget.metadata.ratingKey); + final settings = await SettingsService.getInstance(); + final introPattern = settings.getIntroPattern(); + final creditsPattern = settings.getCreditsPattern(); + final extras = await client.getPlaybackExtras(widget.metadata.ratingKey, introPattern: introPattern, creditsPattern: creditsPattern); appLogger.d('_loadPlaybackExtras: got ${extras.chapters.length} chapters'); if (mounted) { @@ -948,7 +951,7 @@ class _PlexVideoControlsState extends State with WindowListen final cacheKey = '/library/metadata/${widget.metadata.ratingKey}'; final cached = await PlexApiCache.instance.get(serverId, cacheKey); if (cached != null) { - final extras = _parsePlaybackExtrasFromCache(cached); + final extras = await _parsePlaybackExtrasFromCache(cached); appLogger.d('_loadPlaybackExtras: loaded ${extras.chapters.length} chapters from cache'); if (mounted) { setState(() { @@ -966,7 +969,7 @@ class _PlexVideoControlsState extends State with WindowListen } /// Parse PlaybackExtras from cached API response (for offline playback) - PlaybackExtras _parsePlaybackExtrasFromCache(Map cached) { + Future _parsePlaybackExtrasFromCache(Map cached) async { final chapters = []; final markers = []; @@ -1003,7 +1006,13 @@ class _PlexVideoControlsState extends State with WindowListen } } - return PlaybackExtras.withChapterFallback(chapters: chapters, markers: markers); + final settings = await SettingsService.getInstance(); + return PlaybackExtras.withChapterFallback( + chapters: chapters, + markers: markers, + introPatternStr: settings.getIntroPattern(), + creditsPatternStr: settings.getCreditsPattern(), + ); } TrackControlsState _buildTrackControlsState({