diff --git a/frontend/package.json b/frontend/package.json index b5951d5..8d17f4b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -25,6 +25,7 @@ "@tiptap/vue-3": "^3.0.0", "d3": "^7", "dompurify": "^3.1.0", + "lucide-vue-next": "^0.469.0", "marked": "^17.0.0", "pinia": "^3.0.0", "vue": "3.5.30", diff --git a/frontend/src/components/AppHeader.vue b/frontend/src/components/AppHeader.vue index d824f25..a975ba2 100644 --- a/frontend/src/components/AppHeader.vue +++ b/frontend/src/components/AppHeader.vue @@ -7,6 +7,7 @@ import { useAuthStore } from "@/stores/auth"; import { useChatStore } from "@/stores/chat"; import AppLogo from "@/components/AppLogo.vue"; import NotificationBell from "@/components/NotificationBell.vue"; +import { Sun, Moon, Settings } from "lucide-vue-next"; const { theme, toggleTheme } = useTheme(); const { toggleShortcuts } = useShortcuts(); @@ -94,15 +95,13 @@ router.afterEach(() => { - - - - +
@@ -137,7 +136,8 @@ router.afterEach(() => { {{ statusShortLabel }} - +
{{ authStore.user?.username }} diff --git a/frontend/src/components/ChatInputBar.vue b/frontend/src/components/ChatInputBar.vue index 1d4f4c1..fa33639 100644 --- a/frontend/src/components/ChatInputBar.vue +++ b/frontend/src/components/ChatInputBar.vue @@ -10,6 +10,15 @@ import { useChatStore } from '@/stores/chat' import { useSettingsStore } from '@/stores/settings' import { useToastStore } from '@/stores/toast' import type { Note } from '@/types/note' +import { + Paperclip, + Volume2, + VolumeX, + Square, + Mic, + Loader2, + ArrowUp, +} from 'lucide-vue-next' const props = withDefaults(defineProps<{ /** Textarea placeholder */ @@ -277,9 +286,7 @@ defineExpose({ focus, prefill }) :disabled="!store.chatReady" title="Attach a note" > - - - +
- - - - - - + +
@@ -371,12 +374,8 @@ defineExpose({ focus, prefill }) :title="recorder.recording.value ? 'Click to stop (or wait for silence)' : 'Click to speak'" :aria-label="recorder.recording.value ? 'Stop recording' : 'Start recording'" > - - - - - - + +
@@ -387,14 +386,14 @@ defineExpose({ focus, prefill }) @click="emit('abort')" title="Stop generation" > - + + >
@@ -484,6 +483,8 @@ defineExpose({ focus, prefill }) z-index: 1; } .btn-mic.mic-transcribing { opacity: 0.5; } +.mic-loader { animation: mic-spin 1s linear infinite; } +@keyframes mic-spin { to { transform: rotate(360deg); } } /* Mic wrapper + live amplitude halo. The glow is a filled red disc absolutely positioned behind the button, scaled/faded by the diff --git a/frontend/src/components/ChatPanel.vue b/frontend/src/components/ChatPanel.vue index cf6d2f2..4a34c2d 100644 --- a/frontend/src/components/ChatPanel.vue +++ b/frontend/src/components/ChatPanel.vue @@ -6,6 +6,7 @@ import ChatStreamingBubble from '@/components/ChatStreamingBubble.vue' import ChatInputBar from '@/components/ChatInputBar.vue' import ToolCallCard from '@/components/ToolCallCard.vue' import type { Message, ToolCallRecord } from '@/types/chat' +import { Mic, ChevronDown, X } from 'lucide-vue-next' const props = withDefaults(defineProps<{ variant: 'full' | 'widget' @@ -372,7 +373,7 @@ defineExpose({ focus, prefill, send, contextCount, sidebarOpen, toggleContextSid @@ -391,7 +392,7 @@ defineExpose({ focus, prefill, send, contextCount, sidebarOpen, toggleContextSid :class="{ collapsed: collapsedSections.has('auto') }" @click="toggleSection('auto')" > - + Auto-included {{ autoInjectedNotes.length }} @@ -404,7 +405,7 @@ defineExpose({ focus, prefill, send, contextCount, sidebarOpen, toggleContextSid class="context-note-score" :class="{ 'score-high': note.score >= 0.75, 'score-medium': note.score >= 0.60 && note.score < 0.75, 'score-low': note.score < 0.60 }" >{{ Math.round(note.score * 100) }}% - + @@ -414,7 +415,7 @@ defineExpose({ focus, prefill, send, contextCount, sidebarOpen, toggleContextSid :class="{ collapsed: collapsedSections.has('suggested'), 'context-sidebar-header-gap': autoInjectedNotes.length }" @click="toggleSection('suggested')" > - + Suggested {{ suggestedNotes.length }} @@ -436,14 +437,14 @@ defineExpose({ focus, prefill, send, contextCount, sidebarOpen, toggleContextSid :class="{ collapsed: collapsedSections.has('included'), 'context-sidebar-header-gap': autoInjectedNotes.length || suggestedNotes.length }" @click="toggleSection('included')" > - + In Context {{ includedNotes.length }}
{{ note.title }} - +
diff --git a/frontend/src/components/EventSlideOver.vue b/frontend/src/components/EventSlideOver.vue index 5ba73a6..e5cd769 100644 --- a/frontend/src/components/EventSlideOver.vue +++ b/frontend/src/components/EventSlideOver.vue @@ -1,4 +1,5 @@