Skip to content

fix: Fix snooze in All Inboxes#170

Open
mickn wants to merge 3 commits into
ankitvgupta:mainfrom
mickn:codex/fix-all-inboxes-snooze-upstream
Open

fix: Fix snooze in All Inboxes#170
mickn wants to merge 3 commits into
ankitvgupta:mainfrom
mickn:codex/fix-all-inboxes-snooze-upstream

Conversation

@mickn

@mickn mickn commented Jun 3, 2026

Copy link
Copy Markdown

Summary

  • Previously ’snooze’ would only work in individual email views, but not in All Inboxes 'view'.
  • Allow the snooze menu to open from All Inboxes by falling back to the selected email's owning account when no account filter is active.
  • Preserve per-thread account IDs for cross-account batch snooze and undo flows.
  • Add an E2E regression covering snooze menu opening in All Inboxes.

Root Cause

SnoozeOverlay returned null when currentAccountId was null. All Inboxes intentionally has no active account filter, so selected emails with valid accountId values still could not show the snooze menu.

Validation

  • npm run typecheck
  • EXO_DEMO_MODE=true npx playwright test --project=e2e tests/e2e/snooze.spec.ts --workers=1 --reporter=line

@mickn mickn changed the title [codex] Fix snooze in All Inboxes fix: Fix snooze in All Inboxes Jun 3, 2026
@mickn mickn marked this pull request as ready for review June 3, 2026 17:39
@greptile-apps

greptile-apps Bot commented Jun 3, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes snooze functionality in the "All Inboxes" view, where SnoozeOverlay previously returned null because currentAccountId is intentionally null in that view. The fix introduces a fallback to the selected email's owning accountId and propagates per-thread account IDs through the batch snooze and undo flows.

  • Core fix (App.tsx): selectedAccountId falls back to selectedEmail?.accountId when no account filter is active; both batch and single-thread undo items now include a snoozedThreadAccounts map, addressing the coalesced-undo cross-account bug from the prior review.
  • New utility (snooze-accounts.ts): buildSnoozeThreadAccounts resolves the owning account per thread in batch snooze, enabling correct cross-account batches in All Inboxes; covered by focused unit tests.
  • Undo fix (UndoActionToast.tsx / store/index.ts): unsnooze now looks up per-thread account from snoozedThreadAccounts first, falling back to the item-level accountId; the store merge logic correctly spreads both maps when rapid snoozes are coalesced.

Confidence Score: 5/5

Safe to merge — the fix is well-scoped, all undo paths now carry per-thread account IDs, and the changes are covered by both unit and E2E tests.

The snooze fallback logic is straightforward, the store merge for snoozedThreadAccounts correctly uses object spread, and both batch and single-thread undo items now carry the per-thread account map needed for cross-account unsnooze. The previously flagged single-thread undo omission is fully addressed in this diff.

src/renderer/utils/snooze-accounts.ts — the if (resolved) guard in the loop has a minor edge case worth hardening.

Important Files Changed

