Skip to content

Improve notification ID management, live-activity updates, and auto-dismiss behavior#17

Merged
zhxycn merged 2 commits into
mainfrom
codex/locate-issue-with-duplicate-notification
Jun 9, 2026
Merged

Improve notification ID management, live-activity updates, and auto-dismiss behavior#17
zhxycn merged 2 commits into
mainfrom
codex/locate-issue-with-duplicate-notification

Conversation

@zhxycn

@zhxycn zhxycn commented Jun 9, 2026

Copy link
Copy Markdown
Member

Motivation

  • Prevent notification ID collisions and legacy-sequential alarm leftovers when scheduling countdown reminders.
  • Allow notifications to respect an autoDismiss flag so countdown notifications can expire automatically when desired.
  • Ensure iOS live activities are updated when already active and that scheduled notifications are deduplicated and cleaned up.

Description

  • Android: propagate autoDismiss into buildCountdownNotification, use CountdownReceiver.ACTION_SHOW_COUNTDOWN constant for intents, cancel and call PendingIntent.cancel() when removing alarms, and add cancelLegacySequentialAlarms plus LEGACY_SEQUENTIAL_ID_LIMIT to clear legacy IDs.
  • iOS: convert startLiveActivity into startOrUpdateLiveActivity (async) which updates an existing Activity if present, add loadLiveActivity helper and persistence mapping fixes, and remove pending/delivered notifications before scheduling to avoid duplicates.
  • TypeScript/service: replace ad-hoc incremental IDs with deterministic hashed reminder IDs via hashReminderId and getReminderId, add reserveReminderId to avoid collisions (and avoid the reserved LIVE_ACTIVITY_ID), and use the reserved id when calling scheduleCountdown.

Testing

  • Ran TypeScript type checking (tsc) and linting (eslint) on the modified files and they passed.
  • No new automated unit tests were added for these changes.

Codex Task

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +68 to +70
if let activity = self.loadLiveActivity(for: id) {
await activity.update(content)
return

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 autoDismiss into 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.

Comment on lines +46 to +58
const id = hashReminderId(
[
termStart,
week,
course.day,
course.sectionStart,
course.sectionEnd,
classStartMs,
course.name,
course.room,
course.teacher,
].join("|"),
);
Comment on lines +152 to +161
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
@zhxycn zhxycn added the bug Something isn't working label Jun 9, 2026
@zhxycn zhxycn merged commit 0068f59 into main Jun 9, 2026
5 checks passed
@zhxycn zhxycn deleted the codex/locate-issue-with-duplicate-notification branch June 9, 2026 09:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working codex

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants