diff --git a/src/lib/components/chat/ArtifactViewer.svelte b/src/lib/components/chat/ArtifactViewer.svelte
index 3cd408d..2d0f8a8 100644
--- a/src/lib/components/chat/ArtifactViewer.svelte
+++ b/src/lib/components/chat/ArtifactViewer.svelte
@@ -2,7 +2,6 @@
import { Dialog } from 'bits-ui';
import { Badge } from '$lib/components/ui/badge/index.js';
import { toast } from '$lib/stores/toast';
- import { onMount } from 'svelte';
import type { Artifact } from '$lib/types';
let {
@@ -18,19 +17,24 @@
let editorInstance: any = null;
$effect(() => {
- if (open && artifact && artifact.type === 'code' && editorContainer && !editorInstance) {
+ if (open && artifact && (artifact.type === 'code' || artifact.type === 'diff') && editorContainer && !editorInstance) {
loadMonaco();
}
+ // Cleanup on close
+ if (!open && editorInstance) {
+ editorInstance.dispose();
+ editorInstance = null;
+ }
});
async function loadMonaco() {
try {
const monaco = await import('monaco-editor');
monacoReady = true;
- if (editorContainer) {
+ if (editorContainer && artifact) {
editorInstance = monaco.editor.create(editorContainer, {
- value: artifact?.content || '',
- language: mapLang(artifact?.language || ''),
+ value: artifact.content,
+ language: artifact.type === 'diff' ? 'diff' : mapLang(artifact.language),
readOnly: true,
theme: document.documentElement.classList.contains('dark') ? 'vs-dark' : 'vs',
minimap: { enabled: false },
@@ -53,8 +57,7 @@
go: 'go', rs: 'rust', java: 'java', cpp: 'cpp', c: 'c',
html: 'html', css: 'css', scss: 'scss', json: 'json',
yaml: 'yaml', yml: 'yaml', md: 'markdown', sh: 'shell',
- bash: 'shell', sql: 'sql', xml: 'xml', svelte: 'html',
- svg: 'xml'
+ bash: 'shell', sql: 'sql', xml: 'xml', svelte: 'html', svg: 'xml'
};
return map[lang] || lang || 'plaintext';
}
@@ -94,12 +97,8 @@
{artifact.language || artifact.type}
-
-
+
+
{/if}
+ {:else if artifact.type === 'mermaid'}
+
{:else}
{artifact.content}
diff --git a/src/lib/components/chat/ChatMessage.svelte b/src/lib/components/chat/ChatMessage.svelte
index d54e6c5..63081a2 100644
--- a/src/lib/components/chat/ChatMessage.svelte
+++ b/src/lib/components/chat/ChatMessage.svelte
@@ -4,18 +4,24 @@
import hljs from 'highlight.js';
import { toast } from '$lib/stores/toast';
import { onMount } from 'svelte';
+ import type { Artifact } from '$lib/types';
let {
content = '',
role = 'assistant' as 'user' | 'assistant',
- status = 'complete' as 'sending' | 'streaming' | 'complete' | 'error'
+ status = 'complete' as 'sending' | 'streaming' | 'complete' | 'error',
+ artifacts = [] as Artifact[],
+ onArtifactClick
}: {
content?: string;
role?: 'user' | 'assistant';
status?: 'sending' | 'streaming' | 'complete' | 'error';
+ artifacts?: Artifact[];
+ onArtifactClick?: (artifact: Artifact) => void;
} = $props();
let ready = $state(false);
+ let copiedId = $state
(null);
onMount(() => {
marked.setOptions({
@@ -40,10 +46,15 @@
}
});
- function copyCode(code: string, e: Event) {
- e.stopPropagation();
+ function copyCode(code: string, id: string) {
navigator.clipboard.writeText(code);
+ copiedId = id;
toast('Copied to clipboard');
+ setTimeout(() => { copiedId = null; }, 2000);
+ }
+
+ function handleArtifactClick(a: Artifact) {
+ onArtifactClick?.(a);
}
@@ -60,9 +71,9 @@
)}>
{#if !content && status === 'streaming'}
-
-
-
+
+
+
{:else if content}
@@ -70,13 +81,48 @@
{#if status === 'streaming'}
-
+
{/if}
{/if}
{#if status === 'error'}
Error generating response
{/if}
+
+
+ {#if artifacts && artifacts.length > 0}
+
+ {#each artifacts as a (a.id)}
+
+ {/each}
+
+ {/if}
{#if role === 'user'}
@@ -99,23 +145,6 @@
margin: 0.5rem 0;
position: relative;
}
- :global(.prose pre:hover .copy-btn) {
- opacity: 1;
- }
- :global(.copy-btn) {
- position: absolute;
- top: 0.5rem;
- right: 0.5rem;
- opacity: 0;
- transition: opacity 0.15s;
- padding: 0.25rem 0.5rem;
- font-size: 0.7rem;
- border-radius: 0.25rem;
- background: hsl(var(--color-muted));
- color: hsl(var(--color-muted-foreground));
- border: 1px solid hsl(var(--color-border));
- cursor: pointer;
- }
:global(.prose code) {
font-size: 0.8rem;
padding: 0.1rem 0.3rem;
diff --git a/src/lib/components/chat/Sidebar.svelte b/src/lib/components/chat/Sidebar.svelte
index 97fefd1..c221cf6 100644
--- a/src/lib/components/chat/Sidebar.svelte
+++ b/src/lib/components/chat/Sidebar.svelte
@@ -1,9 +1,10 @@