From 8ac22c97c2c7738e8c538877bd949761c238988e Mon Sep 17 00:00:00 2001 From: qzl Date: Fri, 20 Mar 2026 18:26:11 +0800 Subject: [PATCH] feat(calendar): add ReminderQueueManager for handling reminder queue --- .../reminders/reminder_queue_manager.dart | 31 ++++++++++ .../reminder_queue_manager_test.dart | 60 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 apps/lib/features/calendar/reminders/reminder_queue_manager.dart create mode 100644 apps/test/features/calendar/reminders/reminder_queue_manager_test.dart diff --git a/apps/lib/features/calendar/reminders/reminder_queue_manager.dart b/apps/lib/features/calendar/reminders/reminder_queue_manager.dart new file mode 100644 index 0000000..5636516 --- /dev/null +++ b/apps/lib/features/calendar/reminders/reminder_queue_manager.dart @@ -0,0 +1,31 @@ +import 'models/reminder_payload.dart'; + +class ReminderQueueManager { + ReminderPayload? _currentPayload; + final List _pending = []; + + void enqueueFromClick(ReminderPayload payload) { + _currentPayload = payload; + } + + void enqueuePending(List payloads) { + payloads.sort((a, b) => a.startAt.compareTo(b.startAt)); + _pending.addAll(payloads); + } + + ReminderPayload? get currentPayload => _currentPayload; + + bool get isEmpty => _currentPayload == null && _pending.isEmpty; + + void dequeueCurrent() { + _currentPayload = null; + if (_pending.isNotEmpty) { + _currentPayload = _pending.removeAt(0); + } + } + + void clear() { + _currentPayload = null; + _pending.clear(); + } +} diff --git a/apps/test/features/calendar/reminders/reminder_queue_manager_test.dart b/apps/test/features/calendar/reminders/reminder_queue_manager_test.dart new file mode 100644 index 0000000..ab12ccc --- /dev/null +++ b/apps/test/features/calendar/reminders/reminder_queue_manager_test.dart @@ -0,0 +1,60 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:social_app/features/calendar/reminders/reminder_queue_manager.dart'; +import 'package:social_app/features/calendar/reminders/models/reminder_payload.dart'; + +void main() { + group('ReminderQueueManager', () { + test('按点击顺序处理,第一条处理完后处理剩余的按时间排序', () { + final manager = ReminderQueueManager(); + + final event1 = ReminderPayload( + eventId: '1', + title: 'Event 1', + startAt: DateTime(2026, 3, 20, 10, 1), + timezone: 'UTC', + mode: ReminderPayloadMode.single, + ); + final event2 = ReminderPayload( + eventId: '2', + title: 'Event 2', + startAt: DateTime(2026, 3, 20, 10, 2), + timezone: 'UTC', + mode: ReminderPayloadMode.single, + ); + final event3 = ReminderPayload( + eventId: '3', + title: 'Event 3', + startAt: DateTime(2026, 3, 20, 10, 3), + timezone: 'UTC', + mode: ReminderPayloadMode.single, + ); + + manager.enqueueFromClick(event2); + manager.enqueuePending([event1, event3]); + + expect(manager.currentPayload?.eventId, '2'); + manager.dequeueCurrent(); + expect(manager.currentPayload?.eventId, '1'); + manager.dequeueCurrent(); + expect(manager.currentPayload?.eventId, '3'); + manager.dequeueCurrent(); + expect(manager.isEmpty, true); + }); + + test('单条通知处理完直接清空', () { + final manager = ReminderQueueManager(); + final event = ReminderPayload( + eventId: '1', + title: 'Event 1', + startAt: DateTime.now(), + timezone: 'UTC', + mode: ReminderPayloadMode.single, + ); + + manager.enqueueFromClick(event); + expect(manager.isEmpty, false); + manager.dequeueCurrent(); + expect(manager.isEmpty, true); + }); + }); +}