Appearance
MessageList Component
- File: src/components/chat/MessageList.svelte
Overview
The MessageList component handles the display and management of chat messages in both group and individual conversations. It supports regular chat groups and meeting-specific chats with features like message history, participant management, and real-time updates.
Type Definitions
Message Interface
ts
interface IMessage {
id: number; // Message identifier
content: string; // Message content
contentType: string; // Type of message
date: Date; // Timestamp
by: number; // Sender ID
mine: boolean; // Message ownership flag
isPrivate: boolean; // Private message indicator
targetName: string; // Target recipient name
}Module Functions
1. Message Retrieval
svelte
// Fetch chat messages
async function getChatMessages(groupId: number, myId: number) {
// Returns formatted chat messages with timestamps and ownership
}
// Fetch meeting messages
async function getMeetingMessages(meetingId: number, myId: number) {
// Returns meeting-specific messages with additional metadata
}
// Fetch participants
async function getParticipants(groupId: number, isMeeting: boolean) {
// Returns list of chat/meeting participants
}Component Props
svelte
export let contact; // Chat contact/group info
export let myId; // Current user ID
export let inCallView; // Call view mode flag
export let contacts; // List of contacts
export let chatTarget; // Current chat target
export let readonly; // Read-only mode flagFeatures
1. Message Management
svelte
async function refreshChatMessages() {
// Fetch and format messages
// Add timestamps and headers
// Handle message grouping
// Update message list
}2. Real-time Updates
svelte
// Subscribe to new messages
onMount(() => {
subscribe("onNewMessage", onNewMessage);
});
// Handle new messages
async function onNewMessage(data) {
if (data?.groupId == contact?.id ||
(isMeeting && data.eventId === contact?.id)) {
await refreshChatMessages();
}
}3. Message Sending
svelte
async function send({detail}) {
const payload = isMeeting
? { meetingId: contact.id }
: { groupId: +contact.id };
payload.content = detail.content;
payload.contentType = MessageContentType.text;
await sendMessage(payload);
await refreshChatMessages();
}UI Components
1. Header Section
svelte
<div class="flex justify-between mx-4 mt-2">
<!-- Back button -->
<!-- Contact avatar -->
<!-- Contact info -->
<!-- Details toggle -->
</div>2. Details Panel
svelte
{#if showDetails}
<div transition:slide={{duration:150}}>
<!-- Group participants or contact details -->
</div>
{/if}3. Message List
svelte
<div class="flex-grow overflow-y-auto" bind:this={scrollingDiv}>
{#each messages as message (message.id)}
<!-- Date headers -->
<ChatEntry
{message}
time={message.time}
participant={participantList[message.by]}
{isGroup}
/>
{/each}
</div>Auto-Scrolling
Implementation
svelte
let autoScroll;
beforeUpdate(() => {
autoScroll = scrollingDiv &&
(scrollingDiv.offsetHeight + scrollingDiv.scrollTop) >
(scrollingDiv.scrollHeight - 20);
});
afterUpdate(() => {
if (autoScroll) scrollingDiv.scrollTo(0, scrollingDiv.scrollHeight);
});Participant Management
State Management
svelte
let participants = [];
let participantList = {};
$: participantList = participants?.reduce((s, x) => {
s[x.id] = x;
return s;
}, {}) || {};