diff --git a/client/lib/core/theme/theme_controller.dart b/client/lib/core/theme/theme_controller.dart new file mode 100644 index 0000000..2d8fb66 --- /dev/null +++ b/client/lib/core/theme/theme_controller.dart @@ -0,0 +1,25 @@ +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +const _kKey = 'app_theme'; +const _kValid = {'a', 'b', 'c'}; + +class ThemeController extends StateNotifier { + ThemeController() : super('a'); + + Future restore() async { + final prefs = await SharedPreferences.getInstance(); + final v = prefs.getString(_kKey); + if (v != null && _kValid.contains(v)) state = v; + } + + Future set(String key) async { + if (!_kValid.contains(key)) return; + state = key; + final prefs = await SharedPreferences.getInstance(); + await prefs.setString(_kKey, key); + } +} + +final themeControllerProvider = + StateNotifierProvider((ref) => ThemeController()); diff --git a/client/test/theme/theme_controller_test.dart b/client/test/theme/theme_controller_test.dart new file mode 100644 index 0000000..5d8c33e --- /dev/null +++ b/client/test/theme/theme_controller_test.dart @@ -0,0 +1,25 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:jiu_client/core/theme/theme_controller.dart'; + +void main() { + setUp(() => SharedPreferences.setMockInitialValues({})); + + test('默认 a;set 持久化并可 restore', () async { + final c = ProviderContainer(); + expect(c.read(themeControllerProvider), 'a'); + await c.read(themeControllerProvider.notifier).set('c'); + expect(c.read(themeControllerProvider), 'c'); + + final c2 = ProviderContainer(); + await c2.read(themeControllerProvider.notifier).restore(); + expect(c2.read(themeControllerProvider), 'c'); + }); + + test('非法 key 被忽略', () async { + final c = ProviderContainer(); + await c.read(themeControllerProvider.notifier).set('zzz'); + expect(c.read(themeControllerProvider), 'a'); + }); +}