feat: chat history ui

This commit is contained in:
Shibo Lyu 2024-08-31 04:49:26 +08:00
parent 0582dffa1c
commit aebe100799
16 changed files with 325 additions and 8 deletions

View file

@ -1,8 +1,24 @@
<script lang="ts">
import { page } from '$app/stores';
import BgPattern from '$lib/components/BgPattern.svelte';
import { createRandomMessage } from '$lib/mock/messages';
import type { Message } from '$lib/types';
import { onMount } from 'svelte';
import ChatHeader from './ChatHeader.svelte';
import ChatHistory from './ChatHistory.svelte';
import ChatInput from './ChatInput.svelte';
let messages: Message[] = Array.from({ length: 10 }).map(createRandomMessage);
// onMount(() => {
// const interval = setInterval(
// () => {
// messages = [...messages, createRandomMessage()];
// },
// 3000 + Math.random() * 10000
// );
// return () => clearInterval(interval);
// });
</script>
<div class="flex h-full w-full flex-col justify-stretch">
@ -10,6 +26,8 @@
chat={{ id: 'blah', name: 'Blah IM Interest Group', type: 'group' }}
outsideUnreadCount={263723}
/>
<BgPattern class="flex-1" pattern="charlieBrown"></BgPattern>
<BgPattern class="flex-1" pattern="charlieBrown">
<ChatHistory {messages} mySenderId={'_send'} />
</BgPattern>
<ChatInput />
</div>

View file

@ -0,0 +1,17 @@
<script lang="ts">
import { VList } from 'virtua/svelte';
import type { Message } from '$lib/types';
import ChatMessage from './ChatMessage.svelte';
export let messages: Message[] = [];
export let mySenderId: string;
let ref: VList<Message>;
$: ref?.scrollToIndex(messages.length - 1, { align: 'end', smooth: true });
</script>
<VList data={messages} let:item={message} class="size-full pt-2" bind:this={ref}>
<ChatMessage {message} isMyself={mySenderId === message.sender.id} />
</VList>

View file

@ -0,0 +1,26 @@
<script lang="ts">
import RichTextRenderer from '$lib/components/RichTextRenderer.svelte';
import { tw } from '$lib/tw';
import type { Message } from '$lib/types';
import { AvatarBeam } from 'svelte-boring-avatars';
export let message: Message;
export let isMyself: boolean;
</script>
<div class={tw('mb-2 flex items-end gap-2 px-2', isMyself && 'flex-row-reverse')}>
<div>
<AvatarBeam size={30} name={message.sender.name} />
</div>
<div class="relative flex-1">
<div
class="
relative inline-block max-w-[50%] rounded-2xl bg-sb-primary px-3 py-2 shadow-sm ring-1 ring-ss-secondary
before:absolute before:-bottom-[2px] before:-start-5 before:z-0 before:box-content before:h-6 before:w-5 before:rounded-ee-[16px_12px] before:border-e-[10px] before:border-sb-primary before:text-ss-secondary before:drop-shadow-[-1px_0]
after:absolute after:-bottom-[2px] after:-start-5 after:-z-10 after:box-content after:h-6 after:w-5 after:rounded-ee-[16px_12px] after:border-e-[10px] after:text-ss-secondary after:drop-shadow-[0_1px]
"
>
<RichTextRenderer content={message.content} class="z-10" />
</div>
</div>
</div>