Skip to content

fix(ToastProvider): dismiss stuck toasts in a background tab (DS-4709) - #448

Open
KamilEmeleev wants to merge 2 commits into
mainfrom
fix/ds-4709
Open

fix(ToastProvider): dismiss stuck toasts in a background tab (DS-4709)#448
KamilEmeleev wants to merge 2 commits into
mainfrom
fix/ds-4709

Conversation

@KamilEmeleev

@KamilEmeleev KamilEmeleev commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • Bug Fixes
    • Improved toast timing accuracy when notifications are queued in bursts or updates are delayed.
    • Preserved toast lifetime correctly across visibility changes, pauses, resumes, and system clock adjustments.
    • Ensured expired notifications close in the correct order and spacing.
    • Fixed cleanup behavior for paused notifications, manually closed toasts, and close actions that add new notifications.
    • Improved ticker cleanup to prevent unnecessary ongoing processing.

@KamilEmeleev KamilEmeleev added the bug Something isn't working label Aug 6, 2026
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit 046bb1e):

https://react-koobiq-next--prs-448-xxnqo1xy.web.app

(expires Tue, 11 Aug 2026 12:11:21 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: fc29847d4a9e5cb1adf458c76a9b681c76e2eeff

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e5544353-a2f6-4e3a-b0e6-28101be710ea

📥 Commits

Reviewing files that changed from the base of the PR and between 414611a and 046bb1e.

📒 Files selected for processing (2)
  • packages/components/src/components/ToastProvider/KbqToastQueue.test.ts
  • packages/components/src/components/ToastProvider/KbqToastQueue.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/components/src/components/ToastProvider/KbqToastQueue.test.ts
  • packages/components/src/components/ToastProvider/KbqToastQueue.ts

📝 Walkthrough

Walkthrough

KbqToastQueue now tracks enqueue, expiry, and pause timestamps. It handles visibility changes, delayed ticker execution, clock rollback, callback-driven additions, and timed-toast cleanup. Tests cover timing, pause/resume, manual close, reentrancy, and ticker lifecycle behavior.

Changes

Toast queue timing and lifecycle

Layer / File(s) Summary
Timing state and pause lifecycle
packages/components/src/components/ToastProvider/KbqToastQueue.ts, packages/components/src/components/ToastProvider/KbqToastQueue.test.ts
The queue records enqueue and pause timestamps. Pause and resume operations preserve TTL and close-delay timing. Visibility changes trigger ticker processing.
Callback-safe toast removal
packages/components/src/components/ToastProvider/KbqToastQueue.ts, packages/components/src/components/ToastProvider/KbqToastQueue.test.ts
Toast entries are removed before onClose callbacks run. Callbacks can add new toasts without corrupting timed-toast tracking.
Elapsed-time ticker processing
packages/components/src/components/ToastProvider/KbqToastQueue.ts, packages/components/src/components/ToastProvider/KbqToastQueue.test.ts
Ticker processing accounts for elapsed time, delayed ticks, enqueue timestamps, expiry timestamps, and backward clock changes. It closes eligible timed toasts while preserving close spacing.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant BrowserDocument
  participant KbqToastQueue
  participant Ticker

  KbqToastQueue->>Ticker: start ticker
  Ticker->>KbqToastQueue: process elapsed time
  BrowserDocument->>KbqToastQueue: visibility becomes visible
  KbqToastQueue->>Ticker: run immediate tick
  Ticker->>KbqToastQueue: close eligible timed toasts
  KbqToastQueue->>KbqToastQueue: invoke onClose after deletion
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: fixing ToastProvider to dismiss toasts that become stuck in background tabs.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/ds-4709

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/components/src/components/ToastProvider/KbqToastQueue.ts`:
- Around line 217-231: Make clear() callback-safe by snapshotting and detaching
the existing queue before invoking any onClose callbacks, then process only the
detached toasts so callbacks cannot reprocess them. Preserve toasts added
through add() during callbacks in the live queue, and add a regression test
covering an onClose handler that calls add().
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: cb372fdc-f771-4da1-952b-6ae0404b27d1

📥 Commits

Reviewing files that changed from the base of the PR and between 3bf6163 and 414611a.

📒 Files selected for processing (2)
  • packages/components/src/components/ToastProvider/KbqToastQueue.test.ts
  • packages/components/src/components/ToastProvider/KbqToastQueue.ts

Comment thread packages/components/src/components/ToastProvider/KbqToastQueue.ts

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

Fixes ToastProvider/ToastQueue auto-dismiss behavior when the browser tab is backgrounded and timer ticks are heavily throttled, ensuring expired toasts are dismissed promptly (and in the correct order) once execution resumes.

Changes:

  • Added more robust time accounting in ToastQueue (per-toast addedAt, expiredAt, pause/resume adjustments) to handle delayed ticks and maintain close spacing.
  • Added a visibilitychange listener to force an immediate catch-up tick when the tab becomes visible again.
  • Expanded ToastQueue unit tests to cover background-tab throttling, visibility resume, pause/resume interactions, and clock skew scenarios.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
packages/components/src/components/ToastProvider/KbqToastQueue.ts Updates the queue/ticker logic to correctly catch up on throttled ticks and visibility changes while preserving FIFO close order and close spacing.
packages/components/src/components/ToastProvider/KbqToastQueue.test.ts Adds targeted tests for delayed ticks, visibility catch-up, pause/resume timing, and related edge cases.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


// a toast queued mid-tick has only lived through part of it,
// and a system clock moved backwards must not add time back
const step = Math.max(0, Math.min(elapsed, now - (toast.addedAt ?? now)));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants