feat(04-01): NotificationSettingsNotifier with SharedPreferences persistence and full test suite
- Fix NotificationService API calls to use flutter_local_notifications v21 named parameters - Expose nextInstanceOf as @visibleForTesting public method for unit testing - Create NotificationSettingsNotifier with @Riverpod(keepAlive: true) - NotificationSettings data class with enabled bool + TimeOfDay fields - Persist notifications_enabled, notifications_hour, notifications_minute to SharedPreferences - Sync default state in build(), async _load() overrides on hydration - Update tests to use correct Riverpod 3 provider name (notificationSettingsProvider) - Add makeContainer() helper to await initial _load() before asserting mutations - All 84 tests pass (72 existing + 12 new notification tests)
This commit is contained in:
52
lib/core/notifications/notification_settings_notifier.dart
Normal file
52
lib/core/notifications/notification_settings_notifier.dart
Normal file
@@ -0,0 +1,52 @@
|
||||
import 'package:flutter/material.dart' show TimeOfDay;
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
part 'notification_settings_notifier.g.dart';
|
||||
|
||||
class NotificationSettings {
|
||||
final bool enabled;
|
||||
final TimeOfDay time;
|
||||
|
||||
const NotificationSettings({required this.enabled, required this.time});
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
class NotificationSettingsNotifier extends _$NotificationSettingsNotifier {
|
||||
static const _enabledKey = 'notifications_enabled';
|
||||
static const _hourKey = 'notifications_hour';
|
||||
static const _minuteKey = 'notifications_minute';
|
||||
|
||||
@override
|
||||
NotificationSettings build() {
|
||||
_load();
|
||||
return const NotificationSettings(
|
||||
enabled: false,
|
||||
time: TimeOfDay(hour: 7, minute: 0),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _load() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final enabled = prefs.getBool(_enabledKey) ?? false;
|
||||
final hour = prefs.getInt(_hourKey) ?? 7;
|
||||
final minute = prefs.getInt(_minuteKey) ?? 0;
|
||||
state = NotificationSettings(
|
||||
enabled: enabled,
|
||||
time: TimeOfDay(hour: hour, minute: minute),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> setEnabled(bool enabled) async {
|
||||
state = NotificationSettings(enabled: enabled, time: state.time);
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setBool(_enabledKey, enabled);
|
||||
}
|
||||
|
||||
Future<void> setTime(TimeOfDay time) async {
|
||||
state = NotificationSettings(enabled: state.enabled, time: time);
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setInt(_hourKey, time.hour);
|
||||
await prefs.setInt(_minuteKey, time.minute);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user