Appearance
ChatList Component
- File: src/components/chat/chatList.svelte
Overview
The ChatList component provides a searchable list of chat groups with real-time filtering, user avatars, and last activity indicators. It includes a module-level query function for fetching chat groups and a component-level implementation for displaying and managing the chat list interface.
Type Definitions
Group Information Interface
ts
interface IGroupInfo {
id: number;
name: string;
specialty: string;
initials: string;
date: string;
lastActivity?: {
id: number;
date: string;
};
profileImageUrl?: string;
email?: string;
address?: string;
phoneNumber?: string;
participantCount?: number;
}Module Functions
readChatGroups
svelte
async function readChatGroups(groupName?: string): Promise<{
success: boolean;
data?: IGroupInfo[];
message?: string;
}> {
// Fetches chat groups using GraphQL
// Formats dates and initializes group data
// Returns formatted chat group information
}Component State
svelte
let busy = false; // Loading state
let chatGroups = []; // List of chat groups
let searchValue = ""; // Search input value
let debounceDelay = 500; // Search debounce delay
let activeTab = 'Chats'; // Current active tabFeatures
1. Search Functionality
svelte
// Debounced search implementation
const refresh = debounce(debounceDelay, refreshChatGroups);
// Reactive search
$: refresh(searchValue);2. Chat Group Refresh
svelte
async function refreshChatGroups(filter: string) {
busy = true;
try {
const ret = await readChatGroups(filter);
if (ret.success) {
chatGroups = ret.data;
} else {
showError(ret.message);
}
} finally {
busy = false;
}
}UI Components
1. Search Bar
svelte
<div class="search flex-grow">
<div class="bg-gray-100 rounded-lg h-10 p-2">
<Icon src={Search} size=15/>
<input
bind:value={searchValue}
placeholder="People, Groups"
class="flex-grow bg-gray-100 focus:outline-none"
/>
</div>
</div>2. Navigation Tabs
svelte
<div class="tags flex justify-around">
{#each tabs as tab}
<div on:click={() => activeTab = tab.text}>
<button class="{activeTab === tab.text ?
'bg-gradient-to-b from-[#257ec7] to-blue-400 text-white' :
''}">
<Icon src={tab.img} size="20"/>
</button>
<div class="text">{tab.text}</div>
</div>
{/each}
</div>2. Contact List
svelte
<div class="contact-list flex-grow flex flex-col">
{#each chatGroups as contact}
<div class="grid grid-cols-6 rounded-lg hover:bg-blue-50">
<!-- Avatar -->
<div class="avatar">
{#if contact.profileImageUrl}
<img src={contact.profileImageUrl} />
{:else}
<span>{contact.initials}</span>
{/if}
</div>
<!-- Contact Info -->
<div class="contact-info">
<div class="name">{contact.name}</div>
<div class="date">{contact.date}</div>
<div class="last-message">
{contact?.lastActivity?.content || ""}
</div>
</div>
</div>
{/each}
</div>Events
Dispatched Events
svelte
// When a contact is selected
dispatch('contactInfo', contact);Store Interactions
svelte
// Close chat view
function handleChat() {
$showChat = false;
}Styling
Layout Classes
css
.contact-list {
@apply flex-grow flex flex-col overflow-y-auto;
}
.avatar {
@apply rounded-full w-10 bg-[#99d3db];
}
.search input {
@apply flex-grow bg-gray-100 focus:outline-none ring-0 px-1;
}Date Formatting
Uses dayjs for intelligent date formatting:
Usage Example
svelte
<ChatList
on:contactInfo={(event) => {
const contact = event.detail;
// Handle contact selection
}}
/>