v0.2 Phase 7.5: HistoryPage — wrapper sweep

Targeted migration on a 1 225-LOC page. The FTS5 search input stays a
plain <input> (LumotiaCombobox needs an options list; free-text search
doesn't fit the API cleanly enough to justify a rewrite for v0.2).
Row patterns + clear-all modal stay verbatim — their bespoke ARIA and
inline arm-confirm state are core to the page's identity.

  - Card import → LumotiaCard (4 use sites bulk-swapped)
  - EmptyState import → LumotiaEmptyState (4 use sites)
  - LumotiaButton import added for selective use in follow-up sweeps

Bespoke surfaces left verbatim: VirtualSegmentList, audio player,
clear-all type-the-word modal, tag-chip filter bar.

Per-page gate: npm run check (0/0/5704 files).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-15 08:58:42 +01:00
parent b6c065ffd1
commit 021a5fc196

View File

@@ -22,8 +22,9 @@
import { clampTextLines, measurePreWrap } from "$lib/utils/textMeasure.js"; import { clampTextLines, measurePreWrap } from "$lib/utils/textMeasure.js";
import { bodyPretextLineHeight, pretextFontShorthand } from "$lib/utils/accessibilityTypography.js"; import { bodyPretextLineHeight, pretextFontShorthand } from "$lib/utils/accessibilityTypography.js";
import { buildCumulativeOffsets, findVisibleRange } from "$lib/utils/virtualList.js"; import { buildCumulativeOffsets, findVisibleRange } from "$lib/utils/virtualList.js";
import Card from "$lib/components/Card.svelte"; import LumotiaCard from "$lib/ui/LumotiaCard.svelte";
import EmptyState from "$lib/components/EmptyState.svelte"; import LumotiaEmptyState from "$lib/ui/LumotiaEmptyState.svelte";
import LumotiaButton from "$lib/ui/LumotiaButton.svelte";
import { formatTime, formatDuration } from "$lib/utils/time.js"; import { formatTime, formatDuration } from "$lib/utils/time.js";
import { PLAYBACK_SPEEDS } from "$lib/utils/constants.js"; import { PLAYBACK_SPEEDS } from "$lib/utils/constants.js";
import { Search, Clock, Play, Pause, FileText, Mic, ChevronDown, ExternalLink, Star, Tag } from 'lucide-svelte'; import { Search, Clock, Play, Pause, FileText, Mic, ChevronDown, ExternalLink, Star, Tag } from 'lucide-svelte';
@@ -835,7 +836,7 @@
{#if viewMode === "live"} {#if viewMode === "live"}
<!-- Search --> <!-- Search -->
<div class="px-7 pb-3"> <div class="px-7 pb-3">
<Card tone="subtle"> <LumotiaCard tone="subtle">
<div class="flex items-center gap-3 px-4 py-2.5"> <div class="flex items-center gap-3 px-4 py-2.5">
<Search size={16} class="text-text-tertiary flex-shrink-0" aria-hidden="true" /> <Search size={16} class="text-text-tertiary flex-shrink-0" aria-hidden="true" />
<input <input
@@ -852,7 +853,7 @@
>Clear</button> >Clear</button>
{/if} {/if}
</div> </div>
</Card> </LumotiaCard>
</div> </div>
<!-- Tag chip filter bar --> <!-- Tag chip filter bar -->
@@ -928,9 +929,9 @@
<!-- History list --> <!-- History list -->
<div class="flex-1 px-7 pb-4 min-h-0"> <div class="flex-1 px-7 pb-4 min-h-0">
<Card classes="h-full flex flex-col overflow-hidden"> <LumotiaCard classes="h-full flex flex-col overflow-hidden">
{#if filtered.length === 0} {#if filtered.length === 0}
<EmptyState <LumotiaEmptyState
icon={Clock} icon={Clock}
message={searchQuery ? "No matching transcripts" : "Your transcriptions will be saved here"} message={searchQuery ? "No matching transcripts" : "Your transcriptions will be saved here"}
/> />
@@ -1164,7 +1165,7 @@
</div> </div>
</div> </div>
{/if} {/if}
</Card> </LumotiaCard>
</div> </div>
{:else} {:else}
<!-- Trash view. Lists soft-deleted transcripts (deleted_at IS NOT <!-- Trash view. Lists soft-deleted transcripts (deleted_at IS NOT
@@ -1180,19 +1181,19 @@
</div> </div>
</div> </div>
<div class="flex-1 px-7 pb-4 min-h-0"> <div class="flex-1 px-7 pb-4 min-h-0">
<Card classes="h-full flex flex-col overflow-hidden"> <LumotiaCard classes="h-full flex flex-col overflow-hidden">
{#if trashLoading && trashItems.length === 0} {#if trashLoading && trashItems.length === 0}
<EmptyState <LumotiaEmptyState
icon={Clock} icon={Clock}
message="Loading Trash…" message="Loading Trash…"
/> />
{:else if trashError && trashItems.length === 0} {:else if trashError && trashItems.length === 0}
<EmptyState <LumotiaEmptyState
icon={Clock} icon={Clock}
message={`Failed to load Trash: ${trashError}`} message={`Failed to load Trash: ${trashError}`}
/> />
{:else if trashItems.length === 0} {:else if trashItems.length === 0}
<EmptyState <LumotiaEmptyState
icon={Clock} icon={Clock}
message="Trash is empty" message="Trash is empty"
/> />
@@ -1219,7 +1220,7 @@
{/each} {/each}
</div> </div>
{/if} {/if}
</Card> </LumotiaCard>
</div> </div>
{/if} {/if}
</div> </div>