diff --git a/src/screens/settings_reminders/edit_reminder_modal.tsx b/src/screens/settings_reminders/edit_reminder_modal.tsx index 66751442..f35718c9 100644 --- a/src/screens/settings_reminders/edit_reminder_modal.tsx +++ b/src/screens/settings_reminders/edit_reminder_modal.tsx @@ -45,6 +45,8 @@ export function EditReminderModal({ duration: reminderState?.duration || defaultDuration, durationModifier: reminderState?.durationModifier || -1, prayer: reminderState?.prayer || Prayer.Fajr, + modified: Date.now(), + whenIsFired: undefined, }); } else { setDraftReminderState(null); diff --git a/src/store/settings.ts b/src/store/settings.ts index 785e4538..8f981468 100644 --- a/src/store/settings.ts +++ b/src/store/settings.ts @@ -24,6 +24,12 @@ export type Reminder = { duration: number; /** has a value of `-1` or `+1` */ durationModifier: number; + /** when is this reminder scheduled to be fired. can be undefined if not scheduled yet. or an outdated timestamp. */ + whenIsFired?: number; + /** timestamp of when it was scheduled. */ + whenScheduled?: number; + /** timestamp of when it was modified. */ + modified?: number; }; export type SettingsStore = { diff --git a/src/tasks/set_reminder.ts b/src/tasks/set_reminder.ts index 05b241e6..8580b674 100644 --- a/src/tasks/set_reminder.ts +++ b/src/tasks/set_reminder.ts @@ -13,7 +13,7 @@ import { REMINDER_CHANNEL_NAME, } from '@/constants/notification'; import {hasAtLeastOneNotificationSetting} from '@/store/calculation_settings'; -import {Reminder} from '@/store/settings'; +import {Reminder, settings} from '@/store/settings'; import {getNextDayBeginning, getTime} from '@/utils/date'; type SetReminderOptions = { @@ -22,6 +22,25 @@ type SetReminderOptions = { reminders: Array; }; +function needSchedulePredicate(reminder: Reminder) { + if (reminder.whenIsFired) { + if (Date.now() <= reminder.whenIsFired) { + return false; + } + } + return true; +} + +function needToCancelPredicate(reminder: Reminder) { + if (!reminder.enabled) return true; + if (!reminder.whenScheduled) return false; + if (!reminder.modified) return false; + if (reminder.whenScheduled <= reminder.modified) { + return true; + } + return false; +} + export async function setReminders(options: SetReminderOptions) { const notificationSettingsIsValid = hasAtLeastOneNotificationSetting(); @@ -43,10 +62,14 @@ export async function setReminders(options: SetReminderOptions) { }); await notifee - .cancelTriggerNotifications(options.reminders.map(r => r.id)) + .cancelTriggerNotifications( + options.reminders.filter(needToCancelPredicate).map(r => r.id), + ) .catch(console.error); - for (const reminder of options.reminders.filter(r => r.enabled)) { + for (const reminder of options.reminders + .filter(r => r.enabled) + .filter(needSchedulePredicate)) { let pTime = prayerTimes[reminder.prayer].getTime(); if (pTime < Date.now()) { pTime = tomorrowPrayerTimes[reminder.prayer].getTime(); @@ -54,6 +77,8 @@ export async function setReminders(options: SetReminderOptions) { const timestamp = pTime + reminder.duration * reminder.durationModifier; + if (timestamp < Date.now()) continue; + const trigger: TimestampTrigger = { type: TriggerType.TIMESTAMP, timestamp, @@ -78,6 +103,13 @@ export async function setReminders(options: SetReminderOptions) { }, trigger, ) + .then(() => { + settings.getState().saveReminder({ + ...reminder, + whenScheduled: Date.now(), + whenIsFired: timestamp, + }); + }) .catch(console.error); if (!options?.noToast) {