This commit is contained in:
Timothy Jaeryang Baek 2026-10-16 01:47:20 +04:00
parent 8191ac30dd
commit 05b038560a
3 changed files with 263 additions and 313 deletions

View file

@ -1,4 +1,8 @@
<script lang="ts">
import EditPencilIcon from '$lib/components/layout/Sidebar/icons/EditPencil.svelte';
import CopyIcon from '$lib/components/layout/Sidebar/icons/Copy.svelte';
import TrashIcon from '$lib/components/layout/Sidebar/icons/Trash.svelte';
import ChevronRightIcon from '$lib/components/layout/Sidebar/icons/ChevronRight.svelte';
import { resolveLocalizedFunction } from '$lib/utils/localizedContent';
import { functions as localizedFunctions } from '$lib/stores';
import { toast } from 'svelte-sonner';
@ -48,8 +52,7 @@
import Tooltip from '$lib/components/common/Tooltip.svelte';
import RateComment from './RateComment.svelte';
import WebSearchResults from './ResponseMessage/WebSearchResults.svelte';
import Sparkles from '$lib/components/icons/Sparkles.svelte';
import ArrowUpLeft from '$lib/components/icons/ArrowUpLeft.svelte';
import Sparkles from '$lib/components/layout/Sidebar/icons/Sparkles.svelte';
import DeleteConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
@ -952,7 +955,10 @@
{:else if !edit}
<div
bind:this={buttonsContainerElement}
class="flex items-center justify-start overflow-x-auto whitespace-nowrap buttons text-gray-600 dark:text-gray-500 mt-0.5 [&>*]:shrink-0"
class="flex items-center justify-start overflow-x-auto whitespace-nowrap buttons {($settings?.highContrastMode ??
false)
? 'text-gray-600 dark:text-gray-500'
: 'text-gray-600/80 dark:text-gray-500/70'} mt-0.5 [&>*]:shrink-0"
>
{#if message.done || siblings.length > 1}
{#if message.done && onInsertToNote && visibleResponseContent}
@ -961,12 +967,26 @@
aria-label={$i18n.t('Insert into note')}
class="{isLastMessage || ($settings?.highContrastMode ?? false)
? 'visible'
: 'hover-reveal'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition"
: 'hover-reveal'} inline-flex size-7 shrink-0 items-center justify-center p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-gray-400 hover:text-gray-600 transition"
on:click={() => {
onInsertToNote?.(visibleResponseContent);
}}
>
<ArrowUpLeft className="size-3.5" strokeWidth="2" />
<svg
class="size-4"
aria-hidden="true"
viewBox="0 0 24 24"
stroke-width="1.5"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M19 19L6 6M6 6L6 18.48M6 6L18.48 6"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
</Tooltip>
{/if}
@ -975,31 +995,17 @@
<div class="flex self-center min-w-fit" dir="ltr">
<button
aria-label={$i18n.t('Previous message')}
class="self-center p-1 hover:bg-black/5 dark:hover:bg-white/5 dark:hover:text-white hover:text-black rounded-md transition"
class="self-center inline-flex size-7 shrink-0 items-center justify-center p-1.5 hover:bg-black/5 dark:hover:bg-white/5 dark:hover:text-gray-400 hover:text-gray-600 rounded-md transition"
on:click={() => {
showPreviousMessage(message);
}}
>
<svg
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="2.5"
class="size-3.5"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15.75 19.5 8.25 12l7.5-7.5"
/>
</svg>
<ChevronRightIcon className="size-4 rotate-180" />
</button>
{#if messageIndexEdit}
<div
class="text-sm flex justify-center font-normal self-center dark:text-gray-100 min-w-fit"
class="text-sm flex justify-center font-normal self-center dark:text-gray-500 min-w-fit"
>
<input
id="message-index-input-{message.id}"
@ -1020,13 +1026,13 @@
messageIndexEdit = false;
}
}}
class="bg-transparent font-normal self-center dark:text-gray-100 min-w-fit outline-hidden"
class="bg-transparent font-normal self-center dark:text-gray-500 min-w-fit outline-hidden"
/>/{siblings.length}
</div>
{:else}
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
class="text-sm tracking-widest font-normal self-center dark:text-gray-100 min-w-fit"
class="text-sm tracking-widest font-normal self-center dark:text-gray-500 min-w-fit"
on:dblclick={async () => {
messageIndexEdit = true;
@ -1043,27 +1049,13 @@
{/if}
<button
class="self-center p-1 hover:bg-black/5 dark:hover:bg-white/5 dark:hover:text-white hover:text-black rounded-md transition"
class="self-center inline-flex size-7 shrink-0 items-center justify-center p-1.5 hover:bg-black/5 dark:hover:bg-white/5 dark:hover:text-gray-400 hover:text-gray-600 rounded-md transition"
on:click={() => {
showNextMessage(message);
}}
aria-label={$i18n.t('Next message')}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
aria-hidden="true"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="2.5"
class="size-3.5"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="m8.25 4.5 7.5 7.5-7.5 7.5"
/>
</svg>
<ChevronRightIcon className="size-4" />
</button>
</div>
{/if}
@ -1076,26 +1068,12 @@
aria-label={$i18n.t('Edit')}
class="{isLastMessage || ($settings?.highContrastMode ?? false)
? 'visible'
: 'hover-reveal'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition"
: 'hover-reveal'} inline-flex size-7 shrink-0 items-center justify-center p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-gray-400 hover:text-gray-600 transition"
on:click={() => {
editMessageHandler();
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2.3"
aria-hidden="true"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L6.832 19.82a4.5 4.5 0 01-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 011.13-1.897L16.863 4.487zm0 0L19.5 7.125"
/>
</svg>
<EditPencilIcon />
</button>
</Tooltip>
{/if}
@ -1106,26 +1084,12 @@
aria-label={$i18n.t('Copy')}
class="{isLastMessage || ($settings?.highContrastMode ?? false)
? 'visible'
: 'hover-reveal'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition copy-response-button"
: 'hover-reveal'} inline-flex size-7 shrink-0 items-center justify-center p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-gray-400 hover:text-gray-600 transition copy-response-button"
on:click={() => {
copyToClipboard(visibleResponseContent);
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
aria-hidden="true"
viewBox="0 0 24 24"
stroke-width="2.3"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15.666 3.888A2.25 2.25 0 0013.5 2.25h-3c-1.03 0-1.9.693-2.166 1.638m7.332 0c.055.194.084.4.084.612v0a.75.75 0 01-.75.75H9a.75.75 0 01-.75-.75v0c0-.212.03-.418.084-.612m7.332 0c.646.049 1.288.11 1.927.184 1.1.128 1.907 1.077 1.907 2.185V19.5a2.25 2.25 0 01-2.25 2.25H6.75A2.25 2.25 0 014.5 19.5V6.257c0-1.108.806-2.057 1.907-2.185a48.208 48.208 0 011.927-.184"
/>
</svg>
<CopyIcon />
</button>
</Tooltip>
@ -1136,7 +1100,7 @@
id="speak-button-{message.id}"
class="{isLastMessage || ($settings?.highContrastMode ?? false)
? 'visible'
: 'hover-reveal'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition"
: 'hover-reveal'} inline-flex size-7 shrink-0 items-center justify-center p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-gray-400 hover:text-gray-600 transition"
on:click={() => {
if (!loadingSpeech) {
if (speaking) {
@ -1149,67 +1113,70 @@
>
{#if loadingSpeech}
<svg
class=" w-4 h-4"
fill="currentColor"
viewBox="0 0 24 24"
class="size-4 animate-spin"
aria-hidden="true"
stroke-width="1.5"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<style>
.spinner_S1WN {
animation: spinner_MGfb 0.8s linear infinite;
animation-delay: -0.8s;
}
.spinner_Km9P {
animation-delay: -0.65s;
}
.spinner_JApP {
animation-delay: -0.5s;
}
@keyframes spinner_MGfb {
93.75%,
100% {
opacity: 0.2;
}
}
</style>
<circle class="spinner_S1WN" cx="4" cy="12" r="3" />
<circle class="spinner_S1WN spinner_Km9P" cx="12" cy="12" r="3" />
<circle class="spinner_S1WN spinner_JApP" cx="20" cy="12" r="3" />
<path
d="M21.8883 13.5C21.1645 18.3113 17.013 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C16.1006 2 19.6248 4.46819 21.1679 8"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M17 8H21.4C21.7314 8 22 7.73137 22 7.4V3"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
{:else if speaking}
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
class="size-4"
aria-hidden="true"
stroke-width="2.3"
stroke="currentColor"
class="w-4 h-4"
viewBox="0 0 24 24"
stroke-width="1.5"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M18 14L20.0005 12M22 10L20.0005 12M20.0005 12L18 10M20.0005 12L22 14"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
d="M17.25 9.75 19.5 12m0 0 2.25 2.25M19.5 12l2.25-2.25M19.5 12l-2.25 2.25m-10.5-6 4.72-4.72a.75.75 0 0 1 1.28.53v15.88a.75.75 0 0 1-1.28.53l-4.72-4.72H4.51c-.88 0-1.704-.507-1.938-1.354A9.009 9.009 0 0 1 2.25 12c0-.83.112-1.633.322-2.396C2.806 8.756 3.63 8.25 4.51 8.25H6.75Z"
/>
<path
d="M2 13.8571V10.1429C2 9.03829 2.89543 8.14286 4 8.14286H6.9C7.09569 8.14286 7.28708 8.08544 7.45046 7.97772L13.4495 4.02228C14.1144 3.5839 15 4.06075 15 4.85714V19.1429C15 19.9392 14.1144 20.4161 13.4495 19.9777L7.45046 16.0223C7.28708 15.9146 7.09569 15.8571 6.9 15.8571H4C2.89543 15.8571 2 14.9617 2 13.8571Z"
stroke="currentColor"
/>
</svg>
{:else}
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
class="size-4"
aria-hidden="true"
stroke-width="2.3"
stroke="currentColor"
class="w-4 h-4"
viewBox="0 0 24 24"
stroke-width="1.5"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M1 13.8571V10.1429C1 9.03829 1.89543 8.14286 3 8.14286H5.9C6.09569 8.14286 6.28708 8.08544 6.45046 7.97772L12.4495 4.02228C13.1144 3.5839 14 4.06075 14 4.85714V19.1429C14 19.9392 13.1144 20.4161 12.4495 19.9777L6.45046 16.0223C6.28708 15.9146 6.09569 15.8571 5.9 15.8571H3C1.89543 15.8571 1 14.9617 1 13.8571Z"
stroke="currentColor"
/>
<path
d="M17.5 7.5C17.5 7.5 19 9 19 11.5C19 14 17.5 15.5 17.5 15.5"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M20.5 4.5C20.5 4.5 23 7 23 11.5C23 16 20.5 18.5 20.5 18.5"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
d="M19.114 5.636a9 9 0 010 12.728M16.463 8.288a5.25 5.25 0 010 7.424M6.75 8.25l4.72-4.72a.75.75 0 011.28.53v15.88a.75.75 0 01-1.28.53l-4.72-4.72H4.51c-.88 0-1.704-.507-1.938-1.354A9.01 9.01 0 012.25 12c0-.83.112-1.633.322-2.396C2.806 8.756 3.63 8.25 4.51 8.25H6.75z"
/>
</svg>
{/if}
@ -1236,25 +1203,37 @@
aria-hidden="true"
class=" {isLastMessage || ($settings?.highContrastMode ?? false)
? 'visible'
: 'hover-reveal'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition whitespace-pre-wrap"
: 'hover-reveal'} inline-flex size-7 shrink-0 items-center justify-center p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-gray-400 hover:text-gray-600 transition whitespace-pre-wrap"
on:click={() => {
console.log(message);
}}
id="info-{message.id}"
>
<svg
class="size-4"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
stroke-width="1.5"
viewBox="0 0 24 24"
stroke-width="2.3"
stroke="currentColor"
class="w-4 h-4"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 11.5V16.5"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M12 7.51L12.01 7.49889"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
d="M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z"
/>
</svg>
</button>
@ -1267,26 +1246,49 @@
aria-label={$i18n.t('Fork chat')}
class="{isLastMessage || ($settings?.highContrastMode ?? false)
? 'visible'
: 'hover-reveal'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition"
: 'hover-reveal'} inline-flex size-7 shrink-0 items-center justify-center p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-gray-400 hover:text-gray-600 transition"
on:click={() => {
forkHandler?.(message.id);
}}
>
<svg
class="w-4 h-4"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="1.8"
stroke-linecap="round"
stroke-linejoin="round"
class="size-4 -scale-x-100 -scale-y-100 -rotate-90"
aria-hidden="true"
viewBox="0 0 24 24"
stroke-width="1.5"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M4 12H9" />
<path d="M9 12C12.5 12 12.5 7 16 7H20" />
<path d="M17 4L20 7L17 10" />
<path d="M9 12C12.5 12 12.5 17 16 17H20" />
<path d="M17 14L20 17L17 20" />
<path
d="M17 7C18.1046 7 19 6.10457 19 5C19 3.89543 18.1046 3 17 3C15.8954 3 15 3.89543 15 5C15 6.10457 15.8954 7 17 7Z"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M7 7C8.10457 7 9 6.10457 9 5C9 3.89543 8.10457 3 7 3C5.89543 3 5 3.89543 5 5C5 6.10457 5.89543 7 7 7Z"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M7 21C8.10457 21 9 20.1046 9 19C9 17.8954 8.10457 17 7 17C5.89543 17 5 17.8954 5 19C5 20.1046 5.89543 21 7 21Z"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M7 7V17"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M17 7V8C17 10.5 15 11 15 11L9 13C9 13 7 13.5 7 16V17"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
</Tooltip>
@ -1299,11 +1301,11 @@
aria-label={$i18n.t('Good Response')}
class="{isLastMessage || ($settings?.highContrastMode ?? false)
? 'visible'
: 'hover-reveal'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg {(
: 'hover-reveal'} inline-flex size-7 shrink-0 items-center justify-center p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg {(
message?.annotation?.rating ?? ''
).toString() === '1'
? 'bg-gray-100 dark:bg-gray-800'
: ''} dark:hover:text-white hover:text-black transition disabled:cursor-progress disabled:hover:bg-transparent"
: ''} dark:hover:text-gray-400 hover:text-gray-600 transition disabled:cursor-progress disabled:hover:bg-transparent"
disabled={feedbackLoading}
on:click={async (e) => {
e.stopPropagation();
@ -1316,18 +1318,23 @@
}}
>
<svg
class="size-4"
aria-hidden="true"
stroke="currentColor"
fill="none"
stroke-width="2.3"
stroke-width="1.5"
viewBox="0 0 24 24"
stroke-linecap="round"
stroke-linejoin="round"
class="w-4 h-4"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3"
d="M16.4724 20H4.1C3.76863 20 3.5 19.7314 3.5 19.4V9.6C3.5 9.26863 3.76863 9 4.1 9H6.86762C7.57015 9 8.22116 8.6314 8.5826 8.02899L11.293 3.51161C11.8779 2.53688 13.2554 2.44422 13.9655 3.33186C14.3002 3.75025 14.4081 4.30635 14.2541 4.81956L13.2317 8.22759C13.1162 8.61256 13.4045 9 13.8064 9H18.3815C19.7002 9 20.658 10.254 20.311 11.5262L18.4019 18.5262C18.1646 19.3964 17.3743 20 16.4724 20Z"
stroke="currentColor"
stroke-linecap="round"
/>
<path
d="M7 20L7 9"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
@ -1338,11 +1345,11 @@
aria-label={$i18n.t('Bad Response')}
class="{isLastMessage || ($settings?.highContrastMode ?? false)
? 'visible'
: 'hover-reveal'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg {(
: 'hover-reveal'} inline-flex size-7 shrink-0 items-center justify-center p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg {(
message?.annotation?.rating ?? ''
).toString() === '-1'
? 'bg-gray-100 dark:bg-gray-800'
: ''} dark:hover:text-white hover:text-black transition disabled:cursor-progress disabled:hover:bg-transparent"
: ''} dark:hover:text-gray-400 hover:text-gray-600 transition disabled:cursor-progress disabled:hover:bg-transparent"
disabled={feedbackLoading}
on:click={async (e) => {
e.stopPropagation();
@ -1355,18 +1362,23 @@
}}
>
<svg
class="size-4"
aria-hidden="true"
stroke="currentColor"
fill="none"
stroke-width="2.3"
stroke-width="1.5"
viewBox="0 0 24 24"
stroke-linecap="round"
stroke-linejoin="round"
class="w-4 h-4"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17"
d="M16.4724 3.5H4.1C3.76863 3.5 3.5 3.76863 3.5 4.1V13.9C3.5 14.2314 3.76863 14.5 4.1 14.5H6.86762C7.57015 14.5 8.22116 14.8686 8.5826 15.471L11.293 19.9884C11.8779 20.9631 13.2554 21.0558 13.9655 20.1681C14.3002 19.7497 14.4081 19.1937 14.2541 18.6804L13.2317 15.2724C13.1162 14.8874 13.4045 14.5 13.8064 14.5H18.3815C19.7002 14.5 20.658 13.246 20.311 11.9738L18.4019 4.97376C18.1646 4.10364 17.3743 3.5 16.4724 3.5Z"
stroke="currentColor"
stroke-linecap="round"
/>
<path
d="M7 14.5L7 3.5"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
@ -1381,29 +1393,24 @@
id="continue-response-button"
class="{isLastMessage || ($settings?.highContrastMode ?? false)
? 'visible'
: 'hover-reveal'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition"
: 'hover-reveal'} inline-flex size-7 shrink-0 items-center justify-center p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-gray-400 hover:text-gray-600 transition"
on:click={() => {
continueResponse(message);
}}
>
<svg
class="size-4"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
stroke-width="1.5"
viewBox="0 0 24 24"
stroke-width="2.3"
stroke="currentColor"
class="w-4 h-4"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6.90588 4.53682C6.50592 4.2998 6 4.58808 6 5.05299V18.947C6 19.4119 6.50592 19.7002 6.90588 19.4632L18.629 12.5162C19.0211 12.2838 19.0211 11.7162 18.629 11.4838L6.90588 4.53682Z"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
d="M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"
/>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15.91 11.672a.375.375 0 0 1 0 .656l-5.603 3.113a.375.375 0 0 1-.557-.328V8.887c0-.286.307-.466.557-.327l5.603 3.112Z"
/>
</svg>
</button>
@ -1457,21 +1464,39 @@
aria-label={$i18n.t('Regenerate')}
class="{isLastMessage || ($settings?.highContrastMode ?? false)
? 'visible'
: 'hover-reveal'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition"
: 'hover-reveal'} inline-flex size-7 shrink-0 items-center justify-center p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-gray-400 hover:text-gray-600 transition"
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2.3"
class="size-4"
aria-hidden="true"
stroke="currentColor"
class="w-4 h-4"
stroke-width="1.5"
viewBox="-2 -2 28 28"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M21.1679 8C19.6247 4.46819 16.1006 2 11.9999 2C6.81459 2 2.55104 5.94668 2.04932 11"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M17 8H21.4C21.7314 8 22 7.73137 22 7.4V3"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M2.88146 16C4.42458 19.5318 7.94874 22 12.0494 22C17.2347 22 21.4983 18.0533 22 13"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M7.04932 16H2.64932C2.31795 16 2.04932 16.2686 2.04932 16.6V21"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182m0-4.991v4.99"
/>
</svg>
</button>
@ -1484,7 +1509,7 @@
aria-label={$i18n.t('Regenerate')}
class="{isLastMessage || ($settings?.highContrastMode ?? false)
? 'visible'
: 'hover-reveal'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition regenerate-response-button"
: 'hover-reveal'} inline-flex size-7 shrink-0 items-center justify-center p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-gray-400 hover:text-gray-600 transition regenerate-response-button"
on:click={() => {
showRateComment = false;
regenerateResponse(message);
@ -1503,18 +1528,36 @@
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2.3"
class="size-4"
aria-hidden="true"
stroke="currentColor"
class="w-4 h-4"
stroke-width="1.5"
viewBox="-2 -2 28 28"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M21.1679 8C19.6247 4.46819 16.1006 2 11.9999 2C6.81459 2 2.55104 5.94668 2.04932 11"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M17 8H21.4C21.7314 8 22 7.73137 22 7.4V3"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M2.88146 16C4.42458 19.5318 7.94874 22 12.0494 22C17.2347 22 21.4983 18.0533 22 13"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M7.04932 16H2.64932C2.31795 16 2.04932 16.2686 2.04932 16.6V21"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182m0-4.991v4.99"
/>
</svg>
</button>
@ -1540,7 +1583,7 @@
)}
class="{isLastMessage || ($settings?.highContrastMode ?? false)
? 'visible'
: 'hover-reveal'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition"
: 'hover-reveal'} inline-flex size-7 shrink-0 items-center justify-center p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-gray-400 hover:text-gray-600 transition"
on:click={() => {
actionMessage(action.id, message);
}}
@ -1562,7 +1605,7 @@
/>
</div>
{:else}
<Sparkles strokeWidth="2.1" className="size-4" />
<Sparkles />
{/if}
</button>
</Tooltip>
@ -1577,7 +1620,7 @@
id="delete-response-button"
class="{isLastMessage || ($settings?.highContrastMode ?? false)
? 'visible'
: 'hover-reveal'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition disabled:opacity-50 disabled:hover:bg-transparent"
: 'hover-reveal'} inline-flex size-7 shrink-0 items-center justify-center p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-gray-400 hover:text-gray-600 transition disabled:opacity-50 disabled:hover:bg-transparent"
disabled={!allowDelete}
on:click={(e) => {
if (!allowDelete) {
@ -1590,21 +1633,7 @@
}
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
aria-hidden="true"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0"
/>
</svg>
<TrashIcon />
</button>
</Tooltip>
{/if}

View file

@ -1,4 +1,8 @@
<script lang="ts">
import EditPencilIcon from '$lib/components/layout/Sidebar/icons/EditPencil.svelte';
import CopyIcon from '$lib/components/layout/Sidebar/icons/Copy.svelte';
import TrashIcon from '$lib/components/layout/Sidebar/icons/Trash.svelte';
import ChevronRightIcon from '$lib/components/layout/Sidebar/icons/ChevronRight.svelte';
import { toast } from 'svelte-sonner';
import { tick, getContext, onMount } from 'svelte';
@ -442,11 +446,13 @@
{#if edit !== true && !(message?.meta?.internal === true && message?.meta?.type === 'subagent') && !(message?.meta?.internal === true && message?.meta?.type === 'timer')}
<div
class=" flex {($settings?.chatBubble ?? true)
class="flex items-center {($settings?.chatBubble ?? true)
? isOwn
? 'justify-end'
: 'justify-start'
: 'items-center'} text-gray-600 dark:text-gray-500"
: 'items-center'} {($settings?.highContrastMode ?? false)
? 'text-gray-600 dark:text-gray-500'
: 'text-gray-600/80 dark:text-gray-500/70'}"
>
{#if message.timestamp}
<Tooltip
@ -473,30 +479,17 @@
<div class="flex self-center" dir="ltr">
<button
aria-label={$i18n.t('Previous message')}
class="self-center p-1 hover:bg-black/5 dark:hover:bg-white/5 dark:hover:text-white hover:text-black rounded-md transition"
class="self-center inline-flex size-7 shrink-0 items-center justify-center p-1.5 hover:bg-black/5 dark:hover:bg-white/5 dark:hover:text-gray-400 hover:text-gray-600 rounded-md transition"
on:click={() => {
showPreviousMessage(message);
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="2.5"
class="size-3.5"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15.75 19.5 8.25 12l7.5-7.5"
/>
</svg>
<ChevronRightIcon className="size-4 rotate-180" />
</button>
{#if messageIndexEdit}
<div
class="text-sm flex justify-center font-normal self-center dark:text-gray-100 min-w-fit"
class="text-sm flex justify-center font-normal self-center dark:text-gray-500 min-w-fit"
>
<input
id="message-index-input-{message.id}"
@ -517,13 +510,13 @@
messageIndexEdit = false;
}
}}
class="bg-transparent font-normal self-center dark:text-gray-100 min-w-fit outline-hidden"
class="bg-transparent font-normal self-center dark:text-gray-500 min-w-fit outline-hidden"
/>/{siblings.length}
</div>
{:else}
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
class="text-sm tracking-widest font-normal self-center dark:text-gray-100 min-w-fit"
class="text-sm tracking-widest font-normal self-center dark:text-gray-500 min-w-fit"
on:dblclick={async () => {
messageIndexEdit = true;
@ -541,25 +534,12 @@
<button
aria-label={$i18n.t('Next message')}
class="self-center p-1 hover:bg-black/5 dark:hover:bg-white/5 dark:hover:text-white hover:text-black rounded-md transition"
class="self-center inline-flex size-7 shrink-0 items-center justify-center p-1.5 hover:bg-black/5 dark:hover:bg-white/5 dark:hover:text-gray-400 hover:text-gray-600 rounded-md transition"
on:click={() => {
showNextMessage(message);
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="2.5"
class="size-3.5"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="m8.25 4.5 7.5 7.5-7.5 7.5"
/>
</svg>
<ChevronRightIcon className="size-4" />
</button>
</div>
{/if}
@ -569,26 +549,13 @@
<button
class="{($settings?.highContrastMode ?? false)
? ''
: 'hover-reveal'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition edit-user-message-button"
: 'hover-reveal'} inline-flex size-7 shrink-0 items-center justify-center p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-gray-400 hover:text-gray-600 transition edit-user-message-button"
aria-label={$i18n.t('Edit')}
on:click={() => {
editMessageHandler();
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2.3"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L6.832 19.82a4.5 4.5 0 01-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 011.13-1.897L16.863 4.487zm0 0L19.5 7.125"
/>
</svg>
<EditPencilIcon />
</button>
</Tooltip>
{/if}
@ -598,26 +565,13 @@
<button
class="{($settings?.highContrastMode ?? false)
? ''
: 'hover-reveal'} p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-white hover:text-black transition"
: 'hover-reveal'} inline-flex size-7 shrink-0 items-center justify-center p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-lg dark:hover:text-gray-400 hover:text-gray-600 transition"
aria-label={$i18n.t('Copy')}
on:click={() => {
copyToClipboard(message.content);
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2.3"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15.666 3.888A2.25 2.25 0 0013.5 2.25h-3c-1.03 0-1.9.693-2.166 1.638m7.332 0c.055.194.084.4.084.612v0a.75.75 0 01-.75.75H9a.75.75 0 01-.75-.75v0c0-.212.03-.418.084-.612m7.332 0c.646.049 1.288.11 1.927.184 1.1.128 1.907 1.077 1.907 2.185V19.5a2.25 2.25 0 01-2.25 2.25H6.75A2.25 2.25 0 014.5 19.5V6.257c0-1.108.806-2.057 1.907-2.185a48.208 48.208 0 011.927-.184"
/>
</svg>
<CopyIcon />
</button>
</Tooltip>
{/if}
@ -629,7 +583,7 @@
aria-label={$i18n.t('Delete')}
class="{($settings?.highContrastMode ?? false)
? ''
: 'hover-reveal'} p-1 rounded-sm dark:hover:text-white hover:text-black transition"
: 'hover-reveal'} inline-flex size-7 shrink-0 items-center justify-center p-1.5 rounded-lg dark:hover:text-gray-400 hover:text-gray-600 transition"
on:click={(e) => {
if (e.shiftKey) {
deleteMessageHandler();
@ -638,20 +592,7 @@
}
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
class="w-4 h-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0"
/>
</svg>
<TrashIcon />
</button>
</Tooltip>
{/if}
@ -662,30 +603,17 @@
<div class="flex self-center" dir="ltr">
<button
aria-label={$i18n.t('Previous message')}
class="self-center p-1 hover:bg-black/5 dark:hover:bg-white/5 dark:hover:text-white hover:text-black rounded-md transition"
class="self-center inline-flex size-7 shrink-0 items-center justify-center p-1.5 hover:bg-black/5 dark:hover:bg-white/5 dark:hover:text-gray-400 hover:text-gray-600 rounded-md transition"
on:click={() => {
showPreviousMessage(message);
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="2.5"
class="size-3.5"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15.75 19.5 8.25 12l7.5-7.5"
/>
</svg>
<ChevronRightIcon className="size-4 rotate-180" />
</button>
{#if messageIndexEdit}
<div
class="text-sm flex justify-center font-normal self-center dark:text-gray-100 min-w-fit"
class="text-sm flex justify-center font-normal self-center dark:text-gray-500 min-w-fit"
>
<input
id="message-index-input-{message.id}"
@ -706,13 +634,13 @@
messageIndexEdit = false;
}
}}
class="bg-transparent font-normal self-center dark:text-gray-100 min-w-fit outline-hidden"
class="bg-transparent font-normal self-center dark:text-gray-500 min-w-fit outline-hidden"
/>/{siblings.length}
</div>
{:else}
<!-- svelte-ignore a11y-no-static-element-interactions -->
<div
class="text-sm tracking-widest font-normal self-center dark:text-gray-100 min-w-fit"
class="text-sm tracking-widest font-normal self-center dark:text-gray-500 min-w-fit"
on:dblclick={async () => {
messageIndexEdit = true;
@ -730,25 +658,12 @@
<button
aria-label={$i18n.t('Next message')}
class="self-center p-1 hover:bg-black/5 dark:hover:bg-white/5 dark:hover:text-white hover:text-black rounded-md transition"
class="self-center inline-flex size-7 shrink-0 items-center justify-center p-1.5 hover:bg-black/5 dark:hover:bg-white/5 dark:hover:text-gray-400 hover:text-gray-600 rounded-md transition"
on:click={() => {
showNextMessage(message);
}}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
stroke-width="2.5"
class="size-3.5"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="m8.25 4.5 7.5 7.5-7.5 7.5"
/>
</svg>
<ChevronRightIcon className="size-4" />
</button>
</div>
{/if}

View file

@ -48,7 +48,11 @@
{/snippet}
<div class="flex shrink-0 items-center gap-1" data-chat-participants draggable="false">
<div class="flex items-center {mode === 'presence' ? '-space-x-2' : '-space-x-1'} rtl:space-x-reverse">
<div
class="flex items-center {mode === 'presence'
? '-space-x-2'
: '-space-x-1'} rtl:space-x-reverse"
>
{#each people.slice(0, 3) as person (person.id)}
<div class="relative rounded-full hover:z-10 focus-within:z-10">
<ProfilePreview
@ -102,7 +106,9 @@
{/if}
<ul class="space-y-1">
{#each people as person (person.id)}
<li class="rounded-lg p-1 hover:bg-gray-50 dark:hover:bg-gray-800">
<li
class="rounded-lg p-1 hover:bg-gray-50 dark:hover:bg-gray-800 [&>button]:max-w-full"
>
<ProfilePreview
side={mode === 'presence' ? 'bottom' : 'right'}
align={mode === 'presence' ? 'end' : 'center'}