chat room is scrollable

This commit is contained in:
littlemoonstones 2023-03-12 14:22:43 +08:00
parent 66c0fe57df
commit 87a8fdc1d4
2 changed files with 136 additions and 111 deletions

View File

@ -94,4 +94,16 @@ div.copy-prompt {
position: absolute; position: absolute;
top: 5px; top: 5px;
right: 5px; right: 5px;
}
.message-container{
display: flex;
flex-direction: column;
height: 720px;
}
.message-list{
// max-height: 100%;
overflow-y: auto;
flex: 1;
margin-bottom: 10px;
} }

View File

@ -102,7 +102,7 @@
// Scroll to the bottom of the page after any updates to the messages array // Scroll to the bottom of the page after any updates to the messages array
window.scrollTo(0, document.body.scrollHeight); window.scrollTo(0, document.body.scrollHeight);
input.focus(); input.focus();
copyFunction() copyFunction();
}); });
// Marked options // Marked options
@ -286,7 +286,13 @@
const copyPrompt = document.createElement("div"); const copyPrompt = document.createElement("div");
copyPrompt.className = "copy-prompt"; copyPrompt.className = "copy-prompt";
const copyPromptText = document.createElement("button"); const copyPromptText = document.createElement("button");
copyPromptText.classList.add("button", "is-light", "is-outlined", "is-small", "is-responsive"); copyPromptText.classList.add(
"button",
"is-light",
"is-outlined",
"is-small",
"is-responsive"
);
copyPromptText.innerHTML = showCopyMessage; copyPromptText.innerHTML = showCopyMessage;
copyPrompt.appendChild(copyPromptText); copyPrompt.appendChild(copyPromptText);
block.appendChild(copyPrompt); block.appendChild(copyPrompt);
@ -301,7 +307,7 @@
}, 1000); }, 1000);
}); });
}); });
} };
</script> </script>
<nav class="level chat-header"> <nav class="level chat-header">
@ -357,118 +363,125 @@
</p> </p>
</div> </div>
</nav> </nav>
<div class="is-fullhd message-container">
{#each chat.messages as message} <div class="message-list">
{#if message.role === "user"} {#each chat.messages as message}
<article {#if message.role === "user"}
class="message is-info user-message" <article
class:has-text-right={message.content class="message is-info user-message"
.split("\n") class:has-text-right={message.content
.filter((line) => line.trim()).length === 1} .split("\n")
> .filter((line) => line.trim()).length === 1}
<div class="message-body content">
<a
href={"#"}
class="greyscale is-pulled-right ml-2 is-hidden editbutton"
on:click={() => {
input.value = message.content;
input.focus();
}}
> >
✏️ <div class="message-body content">
</a> <a
<SvelteMarkdown href={"#"}
source={message.content} class="greyscale is-pulled-right ml-2 is-hidden editbutton"
options={markedownOptions} on:click={() => {
renderers={{ input.value = message.content;
code: Code, input.focus();
}} }}
/>
</div>
</article>
{:else if message.role === "system" || message.role === "error"}
<article class="message is-danger">
<div class="message-body content">
<SvelteMarkdown
source={message.content}
options={markedownOptions}
renderers={{
code: Code,
}}
/>
</div>
</article>
{:else}
<article class="message is-success">
<div class="message-body content">
<SvelteMarkdown
source={message.content}
options={markedownOptions}
renderers={{
code: Code,
}}
/>
{#if message.usage}
<p class="is-size-7">
This message was generated using <span class="has-text-weight-bold"
>{message.usage.total_tokens}</span
> >
tokens ~= ✏️
<span class="has-text-weight-bold" </a>
>${(message.usage.total_tokens * token_price).toFixed(6)}</span <SvelteMarkdown
> source={message.content}
</p> options={markedownOptions}
{/if} renderers={{
</div> code: Code,
</article> }}
{/if} />
{/each} </div>
</article>
{:else if message.role === "system" || message.role === "error"}
<article class="message is-danger">
<div class="message-body content">
<SvelteMarkdown
source={message.content}
options={markedownOptions}
renderers={{
code: Code,
}}
/>
</div>
</article>
{:else}
<article class="message is-success">
<div class="message-body content">
<SvelteMarkdown
source={message.content}
options={markedownOptions}
renderers={{
code: Code,
}}
/>
{#if message.usage}
<p class="is-size-7">
This message was generated using <span
class="has-text-weight-bold"
>{message.usage.total_tokens}</span
>
tokens ~=
<span class="has-text-weight-bold"
>${(message.usage.total_tokens * token_price).toFixed(
6
)}</span
>
</p>
{/if}
</div>
</article>
{/if}
{/each}
</div>
<div class="message-send">
{#if updating}
<progress class="progress is-small is-dark" max="100" />
{/if}
{#if updating} <form
<progress class="progress is-small is-dark" max="100" /> class="field has-addons has-addons-right"
{/if} on:submit|preventDefault={() => submitForm()}
<form
class="field has-addons has-addons-right"
on:submit|preventDefault={() => submitForm()}
>
<p class="control is-expanded">
<textarea
class="input is-info is-focused chat-input"
placeholder="Type your message here..."
rows="1"
on:keydown={(e) => {
// Only send if Enter is pressed, not Shift+Enter
if (e.key === "Enter" && !e.shiftKey) {
submitForm();
e.preventDefault();
}
}}
on:input={(e) => {
// Resize the textarea to fit the content - auto is important to reset the height after deleting content
input.style.height = "auto";
input.style.height = input.scrollHeight + "px";
}}
bind:this={input}
/>
</p>
<p class="control" class:is-hidden={!recognition}>
<button
class="button"
class:is-pulse={recording}
on:click|preventDefault={recordToggle}
><span class="greyscale">🎤</span></button
> >
</p> <p class="control is-expanded">
<p class="control"> <textarea
<button class="button" on:click|preventDefault={showSettings} class="input is-info is-focused chat-input"
><span class="greyscale">⚙️</span></button placeholder="Type your message here..."
> rows="1"
</p> on:keydown={(e) => {
<p class="control"> // Only send if Enter is pressed, not Shift+Enter
<button class="button is-info" type="submit">Send</button> if (e.key === "Enter" && !e.shiftKey) {
</p> submitForm();
</form> e.preventDefault();
}
}}
on:input={(e) => {
// Resize the textarea to fit the content - auto is important to reset the height after deleting content
input.style.height = "auto";
input.style.height = input.scrollHeight + "px";
}}
bind:this={input}
/>
</p>
<p class="control" class:is-hidden={!recognition}>
<button
class="button"
class:is-pulse={recording}
on:click|preventDefault={recordToggle}
><span class="greyscale">🎤</span></button
>
</p>
<p class="control">
<button class="button" on:click|preventDefault={showSettings}
><span class="greyscale">⚙️</span></button
>
</p>
<p class="control">
<button class="button is-info" type="submit">Send</button>
</p>
</form>
</div>
</div>
<svelte:window <svelte:window
on:keydown={(event) => { on:keydown={(event) => {