Skip to content

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 tab

Features

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

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
  }}
/>

Released under the MIT License.