mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-21 15:26:43 +02:00
feat(web): PillNav bar mode, fullscreen, local STT + mic button
PillNav overhaul: - Dropdown-as-bar: theme/AI/sync/user menus render as horizontal bars in the bottom stack (PillDropdownBar) instead of floating popovers. New onOpenBar/activeBarId props on PillNavigation. - iconOnly pills: tags/search/workbench-tabs pills show only icons. Home pill removed. New iconOnly flag on PillNavItem. - Segmented toggle groups: items sharing a `group` id render as a single segmented pill (e.g. Light/Dark/System triple). - Fullscreen mode: press "f" to hide all bottom chrome, Esc to exit. - QuickInputBar + bottom bar visibility toggles via new pills. - Progress ring on AI trigger pill during model download (conic-gradient ::after, follows pill border-radius). @mana/local-stt — new package for browser-local speech-to-text: - Whisper models via transformers.js v4 (WebGPU + WASM fallback) - Same Web Worker architecture as @mana/local-llm - Two models: Whisper Tiny (150 MB) and Whisper Small (950 MB) - Reactive Svelte 5 bindings (getLocalSttStatus, loadLocalStt, transcribe) Voice-to-text integration: - useLocalStt() composable: mic capture via AudioContext + ScriptProcessor, resample to 16kHz mono, feed into Whisper worker - Mic button in QuickInputBar (leftAction slot) with recording/loading/transcribing states + pulse animation - Transcribed text injected into InputBar via new injectedText prop - STT model selector in AI bar alongside LLM tier controls Also: vite.config.ts server.fs.allow expanded to monorepo root so workspace package workers resolve in dev. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8c2f9306e9
commit
3deee755b3
24 changed files with 2145 additions and 28 deletions
|
|
@ -76,6 +76,9 @@
|
|||
locale?: string;
|
||||
/** Use 'static' when inside a flex container (bottom-stack pattern). Default: 'fixed'. */
|
||||
positioning?: 'fixed' | 'static';
|
||||
/** Externally injected text (e.g. from voice input). When this changes
|
||||
* to a non-empty string, the input bar's query is set and focused. */
|
||||
injectedText?: string;
|
||||
}
|
||||
|
||||
let {
|
||||
|
|
@ -106,6 +109,7 @@
|
|||
highlightPatterns,
|
||||
locale = 'de',
|
||||
positioning = 'fixed',
|
||||
injectedText,
|
||||
}: Props = $props();
|
||||
|
||||
// Use settings for autoFocus
|
||||
|
|
@ -125,6 +129,18 @@
|
|||
// Whether search has been explicitly triggered in deferred mode
|
||||
let searchTriggered = $state(false);
|
||||
|
||||
// External text injection (e.g. from voice-to-text). When the prop
|
||||
// changes to a new non-empty value, set the search query and focus.
|
||||
let lastInjected = '';
|
||||
$effect(() => {
|
||||
if (injectedText && injectedText !== lastInjected) {
|
||||
lastInjected = injectedText;
|
||||
searchQuery = injectedText;
|
||||
// Focus the input so the user sees and can edit the text
|
||||
requestAnimationFrame(() => inputElement?.focus());
|
||||
}
|
||||
});
|
||||
|
||||
// Context menu state
|
||||
let contextMenuVisible = $state(false);
|
||||
let contextMenuX = $state(0);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue