Wholesale JS -> TS migration of the frontend — stores, utils, actions,
and all Svelte component scripts adopt type annotations. Compile-time
surfaces (app.d.ts, lib/types/) added for shared DTO types.
Build plumbing:
- package.json: dev:frontend script that runs svelte-kit sync first
- tauri.conf.json: beforeDevCommand points at dev:frontend
- run.sh: dropped the sed-hack that temporarily blanked beforeDevCommand;
now relies on npm run dev:frontend to avoid double-Vite
- jsconfig.json: allowImportingTsExtensions
Preserves all Group 1 behaviour:
- page.svelte.ts keeps loadHistory / loadTasks Tauri-first, no
localStorage; saveTranscriptMeta + mapTranscriptRow + mapTaskRow
intact; update_task_cmd and update_transcript_meta_cmd invocations
carry the correct payload shape.
- Toasts, preferences stores typed without behaviour change.
- Viewer still routes segment edits through saveTranscriptMeta; the
Task 1.5 TODO markers are gone.
taskExtractor.ts is functionally improved during the migration:
- multi-task matches in the same sentence
- list-style shopping-verb expansion (get bread, milk, and cheese)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
37 lines
1.4 KiB
Svelte
37 lines
1.4 KiB
Svelte
<script lang="ts">
|
|
import { getPreferences, updatePreferences } from '$lib/stores/preferences.svelte.js';
|
|
|
|
const prefs = getPreferences();
|
|
|
|
const zones = [
|
|
{ id: 'default', label: 'Default', swatch: 'bg-bg' },
|
|
{ id: 'cave', label: 'Cave', description: 'Cool, focused', swatch: 'bg-[#141a1e]' },
|
|
{ id: 'energy', label: 'Energy', description: 'Warm, active', swatch: 'bg-[#1c1815]' },
|
|
{ id: 'reset', label: 'Reset', description: 'Natural, calm', swatch: 'bg-[#161a16]' },
|
|
] as const;
|
|
|
|
function selectZone(id: string) {
|
|
updatePreferences({ zone: id });
|
|
}
|
|
</script>
|
|
|
|
<div class="flex flex-col gap-2">
|
|
<p class="text-[12px] text-text-secondary font-medium">Sensory zone</p>
|
|
<div class="grid grid-cols-4 gap-2">
|
|
{#each zones as zone}
|
|
<button
|
|
class="flex flex-col items-center gap-1.5 p-3 rounded-xl border
|
|
{prefs.zone === zone.id || (zone.id === 'default' && !prefs.zone)
|
|
? 'border-accent bg-accent-subtle'
|
|
: 'border-border-subtle hover:border-border'}"
|
|
style="transition-duration: var(--duration-ui)"
|
|
onclick={() => selectZone(zone.id)}
|
|
aria-pressed={prefs.zone === zone.id || (zone.id === 'default' && !prefs.zone)}
|
|
>
|
|
<div class="w-8 h-8 rounded-lg {zone.swatch} border border-border-subtle"></div>
|
|
<span class="text-[11px] text-text-secondary">{zone.label}</span>
|
|
</button>
|
|
{/each}
|
|
</div>
|
|
</div>
|