The src/lib/ directory was being excluded by a Python .gitignore rule for lib/ (meant for Python's build output). Changed to /lib/ so it only matches root-level lib/ and doesn't block src/lib/. Adds 8 files that were created but missed in the initial commit: - 5 Svelte components (Header, StatusBar, Controls, TranscriptionDisplay, Settings) - 3 TypeScript stores (backend, config, transcriptions) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
111 lines
2.3 KiB
Svelte
111 lines
2.3 KiB
Svelte
<script lang="ts">
|
|
import { transcriptionStore } from "$lib/stores/transcriptions";
|
|
import { configStore } from "$lib/stores/config";
|
|
|
|
let container: HTMLDivElement | undefined = $state();
|
|
let showTimestamps = $derived(configStore.config.display.show_timestamps);
|
|
let items = $derived(transcriptionStore.items);
|
|
|
|
$effect(() => {
|
|
// Trigger on items length change to auto-scroll
|
|
const _len = items.length;
|
|
if (container) {
|
|
requestAnimationFrame(() => {
|
|
if (container) {
|
|
container.scrollTop = container.scrollHeight;
|
|
}
|
|
});
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<div class="transcription-display" bind:this={container}>
|
|
{#each items as item (item.id)}
|
|
<div class="transcription-item" class:preview={item.isPreview}>
|
|
{#if showTimestamps && item.timestamp}
|
|
<span class="timestamp">[{item.timestamp}]</span>
|
|
{/if}
|
|
{#if item.userName}
|
|
<span class="user-name">{item.userName}:</span>
|
|
{/if}
|
|
{#if item.isPreview}
|
|
<span class="preview-indicator">[...]</span>
|
|
{/if}
|
|
<span class="text">{item.text}</span>
|
|
</div>
|
|
{:else}
|
|
<div class="empty-state">
|
|
Transcriptions will appear here...
|
|
</div>
|
|
{/each}
|
|
</div>
|
|
|
|
<style>
|
|
.transcription-display {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
padding: 12px 20px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
}
|
|
|
|
.transcription-item {
|
|
padding: 6px 10px;
|
|
border-radius: 4px;
|
|
background-color: rgba(255, 255, 255, 0.03);
|
|
animation: fadeIn 0.2s ease-out;
|
|
line-height: 1.6;
|
|
word-wrap: break-word;
|
|
}
|
|
|
|
.transcription-item.preview {
|
|
font-style: italic;
|
|
opacity: 0.7;
|
|
}
|
|
|
|
.timestamp {
|
|
color: #888;
|
|
font-size: 0.85em;
|
|
margin-right: 8px;
|
|
font-family: monospace;
|
|
}
|
|
|
|
.user-name {
|
|
color: #4caf50;
|
|
font-weight: 700;
|
|
margin-right: 6px;
|
|
}
|
|
|
|
.preview-indicator {
|
|
color: #888;
|
|
font-size: 0.85em;
|
|
margin-right: 4px;
|
|
}
|
|
|
|
.text {
|
|
color: #ffffff;
|
|
}
|
|
|
|
.empty-state {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
height: 100%;
|
|
color: var(--text-muted);
|
|
font-size: 15px;
|
|
font-style: italic;
|
|
}
|
|
|
|
@keyframes fadeIn {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(4px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
</style>
|