"googlemock/vscode:/vscode.git/clone" did not exist on "82febb8eafc0425601b0d46567dc66c7750233ff"
Commit ea69c24b authored by Timothy J. Baek's avatar Timothy J. Baek
Browse files

fix: allow message switch during regeneration


Co-Authored-By: default avatarPandazki <onlrrr@gmail.com>
parent a32a7527
...@@ -352,192 +352,192 @@ ...@@ -352,192 +352,192 @@
{/if} {/if}
</Name> </Name>
{#if message.content === ''} {#if message.files}
<Skeleton /> <div class="my-2.5 w-full flex overflow-x-auto gap-2 flex-wrap">
{:else} {#each message.files as file}
{#if message.files} <div>
<div class="my-2.5 w-full flex overflow-x-auto gap-2 flex-wrap"> {#if file.type === 'image'}
{#each message.files as file} <Image src={file.url} />
<div> {/if}
{#if file.type === 'image'} </div>
<Image src={file.url} /> {/each}
{/if} </div>
</div> {/if}
{/each}
</div>
{/if}
<div <div
class="prose chat-{message.role} w-full max-w-full dark:prose-invert prose-headings:my-0 prose-p:m-0 prose-p:-mb-6 prose-pre:my-0 prose-table:my-0 prose-blockquote:my-0 prose-img:my-0 prose-ul:-my-4 prose-ol:-my-4 prose-li:-my-3 prose-ul:-mb-6 prose-ol:-mb-8 prose-ol:p-0 prose-li:-mb-4 whitespace-pre-line" class="prose chat-{message.role} w-full max-w-full dark:prose-invert prose-headings:my-0 prose-p:m-0 prose-p:-mb-6 prose-pre:my-0 prose-table:my-0 prose-blockquote:my-0 prose-img:my-0 prose-ul:-my-4 prose-ol:-my-4 prose-li:-my-3 prose-ul:-mb-6 prose-ol:-mb-8 prose-ol:p-0 prose-li:-mb-4 whitespace-pre-line"
> >
<div> <div>
{#if edit === true} {#if edit === true}
<div class=" w-full"> <div class=" w-full">
<textarea <textarea
id="message-edit-{message.id}" id="message-edit-{message.id}"
bind:this={editTextAreaElement} bind:this={editTextAreaElement}
class=" bg-transparent outline-none w-full resize-none" class=" bg-transparent outline-none w-full resize-none"
bind:value={editedContent} bind:value={editedContent}
on:input={(e) => { on:input={(e) => {
e.target.style.height = ''; e.target.style.height = '';
e.target.style.height = `${e.target.scrollHeight}px`; e.target.style.height = `${e.target.scrollHeight}px`;
}}
/>
<div class=" mt-2 mb-1 flex justify-center space-x-2 text-sm font-medium">
<button
class="px-4 py-2 bg-emerald-700 hover:bg-emerald-800 text-gray-100 transition rounded-lg"
on:click={() => {
editMessageConfirmHandler();
}} }}
/> >
{$i18n.t('Save')}
<div class=" mt-2 mb-1 flex justify-center space-x-2 text-sm font-medium"> </button>
<button
class="px-4 py-2 bg-emerald-700 hover:bg-emerald-800 text-gray-100 transition rounded-lg" <button
on:click={() => { class=" px-4 py-2 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-100 transition outline outline-1 outline-gray-200 dark:outline-gray-600 rounded-lg"
editMessageConfirmHandler(); on:click={() => {
}} cancelEditMessage();
> }}
{$i18n.t('Save')} >
</button> {$i18n.t('Cancel')}
</button>
<button
class=" px-4 py-2 hover:bg-gray-100 dark:bg-gray-800 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-100 transition outline outline-1 outline-gray-200 dark:outline-gray-600 rounded-lg"
on:click={() => {
cancelEditMessage();
}}
>
{$i18n.t('Cancel')}
</button>
</div>
</div> </div>
{:else} </div>
<div class="w-full"> {:else}
{#if message?.error === true} <div class="w-full">
<div {#if message?.error === true}
class="flex mt-2 mb-4 space-x-2 border px-4 py-3 border-red-800 bg-red-800/30 font-medium rounded-lg" <div
class="flex mt-2 mb-4 space-x-2 border px-4 py-3 border-red-800 bg-red-800/30 font-medium rounded-lg"
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-5 h-5 self-center"
> >
<svg <path
xmlns="http://www.w3.org/2000/svg" stroke-linecap="round"
fill="none" stroke-linejoin="round"
viewBox="0 0 24 24" d="M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z"
stroke-width="1.5" />
stroke="currentColor" </svg>
class="w-5 h-5 self-center"
> <div class=" self-center">
<path {message.content}
stroke-linecap="round"
stroke-linejoin="round"
d="M12 9v3.75m9-.75a9 9 0 11-18 0 9 9 0 0118 0zm-9 3.75h.008v.008H12v-.008z"
/>
</svg>
<div class=" self-center">
{message.content}
</div>
</div> </div>
{:else} </div>
{#each tokens as token} {:else if message.content === ''}
{#if token.type === 'code'} <Skeleton />
<CodeBlock {:else}
lang={token.lang} {#each tokens as token}
code={revertSanitizedResponseContent(token.text)} {#if token.type === 'code'}
/> <CodeBlock
{:else} lang={token.lang}
{@html marked.parse(token.raw, { code={revertSanitizedResponseContent(token.text)}
...defaults, />
gfm: true, {:else}
breaks: true, {@html marked.parse(token.raw, {
renderer ...defaults,
})} gfm: true,
{/if} breaks: true,
{/each} renderer
<!-- {@html marked(message.content.replaceAll('\\', '\\\\'))} --> })}
{/if} {/if}
{/each}
{#if message.citations} <!-- {@html marked(message.content.replaceAll('\\', '\\\\'))} -->
<hr class=" dark:border-gray-800 my-1" /> {/if}
<div class="my-2.5 w-full flex flex-col gap-1">
{#each message.citations.reduce((acc, citation) => { {#if message.citations}
citation.document.forEach((document, index) => { <hr class=" dark:border-gray-800 my-1" />
const metadata = citation.metadata?.[index]; <div class="my-2.5 w-full flex flex-col gap-1">
const id = metadata?.source ?? 'N/A'; {#each message.citations.reduce((acc, citation) => {
citation.document.forEach((document, index) => {
const existingSource = acc.find((item) => item.id === id); const metadata = citation.metadata?.[index];
const id = metadata?.source ?? 'N/A';
if (existingSource) {
existingSource.document.push(document); const existingSource = acc.find((item) => item.id === id);
existingSource.metadata.push(metadata);
} else { if (existingSource) {
acc.push( { id: id, source: citation?.source, document: [document], metadata: metadata ? [metadata] : [] } ); existingSource.document.push(document);
} existingSource.metadata.push(metadata);
}); } else {
return acc; acc.push( { id: id, source: citation?.source, document: [document], metadata: metadata ? [metadata] : [] } );
}, []) as citation, idx} }
<div class="flex gap-1 text-xs font-semibold"> });
<div> return acc;
[{idx + 1}] }, []) as citation, idx}
</div> <div class="flex gap-1 text-xs font-semibold">
<div>
<button [{idx + 1}]
class="dark:text-gray-500 underline"
on:click={() => {
showCitationModal = true;
selectedCitation = citation;
}}
>
{citation.source.name}
</button>
</div> </div>
{/each}
</div>
{/if}
{#if message.done} <button
<div class="dark:text-gray-500 underline"
class=" flex justify-start space-x-1 overflow-x-auto buttons text-gray-700 dark:text-gray-500" on:click={() => {
> showCitationModal = true;
{#if siblings.length > 1} selectedCitation = citation;
<div class="flex self-center min-w-fit"> }}
<button >
class="self-center dark:hover:text-white hover:text-black transition" {citation.source.name}
on:click={() => { </button>
showPreviousMessage(message); </div>
}} {/each}
</div>
{/if}
{#if message.done || siblings.length > 1}
<div
class=" flex justify-start space-x-1 overflow-x-auto buttons text-gray-700 dark:text-gray-500"
>
{#if siblings.length > 1}
<div class="flex self-center min-w-fit">
<button
class="self-center dark:hover:text-white hover:text-black transition"
on:click={() => {
showPreviousMessage(message);
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="w-4 h-4"
> >
<svg <path
xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd"
viewBox="0 0 20 20" d="M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z"
fill="currentColor" clip-rule="evenodd"
class="w-4 h-4" />
> </svg>
<path </button>
fill-rule="evenodd"
d="M12.79 5.23a.75.75 0 01-.02 1.06L8.832 10l3.938 3.71a.75.75 0 11-1.04 1.08l-4.5-4.25a.75.75 0 010-1.08l4.5-4.25a.75.75 0 011.06.02z"
clip-rule="evenodd"
/>
</svg>
</button>
<div class="text-xs font-bold self-center min-w-fit dark:text-gray-100"> <div class="text-xs font-bold self-center min-w-fit dark:text-gray-100">
{siblings.indexOf(message.id) + 1} / {siblings.length} {siblings.indexOf(message.id) + 1} / {siblings.length}
</div> </div>
<button <button
class="self-center dark:hover:text-white hover:text-black transition" class="self-center dark:hover:text-white hover:text-black transition"
on:click={() => { on:click={() => {
showNextMessage(message); showNextMessage(message);
}} }}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="w-4 h-4"
> >
<svg <path
xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd"
viewBox="0 0 20 20" d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z"
fill="currentColor" clip-rule="evenodd"
class="w-4 h-4" />
> </svg>
<path </button>
fill-rule="evenodd" </div>
d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z" {/if}
clip-rule="evenodd"
/>
</svg>
</button>
</div>
{/if}
{#if message.done}
{#if !readOnly} {#if !readOnly}
<Tooltip content={$i18n.t('Edit')} placement="bottom"> <Tooltip content={$i18n.t('Edit')} placement="bottom">
<button <button
...@@ -898,24 +898,24 @@ ...@@ -898,24 +898,24 @@
</button> </button>
</Tooltip> </Tooltip>
{/if} {/if}
</div> {/if}
{/if} </div>
{/if}
{#if showRateComment}
<RateComment {#if showRateComment}
messageId={message.id} <RateComment
bind:show={showRateComment} messageId={message.id}
bind:message bind:show={showRateComment}
on:submit={() => { bind:message
updateChatMessages(); on:submit={() => {
}} updateChatMessages();
/> }}
{/if} />
</div> {/if}
{/if} </div>
</div> {/if}
</div> </div>
{/if} </div>
</div> </div>
</div> </div>
{/key} {/key}
......
<div class="w-full mt-3"> <div class="w-full mt-3 mb-4">
<div class="animate-pulse flex w-full"> <div class="animate-pulse flex w-full">
<div class="space-y-2 w-full"> <div class="space-y-2 w-full">
<div class="h-2 bg-gray-200 dark:bg-gray-600 rounded mr-14" /> <div class="h-2 bg-gray-200 dark:bg-gray-600 rounded mr-14" />
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment