Improve notification ID management, live-activity updates, and auto-dismiss behavior#17
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7fd9a2eaf5
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if let activity = self.loadLiveActivity(for: id) { | ||
| await activity.update(content) | ||
| return |
There was a problem hiding this comment.
Recreate live activities when the course text changes
When showUpcomingLiveActivity reuses LIVE_ACTIVITY_ID for the next class, this update path only changes the ContentState target time. The widget renders the course name and room from immutable Activity attributes (context.attributes.title / subtitle), so an existing live activity from a previous class will keep showing the old course text while counting down to the new class. In the case where the loaded activity's title/body differ, end it and request a new activity (or move those fields into the mutable state).
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Pull request overview
This PR improves the cross-platform countdown reminder/notification lifecycle by making reminder IDs deterministic (to avoid collisions), ensuring iOS Live Activities are updated when already active, and improving cleanup/deduplication behavior for scheduled notifications/alarms.
Changes:
- TypeScript: replace sequential notification IDs with deterministic hashed IDs and reserve IDs to avoid collisions with other scheduled reminders / the live-activity ID.
- iOS: change Live Activity logic to “start or update” and remove pending/delivered notifications with the same identifier before scheduling to reduce duplicates.
- Android: propagate
autoDismissinto countdown notification construction, standardize receiver intent actions, and improve alarm cancellation/legacy cleanup behavior.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| services/course-notification.ts | Introduces hashed reminder IDs + ID reservation to avoid notification ID collisions. |
| modules/notification/ios/NotificationModule.swift | Updates Live Activity handling to update an existing activity; removes pending/delivered notifications before adding new requests. |
| modules/notification/android/src/main/java/dev/tokenteam/iwut/notification/NotificationModule.kt | Threads autoDismiss into notification timeouts; fixes intent action usage; improves alarm cancellation and legacy cleanup. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const id = hashReminderId( | ||
| [ | ||
| termStart, | ||
| week, | ||
| course.day, | ||
| course.sectionStart, | ||
| course.sectionEnd, | ||
| classStartMs, | ||
| course.name, | ||
| course.room, | ||
| course.teacher, | ||
| ].join("|"), | ||
| ); |
| private fun cancelLegacySequentialAlarms(context: Context) { | ||
| for (id in 0 until LEGACY_SEQUENTIAL_ID_LIMIT) { | ||
| cancelScheduledAlarm(context, id) | ||
| } | ||
| } | ||
|
|
||
| companion object { | ||
| private const val PREFS_NAME = "notification_ids" | ||
| private const val KEY_IDS = "scheduled_ids" | ||
| private const val LEGACY_SEQUENTIAL_ID_LIMIT = 1024 |
Motivation
autoDismissflag so countdown notifications can expire automatically when desired.Description
autoDismissintobuildCountdownNotification, useCountdownReceiver.ACTION_SHOW_COUNTDOWNconstant for intents, cancel and callPendingIntent.cancel()when removing alarms, and addcancelLegacySequentialAlarmsplusLEGACY_SEQUENTIAL_ID_LIMITto clear legacy IDs.startLiveActivityintostartOrUpdateLiveActivity(async) which updates an existing Activity if present, addloadLiveActivityhelper and persistence mapping fixes, and remove pending/delivered notifications before scheduling to avoid duplicates.hashReminderIdandgetReminderId, addreserveReminderIdto avoid collisions (and avoid the reservedLIVE_ACTIVITY_ID), and use the reserved id when callingscheduleCountdown.Testing
tsc) and linting (eslint) on the modified files and they passed.Codex Task