summaryrefslogtreecommitdiff
path: root/player-android/lib/main.dart
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-22 09:25:48 +0300
committerPaul Buetow <paul@buetow.org>2026-05-22 09:25:48 +0300
commitcce598d8b698ecf4490127d5fad9bd0995ec1050 (patch)
tree11e617532e10915097c962f877b61e4476a33751 /player-android/lib/main.dart
parent1824175276fcd29d4b6d4c14277c62e73247b7e2 (diff)
Implement Material 3 theming with light + dark mode toggle (fb)
Adds ThemeNotifier (AsyncNotifier) backed by shared_preferences to persist the user's light/dark/system preference across restarts. Color schemes derive from the dark and light palettes defined in player-server/docs/theming.md. MaterialApp now consumes themeProvider for themeMode, theme, and darkTheme; SettingsScreen gains a SegmentedButton appearance section for the toggle. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'player-android/lib/main.dart')
-rw-r--r--player-android/lib/main.dart18
1 files changed, 16 insertions, 2 deletions
diff --git a/player-android/lib/main.dart b/player-android/lib/main.dart
index 99e85cb..2c1b193 100644
--- a/player-android/lib/main.dart
+++ b/player-android/lib/main.dart
@@ -5,6 +5,7 @@ import 'package:just_audio/just_audio.dart';
import 'providers/audio_handler_provider.dart';
import 'providers/progress_queue_provider.dart';
+import 'providers/theme_provider.dart';
import 'router.dart';
import 'services/audio_handler.dart';
@@ -68,9 +69,13 @@ void main() async {
/// Root application widget.
///
-/// Uses [ConsumerWidget] to read [routerProvider] from Riverpod so that the
-/// same [GoRouter] instance (and its navigator key) is reused across rebuilds.
+/// Uses [ConsumerWidget] to read [routerProvider] and [themeProvider] from
+/// Riverpod so that the same [GoRouter] instance and the persisted [ThemeMode]
+/// are both available without additional state management in the widget itself.
+///
/// [MaterialApp.router] delegates all navigation decisions to go_router.
+/// [themeMode] is driven by [themeProvider] so the user's light/dark preference
+/// takes effect immediately on every screen and survives app restarts.
class PlayerAndroidApp extends ConsumerWidget {
const PlayerAndroidApp({super.key});
@@ -78,9 +83,18 @@ class PlayerAndroidApp extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final router = ref.watch(routerProvider);
+ // Default to ThemeMode.system while the preference is loading so the app
+ // does not flash an incorrect theme during startup.
+ final themeMode =
+ ref.watch(themeProvider).valueOrNull ?? ThemeMode.system;
+
return MaterialApp.router(
title: 'Player',
routerConfig: router,
+ // Material 3 is enabled in both ThemeData instances; see theme_provider.dart.
+ theme: buildLightTheme(),
+ darkTheme: buildDarkTheme(),
+ themeMode: themeMode,
);
}
}