We were unable to construct the commit group for this pull request: Author does not currently possess a GitClear subscription seat.

fix: global search panel - Messages filter, Dock icon, fast-reopen race #2380

Merged
requilence opened 11:49am on September 15, 2026 wanted to merge 4 commits into anyproto/anytype-ts develop from
fix/JS-9875-global-search-panel

Pull Request Overview

  • Opened on September 15, 2026
  • Status Merged
  • Commit count 4 with first commit September 15, 2026

Total Delta

0 Total Diff Delta

Open Days

Open 4 weekdays

Test Delta

0 Diff Delta in Test Files
Breakdown by Phase

How long has this pull request spent in each phase of its lifecycle?

Data pending calculation for pull request

Author avatar

fix: global search panel - Messages filter, Dock icon, fast-reopen race

Closes JS-9875.

Four fixes found while testing the OS-global quick search panel, plus one vault loader spacing fix. One commit per concern.

1. No "Messages" chip in the panel

Two independent causes, both needed:



  • hasMessageContainers() branched on scopeId == S.Common.space. The panel boots spaceless, so '' == '' sent it down the in-space arm and looked for per-space chat subscriptions that window never creates - the chip could never be offered. isCurrentSpace() exists for exactly this trap (its own comment names the panel). loadMessages had the same compare and was firing resolveMessageChats for rows the panel resolves cross-space anyway.

  • The lite boot dropped chatGlobal / discussionGlobal as "vault UI". They are not: the chip gates on them, and getMessageChat() resolves the chat behind every message row through them - without them a message row cannot even be opened. Lite now keeps the whole global list and drops only the per-space createSubSpace fan-out. The four subscriptions are issued in parallel, so boot waits on the slowest rather than the sum.

2. App disappears from the macOS Dock and loses the menu bar

createQuickSearch called setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true }) without skipTransformProcessType: true. Electron flips the process to UIElementApplication to float over other apps' fullscreen Spaces, which strips the Dock icon and menu bar app-wide, and app.dock.show() does not bring them back (electron#26350). The local-link approval window already carries the flag for this reason; the panel now does too.

3. Empty panel when closing and reopening fast

S.Popup.close() fires onClose immediately - which for this popup hides the panel window - but only removes the popup 200ms later, writing back the list as it looked when the close began. A reopen inside that window was skipped by if (S.Popup.isOpen('search')) return, and the pending write then wiped it: visible window, no content. onQuickSearchPopup now tells "open and settled" apart from "open but closing" and defers the reopen past the pending close.

Fixed at the call site rather than in the store on purpose: cancelling the pending close would leave the popup mounted without its show class (added on mount only, and the close's raf already stripped it), i.e. present but invisible - a reopen has to remount. The stale-snapshot write in S.Popup.close is generic though - any popup reopened within 200ms of closing is clobbered the same way. Quick search is just the one place that reliably does it, because its close and its reopen are driven by the same keystroke. Worth hardening separately.

4. Panel dismissal on blur was untestable in dev

The blur handler returned early on is.development, which is redundant with the devtools check below it - dev force-opens the panel's devtools, and that check already suppresses the hide. Removed, so closing the panel's devtools gives release dismissal behaviour.

5. Vault recovery loader flush against the collapsed rail's top edge

The icons-only rail collapses the vault head to 0 height, and .recoveryProgress.isMinimal carried all 8px of its spacing on the bottom, where the list's own padding already provides it. The spinner started at y=0 of the rail and was clipped by the page's overflow: hidden. The 8px moves to the top; the block keeps its height, so nothing below it shifts.

Testing

bun run typecheck (app + electron), bun run lint and bun run build:electron all pass; lint warnings are unchanged from develop.

The behavioural fixes need a manual pass - the panel is a separate always-on-top window opened by a global hotkey, and the Messages path needs an account with chats:


  • [ ] Panel (minimised app): Messages chip is offered, filters to messages, a message row opens its chat in the main window

  • [ ] Opening the panel leaves the Dock icon and the menu bar in place

  • [ ] Close + reopen the panel fast: it comes back with the search popup, never empty

  • [ ] Release build: clicking away still dismisses the panel

  • [ ] Collapsed vault during a cold sync: the spinner clears the rail's top edge

Known gap, same class, not fixed here

"By me" is also missing from the panel's chip row: U.Space.getParticipant() resolves you from the per-space participant subscription, which the spaceless panel has no equivalent of. The other person chips work because they come from the popup's own cross-space participants subscription, so the fix is to resolve self from there.

PR was closed without comments.