diff --git a/package.json b/package.json index 2661077..24091cf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hermes-web-ui", - "version": "0.4.7", + "version": "0.4.8", "description": "Self-hosted AI chat dashboard for Hermes Agent — multi-model (Claude, GPT, Gemini, DeepSeek) web UI with Telegram, Discord, Slack, WhatsApp integration", "repository": { "type": "git", diff --git a/packages/client/src/components/hermes/chat/MarkdownRenderer.vue b/packages/client/src/components/hermes/chat/MarkdownRenderer.vue index 57e9e5b..5bbb0fd 100644 --- a/packages/client/src/components/hermes/chat/MarkdownRenderer.vue +++ b/packages/client/src/components/hermes/chat/MarkdownRenderer.vue @@ -84,6 +84,19 @@ function withTimeout(promise: Promise, timeoutMs: number, label: string): }) } +function getScrollParent(el: HTMLElement | null): HTMLElement | null { + if (!el) return null + let current: HTMLElement | null = el.parentElement + while (current) { + const { overflow, overflowY } = getComputedStyle(current) + if (overflow === 'auto' || overflow === 'scroll' || overflowY === 'auto' || overflowY === 'scroll') { + return current + } + current = current.parentElement + } + return null +} + function cleanupMermaidRenderArtifacts(id: string): void { document.getElementById(id)?.remove() document.getElementById(`d${id}`)?.remove() @@ -158,6 +171,13 @@ async function renderMermaidDiagrams(): Promise { element.removeAttribute('data-mermaid-pending') element.removeAttribute('data-mermaid-source') element.innerHTML = result.svg + // After mermaid renders, scroll the nearest scrollable ancestor to bottom + nextTick(() => { + const scrollParent = getScrollParent(markdownBody.value) + if (scrollParent) { + scrollParent.scrollTop = scrollParent.scrollHeight + } + }) } catch { cleanupMermaidRenderArtifacts(`${componentId}-${generation}-${index}`) if (unmounted || generation !== renderGeneration || !root.contains(element)) return @@ -329,6 +349,10 @@ function handleMarkdownClick(event: MouseEvent): void { color: $text-secondary; font-size: 13px; font-family: $font-code; + min-height: 60px; + display: flex; + align-items: center; + justify-content: center; } } diff --git a/packages/client/src/components/hermes/chat/MessageItem.vue b/packages/client/src/components/hermes/chat/MessageItem.vue index 36bf497..cfa5e88 100644 --- a/packages/client/src/components/hermes/chat/MessageItem.vue +++ b/packages/client/src/components/hermes/chat/MessageItem.vue @@ -22,6 +22,7 @@ const toast = useMessage(); const isSystem = computed(() => props.message.role === "system"); const toolExpanded = ref(false); +const previewUrl = ref(null); const chatStore = useChatStore(); const settingsStore = useSettingsStore(); @@ -338,6 +339,7 @@ const renderedToolResult = computed(() => { :src="att.url" :alt="att.name" class="msg-attachment-thumb" + @click="previewUrl = att.url" /> + +
+ +
+