feat: 1-to-1 message render + web data-lake backend
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
<script lang="ts">
|
||||
import { getPeer } from "$lib/api/endpoints";
|
||||
import type { PeerView } from "$lib/api/types";
|
||||
import Avatar from "$lib/components/ui/Avatar.svelte";
|
||||
import { peerName } from "$lib/format/peer";
|
||||
import { accounts } from "$lib/stores/accounts.svelte";
|
||||
import { chats } from "$lib/stores/chats.svelte";
|
||||
|
||||
interface Props {
|
||||
chatId: number;
|
||||
}
|
||||
|
||||
let { chatId }: Props = $props();
|
||||
|
||||
const isDm = $derived(chatId > 0);
|
||||
const chat = $derived(chats.byId(chatId));
|
||||
let peer = $state<PeerView | null>(null);
|
||||
|
||||
$effect(() => {
|
||||
if (accounts.selectedId === null || !isDm) {
|
||||
peer = null;
|
||||
return;
|
||||
}
|
||||
let active = true;
|
||||
peer = null;
|
||||
getPeer(chatId)
|
||||
.then((result) => {
|
||||
if (active) {
|
||||
peer = result;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
if (active) {
|
||||
peer = null;
|
||||
}
|
||||
});
|
||||
return () => {
|
||||
active = false;
|
||||
};
|
||||
});
|
||||
|
||||
const fallbackTitle = $derived(chat?.title ?? `Chat ${chatId}`);
|
||||
const title = $derived(isDm && peer ? peerName(peer) : fallbackTitle);
|
||||
const subtitle = $derived.by(() => {
|
||||
if (isDm) {
|
||||
if (peer?.username) {
|
||||
return `@${peer.username}`;
|
||||
}
|
||||
return peer?.phone ?? `ID ${chatId}`;
|
||||
}
|
||||
const count = chat?.message_count ?? 0;
|
||||
return count > 0 ? `${count} messages` : "group";
|
||||
});
|
||||
const avatarKind = $derived(isDm ? "peer" : "chat");
|
||||
const hasAvatar = $derived(chat?.has_avatar ?? Boolean(peer?.has_avatar));
|
||||
</script>
|
||||
|
||||
<header class="chat-header">
|
||||
<Avatar
|
||||
name={title}
|
||||
colorKey={chatId}
|
||||
size={2.5}
|
||||
avatar={{ kind: avatarKind, id: chatId }}
|
||||
{hasAvatar}
|
||||
deleted={peer?.is_deleted_account ?? false}
|
||||
/>
|
||||
<div class="info">
|
||||
<h2 class="title">{title}</h2>
|
||||
<span class="subtitle">{subtitle}</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<style lang="scss">
|
||||
.chat-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.625rem;
|
||||
|
||||
height: var(--header-height);
|
||||
padding: 0 1rem;
|
||||
border-bottom: 1px solid var(--color-borders);
|
||||
|
||||
background-color: var(--color-background);
|
||||
}
|
||||
|
||||
.info {
|
||||
overflow: hidden;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
overflow: hidden;
|
||||
margin: 0;
|
||||
font-size: 1rem;
|
||||
font-weight: var(--font-weight-medium);
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 0.8125rem;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user