feat: chat detail frame

This commit is contained in:
Shibo Lyu 2024-08-30 16:58:03 +08:00
parent 78339cd0b9
commit 793217a2a0
10 changed files with 176 additions and 51 deletions

View file

@ -1,4 +1,5 @@
<script lang="ts">
import { formatMessageDate, formatUnreadCount } from '$lib/formatters';
import { AvatarBeam } from 'svelte-boring-avatars';
export let chat: {
@ -7,38 +8,6 @@
lastMessage: { sender: { id: string; name: string }; content: string; date: Date };
unreadCount?: number;
};
const sameDayFormatter = new Intl.DateTimeFormat('default', {
hour: '2-digit',
minute: '2-digit'
});
const sameYearFormatter = new Intl.DateTimeFormat('default', {
month: 'short',
day: 'numeric'
});
const otherYearFormatter = new Intl.DateTimeFormat('default', {
year: 'numeric',
month: 'short',
day: 'numeric'
});
const formatDate = (date: Date) => {
const now = new Date();
if (date.getFullYear() === now.getFullYear()) {
if (date.getMonth() === now.getMonth() && date.getDate() === now.getDate()) {
return sameDayFormatter.format(date);
} else {
return sameYearFormatter.format(date);
}
} else {
return otherYearFormatter.format(date);
}
};
const unreadCountFormatter = new Intl.NumberFormat('default', {
notation: 'compact',
compactDisplay: 'short'
});
</script>
<li
@ -51,7 +20,13 @@
<div class="relative min-w-0 flex-1">
<div class="flex items-center gap-1">
<h3 class="flex-1 truncate text-sm font-semibold">{chat.name}</h3>
<time class="truncate text-xs text-sf-tertiary">{formatDate(chat.lastMessage.date)}</time>
<time
class="truncate text-xs text-sf-tertiary"
datetime={chat.lastMessage.date.toISOString()}
title={formatMessageDate(chat.lastMessage.date, true)}
>
{formatMessageDate(chat.lastMessage.date)}
</time>
</div>
<div class="flex items-end gap-1">
<p class="line-clamp-2 h-[2.5em] text-sm leading-tight text-sf-secondary">
@ -64,7 +39,7 @@
<span
class="whitespace-nowrap rounded-full bg-slate-400 px-1.5 py-0.5 text-xs text-slate-50 dark:bg-slate-500 dark:text-slate-950"
>
{unreadCountFormatter.format(chat.unreadCount)}
{formatUnreadCount(chat.unreadCount)}
</span>
{/if}
</div>

View file

@ -1,6 +1,15 @@
<script lang="ts">
import { page } from '$app/stores';
import Button from '$lib/components/Button.svelte';
import BgPattern from '$lib/components/BgPattern.svelte';
import ChatHeader from './ChatHeader.svelte';
import ChatInput from './ChatInput.svelte';
</script>
<p><Button href="/">Close</Button> History Page for {$page.params.chatId}</p>
<div class="flex h-full w-full flex-col justify-stretch">
<ChatHeader
chat={{ id: 'blah', name: 'Blah IM Interest Group', type: 'group' }}
outsideUnreadCount={263723}
/>
<BgPattern class="flex-1" pattern="charlieBrown"></BgPattern>
<ChatInput />
</div>

View file

@ -0,0 +1,32 @@
<script lang="ts">
import Button from '$lib/components/Button.svelte';
import { formatUnreadCount } from '$lib/formatters';
import type { Chat } from '$lib/types';
import { AvatarBeam } from 'svelte-boring-avatars';
export let chat: Chat;
export let outsideUnreadCount = 0;
</script>
<div class="flex w-full gap-2 border-b border-ss-secondary bg-sb-primary p-2 shadow-sm">
<Button href="/" class="rounded-full sm:hidden">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="-me-0.5 -ms-1 size-5"
>
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5 8.25 12l7.5-7.5" />
</svg>
{#if outsideUnreadCount}
<span class="text-xs text-sf-tertiary">{formatUnreadCount(outsideUnreadCount)}</span>
{/if}
<span class="sr-only">Back</span>
</Button>
<div class="flex flex-1 flex-col justify-center text-center">
<h3 class="truncate text-sm font-semibold">{chat.name}</h3>
</div>
<AvatarBeam size={30} name={chat.name} />
</div>

View file

@ -0,0 +1,43 @@
<script lang="ts">
import Button from '$lib/components/Button.svelte';
import RichTextInput from '$lib/components/RichTextInput.svelte';
import type { Delta } from 'typewriter-editor';
let delta: Delta | null = null;
</script>
<div class="flex items-end gap-2 border-t border-ss-secondary bg-sb-primary p-2 shadow-sm">
<Button class="p-1.5">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="size-5"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="m18.375 12.739-7.693 7.693a4.5 4.5 0 0 1-6.364-6.364l10.94-10.94A3 3 0 1 1 19.5 7.372L8.552 18.32m.009-.01-.01.01m5.699-9.941-7.81 7.81a1.5 1.5 0 0 0 2.112 2.13"
/>
</svg>
<span class="sr-only">Attach</span>
</Button>
<RichTextInput bind:delta placeholder="Message" class="max-h-40 flex-1" />
<Button
class="before:from-accent-400 before:to-accent-500 relative p-1.5 ring-0 before:absolute before:-inset-px before:rounded-[7px] before:bg-gradient-to-b before:from-40% before:ring-1 before:ring-inset before:ring-black/10"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
class="z-10 size-5 text-slate-50 drop-shadow-[0_-1px_0_theme(colors.black/0.2)]"
>
<path
d="M3.478 2.404a.75.75 0 0 0-.926.941l2.432 7.905H13.5a.75.75 0 0 1 0 1.5H4.984l-2.432 7.905a.75.75 0 0 0 .926.94 60.519 60.519 0 0 0 18.445-8.986.75.75 0 0 0 0-1.218A60.517 60.517 0 0 0 3.478 2.404Z"
/>
</svg>
<span class="sr-only">Send</span>
</Button>
</div>