From 54dc24986ff45eb9804850b2a8220e64cb4d4ad3 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Fri, 16 May 2025 21:47:43 +0400 Subject: [PATCH] feat: preview html --- src/lib/components/chat/Artifacts.svelte | 11 ++++++-- src/lib/components/chat/MessageInput.svelte | 2 -- .../components/chat/Messages/CodeBlock.svelte | 26 +++++++++++++++++-- .../chat/Messages/ContentRenderer.svelte | 24 +++++++++++++---- .../components/chat/Messages/Markdown.svelte | 14 +++++++++- .../Messages/Markdown/MarkdownTokens.svelte | 4 +++ .../chat/Messages/ResponseMessage.svelte | 18 ++----------- src/lib/stores/index.ts | 2 ++ 8 files changed, 73 insertions(+), 28 deletions(-) diff --git a/src/lib/components/chat/Artifacts.svelte b/src/lib/components/chat/Artifacts.svelte index f53e75507..180ed7277 100644 --- a/src/lib/components/chat/Artifacts.svelte +++ b/src/lib/components/chat/Artifacts.svelte @@ -4,7 +4,7 @@ const i18n = getContext('i18n'); const dispatch = createEventDispatcher(); - import { chatId, settings, showArtifacts, showControls } from '$lib/stores'; + import { artifactCode, chatId, settings, showArtifacts, showControls } from '$lib/stores'; import XMark from '../icons/XMark.svelte'; import { copyToClipboard, createMessagesList } from '$lib/utils'; import ArrowsPointingOut from '../icons/ArrowsPointingOut.svelte'; @@ -180,7 +180,14 @@ } }; - onMount(() => {}); + onMount(() => { + artifactCode.subscribe((value) => { + if (contents) { + const codeIdx = contents.findIndex((content) => content.content.includes(value)); + selectedContentIdx = codeIdx !== -1 ? codeIdx : 0; + } + }); + });
diff --git a/src/lib/components/chat/MessageInput.svelte b/src/lib/components/chat/MessageInput.svelte index ba705146f..867bb9f24 100644 --- a/src/lib/components/chat/MessageInput.svelte +++ b/src/lib/components/chat/MessageInput.svelte @@ -957,8 +957,6 @@ ? (e.key === 'Enter' || e.keyCode === 13) && isCtrlPressed : (e.key === 'Enter' || e.keyCode === 13) && !e.shiftKey; - console.log('Enter pressed:', enterPressed); - if (enterPressed) { e.preventDefault(); } diff --git a/src/lib/components/chat/Messages/CodeBlock.svelte b/src/lib/components/chat/Messages/CodeBlock.svelte index ca663f61d..bd5195870 100644 --- a/src/lib/components/chat/Messages/CodeBlock.svelte +++ b/src/lib/components/chat/Messages/CodeBlock.svelte @@ -17,6 +17,7 @@ import ChevronUp from '$lib/components/icons/ChevronUp.svelte'; import ChevronUpDown from '$lib/components/icons/ChevronUpDown.svelte'; import CommandLine from '$lib/components/icons/CommandLine.svelte'; + import Cube from '$lib/components/icons/Cube.svelte'; const i18n = getContext('i18n'); @@ -24,9 +25,11 @@ export let onSave = (e) => {}; export let onCode = (e) => {}; + export let onPreview = (e) => {}; export let save = false; export let run = true; + export let preview = false; export let collapsed = false; export let token; @@ -88,6 +91,10 @@ }, 1000); }; + const previewCode = () => { + onPreview(code); + }; + const checkPythonCode = (str) => { // Check if the string contains typical Python syntax characters const pythonSyntax = [ @@ -430,7 +437,7 @@ class="flex gap-1 items-center bg-none border-none bg-gray-50 hover:bg-gray-100 dark:bg-gray-850 dark:hover:bg-gray-800 transition rounded-md px-1.5 py-0.5" on:click={collapseCodeBlock} > -
+
@@ -439,6 +446,21 @@
+ {#if preview && ['html', 'svg'].includes(lang)} + + {/if} + {#if ($config?.features?.enable_code_execution ?? true) && (lang.toLowerCase() === 'python' || lang.toLowerCase() === 'py' || (lang === '' && checkPythonCode(code)))} {#if executing}
@@ -453,7 +475,7 @@ executePython(code); }} > -
+
diff --git a/src/lib/components/chat/Messages/ContentRenderer.svelte b/src/lib/components/chat/Messages/ContentRenderer.svelte index 74487255d..895390c8e 100644 --- a/src/lib/components/chat/Messages/ContentRenderer.svelte +++ b/src/lib/components/chat/Messages/ContentRenderer.svelte @@ -1,10 +1,17 @@ {#key id} - + {/key} diff --git a/src/lib/components/chat/Messages/Markdown/MarkdownTokens.svelte b/src/lib/components/chat/Messages/Markdown/MarkdownTokens.svelte index 9f80fbc77..53c61fe80 100644 --- a/src/lib/components/chat/Messages/Markdown/MarkdownTokens.svelte +++ b/src/lib/components/chat/Messages/Markdown/MarkdownTokens.svelte @@ -29,9 +29,11 @@ export let attributes = {}; export let save = false; + export let preview = false; export let onUpdate: Function = () => {}; export let onCode: Function = () => {}; + export let onPreview: Function = () => {}; export let onTaskClick: Function = () => {}; export let onSourceClick: Function = () => {}; @@ -95,7 +97,9 @@ code={token?.text ?? ''} {attributes} {save} + {preview} {onCode} + {onPreview} onSave={(value) => { onUpdate({ raw: token.raw, diff --git a/src/lib/components/chat/Messages/ResponseMessage.svelte b/src/lib/components/chat/Messages/ResponseMessage.svelte index 1caea61c9..eae35bbb3 100644 --- a/src/lib/components/chat/Messages/ResponseMessage.svelte +++ b/src/lib/components/chat/Messages/ResponseMessage.svelte @@ -806,6 +806,7 @@ sources={message.sources} floatingButtons={message?.done && !readOnly} save={!readOnly} + preview={!readOnly} {model} onTaskClick={async (e) => { console.log(e); @@ -840,28 +841,13 @@ onAddMessages={({ modelId, parentId, messages }) => { addMessages({ modelId, parentId, messages }); }} - on:update={(e) => { - const { raw, oldContent, newContent } = e.detail; - + onUpdate={({ raw, oldContent, newContent }) => { history.messages[message.id].content = history.messages[ message.id ].content.replace(raw, raw.replace(oldContent, newContent)); updateChat(); }} - on:select={(e) => { - const { type, content } = e.detail; - - if (type === 'explain') { - submitMessage( - message.id, - `Explain this section to me in more detail\n\n\`\`\`\n${content}\n\`\`\`` - ); - } else if (type === 'ask') { - const input = e.detail?.input ?? ''; - submitMessage(message.id, `\`\`\`\n${content}\n\`\`\`\n${input}`); - } - }} /> {/if} diff --git a/src/lib/stores/index.ts b/src/lib/stores/index.ts index 7142cd35b..614085236 100644 --- a/src/lib/stores/index.ts +++ b/src/lib/stores/index.ts @@ -74,6 +74,8 @@ export const showOverview = writable(false); export const showArtifacts = writable(false); export const showCallOverlay = writable(false); +export const artifactCode = writable(null); + export const temporaryChatEnabled = writable(false); export const scrollPaginationEnabled = writable(false); export const currentChatPage = writable(1);