From fa92abce31c22644c5d5178a839d9b560edff73e Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Thu, 13 Feb 2025 22:37:01 -0800 Subject: [PATCH] refac --- .../chat/Messages/ContentRenderer.svelte | 3 + .../components/chat/Messages/Markdown.svelte | 3 + .../Messages/Markdown/MarkdownTokens.svelte | 51 +++++++- .../chat/Messages/ResponseMessage.svelte | 3 + .../components/common/RichTextInput.svelte | 118 ++++++++++-------- 5 files changed, 128 insertions(+), 50 deletions(-) diff --git a/src/lib/components/chat/Messages/ContentRenderer.svelte b/src/lib/components/chat/Messages/ContentRenderer.svelte index 04634ba2e..23c8ff803 100644 --- a/src/lib/components/chat/Messages/ContentRenderer.svelte +++ b/src/lib/components/chat/Messages/ContentRenderer.svelte @@ -18,6 +18,8 @@ export let floatingButtons = true; export let onSourceClick = () => {}; + export let onTaskClick = () => {}; + export let onAddMessages = () => {}; let contentContainerElement; @@ -141,6 +143,7 @@ return acc.filter((item, index) => acc.indexOf(item) === index); }, [])} {onSourceClick} + {onTaskClick} on:update={(e) => { dispatch('update', e.detail); }} diff --git a/src/lib/components/chat/Messages/Markdown.svelte b/src/lib/components/chat/Messages/Markdown.svelte index ae2dbf3bd..938c06be4 100644 --- a/src/lib/components/chat/Messages/Markdown.svelte +++ b/src/lib/components/chat/Messages/Markdown.svelte @@ -17,7 +17,9 @@ export let save = false; export let sourceIds = []; + export let onSourceClick = () => {}; + export let onTaskClick = () => {}; let tokens = []; @@ -45,6 +47,7 @@ {tokens} {id} {save} + {onTaskClick} {onSourceClick} on:update={(e) => { dispatch('update', e.detail); diff --git a/src/lib/components/chat/Messages/Markdown/MarkdownTokens.svelte b/src/lib/components/chat/Messages/Markdown/MarkdownTokens.svelte index cf42bd2ec..7fba353df 100644 --- a/src/lib/components/chat/Messages/Markdown/MarkdownTokens.svelte +++ b/src/lib/components/chat/Messages/Markdown/MarkdownTokens.svelte @@ -26,6 +26,8 @@ export let attributes = {}; export let save = false; + + export let onTaskClick: Function = () => {}; export let onSourceClick: Function = () => {}; const headerComponent = (depth: number) => { @@ -168,17 +170,37 @@ {:else if token.type === 'blockquote'}
- +
{:else if token.type === 'list'} {#if token.ordered}
    {#each token.items as item, itemIdx}
  1. + {#if item?.task} + { + onTaskClick({ + id: id, + token: token, + tokenIdx: tokenIdx, + item: item, + itemIdx: itemIdx, + checked: e.target.checked + }); + }} + /> + {/if} +
  2. {/each} @@ -187,15 +209,40 @@ {/if} + {:else if token.type === 'list_item'} + {JSON.stringify(token)} +

    + +

    {:else if token.type === 'details'}
    @@ -203,6 +250,8 @@ id={`${id}-${tokenIdx}-d`} tokens={marked.lexer(token.text)} attributes={token?.attributes} + {onTaskClick} + {onSourceClick} />
    diff --git a/src/lib/components/chat/Messages/ResponseMessage.svelte b/src/lib/components/chat/Messages/ResponseMessage.svelte index 990a17a96..249320c81 100644 --- a/src/lib/components/chat/Messages/ResponseMessage.svelte +++ b/src/lib/components/chat/Messages/ResponseMessage.svelte @@ -716,6 +716,9 @@ floatingButtons={message?.done} save={!readOnly} {model} + onTaskClick={async (e) => { + console.log(e); + }} onSourceClick={async (e) => { console.log(e); let sourceButton = document.getElementById(`source-${e}`); diff --git a/src/lib/components/common/RichTextInput.svelte b/src/lib/components/common/RichTextInput.svelte index 57fbf567b..7fa700dfa 100644 --- a/src/lib/components/common/RichTextInput.svelte +++ b/src/lib/components/common/RichTextInput.svelte @@ -35,6 +35,8 @@ export let value = ''; export let id = ''; + export let raw = false; + export let preserveBreaks = false; export let generateAutoCompletion: Function = async () => null; export let autocomplete = false; @@ -137,25 +139,29 @@ }); } - async function tryParse(value, attempts = 3, interval = 100) { - try { - // Try parsing the value - return marked.parse(value.replaceAll(`\n
    `, `
    `), { - breaks: false - }); - } catch (error) { - // If no attempts remain, fallback to plain text - if (attempts <= 1) { - return value; - } - // Wait for the interval, then retry - await new Promise((resolve) => setTimeout(resolve, interval)); - return tryParse(value, attempts - 1, interval); // Recursive call - } - } + let content = value; - // Usage example - let content = await tryParse(value); + if (!raw) { + async function tryParse(value, attempts = 3, interval = 100) { + try { + // Try parsing the value + return marked.parse(value.replaceAll(`\n
    `, `
    `), { + breaks: false + }); + } catch (error) { + // If no attempts remain, fallback to plain text + if (attempts <= 1) { + return value; + } + // Wait for the interval, then retry + await new Promise((resolve) => setTimeout(resolve, interval)); + return tryParse(value, attempts - 1, interval); // Recursive call + } + } + + // Usage example + content = await tryParse(value); + } editor = new Editor({ element: element, @@ -191,28 +197,33 @@ onTransaction: () => { // force re-render so `editor.isActive` works as expected editor = editor; - let newValue = turndownService - .turndown( - editor - .getHTML() - .replace(/

    <\/p>/g, '
    ') - .replace(/ {2,}/g, (m) => m.replace(/ /g, '\u00a0')) - ) - .replace(/\u00a0/g, ' '); - if (!preserveBreaks) { - newValue = newValue.replace(//g, ''); - } + if (!raw) { + let newValue = turndownService + .turndown( + editor + .getHTML() + .replace(/

    <\/p>/g, '
    ') + .replace(/ {2,}/g, (m) => m.replace(/ /g, '\u00a0')) + ) + .replace(/\u00a0/g, ' '); - if (value !== newValue) { - value = newValue; + if (!preserveBreaks) { + newValue = newValue.replace(//g, ''); + } - // check if the node is paragraph as well - if (editor.isActive('paragraph')) { - if (value === '') { - editor.commands.clearContent(); + if (value !== newValue) { + value = newValue; + + // check if the node is paragraph as well + if (editor.isActive('paragraph')) { + if (value === '') { + editor.commands.clearContent(); + } } } + } else { + value = editor.getHTML(); } }, editorProps: { @@ -340,21 +351,30 @@ // Update the editor content if the external `value` changes $: if ( editor && - value !== - turndownService - .turndown( - (preserveBreaks - ? editor.getHTML().replace(/

    <\/p>/g, '
    ') - : editor.getHTML() - ).replace(/ {2,}/g, (m) => m.replace(/ /g, '\u00a0')) - ) - .replace(/\u00a0/g, ' ') + (raw + ? value !== editor.getHTML() + : value !== + turndownService + .turndown( + (preserveBreaks + ? editor.getHTML().replace(/

    <\/p>/g, '
    ') + : editor.getHTML() + ).replace(/ {2,}/g, (m) => m.replace(/ /g, '\u00a0')) + ) + .replace(/\u00a0/g, ' ')) ) { - editor.commands.setContent( - marked.parse(value.replaceAll(`\n
    `, `
    `), { - breaks: false - }) - ); // Update editor content + if (raw) { + editor.commands.setContent(value); + } else { + preserveBreaks + ? editor.commands.setContent(value) + : editor.commands.setContent( + marked.parse(value.replaceAll(`\n
    `, `
    `), { + breaks: false + }) + ); // Update editor content + } + selectTemplate(); }