fix: allow message switch during regeneration

Co-Authored-By: Pandazki <onlrrr@gmail.com>
This commit is contained in:
Timothy J. Baek 2024-05-07 11:39:32 -07:00
parent a32a752791
commit ea69c24bf7
2 changed files with 189 additions and 189 deletions

View File

@ -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')}
</button>
<div class=" mt-2 mb-1 flex justify-center space-x-2 text-sm font-medium"> <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"
class="px-4 py-2 bg-emerald-700 hover:bg-emerald-800 text-gray-100 transition rounded-lg" on:click={() => {
on:click={() => { cancelEditMessage();
editMessageConfirmHandler(); }}
}} >
> {$i18n.t('Cancel')}
{$i18n.t('Save')} </button>
</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"
>
<path
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"> <div class=" self-center">
{message.content} {message.content}
</div>
</div>
{:else if message.content === ''}
<Skeleton />
{:else}
{#each tokens as token}
{#if token.type === 'code'}
<CodeBlock
lang={token.lang}
code={revertSanitizedResponseContent(token.text)}
/>
{:else}
{@html marked.parse(token.raw, {
...defaults,
gfm: true,
breaks: true,
renderer
})}
{/if}
{/each}
<!-- {@html marked(message.content.replaceAll('\\', '\\\\'))} -->
{/if}
{#if message.citations}
<hr class=" dark:border-gray-800 my-1" />
<div class="my-2.5 w-full flex flex-col gap-1">
{#each message.citations.reduce((acc, citation) => {
citation.document.forEach((document, index) => {
const metadata = citation.metadata?.[index];
const id = metadata?.source ?? 'N/A';
const existingSource = acc.find((item) => item.id === id);
if (existingSource) {
existingSource.document.push(document);
existingSource.metadata.push(metadata);
} else {
acc.push( { id: id, source: citation?.source, document: [document], metadata: metadata ? [metadata] : [] } );
}
});
return acc;
}, []) as citation, idx}
<div class="flex gap-1 text-xs font-semibold">
<div>
[{idx + 1}]
</div>
<button
class="dark:text-gray-500 underline"
on:click={() => {
showCitationModal = true;
selectedCitation = citation;
}}
>
{citation.source.name}
</button>
</div> </div>
</div>
{:else}
{#each tokens as token}
{#if token.type === 'code'}
<CodeBlock
lang={token.lang}
code={revertSanitizedResponseContent(token.text)}
/>
{:else}
{@html marked.parse(token.raw, {
...defaults,
gfm: true,
breaks: true,
renderer
})}
{/if}
{/each} {/each}
<!-- {@html marked(message.content.replaceAll('\\', '\\\\'))} --> </div>
{/if} {/if}
{#if message.citations} {#if message.done || siblings.length > 1}
<hr class=" dark:border-gray-800 my-1" /> <div
<div class="my-2.5 w-full flex flex-col gap-1"> class=" flex justify-start space-x-1 overflow-x-auto buttons text-gray-700 dark:text-gray-500"
{#each message.citations.reduce((acc, citation) => { >
citation.document.forEach((document, index) => { {#if siblings.length > 1}
const metadata = citation.metadata?.[index]; <div class="flex self-center min-w-fit">
const id = metadata?.source ?? 'N/A'; <button
class="self-center dark:hover:text-white hover:text-black transition"
const existingSource = acc.find((item) => item.id === id); on:click={() => {
showPreviousMessage(message);
if (existingSource) { }}
existingSource.document.push(document); >
existingSource.metadata.push(metadata); <svg
} else { xmlns="http://www.w3.org/2000/svg"
acc.push( { id: id, source: citation?.source, document: [document], metadata: metadata ? [metadata] : [] } ); viewBox="0 0 20 20"
} fill="currentColor"
}); class="w-4 h-4"
return acc;
}, []) as citation, idx}
<div class="flex gap-1 text-xs font-semibold">
<div>
[{idx + 1}]
</div>
<button
class="dark:text-gray-500 underline"
on:click={() => {
showCitationModal = true;
selectedCitation = citation;
}}
> >
{citation.source.name} <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">
{siblings.indexOf(message.id) + 1} / {siblings.length}
</div> </div>
{/each}
</div>
{/if}
{#if message.done} <button
<div class="self-center dark:hover:text-white hover:text-black transition"
class=" flex justify-start space-x-1 overflow-x-auto buttons text-gray-700 dark:text-gray-500" on:click={() => {
> showNextMessage(message);
{#if siblings.length > 1} }}
<div class="flex self-center min-w-fit"> >
<button <svg
class="self-center dark:hover:text-white hover:text-black transition" xmlns="http://www.w3.org/2000/svg"
on:click={() => { viewBox="0 0 20 20"
showPreviousMessage(message); 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="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" {/if}
clip-rule="evenodd"
/>
</svg>
</button>
<div class="text-xs font-bold self-center min-w-fit dark:text-gray-100">
{siblings.indexOf(message.id) + 1} / {siblings.length}
</div>
<button
class="self-center dark:hover:text-white hover:text-black transition"
on:click={() => {
showNextMessage(message);
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
fill="currentColor"
class="w-4 h-4"
>
<path
fill-rule="evenodd"
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"
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 @@
</button> </button>
</Tooltip> </Tooltip>
{/if} {/if}
</div> {/if}
{/if} </div>
{/if}
{#if showRateComment} {#if showRateComment}
<RateComment <RateComment
messageId={message.id} messageId={message.id}
bind:show={showRateComment} bind:show={showRateComment}
bind:message bind:message
on:submit={() => { on:submit={() => {
updateChatMessages(); updateChatMessages();
}} }}
/> />
{/if} {/if}
</div> </div>
{/if} {/if}
</div>
</div> </div>
{/if} </div>
</div> </div>
</div> </div>
{/key} {/key}

View File

@ -1,4 +1,4 @@
<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" />