fix(flutter): clear analyze --fatal-infos issues
Three classes:
1. album_cover_cache.dart docstring used <applicationCacheDirectory>
and <albumId> which the analyzer reads as unintended HTML. Wrapped
the path in backticks and used {} placeholders.
2. settings AppearanceSection used RadioListTile.groupValue + onChanged,
deprecated in Flutter 3.32+. Wrapped the radios in a RadioGroup
ancestor (the new API) so individual tiles only declare value +
activeColor. Test updated to read groupValue off the RadioGroup
ancestor.
3. theme_extension.dart factories built FabledSwordTheme(...) without
const, even though all args are static const tokens. Added const to
the outer constructor calls in both .dark() and .light() — this
propagates const to the inner TextStyle(...) calls automatically.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,7 +10,7 @@ import 'package:path_provider/path_provider.dart';
|
|||||||
/// and doesn't carry our Bearer header, so we pre-fetch via the
|
/// and doesn't carry our Bearer header, so we pre-fetch via the
|
||||||
/// authenticated dio and hand the system a local file path instead.
|
/// authenticated dio and hand the system a local file path instead.
|
||||||
///
|
///
|
||||||
/// Cache layout: <applicationCacheDirectory>/album_covers/<albumId>.jpg.
|
/// Cache layout: `{applicationCacheDirectory}/album_covers/{albumId}.jpg`.
|
||||||
/// No explicit eviction — covers are tiny and OS clears app cache when
|
/// No explicit eviction — covers are tiny and OS clears app cache when
|
||||||
/// space is tight.
|
/// space is tight.
|
||||||
class AlbumCoverCache {
|
class AlbumCoverCache {
|
||||||
|
|||||||
@@ -503,26 +503,32 @@ class _AppearanceSection extends ConsumerWidget {
|
|||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final fs = Theme.of(context).extension<FabledSwordTheme>()!;
|
final fs = Theme.of(context).extension<FabledSwordTheme>()!;
|
||||||
final current = ref.watch(themeModeProvider).value ?? AppThemeMode.system;
|
final current = ref.watch(themeModeProvider).value ?? AppThemeMode.system;
|
||||||
return Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
// RadioGroup is the post-Flutter-3.32 API: the ancestor owns
|
||||||
const _SectionHeader('Appearance'),
|
// groupValue/onChanged so individual RadioListTiles don't have
|
||||||
for (final mode in AppThemeMode.values)
|
// to repeat them. Pre-3.32 RadioListTile.groupValue/onChanged
|
||||||
RadioListTile<AppThemeMode>(
|
// are deprecated.
|
||||||
key: Key('appearance_${mode.name}'),
|
return RadioGroup<AppThemeMode>(
|
||||||
title: Text(_label(mode), style: TextStyle(color: fs.parchment)),
|
groupValue: current,
|
||||||
subtitle: mode == AppThemeMode.system
|
onChanged: (m) {
|
||||||
? Text('Match the device setting',
|
if (m != null) {
|
||||||
style: TextStyle(color: fs.ash))
|
ref.read(themeModeProvider.notifier).set(m);
|
||||||
: null,
|
}
|
||||||
value: mode,
|
},
|
||||||
groupValue: current,
|
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||||
activeColor: fs.accent,
|
const _SectionHeader('Appearance'),
|
||||||
onChanged: (m) {
|
for (final mode in AppThemeMode.values)
|
||||||
if (m != null) {
|
RadioListTile<AppThemeMode>(
|
||||||
ref.read(themeModeProvider.notifier).set(m);
|
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,
|
||||||
|
activeColor: fs.accent,
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String _label(AppThemeMode m) => switch (m) {
|
String _label(AppThemeMode m) => switch (m) {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class FabledSwordTheme extends ThemeExtension<FabledSwordTheme> {
|
|||||||
final Color warning, error, info;
|
final Color warning, error, info;
|
||||||
final TextStyle display, body, mono;
|
final TextStyle display, body, mono;
|
||||||
|
|
||||||
factory FabledSwordTheme.dark() => FabledSwordTheme(
|
factory FabledSwordTheme.dark() => const FabledSwordTheme(
|
||||||
accent: FabledSwordFlatTokens.accent,
|
accent: FabledSwordFlatTokens.accent,
|
||||||
obsidian: FabledSwordDarkTokens.obsidian,
|
obsidian: FabledSwordDarkTokens.obsidian,
|
||||||
iron: FabledSwordDarkTokens.iron,
|
iron: FabledSwordDarkTokens.iron,
|
||||||
@@ -50,7 +50,7 @@ class FabledSwordTheme extends ThemeExtension<FabledSwordTheme> {
|
|||||||
mono: TextStyle(fontFamily: FabledSwordFlatTokens.fontMono),
|
mono: TextStyle(fontFamily: FabledSwordFlatTokens.fontMono),
|
||||||
);
|
);
|
||||||
|
|
||||||
factory FabledSwordTheme.light() => FabledSwordTheme(
|
factory FabledSwordTheme.light() => const FabledSwordTheme(
|
||||||
accent: FabledSwordFlatTokens.accent,
|
accent: FabledSwordFlatTokens.accent,
|
||||||
obsidian: FabledSwordLightTokens.obsidian,
|
obsidian: FabledSwordLightTokens.obsidian,
|
||||||
iron: FabledSwordLightTokens.iron,
|
iron: FabledSwordLightTokens.iron,
|
||||||
|
|||||||
@@ -49,11 +49,15 @@ void main() {
|
|||||||
expect(find.byKey(const Key('appearance_light')), findsOneWidget);
|
expect(find.byKey(const Key('appearance_light')), findsOneWidget);
|
||||||
expect(find.byKey(const Key('appearance_dark')), findsOneWidget);
|
expect(find.byKey(const Key('appearance_dark')), findsOneWidget);
|
||||||
|
|
||||||
// The dark radio should be selected.
|
// The RadioGroup ancestor owns groupValue post-Flutter-3.32; the
|
||||||
|
// selected mode is read off it rather than off individual tiles.
|
||||||
|
final group = t.widget<RadioGroup<AppThemeMode>>(
|
||||||
|
find.byType(RadioGroup<AppThemeMode>),
|
||||||
|
);
|
||||||
|
expect(group.groupValue, AppThemeMode.dark);
|
||||||
final darkRadio = t.widget<RadioListTile<AppThemeMode>>(
|
final darkRadio = t.widget<RadioListTile<AppThemeMode>>(
|
||||||
find.byKey(const Key('appearance_dark')),
|
find.byKey(const Key('appearance_dark')),
|
||||||
);
|
);
|
||||||
expect(darkRadio.groupValue, AppThemeMode.dark);
|
|
||||||
expect(darkRadio.value, AppThemeMode.dark);
|
expect(darkRadio.value, AppThemeMode.dark);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user