From cd31b2e2e6fbc1ad5b1eda0e6ea00ff5390c82b8 Mon Sep 17 00:00:00 2001 From: edde746 <86283021+edde746@users.noreply.github.com> Date: Mon, 11 May 2026 02:22:49 +0200 Subject: [PATCH] fix(subtitles): remember search language close #1002 --- lib/services/settings_service.dart | 2 ++ lib/utils/language_codes.dart | 6 +++++ .../sheets/subtitle_search_sheet.dart | 25 ++++++++++++++----- test/widgets/subtitle_search_sheet_test.dart | 24 ++++++++++++++++++ 4 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 test/widgets/subtitle_search_sheet_test.dart diff --git a/lib/services/settings_service.dart b/lib/services/settings_service.dart index 3bf2a5eb..d428a5fe 100644 --- a/lib/services/settings_service.dart +++ b/lib/services/settings_service.dart @@ -271,6 +271,7 @@ class SettingsService extends BaseSharedPreferencesService { static const sleepTimerDuration = IntPref('sleep_timer_duration', defaultValue: 30); static const audioSyncOffset = IntPref('audio_sync_offset'); static const subtitleSyncOffset = IntPref('subtitle_sync_offset'); + static const subtitleSearchLanguage = NullableStringPref('subtitle_search_language'); static const volume = DoublePref('volume', defaultValue: 100.0); static const rotationLocked = BoolPref('rotation_locked', defaultValue: true); static const subtitleFontSize = IntPref('subtitle_font_size', defaultValue: 38); @@ -655,6 +656,7 @@ class SettingsService extends BaseSharedPreferencesService { sleepTimerDuration, audioSyncOffset, subtitleSyncOffset, + subtitleSearchLanguage, volume, maxVolume, subtitleFontSize, diff --git a/lib/utils/language_codes.dart b/lib/utils/language_codes.dart index eeefe437..8b055302 100644 --- a/lib/utils/language_codes.dart +++ b/lib/utils/language_codes.dart @@ -25,6 +25,12 @@ class LanguageCodes { return variations.toList(); } + static String? getIso6391Code(String code) { + final normalized = code.toLowerCase().trim().split(RegExp('[-_]')).first; + if (normalized.isEmpty) return null; + return _resolve(normalized)?.code1; + } + /// Get a display name for a language/locale code. /// Handles plain codes ("en" → "English") and locale codes ("en-US" → "English", /// "en-AU" → "English (Australia)"). diff --git a/lib/widgets/video_controls/sheets/subtitle_search_sheet.dart b/lib/widgets/video_controls/sheets/subtitle_search_sheet.dart index 37170d2b..3fec5d94 100644 --- a/lib/widgets/video_controls/sheets/subtitle_search_sheet.dart +++ b/lib/widgets/video_controls/sheets/subtitle_search_sheet.dart @@ -10,6 +10,7 @@ import '../../../i18n/strings.g.dart'; import '../../../mixins/controller_disposer_mixin.dart'; import '../../../models/plex/plex_subtitle_search_result.dart'; import '../../../services/plex_client.dart'; +import '../../../services/settings_service.dart'; import '../../../utils/language_codes.dart'; import '../../../utils/provider_extensions.dart'; import '../../../utils/snackbar_helper.dart'; @@ -20,6 +21,13 @@ import '../../../widgets/pill_input_decoration.dart'; import 'base_video_control_sheet.dart'; import '../../loading_indicator_box.dart'; +@visibleForTesting +String resolveSubtitleSearchLanguageCode({String? savedLanguageCode, required Locale systemLocale}) { + return LanguageCodes.getIso6391Code(savedLanguageCode ?? '') ?? + LanguageCodes.getIso6391Code(systemLocale.languageCode) ?? + 'en'; +} + class SubtitleSearchSheet extends StatefulWidget { final String ratingKey; final String serverId; @@ -62,13 +70,14 @@ class _SubtitleSearchSheetState extends State with Controll } void _initDefaultLanguage() { - final locale = WidgetsBinding.instance.platformDispatcher.locale; - final code = locale.languageCode; + final code = resolveSubtitleSearchLanguageCode( + savedLanguageCode: SettingsService.instanceOrNull?.read(SettingsService.subtitleSearchLanguage), + systemLocale: WidgetsBinding.instance.platformDispatcher.locale, + ); final name = LanguageCodes.getLanguageName(code); - if (name != null) { - _languageCode = code; - _languageName = name; - } + if (name == null) return; + _languageCode = code; + _languageName = name; } @override @@ -153,6 +162,10 @@ class _SubtitleSearchSheetState extends State with Controll _languageName = name; _showLanguagePicker = false; }); + final settings = SettingsService.instanceOrNull; + if (settings != null) { + unawaited(settings.write(SettingsService.subtitleSearchLanguage, code)); + } OverlaySheetController.of(context).refocus(); _search(); } diff --git a/test/widgets/subtitle_search_sheet_test.dart b/test/widgets/subtitle_search_sheet_test.dart new file mode 100644 index 00000000..8a532f58 --- /dev/null +++ b/test/widgets/subtitle_search_sheet_test.dart @@ -0,0 +1,24 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:plezy/widgets/video_controls/sheets/subtitle_search_sheet.dart'; + +void main() { + group('resolveSubtitleSearchLanguageCode', () { + test('prefers saved language over system language', () { + expect(resolveSubtitleSearchLanguageCode(savedLanguageCode: 'fr', systemLocale: const Locale('nl')), 'fr'); + }); + + test('normalizes saved locale or three-letter language', () { + expect(resolveSubtitleSearchLanguageCode(savedLanguageCode: 'pt_BR', systemLocale: const Locale('nl')), 'pt'); + expect(resolveSubtitleSearchLanguageCode(savedLanguageCode: 'eng', systemLocale: const Locale('nl')), 'en'); + }); + + test('falls back to system language when saved language is invalid', () { + expect(resolveSubtitleSearchLanguageCode(savedLanguageCode: 'zz', systemLocale: const Locale('nl')), 'nl'); + }); + + test('falls back to English when saved and system languages are invalid', () { + expect(resolveSubtitleSearchLanguageCode(savedLanguageCode: 'zz', systemLocale: const Locale('xx')), 'en'); + }); + }); +}