---
name: History page
type: architecture-map-page
slice: 01-frontend
last_verified: 2026/05/09
---

# History page

> **Where you are:** [Architecture map](../../README.md) → [Frontend](../README.md) → [Pages overview](../pages-overview.md) → History

**Plain English summary.** The transcript browser. Lists everything saved to SQLite, full text searchable via FTS5, with inline expansion to read the full body, audio playback, starring, manual + auto tagging, copy, delete, export to Markdown, and "open in viewer" handoff to the dedicated transcript editor window.

## At a glance

- **Path:** `src/lib/pages/HistoryPage.svelte`
- **LOC:** 974
- **Imports (selected):**
  - Tauri: `invoke` and `convertFileSrc` from `@tauri-apps/api/core`.
  - Stores: `historyStore` helpers from `page.svelte.ts` (`history`, `loadHistory`, `deleteFromHistoryById`, `renameHistoryEntry`), `toasts`, `getPreferences`.
  - Utils: `deriveAutoTags`, `buildFrontmatter`, `buildMarkdown`, `normaliseTag` (frontmatter). `saveTranscriptAsMarkdown`, `exportTranscriptsToDir` (saveMarkdown). `clampTextLines`, `measurePreWrap` (textMeasure). `bodyPretextLineHeight`, `pretextFontShorthand` (accessibilityTypography). `buildCumulativeOffsets`, `findVisibleRange` (virtualList). `formatTime`, `formatDuration` (time). `PLAYBACK_SPEEDS` (constants).
  - Components: `Card`, `EmptyState`.
  - External: `lucide-svelte` (`Search`, `Clock`, `Play`, `Pause`, `FileText`, `Mic`, `ChevronDown`, `ExternalLink`, `Star`, `Tag`).

## What's in here

### List + search

- Loads via `loadHistory` (which calls `list_transcripts` in Rust).
- Search input filters client side (FTS happens server side via `search_transcripts` for some flows; check `page.svelte.ts`).
- Virtualised scrolling using `buildCumulativeOffsets` and `findVisibleRange` from `utils/virtualList.ts`. Row heights use `measurePreWrap` to compute pre wrap heights from the live preferences font.
- Constants: `COLLAPSED_ROW_MIN_HEIGHT`, `COLLAPSED_ROW_VERTICAL_PADDING`, `EXPANDED_BASE_HEIGHT`, `EXPANDED_PADDING`, etc.

### Audio playback

- `convertFileSrc()` maps the saved audio path to a webview URL.
- Inline `<audio>` element. Speed control uses `PLAYBACK_SPEEDS` (`[0.5, 1, 1.5, 2, 3, 5]`).
- A `requestAnimationFrame` loop advances `currentTime`. `cancelAnimationFrame` on stop.

### Per row actions

- Star (toggles `starred` flag, persisted via `update_transcript`).
- Copy (`copy_to_clipboard`).
- Delete (confirms, then calls `delete_transcript`).
- Open in viewer window (`open_viewer_window`, then handoff via `localStorage`).
- Auto tag (calls `extract_content_tags_cmd`, returns suggested tags merged into `tags`).
- Rename via `renameHistoryEntry` store helper.
- Export to markdown via `saveTranscriptAsMarkdown`.

### Bulk

- Bulk auto tag walks the visible list and calls `extract_content_tags_cmd` per row.
- Bulk export to directory via `exportTranscriptsToDir`.

## Tauri command surface

`delete_transcript`, `copy_to_clipboard`, `open_viewer_window`, `extract_content_tags_cmd`. Plus indirect commands from store helpers (`add_transcript`, `update_transcript`, etc) and the dialog plugin used by `saveMarkdown.ts`.

## Watch outs

- Virtual scrolling assumes stable row heights once measured. Toggling preferences (font size, line height) invalidates the measure. The page recomputes on `getPreferences()` change but watch for stutter on rapid changes.
- The viewer handoff writes the transcript ID to `localStorage`. The viewer window then loads from SQLite. Do not put transcript text in `localStorage`.
- Auto tag is rate limited only by user clicks. Bulk over a large library can hammer the LLM. Consider a guard if scaling.
- `convertFileSrc` paths are valid only inside the Tauri webview. If the audio path is missing or moved, `<audio>` will silently fail; show an error state.

## See also

- [Pages: dictation](dictation.md). Where transcripts originate.
- [Stores](../stores.md). `page.svelte.ts` history helpers.
- [Frontend ↔ Tauri bridge](../frontend-tauri-bridge.md). Commands referenced.
- [Windows and routes](../windows-and-routes.md). The viewer window handoff.
