vue-advanced-chat

repository·main·Indexed 24 days ago

https://github.com/advanced-chat/vue-advanced-chat

A highly customizable, backend-agnostic real-time chat UI component compatible with Vue, React, and Angular. Version 2.0.9 provides a comprehensive chat rooms interface featuring support for light/dark themes, markdown-like text formatting, file uploads, emoji reactions, and internationalization via the text-messages prop.

Tokens
10.7K
Snippets
15
Records
37
Agent score
80%

What's inside vue-advanced-chat

  1. Customize vue-advanced-chat using Named Slots

    main

    You can customize the appearance and behavior of vue-advanced-chat by providing custom templates via named slots. Slots can be static (e.g., room-header) or dynamic, requiring specific IDs for rooms or messages (e.g., message_{{MESSAGE_ID}}).

    Common slot categories include:

    • Layout & Headers: rooms-header, room-header, no-room-selected, messages-empty.
    • List Items: room-list-item_{{ROOM_ID}}, room-list-avatar_{{ROOM_ID}}, room-list-info_{{ROOM_ID}}.
    • Messages: message_{{MESSAGE_ID}}, message-avatar_{{MESSAGE_ID}}, message-failure_{{MESSAGE_ID}}.
    • Icons: send-icon, paperclip-icon, search-icon, menu-icon, and various spinner icons like spinner-icon-messages.
    • Empty States: rooms-empty, messages-empty.
    <vue-advanced-chat>
      <div slot="room-header">
        This is a new room header
      </div>
    
      <div v-for="message in messages" :slot="'message_' + message._id">
        <div v-if="message.system">
          System message: {{ message.content }}
        </div>
        <div v-else>
          Normal message: {{ message.content }}
        </div>
      </div>
    
      <div v-for="message in messages" :slot="'message-avatar_' + message._id">
        New Avatar
      </div>
    </vue-advanced-chat>
  2. Performance Best Practices for Data Updates

    main

    The vue-advanced-chat component is performance-oriented and requires specific patterns for updating arrays to ensure reactivity and proper rendering.

    Array Assignment

    Avoid using methods like .push() directly on the reactive arrays. Instead, use array assignment or the spread operator to trigger updates.

    Correct patterns:

    • Reassign the entire array: this.rooms = [...newRooms]
    • Reassign a specific index: this.rooms[roomIndex] = room
    • Use spread for nested updates: this.rooms[i].typingUsers = [...this.rooms[i].typingUsers, typingUserId]

    Incorrect patterns:

    • this.rooms.push(room)
    • this.rooms[roomIndex] = room (without reassigning the parent array)
    • this.rooms[i].typingUsers.push(typingUserId)

    UI Loading Pattern

    To ensure the UI handles loading states correctly, update the messagesLoaded prop every time a new room is fetched.

    // Follow the UI loading pattern by updating messagesLoaded prop every time a new room is fetched
    fetchMessages({ room, options }) {
      this.messagesLoaded = false
    
      // use timeout to imitate async server fetched data
      setTimeout(() => {
        this.messages = []
        this.messagesLoaded = true
      })
    }
  3. Install vue-advanced-chat

    main

    You can install vue-advanced-chat using npm, yarn, or via a CDN link.

    # Using npm
    npm install --save vue-advanced-chat
    
    # Using yarn
    yarn add vue-advanced-chat
    
    # Using CDN
    <script src="https://cdn.jsdelivr.net/npm/vue-advanced-chat@2.0.4/dist/vue-advanced-chat.umd.js"></script>
  4. Recommended development environment for chatkitty

    main

    For the best development experience with this Vue 3 project, use the following tools:

    IDE Setup:

    Browser Setup:

    • Chromium-based (Chrome, Edge, Brave): Install Vue.js devtools and enable the 'Custom Object Formatter' in Chrome DevTools.
    • Firefox: Install Vue.js devtools and enable 'Custom Object Formatter' in Firefox DevTools.
  5. Configure vue-advanced-chat for Vue (Vite/Web Components)

    main

    When using Vue, you must register vue-advanced-chat and emoji-picker as custom elements in your compiler options (e.g., in vite.config.js) to prevent Vue from attempting to resolve them as standard components.

    compilerOptions: {
      isCustomElement: tagName => {
        return tagName === 'vue-advanced-chat' || tagName === 'emoji-picker'
      }
    }
  6. Integrate with ChatKitty

    main

    ChatKitty provides a full-featured UI that integrates with vue-advanced-chat. You can manage your chat backend and UI customization via the ChatKitty console.

    Setup Steps

    1. Create a ChatKitty account at https://console.chatkitty.com.
    2. Create a project and obtain your widgetId.
    3. Install the ChatKitty Vue package:
      npm install @chatkitty/vue
    4. Use the ChatUi component in your Vue application.

    Configuration

    • Set widgetId to your project's widget ID.
    • Set username to the current user's username.
    • Use mode="sandbox" for development (remove this in production).

    Customization

    To use vue-advanced-chat specific themes and features, set the feature schema version to vue-advanced-chat@2 in your ChatKitty project settings. You can also customize styles in the ChatKitty console by setting the styles schema version to vue-advanced-chat@2 and modifying the styles key.

    <script setup>
    import {ChatUi} from '@chatkitty/vue'
    </script>
    
    <template>
      <div style="width: 100vw; height: 100svh">
        <!-- Replace widgetId with your widget ID from console.chatkitty.com -->
        <!-- Set username to the current user's username -->
        <!-- Remove mode="sandbox" in production environment -->
        <ChatUi
          widgetId="5IKgX7UHsLr1cWJ5"
          username=username
          mode="sandbox"/>
      </div>
    </template>
  7. Implement with Firebase/Firestore

    main

    To build a chat app using Firebase/Firestore, you must follow a specific data structure for your collections. A full implementation example is available in the demo/firebase folder of this repository.

    Setup Instructions

    1. Setup Cloud Firestore (for users and rooms) and Realtime Database (for online status).
    2. Clone the repository: git clone https://github.com/advanced-chat/vue-advanced-chat.git.
    3. In demo/firebase/src/database/index.js, replace the config object with your own Firebase configuration.
    4. Navigate to demo/firebase and run npm run serve.

    Required Firestore Data Structure

    Users Collection

    users: {
      USER_ID_1: { _id: '1', username: 'User 1' },
      USER_ID_2: { _id: '2', username: 'User 2' }
    }

    Rooms Collection

    chatRooms: {
      ROOM_ID_1: { users: ['1', '3'] },
      ROOM_ID_2: { users: ['1', '2', '3'] }
    }

    Messages Collection (inside a room document)

    messages: {
      MESSAGE_ID_1: {
        content: 'My first message to <usertag>John</usertag>',
        senderId: '2',
        timestamp: 'December 11, 2019 at 4:00:00 PM',
        seen: true
      }
    }

    Note: You must create a composite index to order rooms by the last message received. You can generate this by clicking the error URL provided in your browser's debugging console after attempting to create a room.

  8. Basic Usage of vue-advanced-chat

    main

    To use the component, first call the register() function. The component expects its main data props (rooms, messages, and roomActions) to be passed as JSON strings.

    <template>
      <vue-advanced-chat
        :current-user-id="currentUserId"
        :rooms="JSON.stringify(rooms)"
        :messages="JSON.stringify(messages)"
        :room-actions="JSON.stringify(roomActions)"
      />
    </template>
    
    <script>
      import { register } from 'vue-advanced-chat'
      register()
    
      // Or if you used CDN import
      // window['vue-advanced-chat'].register()
    
      export default {
        data() {
          return {
            currentUserId: '1234',
            rooms: [],
            messages: [],
            roomActions: [
              { name: 'inviteUser', title: 'Invite User' },
              { name: 'removeUser', title: 'Remove User' },
              { name: 'deleteRoom', title: 'Delete Room' }
            ]
          }
        }
      }
    </script>
  9. Implement custom action handlers

    main

    When using the room-actions, menu-actions, message-actions, or message-selection-actions props, you must implement the corresponding event handlers to execute your logic.

    Example: Handling Menu Actions

    menuActionHandler({ roomId, action }) {
      switch (action.name) {
        case 'inviteUser':
          // call a method to invite a user to the room
        case 'removeUser':
          // call a method to remove a user from the room
        case 'deleteRoom':
          // call a method to delete the room
      }
    }

    Example: Handling Message Actions

    messageActionHandler({ roomId, action, message }) {
      switch (action.name) {
        case 'addMessageToFavorite':
          // call a method to add a message to the favorite list
        case 'shareMessage':
          // call a method to share the message with another user
      }
    }
    menuActionHandler({ roomId, action }) {
      switch (action.name) {
        case 'archiveRoom':
          // call a method to archive the room
      }
    }
    
    messageActionHandler({ roomId, action, message }) {
      switch (action.name) {
        case 'addMessageToFavorite':
          // call a method to add a message to the favorite list
        case 'shareMessage':
          // call a method to share the message with another user
      }
    }