import { listen, emit } from '@tauri-apps/api/event'; import { getCurrentWindow } from '@tauri-apps/api/window'; import { useEffect, useMemo, useState } from 'react'; import type { LiveState } from '../types'; import { getCachedLiveState } from '../lib/liveBus'; import { useAppStore } from '../store/useAppStore'; import { isTauriRuntime } from '../lib/tauri'; export function Overlay() { const settings = useAppStore((s) => s.settings); const [state, setState] = useState(() => getCachedLiveState()); useEffect(() => { if (!isTauriRuntime()) return; let unlisten: (() => void) | undefined; listen('meetvault:live-state', (event) => setState(event.payload)).then((fn) => { unlisten = fn; }); return () => unlisten?.(); }, []); const visible = useMemo(() => state?.transcript.slice(-settings.overlayLines) ?? [], [state, settings.overlayLines]); async function rename(speakerId: string) { const current = state?.speakerNames[speakerId] || speakerId; const next = window.prompt('Rename speaker', current); if (!next) return; if (isTauriRuntime()) await emit('meetvault:rename-speaker', { meetingId: state?.meetingId, speakerId, name: next }); } return (
MeetVault live captions{isTauriRuntime() && }
{visible.length === 0 ?
Waiting for speech…
: visible.map((segment) => (
{segment.text}
))}
); }