|
1 | 1 | // Dart imports: |
2 | 2 | import 'dart:math'; |
| 3 | +import 'dart:io'; |
| 4 | +import 'dart:ui' as ui; |
3 | 5 |
|
4 | 6 | // Flutter imports: |
5 | 7 | import 'package:flutter/material.dart'; |
| 8 | +import 'package:flutter/services.dart'; |
6 | 9 |
|
7 | 10 | // Package imports: |
8 | 11 | import 'package:dio/dio.dart'; |
@@ -161,9 +164,65 @@ class FileName { |
161 | 164 | // UI AND SIMPLE STATE PROVIDERS |
162 | 165 | // ==================================================================== |
163 | 166 |
|
| 167 | +class ThemeModeNotifier extends StateNotifier<ThemeMode> { |
| 168 | + ThemeModeNotifier(super.state); |
| 169 | + |
| 170 | + Future<void> setTheme(ThemeMode mode) async { |
| 171 | + state = mode; |
| 172 | + |
| 173 | + // Save to DB |
| 174 | + String pref = 'system'; |
| 175 | + if (mode == ThemeMode.light) pref = 'light'; |
| 176 | + if (mode == ThemeMode.dark) pref = 'dark'; |
| 177 | + await MyLibraryDb.instance.savePreference('themeMode', pref); |
| 178 | + |
| 179 | + updateSystemUi(mode); |
| 180 | + } |
| 181 | + |
| 182 | + static void updateSystemUi(ThemeMode mode) { |
| 183 | + if (Platform.isAndroid) { |
| 184 | + bool isDark = mode == ThemeMode.dark; |
| 185 | + if (mode == ThemeMode.system) { |
| 186 | + isDark = ui.PlatformDispatcher.instance.platformBrightness == |
| 187 | + Brightness.dark; |
| 188 | + } |
| 189 | + SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( |
| 190 | + systemNavigationBarColor: |
| 191 | + isDark ? Colors.black : Colors.grey.shade200)); |
| 192 | + } |
| 193 | + } |
| 194 | + |
| 195 | + static Future<ThemeMode> getInitialTheme() async { |
| 196 | + try { |
| 197 | + MyLibraryDb dataBase = MyLibraryDb.instance; |
| 198 | + // Check for new theme mode preference |
| 199 | + var themePref = |
| 200 | + await dataBase.getPreference('themeMode').catchError((e) => null); |
| 201 | + if (themePref != null && themePref is String) { |
| 202 | + if (themePref == 'light') return ThemeMode.light; |
| 203 | + if (themePref == 'dark') return ThemeMode.dark; |
| 204 | + return ThemeMode.system; |
| 205 | + } else { |
| 206 | + // Fallback to legacy darkMode preference |
| 207 | + var legacyDark = |
| 208 | + await dataBase.getPreference('darkMode').catchError((e) => null); |
| 209 | + if (legacyDark != null) { |
| 210 | + return (legacyDark == 0) ? ThemeMode.light : ThemeMode.dark; |
| 211 | + } |
| 212 | + } |
| 213 | + } catch (e) { |
| 214 | + // Ignore |
| 215 | + } |
| 216 | + return ThemeMode.system; |
| 217 | + } |
| 218 | +} |
| 219 | + |
164 | 220 | final selectedIndexProvider = StateProvider<int>((ref) => 0); |
165 | 221 | final homePageSelectedIndexProvider = StateProvider<int>((ref) => 0); |
166 | | -final themeModeProvider = StateProvider<ThemeMode>((ref) => ThemeMode.light); |
| 222 | +final themeModeProvider = |
| 223 | + StateNotifierProvider<ThemeModeNotifier, ThemeMode>((ref) { |
| 224 | + return ThemeModeNotifier(ThemeMode.light); |
| 225 | +}); |
167 | 226 | final fontSizeScaleProvider = StateProvider<double>((ref) => 1.0); |
168 | 227 |
|
169 | 228 | // Search Filter States |
|
0 commit comments