app/core/ReminderScheduler.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <QDateTime> | ||
| 4 | #include <QObject> | ||
| 5 | #include <QTimer> | ||
| 6 | #include <QVariantList> | ||
| 7 | #include <functional> | ||
| 8 | |||
| 9 | class CalendarStore; | ||
| 10 | |||
| 11 | // Sprint 93/94: fires appointment and open-task reminders. | ||
| 12 | // | ||
| 13 | // Works on the sync coordinator's store connection (GUI thread). recompute() | ||
| 14 | // expands the appointments of the next two days, applies each occurrence's | ||
| 15 | // reminders (minutes before the start) and the local reminder_state, and | ||
| 16 | // arms ONE timer for the next trigger. Due reminders of the same minute | ||
| 17 | // are reported together (remindersDue) so a busy morning is one | ||
| 18 | // notification. At start, reminders missed while MailJD was not running | ||
| 19 | // (last 12 h, appointment not over yet) are reported once as `missed`. | ||
| 20 | // Dismissed reminders never fire again; snoozed ones fire at the snooze | ||
| 21 | // time. recompute() runs on store changes, every five minutes (resume | ||
| 22 | // from suspend, clock and zone changes) and after every action. | ||
| 23 | class ReminderScheduler final : public QObject { | ||
| 24 | Q_OBJECT | ||
| 25 | public: | ||
| 26 | using Clock = std::function<QDateTime()>; | ||
| 27 | using Enabled = std::function<bool()>; | ||
| 28 | using HiddenCalendars = std::function<QStringList()>; | ||
| 29 | explicit ReminderScheduler(CalendarStore *store, QObject *parent = nullptr); | ||
| 30 | |||
| 31 | 17 | void setClock(Clock clock) { m_clock = std::move(clock); } | |
| 32 | 766 | void setEnabled(Enabled enabled) { m_enabled = std::move(enabled); } | |
| 33 | 769 | void setHiddenCalendars(HiddenCalendars hidden) { m_hidden = std::move(hidden); } | |
| 34 | // Starts the periodic check and reports missed reminders once. | ||
| 35 | void start(); | ||
| 36 | Q_INVOKABLE void recompute(); | ||
| 37 | // Items as reported by remindersDue (uid, accountId, calendarPath, | ||
| 38 | // occurrence). | ||
| 39 | void snooze(const QVariantList &items, int minutes); | ||
| 40 | void dismiss(const QVariantList &items); | ||
| 41 | void snoozeTomorrow(const QVariantList &items); | ||
| 42 | void snoozeUntil(const QVariantList &items, const QDateTime &until); | ||
| 43 | // Epoch seconds of the armed trigger (0 = none); for tests and logs. | ||
| 44 | 21 | qint64 nextTrigger() const { return m_nextTrigger; } | |
| 45 | |||
| 46 | signals: | ||
| 47 | // items: maps with uid, accountId, calendarPath, occurrence (UTC ISO), | ||
| 48 | // summary, location, startIso, minutesBefore, color. | ||
| 49 | void remindersDue(const QVariantList &items, bool missed); | ||
| 50 | |||
| 51 | private: | ||
| 52 | struct Due { | ||
| 53 | QVariantMap item; | ||
| 54 | qint64 trigger = 0; | ||
| 55 | }; | ||
| 56 | QList<Due> collect(qint64 from, qint64 to) const; | ||
| 57 | QList<Due> collectTasks(qint64 from, qint64 to) const; | ||
| 58 | void fire(const QList<Due> &due, bool missed); | ||
| 59 | QDateTime now() const; | ||
| 60 | |||
| 61 | CalendarStore *m_store = nullptr; | ||
| 62 | QTimer m_timer; | ||
| 63 | QTimer m_periodic; | ||
| 64 | Clock m_clock; | ||
| 65 | Enabled m_enabled; | ||
| 66 | HiddenCalendars m_hidden; | ||
| 67 | qint64 m_nextTrigger = 0; | ||
| 68 | }; | ||
| 69 |