Filename Overview
src/renderer/App.tsx Core snooze fix: falls back to email's accountId in All Inboxes, adds snoozedThreadAccounts to both batch and single-thread undo items, uses per-thread account for batch API calls.
src/renderer/components/UndoActionToast.tsx Undo snooze now resolves per-thread account from snoozedThreadAccounts map, falling back to item.accountId — correct for both single and cross-account batch undo.
src/renderer/store/index.ts Adds snoozedThreadAccounts to UndoActionItem type and correctly merges it (object spread) when rapid snooze actions are coalesced.
src/renderer/utils/snooze-accounts.ts New utility to build thread→account map for batch snooze. The if (resolved) guard can silently omit a thread when accountId is an empty string, leaving callers with undefined typed as string.
tests/e2e/snooze.spec.ts Adds E2E regression for snooze menu opening in All Inboxes and verifies snoozedThreadAccounts is populated in the undo queue.
tests/unit/snooze-accounts.spec.ts New unit tests covering all edge cases of buildSnoozeThreadAccounts including cross-account, trigger override, undefined lookups, and empty fallback.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant U as User (All Inboxes)
    participant SO as SnoozeOverlay
    participant BAF as buildSnoozeThreadAccounts
    participant Store as AppStore
    participant API as snooze IPC
    participant UAT as UndoActionToast

    U->>SO: Press 'h' (snooze hotkey)
    Note over SO: currentAccountId = null<br/>selectedAccountId = email.accountId (fallback)
    SO->>SO: Guard passes (selectedAccountId non-null)

    alt Batch snooze (multi-select)
        SO->>BAF: buildSnoozeThreadAccounts(threadIds, lookup, triggerThread, triggerAccount, fallback)
        BAF-->>SO: threadAccountById map
        SO->>API: snooze(emailId, tid, threadAccountById[tid], snoozeUntil) per thread
        SO->>Store: addUndoAction with snoozedThreadAccounts map
    else Single snooze
        SO->>API: snooze handled by SnoozeMenu internally
        SO->>Store: "addUndoAction with snoozedThreadAccounts: {tid: accountId}"
    end

    Note over Store: Merge: rapid 2nd snooze spreads snoozedThreadAccounts

    U->>UAT: Click Undo
    loop for each threadId in snoozedThreadIds
        UAT->>UAT: "threadAccountId = snoozedThreadAccounts[tid] ?? item.accountId"
        UAT->>API: unsnooze(threadId, threadAccountId)
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant U as User (All Inboxes)
    participant SO as SnoozeOverlay
    participant BAF as buildSnoozeThreadAccounts
    participant Store as AppStore
    participant API as snooze IPC
    participant UAT as UndoActionToast

    U->>SO: Press 'h' (snooze hotkey)
    Note over SO: currentAccountId = null<br/>selectedAccountId = email.accountId (fallback)
    SO->>SO: Guard passes (selectedAccountId non-null)

    alt Batch snooze (multi-select)
        SO->>BAF: buildSnoozeThreadAccounts(threadIds, lookup, triggerThread, triggerAccount, fallback)
        BAF-->>SO: threadAccountById map
        SO->>API: snooze(emailId, tid, threadAccountById[tid], snoozeUntil) per thread
        SO->>Store: addUndoAction with snoozedThreadAccounts map
    else Single snooze
        SO->>API: snooze handled by SnoozeMenu internally
        SO->>Store: "addUndoAction with snoozedThreadAccounts: {tid: accountId}"
    end

    Note over Store: Merge: rapid 2nd snooze spreads snoozedThreadAccounts

    U->>UAT: Click Undo
    loop for each threadId in snoozedThreadIds
        UAT->>UAT: "threadAccountId = snoozedThreadAccounts[tid] ?? item.accountId"
        UAT->>API: unsnooze(threadId, threadAccountId)
    end
Loading

Reviews (4): Last reviewed commit: "Harden cross-account batch snooze accoun..." | Re-trigger Greptile

@devin-ai-integration devin-ai-integration 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.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 2 additional findings.

Open in Devin Review

@mickn mickn force-pushed the codex/fix-all-inboxes-snooze-upstream branch from ac6048d to b9a5370 Compare June 3, 2026 19:58
@ankitvgupta

Copy link
Copy Markdown
Owner

nice, recommend using /reviewloop to handle the review comments, and consider the /review skill in gstack as well. will plan to get this in soon

mickn and others added 2 commits June 15, 2026 15:29
From code review of the All-Inboxes snooze fix:

- Extract the per-thread account mapping into a pure, unit-tested helper
  (buildSnoozeThreadAccounts). It always resolves an account for every thread
  via an explicit fallback, so a thread can no longer be silently dropped from
  a batch snooze when its account isn't directly resolvable.
- Single-thread path now records the actually-snoozed email's account
  (snoozedEmail.accountId ?? selectedAccountId), matching the batch path,
  instead of selectedAccountId alone.
- Add unit coverage for the cross-account mapping. A faithful cross-account
  batch E2E isn't possible in demo mode (the snooze IPC only accepts the single
  real demo account), so the mapping is covered at the unit level; documented
  with a NOTE in the e2e spec.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@mickn

mickn commented Jun 17, 2026

Copy link
Copy Markdown
Author

nice, recommend using /reviewloop to handle the review comments, and consider the /review skill in gstack as well. will plan to get this in soon

all comments are processed. should be good to go.

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.

2 participants