Skip to content

CPLAT-12423: stop background rebuilds fighting the session filter - #168

Merged
gavin-jeong merged 1 commit into
masterfrom
CPLAT-12423-filter-caret-and-auto-refilter
Sep 28, 2026
Merged

gavin-jeong merged 1 commit into
masterfrom
CPLAT-12423-filter-caret-and-auto-refilter

Conversation

@gavin-jeong

Copy link
Copy Markdown
Collaborator

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. 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 (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 rebuildSessionList means 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:mon is applied at startup by design, but it lives in config.SearchQuery — 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.

Test plan

  • go build ./... && go vet ./... && go test ./... green
  • Three regression tests added to refresh_while_filtering_test.go, each verified by reverting its fix and confirming it fails:
    • TestBackgroundRefreshKeepsCaretWhileFiltering — caret 2 -> 4 without the fix
    • TestRebuildWhileFilteringKeepsSearchBoxOpen — box closes and text is lost without the fix
    • TestDismissedAutoFilterStaysDismissed — filter reappears without the fix
  • Reproduced both symptoms first by driving the real Update loop, before changing anything

Notes for reviewers

  • The first symptom was reported as "arrow keys don't move the cursor in search". They always did — the caret was being reset a moment later, which is why it looked like the keys did nothing. Worth knowing if similar reports come in.
  • rebuildSessionList's filter handling moved from an if/else chain to a switch with the mid-edit case first. Behaviour for the existing branches is unchanged; the default arm is the old "no interactive filter was active" path.

Security checklist

  • No SecurityGroup rule changes
  • No 0.0.0.0/0 inbound
  • No public subnet resources
  • No IAM user changes
  • No secrets in code, commits, or logs

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.
@upwind-code-us

upwind-code-us Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Upwind Upwind Code Scan - ✅ Passed

0 newly introduced vulnerabilities · 0 resolved · 1 total in this PR vs master

Total breakdown: 🔶 1 High

View full analysis in Upwind Console

Scan completed in 7s

Scan history (1 scan)
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

@upwind-code-us

upwind-code-us Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Upwind Upwind IaC Scan - ✅ Passed

0 newly introduced misconfigurations · 0 resolved · 0 total in this PR vs master

View full analysis in Upwind Console →

Scan completed in 5s

Scan history (1 scan)
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 Kairo-Kim added the auto-review/approved Auto-approved by the Slack auto-reviewer bot label Sep 28, 2026

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

LGTM!

@gavin-jeong
gavin-jeong merged commit 6bd9953 into master Sep 28, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto-review/approved Auto-approved by the Slack auto-reviewer bot

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants