#363 · The timeline browser searches in place, with better cards (#338)
- timeline-app
- pull request
Closes #338 The dashboard's and profiles' timeline lists now search, sort, filter and page in place, with no reload and no redirect. The cards are richer and come in a grid or list layout. ## What changed **Searching in place** (`platform/components/timeline-browser.jsx`, new) - Each list takes its state from the address (`useSearchParams`). Controls change the address with `history.pushState`, or `replaceState` for the rest of a typing spell after its first search, so Back returns to before it. Next.js picks up both calls. - When the address differs from what the server rendered, the list fetches its page from `POST /api/timelines/search`, and the server's other lists stay untouched. - Scroll and focus stay where they were. Nothing jumps to the top; the page only gets shorter when there are fewer results. - After a page change, focus moves to the cards, scrolling back only if their top is above the window. - Loading doesn't move the layout. A thin progress bar runs above the cards, which dim and shimmer in place under `aria-busy`. Skeleton cards show when there's nothing yet. A failed search shows an alert with **Try again**. **Controls** (`timeline-search.jsx`) - Words and tag search as you type (350 ms debounce). **Search** and Enter still apply at once. - Sort and Visibility apply on change. - A **Grid / List** toggle (`aria-pressed`) is kept in `localStorage` and shared by every list on the page. **Cards** (`timeline-card.jsx`, new) - Title, owner and "Changed ". - Badges: Private, Featured, Read-only comparison, Sensitive. - A three-line description excerpt. - **Size**, plus **Span** with a 24-bar density chart. It is an inline SVG drawn with attributes, so the CSP is unchanged. - Tag chips that filter the list, with `aria-current` on the active tag. - Footer with star, compare and fork. - **Timeline image (#339, from #362):** `TimelineCardMedia` renders #362's `TimelineCardImage` above the title (the image or its placeholder, edge to edge), so every list shows it in the same place. The list layout leaves images out. This branch has #362's branch merged in; it merges after #362. **Lists** (`timeline-list.jsx`) - Grid on wide screens, a single column on phones, or the list layout (its actions sit at the side on wide screens). - Arrow keys move between card titles; Up and Down move a row, using the grid's column count; Home and End go to the first and last. - Empty states: a search that finds nothing offers **Clear the search**. An empty "Your timelines" offers **+ New timeline**, and empty favorites say how to add one. - Status lines use `role="status"`, and sections are landmarks labelled by their headings. **Without JavaScript** - The server-rendered forms and links still work. - Every link and form action ends with its list's section, so the reloaded page opens there. Section ids are renamed to match the issue: dashboard `#explore`, `#mine`, `#favorites`, `#drafts`; profile `#timelines`, `#favorites`. **Drafts** (`browser-drafts.jsx`): drafts are searched in the browser, in place, with the same controls and cards. **API** - `searchTimelines` adds `first_time`, `last_time`, `time_span` (in the timeline's own presentation) and `shape` (24 densities, 0–100) to each result, documented in `server/openapi/collaboration.mjs`. - One query per page reads the top three levels of each moment tree by primary key: at most 15 rows a timeline, 180 for a page of 12. - Forks that read through to their source (`index_bases`) and comparisons get `null`, as reading through costs far more. **Docs**: `docs/guide.md` (in-place lists, Back, Grid/List, arrow keys, cards, no-JS) and `docs/browsing.md` (how it works, and the new result fields). ## Tests - **New `test/timeline-browser-live-postgres.mjs`** (added to CI's live-browser steps), Playwright against PostgreSQL. It checks that the page never reloads (a `window` marker survives), and covers: - typing updates the URL and results, keeping focus and the `#explore` hash, with the box still i…
Sources
Open #363 · The timeline browser searches in place, with better cards (#338) in the timeline