mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 09:01:03 -08:00
fix(search): keep in-flight typing when the page rewrites its query params (#1432)
* fix(search): keep in-flight typing when the page rewrites its query params `WorkspaceShellSearchSyncService` re-read `q` on every `NavigationEnd` and unconditionally called `setSearchState(...)`, which cancels the pending debounce and overwrites the search box. Any same-page navigation that carried no search intent — a downloads filter chip writing `?filter=…`, a refresh bump, or the router echoing back our own `q` — therefore ate whatever had been typed since the last applied term. While input is debouncing, ignore a navigation that stays on the same page and carries the term already applied. Real search intent (route change, back/forward, a different `q`) still syncs as before. This is the race behind the flaky `@downloads @electron keeps global and scoped libraries truthful …` e2e test: it clicks a filter chip and fills the searchbox with nothing awaited in between, so under CI load the chip's navigation lands after the keystroke, wipes the term, and `q` is never written. Reproduced deterministically by dispatching the chip click and the `input` event in the same page task; the searchbox value goes to `""` and `q` stays `null`. The new spec fails on the old code for the two regression cases and passes for the three guard cases on both. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(search): keep history authoritative and retire the debounce on Enter Two follow-ups from review of the same-page navigation guard. Greptile: the guard could not tell an app-initiated `q` echo from back/forward landing on a history entry that carries the same term. Key the exemption on `Navigation.trigger === 'imperative'` instead, so browser history always wins over in-flight typing. `lastSuccessfulNavigation` is set immediately before `NavigationEnd` is emitted, so it describes the navigation being handled. Codex: with the guard in place, an Enter commit no longer had its queued debounce cancelled as a side effect of the resulting `NavigationEnd`. Typing "Beta " and pressing Enter before the debounce expired applied the trimmed term, then the stale timeout reapplied the untrimmed one — leaving the box and URL on "Beta" while the provider store searched "Beta ". `applySearchQuery()` now cancels the pending debounce itself, which is the correct owner of that rule rather than relying on a navigation side effect. Both new tests were mutation-checked: dropping either sub-fix fails exactly its own test and no other. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0cba49f3e2
commit
30d76a3a46
5 files changed
+323
-20
No files matched your search
@@ -162,6 +162,22 @@ Search is shell-owned and route-aware:
|
||||
7. Global search uses the header input as its primary input and writes the
|
||||
search phrase to the `q` query parameter, so history/back-forward behavior
|
||||
matches the rest of the workspace.
|
||||
8. The URL is authoritative for the search box only when it carries search
|
||||
intent. `WorkspaceShellSearchSyncService` re-reads `q` on every
|
||||
`NavigationEnd`, but an **app-initiated** navigation that stays on the same
|
||||
page and carries the term already applied is ignored while input is still
|
||||
debouncing — otherwise a page writing an unrelated query param (a downloads
|
||||
filter chip, a refresh bump) or the router echoing back our own `q` would
|
||||
cancel the pending debounce and reset the box, eating everything typed
|
||||
since. Pages are free to write their own query params while the user types;
|
||||
they must not assume the shell will re-apply the search afterwards.
|
||||
9. Browser history overrides that guard. The exemption is keyed on
|
||||
`Navigation.trigger === 'imperative'`, so back/forward always re-applies
|
||||
what the history entry carries, even mid-typing.
|
||||
10. Applying a term explicitly supersedes a queued one. `applySearchQuery()`
|
||||
cancels any pending debounce, so the Enter key committing a trimmed term
|
||||
cannot be overwritten a moment later by the untrimmed keystroke still
|
||||
waiting behind it.
|
||||
|
||||
Rail navigation is also shell-owned:
|
||||
|
||||
|
||||
Reference in new issue
Block a user