File size: 2,779 Bytes
502cb81 4b8b411 60216ec 4b8b411 60216ec 502cb81 0ffe6c3 0bcf467 ce92b65 502cb81 25a5986 eb79b3d 502cb81 de2ec19 cd2e1ea de2ec19 cd2e1ea de2ec19 502cb81 25a5986 502cb81 5213b80 f2e5687 de2ec19 25a5986 502cb81 25a5986 502cb81 5213b80 502cb81 5213b80 d5e14b5 5213b80 25a5986 502cb81 5213b80 f2e5687 5213b80 25a5986 de2ec19 60216ec b34b73b 5213b80 502cb81 eeca96c 60216ec 5213b80 502cb81 5213b80 a979074 5213b80 502cb81 5213b80 ce92b65 5213b80 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
<script lang="ts">
import type { Conversation } from "$lib/types";
import { createEventDispatcher } from "svelte";
import CodeSnippets from "./InferencePlaygroundCodeSnippets.svelte";
import Message from "./InferencePlaygroundMessage.svelte";
import IconPlus from "../Icons/IconPlus.svelte";
export let conversation: Conversation;
export let loading: boolean;
export let viewCode: boolean;
export let hfToken: string;
let shouldScrollToBottom = true;
let isProgrammaticScroll = true;
let conversationLength = conversation.messages.length;
const dispatch = createEventDispatcher<{
addMessage: void;
deleteMessage: number;
}>();
let messageContainer: HTMLDivElement | null = null;
function resizeMessageTextAreas() {
// ideally we would use CSS "field-sizing:content". However, it is currently only supported on Chrome.
if (messageContainer) {
const containerScrollTop = messageContainer.scrollTop;
const textareaEls = messageContainer.querySelectorAll("textarea");
for (const textarea of textareaEls) {
textarea.style.height = "0px";
textarea.style.height = textarea.scrollHeight + "px";
}
messageContainer.scrollTop = containerScrollTop;
}
}
function scrollToBottom() {
if (messageContainer) {
isProgrammaticScroll = true;
messageContainer.scrollTop = messageContainer.scrollHeight;
}
}
$: {
if (conversation.messages.at(-1)) {
resizeMessageTextAreas();
if (shouldScrollToBottom) {
scrollToBottom();
}
}
}
$: if (conversation.messages.length !== conversationLength) {
// enable automatic scrolling when new message was added
conversationLength = conversation.messages.length;
shouldScrollToBottom = true;
}
</script>
<div
class="flex max-h-[calc(100dvh-5.8rem)] flex-col overflow-y-auto overflow-x-hidden @container"
class:animate-pulse={loading && !conversation.streaming}
bind:this={messageContainer}
on:scroll={() => {
// disable automatic scrolling is user initiates scroll
if (!isProgrammaticScroll) {
shouldScrollToBottom = false;
}
isProgrammaticScroll = false;
}}
>
{#if !viewCode}
{#each conversation.messages as message, messageIdx}
<Message
class="border-b"
{message}
{loading}
on:input={resizeMessageTextAreas}
on:delete={() => dispatch("deleteMessage", messageIdx)}
autofocus={!loading && messageIdx === conversation.messages.length - 1}
/>
{/each}
<button
class="flex px-3.5 py-6 hover:bg-gray-50 md:px-6 dark:hover:bg-gray-800/50"
on:click={() => dispatch("addMessage")}
disabled={loading}
>
<div class="flex items-center gap-2 !p-0 text-sm font-semibold">
<IconPlus classNames="text-lg" /> Add message
</div>
</button>
{:else}
<CodeSnippets {conversation} {hfToken} />
{/if}
</div>
|