CPLAT-12423: stop background rebuilds fighting the session filter - #168
Merged
Merged
Conversation
Two reported symptoms, both from a background rebuild overwriting what the user was doing. Arrow keys looked dead in the search box. The caret does move on left/right — it just does not stay. setListItemsPreservingFilter re-applies the query with SetFilterText and restores the editing state with SetFilterState, and both call FilterInput.CursorEnd(). That path runs on the async PR/Jira ref-resolve, which fires repeatedly over several seconds, so every keypress was undone a moment later and the caret snapped back to the end. Typing mid-string was impossible. rebuildSessionList had a related gap: it captured the query only in FilterApplied, never Filtering. Most tick/refresh callers guard on !isFiltering(), but several do not — remote-liveness refresh, :commands, fold toggles — and landing mid-edit closed the search box and discarded the typed text. Handling the mid-edit case inside rebuildSessionList means no caller can get it wrong, rather than auditing ~20 call sites for a guard that is easy to forget. The state filter also kept switching itself back on. "is:live,is:input,is:mon" is applied at startup by design, but it lives in config.SearchQuery, which is separate from the list's own filter, and rebuildSessionList re-applies it whenever no filter is active. Dismissing it with Esc only reset the list, so the next live tick put it straight back a second later — it read as the filter turning itself on over and over. The state-menu path (setSessionListFilter) already cleared config.SearchQuery; only the Esc path was missing it. Esc on an applied filter that is not being edited still leaves it alone in the session list, which is deliberate (#112): closing the preview or clearing a multi-selection must not wipe the filter. Three regression tests, each verified by reverting the fix and confirming it fails.
|
| Commit | Scanned at | New | Resolved | Net |
|---|---|---|---|---|
5a7c7dc < |
2026-09-28 14:09 UTC | 0 | 0 | 0 |
Last scanned: 5a7c7dc · 2026-09-28 14:09 UTC
|
| Commit | Scanned at | New | Resolved | Net |
|---|---|---|---|---|
5a7c7dc < |
2026-09-28 14:09 UTC | 0 | 0 | 0 |
Last scanned: 5a7c7dc · 2026-09-28 14:09 UTC
Kairo-Kim
approved these changes
Sep 28, 2026
mitrilmad
approved these changes
Sep 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
JIRA: https://sendbird.atlassian.net/browse/CPLAT-12423
Two reported symptoms, both from a background rebuild overwriting what the user was doing.
1. Arrow keys looked dead in the search box
The caret does move on left/right — it just does not stay.
setListItemsPreservingFilterre-applies the query withSetFilterTextand restores the editing state withSetFilterState, and both callFilterInput.CursorEnd(). That path runs on the async PR/Jira ref-resolve, which fires repeatedly over several seconds, so every keypress was undone a moment later and the caret snapped back to the end. Typing mid-string was impossible.rebuildSessionListhad a related gap: it captured the query only inFilterApplied, neverFiltering. Most tick/refresh callers guard on!isFiltering(), but several do not — remote-liveness refresh (app.go:1310),:commands, fold toggles — and landing mid-edit closed the search box and discarded the typed text.Handling the mid-edit case inside
rebuildSessionListmeans no caller can get it wrong, rather than auditing ~20 call sites for a guard that is easy to forget.2. The state filter kept switching itself back on
is:live,is:input,is:monis applied at startup by design, but it lives inconfig.SearchQuery— separate from the list's own filter — andrebuildSessionListre-applies it whenever no filter is active. Dismissing it with Esc only reset the list, so the next live tick put it straight back a second later. It read as the filter turning itself on over and over.The state-menu path (
setSessionListFilter) already clearedconfig.SearchQuery; only the Esc path was missing it.Esc on an applied filter that is not being edited still leaves it alone in the session list, which is deliberate (#112): closing the preview or clearing a multi-selection must not wipe the filter.
Test plan
go build ./... && go vet ./... && go test ./...greenrefresh_while_filtering_test.go, each verified by reverting its fix and confirming it fails:TestBackgroundRefreshKeepsCaretWhileFiltering— caret 2 -> 4 without the fixTestRebuildWhileFilteringKeepsSearchBoxOpen— box closes and text is lost without the fixTestDismissedAutoFilterStaysDismissed— filter reappears without the fixUpdateloop, before changing anythingNotes for reviewers
rebuildSessionList's filter handling moved from an if/else chain to aswitchwith the mid-edit case first. Behaviour for the existing branches is unchanged; thedefaultarm is the old "no interactive filter was active" path.Security checklist
0.0.0.0/0inbound