refac: styling

This commit is contained in:
Timothy J. Baek 2024-02-15 16:20:46 -08:00
parent db08ad964c
commit e99d69bfe2
8 changed files with 163 additions and 132 deletions

View file

@ -55,6 +55,11 @@
let isRecording = false; let isRecording = false;
const MIN_DECIBELS = -45; const MIN_DECIBELS = -45;
const scrollToBottom = () => {
const element = document.getElementById('messages-container');
element.scrollTop = element.scrollHeight;
};
const startRecording = async () => { const startRecording = async () => {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
mediaRecorder = new MediaRecorder(stream); mediaRecorder = new MediaRecorder(stream);
@ -371,17 +376,17 @@
</div> </div>
{/if} {/if}
<div class="w-full pt-2 md:pt-0"> <div class="w-full">
<div class="px-2.5 pt-2.5 -mb-0.5 mx-auto inset-x-0 bg-transparent flex justify-center"> <div class="px-2.5 -mb-0.5 mx-auto inset-x-0 bg-transparent flex justify-center">
<div class="flex flex-col max-w-3xl w-full"> <div class="flex flex-col max-w-3xl w-full">
<div> <div class="relative">
{#if autoScroll === false && messages.length > 0} {#if autoScroll === false && messages.length > 0}
<div class=" flex justify-center mb-4"> <div class=" absolute -top-12 left-0 right-0 flex justify-center">
<button <button
class=" bg-white border border-gray-100 dark:border-none dark:bg-white/20 p-1.5 rounded-full" class=" bg-white border border-gray-100 dark:border-none dark:bg-white/20 p-1.5 rounded-full"
on:click={() => { on:click={() => {
autoScroll = true; autoScroll = true;
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }); scrollToBottom();
}} }}
> >
<svg <svg
@ -401,7 +406,7 @@
{/if} {/if}
</div> </div>
<div class="w-full"> <div class="w-full relative">
{#if prompt.charAt(0) === '/'} {#if prompt.charAt(0) === '/'}
<Prompts bind:this={promptsElement} bind:prompt /> <Prompts bind:this={promptsElement} bind:prompt />
{:else if prompt.charAt(0) === '#'} {:else if prompt.charAt(0) === '#'}
@ -432,14 +437,16 @@
bind:chatInputPlaceholder bind:chatInputPlaceholder
{messages} {messages}
/> />
{:else if messages.length == 0 && suggestionPrompts.length !== 0} {/if}
{#if messages.length == 0 && suggestionPrompts.length !== 0}
<Suggestions {suggestionPrompts} {submitPrompt} /> <Suggestions {suggestionPrompts} {submitPrompt} />
{/if} {/if}
</div> </div>
</div> </div>
</div> </div>
<div class="bg-white dark:bg-gray-900"> <div class="bg-white dark:bg-gray-900">
<div class="max-w-3xl px-2.5 -mb-0.5 mx-auto inset-x-0"> <div class="max-w-3xl px-2.5 mx-auto inset-x-0">
<div class=" pb-2"> <div class=" pb-2">
<input <input
bind:this={filesInputElement} bind:this={filesInputElement}

View file

@ -88,7 +88,7 @@
</script> </script>
{#if filteredItems.length > 0 || prompt.split(' ')?.at(0)?.substring(1).startsWith('http')} {#if filteredItems.length > 0 || prompt.split(' ')?.at(0)?.substring(1).startsWith('http')}
<div class="md:px-2 mb-3 text-left w-full"> <div class="md:px-2 mb-3 text-left w-full absolute bottom-0 left-0 right-0">
<div class="flex w-full rounded-lg border border-gray-100 dark:border-gray-700"> <div class="flex w-full rounded-lg border border-gray-100 dark:border-gray-700">
<div class=" bg-gray-100 dark:bg-gray-700 w-10 rounded-l-lg text-center"> <div class=" bg-gray-100 dark:bg-gray-700 w-10 rounded-l-lg text-center">
<div class=" text-lg font-semibold mt-2">#</div> <div class=" text-lg font-semibold mt-2">#</div>

View file

@ -120,7 +120,7 @@
</script> </script>
{#if filteredModels.length > 0} {#if filteredModels.length > 0}
<div class="md:px-2 mb-3 text-left w-full"> <div class="md:px-2 mb-3 text-left w-full absolute bottom-0 left-0 right-0">
<div class="flex w-full rounded-lg border border-gray-100 dark:border-gray-700"> <div class="flex w-full rounded-lg border border-gray-100 dark:border-gray-700">
<div class=" bg-gray-100 dark:bg-gray-700 w-10 rounded-l-lg text-center"> <div class=" bg-gray-100 dark:bg-gray-700 w-10 rounded-l-lg text-center">
<div class=" text-lg font-semibold mt-2">@</div> <div class=" text-lg font-semibold mt-2">@</div>

View file

@ -47,7 +47,7 @@
</script> </script>
{#if filteredPromptCommands.length > 0} {#if filteredPromptCommands.length > 0}
<div class="md:px-2 mb-3 text-left w-full"> <div class="md:px-2 mb-3 text-left w-full absolute bottom-0 left-0 right-0">
<div class="flex w-full rounded-lg border border-gray-100 dark:border-gray-700"> <div class="flex w-full rounded-lg border border-gray-100 dark:border-gray-700">
<div class=" bg-gray-100 dark:bg-gray-700 w-10 rounded-l-lg text-center"> <div class=" bg-gray-100 dark:bg-gray-700 w-10 rounded-l-lg text-center">
<div class=" text-lg font-semibold mt-2">/</div> <div class=" text-lg font-semibold mt-2">/</div>

View file

@ -29,10 +29,16 @@
$: if (autoScroll && bottomPadding) { $: if (autoScroll && bottomPadding) {
(async () => { (async () => {
await tick(); await tick();
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' });
scrollToBottom();
})(); })();
} }
const scrollToBottom = () => {
const element = document.getElementById('messages-container');
element.scrollTop = element.scrollHeight;
};
const copyToClipboard = (text) => { const copyToClipboard = (text) => {
if (!navigator.clipboard) { if (!navigator.clipboard) {
var textArea = document.createElement('textarea'); var textArea = document.createElement('textarea');
@ -160,10 +166,11 @@
await tick(); await tick();
autoScroll = window.innerHeight + window.scrollY >= document.body.offsetHeight - 40; const element = document.getElementById('messages-container');
autoScroll = element.scrollHeight - element.scrollTop === element.clientHeight - 40;
setTimeout(() => { setTimeout(() => {
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }); scrollToBottom();
}, 100); }, 100);
}; };
@ -208,9 +215,11 @@
await tick(); await tick();
autoScroll = window.innerHeight + window.scrollY >= document.body.offsetHeight - 40; const element = document.getElementById('messages-container');
autoScroll = element.scrollHeight - element.scrollTop === element.clientHeight - 40;
setTimeout(() => { setTimeout(() => {
window.scrollTo({ top: document.body.scrollHeight, behavior: 'smooth' }); scrollToBottom();
}, 100); }, 100);
}; };
</script> </script>
@ -218,6 +227,7 @@
{#if messages.length == 0} {#if messages.length == 0}
<Placeholder models={selectedModels} modelfiles={selectedModelfiles} /> <Placeholder models={selectedModels} modelfiles={selectedModelfiles} />
{:else} {:else}
<div class=" pb-10">
{#key chatId} {#key chatId}
{#each messages as message, messageIdx} {#each messages as message, messageIdx}
<div class=" w-full"> <div class=" w-full">
@ -309,4 +319,5 @@
<div class=" mb-10" /> <div class=" mb-10" />
{/if} {/if}
{/key} {/key}
</div>
{/if} {/if}

View file

@ -16,7 +16,7 @@
</script> </script>
{#if models.length > 0} {#if models.length > 0}
<div class="m-auto text-center max-w-md pb-56 px-2"> <div class="m-auto text-center max-w-md px-2">
<div class="flex justify-center mt-8"> <div class="flex justify-center mt-8">
<div class="flex -space-x-4 mb-1"> <div class="flex -space-x-4 mb-1">
{#each models as model, modelIdx} {#each models as model, modelIdx}

View file

@ -137,6 +137,11 @@
}); });
}; };
const scrollToBottom = () => {
const element = document.getElementById('messages-container');
element.scrollTop = element.scrollHeight;
};
////////////////////////// //////////////////////////
// Ollama functions // Ollama functions
////////////////////////// //////////////////////////
@ -316,7 +321,7 @@
await tick(); await tick();
// Scroll down // Scroll down
window.scrollTo({ top: document.body.scrollHeight }); scrollToBottom();
const messagesBody = [ const messagesBody = [
$settings.system $settings.system
@ -469,7 +474,7 @@
} }
if (autoScroll) { if (autoScroll) {
window.scrollTo({ top: document.body.scrollHeight }); scrollToBottom();
} }
} }
@ -508,7 +513,7 @@
await tick(); await tick();
if (autoScroll) { if (autoScroll) {
window.scrollTo({ top: document.body.scrollHeight }); scrollToBottom();
} }
if (messages.length == 2 && messages.at(1).content !== '') { if (messages.length == 2 && messages.at(1).content !== '') {
@ -519,8 +524,7 @@
const sendPromptOpenAI = async (model, userPrompt, responseMessageId, _chatId) => { const sendPromptOpenAI = async (model, userPrompt, responseMessageId, _chatId) => {
const responseMessage = history.messages[responseMessageId]; const responseMessage = history.messages[responseMessageId];
scrollToBottom();
window.scrollTo({ top: document.body.scrollHeight });
const res = await generateOpenAIChatCompletion(localStorage.token, { const res = await generateOpenAIChatCompletion(localStorage.token, {
model: model, model: model,
@ -628,7 +632,7 @@
} }
if (autoScroll) { if (autoScroll) {
window.scrollTo({ top: document.body.scrollHeight }); scrollToBottom();
} }
} }
@ -672,7 +676,7 @@
await tick(); await tick();
if (autoScroll) { if (autoScroll) {
window.scrollTo({ top: document.body.scrollHeight }); scrollToBottom();
} }
if (messages.length == 2) { if (messages.length == 2) {
@ -783,16 +787,18 @@
}; };
</script> </script>
<svelte:window <div class="min-h-screen max-h-screen w-full flex flex-col">
on:scroll={(e) => {
autoScroll = window.innerHeight + window.scrollY >= document.body.offsetHeight - 40;
}}
/>
<div class="min-h-screen w-full flex flex-col">
<Navbar {title} shareEnabled={messages.length > 0} {initNewChat} {tags} {addTag} {deleteTag} /> <Navbar {title} shareEnabled={messages.length > 0} {initNewChat} {tags} {addTag} {deleteTag} />
<div class="flex flex-col justify-center h-full"> <div class="flex flex-col flex-auto">
<div class=" pb-2.5 flex flex-1 flex-col justify-between w-full overflow-hidden"> <div
class=" pb-2.5 flex flex-col justify-between w-full flex-auto overflow-auto h-80"
id="messages-container"
on:scroll={(e) => {
console.log(e.target.scrollHeight, e.target.scrollTop, e.target.clientHeight);
console.log(e.target.scrollHeight - e.target.scrollTop, e.target.clientHeight);
autoScroll = e.target.scrollHeight - e.target.scrollTop <= e.target.clientHeight + 50;
}}
>
<div <div
class="{$settings?.fullScreenMode ?? null class="{$settings?.fullScreenMode ?? null
? 'max-w-full' ? 'max-w-full'
@ -801,7 +807,7 @@
<ModelSelector bind:selectedModels disabled={messages.length > 0} /> <ModelSelector bind:selectedModels disabled={messages.length > 0} />
</div> </div>
<div class=" h-full mt-14 w-full flex flex-col"> <div class=" h-full w-full flex flex-col py-8">
<Messages <Messages
chatId={$chatId} chatId={$chatId}
{selectedModels} {selectedModels}

View file

@ -153,6 +153,11 @@
} }
}; };
const scrollToBottom = () => {
const element = document.getElementById('messages-container');
element.scrollTop = element.scrollHeight;
};
////////////////////////// //////////////////////////
// Ollama functions // Ollama functions
////////////////////////// //////////////////////////
@ -330,7 +335,7 @@
await tick(); await tick();
// Scroll down // Scroll down
window.scrollTo({ top: document.body.scrollHeight }); scrollToBottom();
const messagesBody = [ const messagesBody = [
$settings.system $settings.system
@ -483,7 +488,7 @@
} }
if (autoScroll) { if (autoScroll) {
window.scrollTo({ top: document.body.scrollHeight }); scrollToBottom();
} }
} }
@ -522,7 +527,7 @@
await tick(); await tick();
if (autoScroll) { if (autoScroll) {
window.scrollTo({ top: document.body.scrollHeight }); scrollToBottom();
} }
if (messages.length == 2 && messages.at(1).content !== '') { if (messages.length == 2 && messages.at(1).content !== '') {
@ -534,7 +539,7 @@
const sendPromptOpenAI = async (model, userPrompt, responseMessageId, _chatId) => { const sendPromptOpenAI = async (model, userPrompt, responseMessageId, _chatId) => {
const responseMessage = history.messages[responseMessageId]; const responseMessage = history.messages[responseMessageId];
window.scrollTo({ top: document.body.scrollHeight }); scrollToBottom();
const res = await generateOpenAIChatCompletion(localStorage.token, { const res = await generateOpenAIChatCompletion(localStorage.token, {
model: model, model: model,
@ -642,7 +647,7 @@
} }
if (autoScroll) { if (autoScroll) {
window.scrollTo({ top: document.body.scrollHeight }); scrollToBottom();
} }
} }
@ -686,7 +691,7 @@
await tick(); await tick();
if (autoScroll) { if (autoScroll) {
window.scrollTo({ top: document.body.scrollHeight }); scrollToBottom();
} }
if (messages.length == 2) { if (messages.length == 2) {
@ -797,14 +802,8 @@
}); });
</script> </script>
<svelte:window
on:scroll={(e) => {
autoScroll = window.innerHeight + window.scrollY >= document.body.offsetHeight - 40;
}}
/>
{#if loaded} {#if loaded}
<div class="min-h-screen w-full flex flex-col"> <div class="min-h-screen max-h-screen w-full flex flex-col">
<Navbar <Navbar
{title} {title}
shareEnabled={messages.length > 0} shareEnabled={messages.length > 0}
@ -820,8 +819,16 @@
{addTag} {addTag}
{deleteTag} {deleteTag}
/> />
<div class="justify-center"> <div class="flex flex-col flex-auto">
<div class=" pb-2.5 flex flex-col justify-between w-full"> <div
class=" pb-2.5 flex flex-col justify-between w-full flex-auto overflow-auto h-0"
id="messages-container"
on:scroll={(e) => {
console.log(e.target.scrollHeight, e.target.scrollTop, e.target.clientHeight);
console.log(e.target.scrollHeight - e.target.scrollTop, e.target.clientHeight);
autoScroll = e.target.scrollHeight - e.target.scrollTop <= e.target.clientHeight + 50;
}}
>
<div <div
class="{$settings?.fullScreenMode ?? null class="{$settings?.fullScreenMode ?? null
? 'max-w-full' ? 'max-w-full'