mirror of
https://github.com/vleeuwenmenno/supplements.git
synced 2025-09-11 18:29:12 +02:00
feat: Implement snooze functionality for notifications
- Added snooze duration setting in SettingsScreen. - Created DebugNotificationsScreen to view pending notifications and logs. - Integrated notification logging with NotificationDebugStore. - Enhanced SimpleNotificationService to handle snooze actions and log notifications. - Removed ProfileSetupScreen as it is no longer needed. - Updated NotificationRouter to manage snooze actions without UI. - Refactored settings provider to include snooze duration management.
This commit is contained in:
92
lib/services/notification_debug_store.dart
Normal file
92
lib/services/notification_debug_store.dart
Normal file
@@ -0,0 +1,92 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class NotificationLogEntry {
|
||||
final int id;
|
||||
final String kind; // 'daily' | 'snooze'
|
||||
final String type; // 'single' | 'group'
|
||||
final int whenEpochMs; // exact scheduled time (epoch ms)
|
||||
final int createdAtEpochMs; // when we created the schedule (epoch ms)
|
||||
final String title;
|
||||
final String payload;
|
||||
final int? singleId; // supplement id for single
|
||||
final String? timeKey; // HH:mm for group
|
||||
|
||||
const NotificationLogEntry({
|
||||
required this.id,
|
||||
required this.kind,
|
||||
required this.type,
|
||||
required this.whenEpochMs,
|
||||
required this.createdAtEpochMs,
|
||||
required this.title,
|
||||
required this.payload,
|
||||
this.singleId,
|
||||
this.timeKey,
|
||||
});
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'id': id,
|
||||
'kind': kind,
|
||||
'type': type,
|
||||
'when': whenEpochMs,
|
||||
'createdAt': createdAtEpochMs,
|
||||
'title': title,
|
||||
'payload': payload,
|
||||
'singleId': singleId,
|
||||
'timeKey': timeKey,
|
||||
};
|
||||
|
||||
static NotificationLogEntry fromJson(Map<String, dynamic> map) {
|
||||
return NotificationLogEntry(
|
||||
id: map['id'] is int ? map['id'] as int : int.tryParse('${map['id']}') ?? 0,
|
||||
kind: map['kind'] ?? 'unknown',
|
||||
type: map['type'] ?? 'unknown',
|
||||
whenEpochMs: map['when'] is int ? map['when'] as int : int.tryParse('${map['when']}') ?? 0,
|
||||
createdAtEpochMs: map['createdAt'] is int ? map['createdAt'] as int : int.tryParse('${map['createdAt']}') ?? 0,
|
||||
title: map['title'] ?? '',
|
||||
payload: map['payload'] ?? '',
|
||||
singleId: map['singleId'],
|
||||
timeKey: map['timeKey'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class NotificationDebugStore {
|
||||
NotificationDebugStore._internal();
|
||||
static final NotificationDebugStore instance = NotificationDebugStore._internal();
|
||||
|
||||
static const String _prefsKey = 'notification_log';
|
||||
static const int _maxEntries = 200;
|
||||
|
||||
Future<List<NotificationLogEntry>> getAll() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final raw = prefs.getString(_prefsKey);
|
||||
if (raw == null || raw.isEmpty) return [];
|
||||
try {
|
||||
final list = jsonDecode(raw) as List;
|
||||
return list
|
||||
.map((e) => NotificationLogEntry.fromJson(e as Map<String, dynamic>))
|
||||
.toList();
|
||||
} catch (_) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> add(NotificationLogEntry entry) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final current = await getAll();
|
||||
current.add(entry);
|
||||
// Cap size
|
||||
final trimmed = current.length > _maxEntries
|
||||
? current.sublist(current.length - _maxEntries)
|
||||
: current;
|
||||
final serialized = jsonEncode(trimmed.map((e) => e.toJson()).toList());
|
||||
await prefs.setString(_prefsKey, serialized);
|
||||
}
|
||||
|
||||
Future<void> clear() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.remove(_prefsKey);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user