From 1dc4e77f424996dbefcc2135cfbd18c5d4e7d9d5 Mon Sep 17 00:00:00 2001 From: zarzet <42882290+zarzet@users.noreply.github.com> Date: Sun, 6 Sep 2026 14:05:09 +0700 Subject: [PATCH] refactor(i18n): share supported language choices Use one non-generated language catalog in setup and appearance settings. Filter supported locale codes once and retain the resulting immutable picker list. --- lib/constants/language_choices.dart | 33 ++++++++++++++++ .../settings/appearance_settings_page.dart | 39 ++----------------- lib/screens/setup_screen.dart | 34 +--------------- 3 files changed, 39 insertions(+), 67 deletions(-) create mode 100644 lib/constants/language_choices.dart diff --git a/lib/constants/language_choices.dart b/lib/constants/language_choices.dart new file mode 100644 index 00000000..f264a7c3 --- /dev/null +++ b/lib/constants/language_choices.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; +import 'package:spotiflac_android/l10n/supported_locales.dart'; + +/// Display choices shared by onboarding and appearance settings. +const appLanguageChoices = [ + ('system', 'System Default', Icons.phone_android), + ('en', 'English', Icons.language), + ('ar', 'العربية', Icons.language), + ('id', 'Bahasa Indonesia', Icons.language), + ('de', 'Deutsch', Icons.language), + ('es', 'Español', Icons.language), + ('es_ES', 'Español (España)', Icons.language), + ('fr', 'Français', Icons.language), + ('hi', 'हिन्दी', Icons.language), + ('it', 'Italiano', Icons.language), + ('ja', '日本語', Icons.language), + ('ko', '한국어', Icons.language), + ('nl', 'Nederlands', Icons.language), + ('pt', 'Português', Icons.language), + ('pt_PT', 'Português (Brasil)', Icons.language), + ('ru', 'Русский', Icons.language), + ('tr', 'Türkçe', Icons.language), + ('uk', 'Українська', Icons.language), + ('zh_CN', '简体中文', Icons.language), + ('zh_TW', '繁體中文', Icons.language), +]; + +final supportedLanguageChoices = List<(String, String, IconData)>.unmodifiable( + appLanguageChoices.where( + (choice) => + choice.$1 == 'system' || filteredLocaleCodes.contains(choice.$1), + ), +); diff --git a/lib/screens/settings/appearance_settings_page.dart b/lib/screens/settings/appearance_settings_page.dart index f3392866..180f3cf8 100644 --- a/lib/screens/settings/appearance_settings_page.dart +++ b/lib/screens/settings/appearance_settings_page.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:spotiflac_android/l10n/l10n.dart'; -import 'package:spotiflac_android/l10n/supported_locales.dart'; +import 'package:spotiflac_android/constants/language_choices.dart'; import 'package:spotiflac_android/providers/settings_provider.dart'; import 'package:spotiflac_android/providers/theme_provider.dart'; import 'package:spotiflac_android/utils/adaptive_layout.dart'; @@ -552,39 +552,8 @@ class _LanguageSelector extends StatelessWidget { required this.onChanged, }); - static const _allLanguages = [ - ('system', 'System Default', Icons.phone_android), - ('en', 'English', Icons.language), - ('ar', 'العربية', Icons.language), - ('id', 'Bahasa Indonesia', Icons.language), - ('de', 'Deutsch', Icons.language), - ('es', 'Español', Icons.language), - ('es_ES', 'Español (España)', Icons.language), - ('fr', 'Français', Icons.language), - ('hi', 'हिन्दी', Icons.language), - ('it', 'Italiano', Icons.language), - ('ja', '日本語', Icons.language), - ('ko', '한국어', Icons.language), - ('nl', 'Nederlands', Icons.language), - ('pt', 'Português', Icons.language), - ('pt_PT', 'Português (Brasil)', Icons.language), - ('ru', 'Русский', Icons.language), - ('tr', 'Türkçe', Icons.language), - ('uk', 'Українська', Icons.language), - ('zh_CN', '简体中文', Icons.language), - ('zh_TW', '繁體中文', Icons.language), - ]; - - /// Uses filteredLocaleCodes from supported_locales.dart (generated file). - List<(String, String, IconData)> get _languages { - return _allLanguages.where((lang) { - if (lang.$1 == 'system') return true; - return filteredLocaleCodes.contains(lang.$1); - }).toList(); - } - String _getLanguageName(String code) { - for (final lang in _allLanguages) { + for (final lang in appLanguageChoices) { if (lang.$1 == code) return lang.$2; } return code; @@ -629,9 +598,9 @@ class _LanguageSelector extends StatelessWidget { Flexible( child: ListView.builder( shrinkWrap: true, - itemCount: _languages.length, + itemCount: supportedLanguageChoices.length, itemBuilder: (context, index) { - final lang = _languages[index]; + final lang = supportedLanguageChoices[index]; final isSelected = currentLocale == lang.$1; return ListTile( leading: Icon( diff --git a/lib/screens/setup_screen.dart b/lib/screens/setup_screen.dart index 17df0437..1636cad3 100644 --- a/lib/screens/setup_screen.dart +++ b/lib/screens/setup_screen.dart @@ -7,7 +7,7 @@ import 'package:go_router/go_router.dart'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:spotiflac_android/providers/settings_provider.dart'; import 'package:spotiflac_android/l10n/l10n.dart'; -import 'package:spotiflac_android/l10n/supported_locales.dart'; +import 'package:spotiflac_android/constants/language_choices.dart'; import 'package:spotiflac_android/services/platform_bridge.dart'; import 'package:spotiflac_android/utils/adaptive_layout.dart'; import 'package:spotiflac_android/utils/file_access.dart'; @@ -710,43 +710,13 @@ class _SetupScreenState extends ConsumerState { ); } - static const _allLanguages = [ - ('system', 'System Default', Icons.phone_android), - ('en', 'English', Icons.language), - ('ar', 'العربية', Icons.language), - ('id', 'Bahasa Indonesia', Icons.language), - ('de', 'Deutsch', Icons.language), - ('es', 'Español', Icons.language), - ('es_ES', 'Español (España)', Icons.language), - ('fr', 'Français', Icons.language), - ('hi', 'हिन्दी', Icons.language), - ('it', 'Italiano', Icons.language), - ('ja', '日本語', Icons.language), - ('ko', '한국어', Icons.language), - ('nl', 'Nederlands', Icons.language), - ('pt', 'Português', Icons.language), - ('pt_PT', 'Português (Brasil)', Icons.language), - ('ru', 'Русский', Icons.language), - ('tr', 'Türkçe', Icons.language), - ('uk', 'Українська', Icons.language), - ('zh_CN', '简体中文', Icons.language), - ('zh_TW', '繁體中文', Icons.language), - ]; - - List<(String, String, IconData)> get _filteredLanguages { - return _allLanguages.where((lang) { - if (lang.$1 == 'system') return true; - return filteredLocaleCodes.contains(lang.$1); - }).toList(); - } - void _onLanguageSelected(String locale) { setState(() => _selectedLocale = locale); ref.read(settingsProvider.notifier).setLocale(locale); } Widget _buildLanguageStep(ColorScheme colorScheme) { - final languages = _filteredLanguages; + final languages = supportedLanguageChoices; return LayoutBuilder( builder: (context, constraints) {