feat(flutter/settings): Appearance section with System/Light/Dark picker
Three RadioListTiles between Profile and Password sections. Tap →
themeModeProvider.notifier.set(...) → MaterialApp rebuilds with the
new theme via the existing themeMode wiring.
System has the only subtitle ("Match the device setting") — the
light/dark options are self-explanatory.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import '../library/library_providers.dart' show dioProvider;
|
||||
import '../models/my_profile.dart';
|
||||
import '../shared/widgets/main_app_bar_actions.dart';
|
||||
import '../theme/theme_extension.dart';
|
||||
import '../theme/theme_mode_provider.dart';
|
||||
|
||||
final _settingsApiProvider = FutureProvider<SettingsApi>((ref) async {
|
||||
return SettingsApi(await ref.watch(dioProvider.future));
|
||||
@@ -45,6 +46,8 @@ class SettingsScreen extends ConsumerWidget {
|
||||
children: const [
|
||||
_ProfileSection(),
|
||||
_Divider(),
|
||||
_AppearanceSection(),
|
||||
_Divider(),
|
||||
_PasswordSection(),
|
||||
_Divider(),
|
||||
_ListenBrainzSection(),
|
||||
@@ -492,3 +495,39 @@ InputDecoration _inputDecoration(FabledSwordTheme fs, String label) {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
class _AppearanceSection extends ConsumerWidget {
|
||||
const _AppearanceSection();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final fs = Theme.of(context).extension<FabledSwordTheme>()!;
|
||||
final current = ref.watch(themeModeProvider).value ?? AppThemeMode.system;
|
||||
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
const _SectionHeader('Appearance'),
|
||||
for (final mode in AppThemeMode.values)
|
||||
RadioListTile<AppThemeMode>(
|
||||
key: Key('appearance_${mode.name}'),
|
||||
title: Text(_label(mode), style: TextStyle(color: fs.parchment)),
|
||||
subtitle: mode == AppThemeMode.system
|
||||
? Text('Match the device setting',
|
||||
style: TextStyle(color: fs.ash))
|
||||
: null,
|
||||
value: mode,
|
||||
groupValue: current,
|
||||
activeColor: fs.accent,
|
||||
onChanged: (m) {
|
||||
if (m != null) {
|
||||
ref.read(themeModeProvider.notifier).set(m);
|
||||
}
|
||||
},
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
String _label(AppThemeMode m) => switch (m) {
|
||||
AppThemeMode.system => 'System',
|
||||
AppThemeMode.light => 'Light',
|
||||
AppThemeMode.dark => 'Dark',
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user