import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'shared/settings_persistence.dart'; enum HeaderMode { solid, frosted } enum StartupPage { home, servers, aggregated, discover, settings } const String kStartupPageKey = 'smplayer.startup_page'; StartupPage parseStartupPage(String? s) => switch (s) { 'servers' => StartupPage.servers, 'aggregated' => StartupPage.aggregated, 'discover' => StartupPage.discover, 'settings' => StartupPage.settings, _ => StartupPage.home, }; String startupPageToStr(StartupPage p) => switch (p) { StartupPage.home => 'home', StartupPage.servers => 'servers', StartupPage.aggregated => 'aggregated', StartupPage.discover => 'discover', StartupPage.settings => 'settings', }; String startupPagePath(StartupPage p) => switch (p) { StartupPage.home => '/', StartupPage.servers => '/servers', StartupPage.aggregated => '/aggregated', StartupPage.discover => '/discover', StartupPage.settings => '/settings', }; class AppearanceState { final ThemeMode themeMode; final HeaderMode headerMode; final StartupPage startupPage; const AppearanceState({ this.themeMode = ThemeMode.system, this.headerMode = HeaderMode.frosted, this.startupPage = StartupPage.home, }); AppearanceState copyWith({ ThemeMode? themeMode, HeaderMode? headerMode, StartupPage? startupPage, }) => AppearanceState( themeMode: themeMode ?? this.themeMode, headerMode: headerMode ?? this.headerMode, startupPage: startupPage ?? this.startupPage, ); } class AppearanceNotifier extends AsyncNotifier with SettingsPersistence { static const _keyMode = 'smplayer.theme_mode'; static const _keyHeader = 'smplayer.header_mode'; @override Future build() async { final prefs = await getPrefs(); final raw = prefs.getString(_keyMode) ?? 'system'; final rawHeader = prefs.getString(_keyHeader) ?? 'frosted'; return AppearanceState( themeMode: _parse(raw), headerMode: _parseHeader(rawHeader), startupPage: parseStartupPage(prefs.getString(kStartupPageKey)), ); } static ThemeMode _parse(String s) => switch (s) { 'light' => ThemeMode.light, 'dark' => ThemeMode.dark, _ => ThemeMode.system, }; static String _toStr(ThemeMode m) => switch (m) { ThemeMode.light => 'light', ThemeMode.dark => 'dark', ThemeMode.system => 'system', }; static HeaderMode _parseHeader(String s) => switch (s) { 'solid' => HeaderMode.solid, 'frosted' => HeaderMode.frosted, _ => HeaderMode.frosted, }; static String _headerToStr(HeaderMode m) => switch (m) { HeaderMode.solid => 'solid', HeaderMode.frosted => 'frosted', }; Future setThemeMode(ThemeMode mode) async { final current = state.value ?? const AppearanceState(); state = AsyncValue.data(current.copyWith(themeMode: mode)); await persistField(_keyMode, _toStr(mode)); } Future setHeaderMode(HeaderMode mode) async { final current = state.value ?? const AppearanceState(); state = AsyncValue.data(current.copyWith(headerMode: mode)); await persistField(_keyHeader, _headerToStr(mode)); } Future setStartupPage(StartupPage page) async { final current = state.value ?? const AppearanceState(); state = AsyncValue.data(current.copyWith(startupPage: page)); await persistField(kStartupPageKey, startupPageToStr(page)); } } final initialLocationProvider = Provider((_) => '/'); final appearanceProvider = AsyncNotifierProvider( AppearanceNotifier.new, );