feat(frontend): add scroll to bottom button
This commit is contained in:
@@ -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)}
|
||||||
|
{#if i === messages.length - 1}
|
||||||
|
<div bind:this={lastMessageElement}>
|
||||||
<ChatMessage
|
<ChatMessage
|
||||||
role={message.role}
|
role={message.role}
|
||||||
content={message.content}
|
content={message.content}
|
||||||
isStreaming={message.isStreaming}
|
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>
|
||||||
|
|||||||
Reference in New Issue
Block a user