feat(frontend): add scroll to bottom button

This commit is contained in:
h
2026-01-21 20:41:22 +01:00
parent 03d56006dc
commit 87aa974084

View File

@@ -11,6 +11,27 @@
const usePolling = getContext<boolean>('convex-use-polling') ?? false; const usePolling = getContext<boolean>('convex-use-polling') ?? false;
let mnemonic = $derived(page.params.mnemonic); let mnemonic = $derived(page.params.mnemonic);
let lastMessageElement: HTMLDivElement | null = $state(null);
let showScrollButton = $state(false);
$effect(() => {
if (!lastMessageElement) return;
const observer = new IntersectionObserver(
([entry]) => {
showScrollButton = !entry.isIntersecting;
},
{ threshold: 0, rootMargin: '0px 0px -90% 0px' }
);
observer.observe(lastMessageElement);
return () => observer.disconnect();
});
function scrollToLastMessage() {
lastMessageElement?.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
const chatDataWs = usePolling const chatDataWs = usePolling
? null ? null
: useQuery(api.chats.getWithUser, () => (mnemonic ? { mnemonic } : 'skip')); : useQuery(api.chats.getWithUser, () => (mnemonic ? { mnemonic } : 'skip'));
@@ -118,12 +139,22 @@
<div class="py-4 text-center text-xs text-neutral-500">Not found</div> <div class="py-4 text-center text-xs text-neutral-500">Not found</div>
{:else} {:else}
<div class="space-y-1"> <div class="space-y-1">
{#each messages as message (message._id)} {#each messages as message, i (message._id)}
<ChatMessage {#if i === messages.length - 1}
role={message.role} <div bind:this={lastMessageElement}>
content={message.content} <ChatMessage
isStreaming={message.isStreaming} role={message.role}
/> content={message.content}
isStreaming={message.isStreaming}
/>
</div>
{:else}
<ChatMessage
role={message.role}
content={message.content}
isStreaming={message.isStreaming}
/>
{/if}
{/each} {/each}
</div> </div>
@@ -145,4 +176,13 @@
</div> </div>
</div> </div>
{/if} {/if}
{#if showScrollButton}
<button
onclick={scrollToLastMessage}
class="fixed bottom-12 right-3 z-50 flex h-8 w-8 items-center justify-center rounded-full bg-blue-600 text-white shadow-lg animate-pulse"
>
</button>
{/if}
</div> </div>