Skip to content

fix: let the LiveView drive every scroll - #3980

Closed
chasers wants to merge 2 commits into
fix/load-more-page-windowfrom
fix/search-server-scroll
Closed

chasers wants to merge 2 commits into
fix/load-more-page-windowfrom
fix/search-server-scroll

Conversation

@chasers

@chasers chasers commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Stack 5/7 — "Load more" pagination fixes.

  • Problem: a search does not scroll to the newest results. A fresh page load does not scroll either.
  • Cause: follow-up diffs restore the old scroll anchor and undo the scroll.
  • Fix: the LiveView pushes scroll-to-bottom for every initial page and every tail append.
  • The hook holds the scroll until a frame runs it. It skips the anchor restore until then.
  • data-tailing and scrollToLatest/0 are gone.

🤖 Generated with Claude Code

https://claude.ai/code/session_01YBPF1knvgfghTSdxuYryGL

@chasers
chasers added this pull request to stack #3983 September 14, 2026 18:44
@chasers
chasers force-pushed the fix/search-server-scroll branch from 80bcc16 to 40058df Compare September 14, 2026 19:20
chasers and others added 2 commits September 17, 2026 12:04
A chart click already scrolled the page to the newest results, but running a
search did not, so submitting a query left the viewport wherever it was.

`start_search` now sets the same `scroll_to_bottom_on_result?` flag that
`datetime_update` uses, so the scroll happens once that search's first event
page lands.

The search button and the Enter key both route through one event:
`lql_editor_wrapper_hook.js` binds `monaco.KeyCode.Enter` and the submit
listener to the same `submitSearch/0`, which pushes `start_search`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YQ8Y8zCvSKUFNPvkwH2WS4
A chart click scrolled the page to the newest results, but a search did not.
Scrolling was also split between the server and a `data-tailing` attribute
that the hook read on every update. A fresh load with a querystring never
scrolled. The follow-up diffs of a search (aggregates, pagination buttons)
each ran `restoreScrollAnchor/0` and undid the scroll.

- Every initial event page pushes `scroll-to-bottom`. The initial page is
  always the newest events in range.
- Tail appends push `scroll-to-bottom` too, so `scrollToLatest/0` and
  `data-tailing` come out.
- The hook holds a pending scroll until a frame runs it. It skips the anchor
  restore until then.

The server owns scroll intent. The hook owns viewport stability, which needs
element geometry that the server cannot see.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YBPF1knvgfghTSdxuYryGL
@chasers
chasers force-pushed the fix/search-server-scroll branch from 40058df to e7a01b8 Compare September 17, 2026 19:30
@chasers
chasers removed this pull request from stack #3983 September 17, 2026 21:09
chasers added a commit that referenced this pull request Sep 17, 2026
Squashes the nine-PR load more stack into one commit: #3976, #3977, #3978,
#3979, #3980, #3981, #3982, #3984 and #3986. Merged as a unit so that main
never carries the intermediate states that #3984 corrects.

Pagination

- Keep the "Load more" spinner up until the page query returns.
- Bound a page request to the window in view and say so on the button.
- Store one page window per search in `EventPagination`. The label, the
  query, the cursor shift and the range growth all read it. The window no
  longer doubles on each click.
- Set the page window from a tail result too. A soft pause, play and pause
  used to leave the window nil and drop the next page request.
- Write an implied timestamp range into the query on a page request.
- Keep a one-sided `t:` bound when a page request makes the range explicit.
- Clamp a "next" range extension at now. Each empty click used to push the
  range max another window into the future.
- Cap the cursor of an empty "next" page at the request time.
- Remove timestamp clauses that can never match.
- Stop hiding the load more buttons on a short page.
- Disable the other button while a page request runs.
- Drop a page result or page error that no request waits for.
- Clear the page spinner when a search fails to parse.
- Log a page request that the LiveView drops.

Scrolling

- The LiveView drives every scroll. Every initial event page and every tail
  append pushes `scroll-to-bottom`. The server owns scroll intent. The hook
  owns viewport stability.

Cleanup

- Remove the unused sentinel row: the extra fetched row, `fetch_limit/0`
  and the `has_more?` field that nothing reads.
- Build the chart range in the search timezone. An implied range is no
  longer UTC written as local time.
- Remove the 750ms LiveView latency simulator in dev.

Tests

- Cover event pagination against a bigquery source and a postgres source.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@chasers

chasers commented Sep 17, 2026

Copy link
Copy Markdown
Contributor Author

Merged as part of the squashed stack in #3986, which landed on main as 9c9913b. The whole stack merged as one unit so that main never carried the intermediate states that #3984 corrects. This PR's commits are all included there.

@chasers chasers closed this Sep 17, 2026
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