From e4b36719d7d4b9db7f5b7a4ba0287a07ab2ba410 Mon Sep 17 00:00:00 2001 From: Doug Borg Date: Mon, 2 Feb 2026 00:55:46 -0700 Subject: [PATCH] Migrate Radio groupValue/onChanged to RadioGroup widget --- .../settings/sections/language_section.dart | 96 ++++++++++--------- lib/widgets/refine_tags_sheet.dart | 48 +++++----- 2 files changed, 73 insertions(+), 71 deletions(-) diff --git a/lib/screens/settings/sections/language_section.dart b/lib/screens/settings/sections/language_section.dart index ccf58ca..6f122be 100644 --- a/lib/screens/settings/sections/language_section.dart +++ b/lib/screens/settings/sections/language_section.dart @@ -25,6 +25,7 @@ class _LanguageSectionState extends State { Future _loadSelectedLanguage() async { final prefs = await SharedPreferences.getInstance(); + if (!mounted) return; setState(() { _selectedLanguage = prefs.getString('language_code'); }); @@ -33,11 +34,12 @@ class _LanguageSectionState extends State { Future _loadLanguageNames() async { final locService = LocalizationService.instance; final Map names = {}; - + for (String langCode in locService.availableLanguages) { names[langCode] = await locService.getLanguageDisplayName(langCode); } - + + if (!mounted) return; setState(() { _languageNames = names; }); @@ -58,44 +60,46 @@ class _LanguageSectionState extends State { animation: LocalizationService.instance, builder: (context, child) { final locService = LocalizationService.instance; - + return SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Language section - // System Default option - RadioListTile( - title: Text(locService.t('settings.systemDefault')), - value: null, + RadioGroup( groupValue: _selectedLanguage, onChanged: _setLanguage, - ), - // English always appears second (if available) - if (locService.availableLanguages.contains('en')) - RadioListTile( - title: Text(_languageNames['en'] ?? 'English'), - value: 'en', - groupValue: _selectedLanguage, - onChanged: _setLanguage, - ), - // Other language options (excluding English since it's already shown) - ...locService.availableLanguages - .where((langCode) => langCode != 'en') - .map((langCode) => - RadioListTile( - title: Text(_languageNames[langCode] ?? langCode.toUpperCase()), - value: langCode, - groupValue: _selectedLanguage, - onChanged: _setLanguage, + child: Column( + children: [ + // System Default option + RadioListTile( + title: Text(locService.t('settings.systemDefault')), + value: null, + ), + // English always appears second (if available) + if (locService.availableLanguages.contains('en')) + RadioListTile( + title: Text(_languageNames['en'] ?? 'English'), + value: 'en', + ), + // Other language options (excluding English since it's already shown) + ...locService.availableLanguages + .where((langCode) => langCode != 'en') + .map((langCode) => + RadioListTile( + title: Text(_languageNames[langCode] ?? langCode.toUpperCase()), + value: langCode, + ), + ), + ], ), ), - + // Divider between language and units const SizedBox(height: 24), const Divider(), const SizedBox(height: 16), - + // Distance Units section Text( locService.t('settings.distanceUnit'), @@ -105,33 +109,33 @@ class _LanguageSectionState extends State { Text( locService.t('settings.distanceUnitSubtitle'), style: Theme.of(context).textTheme.bodySmall?.copyWith( - color: Theme.of(context).textTheme.bodySmall?.color?.withOpacity(0.7), + color: Theme.of(context).textTheme.bodySmall?.color?.withValues(alpha: 0.7), ), ), const SizedBox(height: 8), - - // Metric option - RadioListTile( - title: Text(locService.t('units.metricDescription')), - value: DistanceUnit.metric, - groupValue: appState.distanceUnit, - onChanged: (unit) { - if (unit != null) { - appState.setDistanceUnit(unit); - } - }, - ), - - // Imperial option - RadioListTile( - title: Text(locService.t('units.imperialDescription')), - value: DistanceUnit.imperial, + + RadioGroup( groupValue: appState.distanceUnit, onChanged: (unit) { if (unit != null) { appState.setDistanceUnit(unit); } }, + child: Column( + children: [ + // Metric option + RadioListTile( + title: Text(locService.t('units.metricDescription')), + value: DistanceUnit.metric, + ), + + // Imperial option + RadioListTile( + title: Text(locService.t('units.imperialDescription')), + value: DistanceUnit.imperial, + ), + ], + ), ), ], ), @@ -141,4 +145,4 @@ class _LanguageSectionState extends State { }, ); } -} \ No newline at end of file +} diff --git a/lib/widgets/refine_tags_sheet.dart b/lib/widgets/refine_tags_sheet.dart index 7edc0dd..5ee9e5d 100644 --- a/lib/widgets/refine_tags_sheet.dart +++ b/lib/widgets/refine_tags_sheet.dart @@ -248,34 +248,32 @@ class _RefineTagsSheetState extends State { ) else ...[ Card( - child: Column( - children: [ - // Show existing operator profile first if it exists - if (hasExistingOperatorProfile) ...[ + child: RadioGroup( + groupValue: _selectedOperatorProfile, + onChanged: (value) => setState(() => _selectedOperatorProfile = value), + child: Column( + children: [ + // Show existing operator profile first if it exists + if (hasExistingOperatorProfile) ...[ + RadioListTile( + title: Text(locService.t('refineTagsSheet.existingOperator')), + subtitle: Text('${widget.selectedOperatorProfile!.tags.length} ${locService.t('refineTagsSheet.existingOperatorTags')}'), + value: widget.selectedOperatorProfile, + ), + const Divider(height: 1), + ], RadioListTile( - title: Text(locService.t('refineTagsSheet.existingOperator')), - subtitle: Text('${widget.selectedOperatorProfile!.tags.length} ${locService.t('refineTagsSheet.existingOperatorTags')}'), - value: widget.selectedOperatorProfile, - groupValue: _selectedOperatorProfile, - onChanged: (value) => setState(() => _selectedOperatorProfile = value), + title: Text(locService.t('refineTagsSheet.none')), + subtitle: Text(locService.t('refineTagsSheet.noAdditionalOperatorTags')), + value: null, ), - const Divider(height: 1), + ...operatorProfiles.map((profile) => RadioListTile( + title: Text(profile.name), + subtitle: Text('${profile.tags.length} ${locService.t('refineTagsSheet.additionalTags')}'), + value: profile, + )), ], - RadioListTile( - title: Text(locService.t('refineTagsSheet.none')), - subtitle: Text(locService.t('refineTagsSheet.noAdditionalOperatorTags')), - value: null, - groupValue: _selectedOperatorProfile, - onChanged: (value) => setState(() => _selectedOperatorProfile = value), - ), - ...operatorProfiles.map((profile) => RadioListTile( - title: Text(profile.name), - subtitle: Text('${profile.tags.length} ${locService.t('refineTagsSheet.additionalTags')}'), - value: profile, - groupValue: _selectedOperatorProfile, - onChanged: (value) => setState(() => _selectedOperatorProfile = value), - )), - ], + ), ), ), const SizedBox(height: 16),