Skip to content

fix: notifications across browsers, show every notification, in-app dialogs - #20

Merged
ttncode merged 3 commits into
mainfrom
fix/notification-replaced-silently
Oct 11, 2026
Merged

ttncode merged 3 commits into
mainfrom
fix/notification-replaced-silently

Conversation

@ttncode

@ttncode ttncode commented Oct 11, 2026 •

Copy link
Copy Markdown
Owner

Summary

Two notification fixes from testing on a real machine.

Ask Chrome directly. The in-app "Turn on" banner and the app-level on/off setting are gone. On first open the app calls Notification.requestPermission(), so Chrome's own Allow/Block prompt is the only step. In the extension the manifest grants the permission, so there is nothing to ask. Menu → Settings → Notifications shows On or Blocked (with how to change it in site settings), or Turn on notifications to ask again when the prompt was dismissed or shown in Chrome's quiet form.

Show every notification. Every notification reused one tag (web) / id (extension). While the previous one was still listed, Chrome swapped the new content in silently without a pop-up, so "Focus session complete" never appeared after an earlier notification. Each notification now gets a fresh id and the previous one is closed/cleared first.

Testing

  • Lint, typecheck, unit tests and build pass.
  • Stubbed permission "default": Chrome's prompt is requested on load with no banner; after allowing, the menu shows Notifications: On and a session ending opens "Focus session complete".
  • Stubbed notifications: the previous notification is closed before the next opens; no shared tag.

Also in this PR

In-app dialogs. Every window.alert/window.confirm is replaced by an in-app dialog styled like the app: OK for messages; Cancel plus a red Delete for destructive confirmations (sessions, habits, notes, tags, goals, comments). Esc cancels, Enter confirms, a click outside cancels, and dialogs queue one at a time.

Firefox and Safari. They ignore a permission request that is not inside a click or key press and answer default immediately, so the ask on load never showed a prompt there. When the browser answers that fast, the app asks again on the user's first click or key press. A Chrome prompt the user dismissed (which takes time to answer) is not asked again. Edge shows its quiet bell in the address bar by default; allow it there or via the menu entry.

Extra testing

  • Firefox-like stub (refuses outside a click): load asks and is refused; the first click asks and grants; later clicks do not ask again.
  • Chrome-like stub where the prompt is dismissed after 1.5 s: no second ask on click.
  • Empty goal → in-app "Please enter a focus goal" dialog; deleting a goal → Esc keeps it, Delete removes it.

…us one

## Summary
Session-complete notifications did not pop up after the sample notification.

**Cause:** every notification reused one tag (web) / id (extension). When a notification with the same tag is still in the notification list, Chrome swaps the new content into it *silently*, without showing a pop-up. The sample sent on "Turn on" stayed in the list, so "Focus session complete" replaced it invisibly.

**Fix:** each notification gets a fresh id, and the previous one is closed (web) / cleared (extension) first, so only one is ever listed and every session or break end pops up.

## Testing
- Lint, typecheck, unit tests and build pass.
- Stubbed Notification API: sample opens without a tag, is closed, then "Focus session complete" opens fresh.
- Reported scenario (Turn on → sample shown → session ends → nothing shown) to be re-checked on a real machine.
Drop the in-app 'Turn on' banner and the app-level on/off setting. The app calls Notification.requestPermission() on first open, so Chrome's own Allow/Block prompt is the only step; the extension is granted by its manifest and needs no ask. Menu → Settings → Notifications shows On / Blocked (with how to change it), or 'Turn on notifications' to ask again when the prompt was dismissed.
@ttncode ttncode changed the title fix: show every notification instead of silently replacing the previous one fix: ask Chrome for notification permission directly and show every notification Oct 11, 2026
Replace every window.alert/confirm with an in-app dialog (OK, or Cancel/confirm with a red Delete for destructive actions; Esc cancels, Enter confirms, queued one at a time).

Firefox and Safari ignore a permission request that is not inside a click or key press and answer 'default' at once, so the ask on load never showed a prompt there. When that happens the app now asks again on the user's first click or key press. A dismissed Chrome prompt (which takes the user time to answer) is not asked again.
@ttncode ttncode changed the title fix: ask Chrome for notification permission directly and show every notification fix: notifications across browsers, show every notification, in-app dialogs Oct 11, 2026
@ttncode
ttncode merged commit 98acfed into main Oct 11, 2026
2 checks passed
@ttncode
ttncode deleted the fix/notification-replaced-silently branch October 11, 2026 16:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant