ChatView Flutter Package

repository·main·Indexed 18 days ago

https://github.com/simformsolutionspvtltd/chatview

A highly customizable Flutter package for integrating professional chat interfaces. It provides two primary UI components: ChatList for displaying conversation lists with pagination and search, and ChatView for active messaging with support for one-on-one and group chats, message reactions, replies, and media sharing. It can be integrated with backends like Firebase using the chatview_connect package.

Tokens
17.9K
Snippets
39
Records
47
Agent score
63%

What's inside ChatView

  1. Overview of ChatView features

    main

    ChatView provides two primary UI components for chat applications:

    ChatList

    Used for displaying a list of conversations. Features include:

    • Smooth animations for adding, removing, and pinning chats.
    • Pagination for large histories and search functionality.
    • Long press menus (pin, mute).
    • Online status indicators and unread message badges.
    • Header and Footer support.

    ChatView

    Used for the actual messaging interface. Features include:

    • One-on-one and group chat support.
    • Message reactions (emojis), replies, and editing.
    • Link previews, voice messages, and image sharing.
    • Custom message types and typing indicators.
    • Message status indicators (sent, delivered, read).
  2. Handle Reply Messages and Historical Loading

    main

    Configure how replies are displayed and how the app fetches older messages when a user taps a reply.

    • RepliedMessageConfiguration: Allows customizing the backgroundColor, verticalBarColor, and repliedMsgAutoScrollConfig (to highlight the original message when scrolling to it).
    • Loading Old Messages: The loadOldReplyMessage callback is triggered when a user taps a reply to a message that is not currently in the loaded list.

    Best Practice: When fetching historical messages, aim to load a range that places the target messageId in the middle of the new list (e.g., if target is 25 and page size is 20, fetch IDs 15 to 35). Use chatController.replaceMessageList(historicalMessages) to update the view.

    repliedMessageConfig: RepliedMessageConfiguration(
      loadOldReplyMessage: (messageId) async {
        try {
          final historicalMessages = await _apiService.getMessagesAroundId(
            messageId: messageId,
            limit: 20,
          );
          _chatController.replaceMessageList(historicalMessages);
        } catch (error) {
          debugPrint('Failed to load old reply message: $error');
        }
      },
      backgroundColor: Colors.blue,
      verticalBarColor: Colors.black,
      repliedMsgAutoScrollConfig: RepliedMsgAutoScrollConfig(
        enableHighlightRepliedMsg: true,
        highlightColor: Colors.grey,
        highlightScale: 1.1,
      ),
    ),
  3. Quickstart: Integrate ChatView

    main

    Follow these steps to implement a basic chat interface:

    1. Create a ChatController: This manages the message list, scroll controller, current user, and other users.
    2. Define your Message list: Create a List<Message> containing your initial data.
    3. Add the ChatView widget: Pass the chatController, an onSendTap callback, and the current chatViewState (e.g., ChatViewState.hasMessages).
    4. Implement onSendTap: Handle new messages by creating a Message object and calling chatController.addMessage(newMessage).
    // 1. Create Controller
    final chatController = ChatController(
      initialMessageList: messageList,
      scrollController: ScrollController(),
      currentUser: ChatUser(id: '1', name: 'Flutter'),
      otherUsers: [ChatUser(id: '2', name: 'Simform')],
    );
    
    // 2. Define Messages
    List<Message> messageList = [
      Message(id: '1', message: "Hi", createdAt: DateTime.now(), sentBy: '1'),
    ];
    
    // 3. Use Widget
    ChatView(
      chatController: chatController,
      onSendTap: (message, replyMessage, messageType) {
        final newMessage = Message(
          id: '3',
          message: message,
          createdAt: DateTime.now(),
          sentBy: chatController.currentUser.id,
          replyMessage: replyMessage,
          messageType: messageType,
        );
        chatController.addMessage(newMessage);
      },
      chatViewState: ChatViewState.hasMessages,
    )
  4. Configure iOS permissions for Image Picker and Voice Messages

    main

    If you are using image picking or voice message features, you must add the following keys to your ios/Runner/Info.plist file to request user permissions:

    <key>NSCameraUsageDescription</key>
    <string>Used to demonstrate image picker plugin</string>
    <key>NSMicrophoneUsageDescription</key>
    <string>Used to capture audio for image picker plugin</string>
    <key>NSPhotoLibraryUsageDescription</key>
    <string>Used to demonstrate image picker plugin</string>

    Note for Voice Messages:

    • This plugin requires iOS 13.0 or higher. Ensure your ios/Podfile has the following line:
      platform :ios, '13.0'
    • If using the specific permission string for voice messages, use: <string>This app requires Mic permission.</string>
  5. Send images with text messages

    main

    To allow users to attach images to their text messages, enable the shouldSendImageWithText flag within the SendMessageConfiguration object passed to sendMessageConfig.

    You can also customize the UI of the image preview before sending by providing a custom widget to the selectedImageViewBuilder field. This builder provides the list of selected images and an onImageRemove callback to handle image deletion.

    sendMessageConfig: SendMessageConfiguration(
      shouldSendImageWithText: true, // Enable sending images with text
      selectedImageViewBuilder: (images, onImageRemove) {
        if (images.isNotEmpty) {
          return SizedBox(
            width: MediaQuery.sizeOf(context).width,
            child: Stack(
              children: [
                Image.file(
                  File(images.first),
                  height: 100,
                ),
                Positioned(
                  right: 0,
                  top: 0,
                  child: IconButton(
                    icon: const Icon(Icons.close),
                    onPressed: () {
                      onImageRemove.call(imagePath: images.first);
                    },
                  ),
                ),
              ],
            ),
          );
        } else {
          return const SizedBox.shrink();
        }
      },
    ),
  6. Configure Android permissions for Voice Messages

    main

    To support voice messages on Android, perform the following two steps:

    1. Update android/app/build.gradle to set the minimum SDK version to 21 or higher:

      minSdkVersion 21
    2. Add the RECORD_AUDIO permission to your AndroidManifest.xml:

      <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    minSdkVersion 21
  7. Migrate VoiceRecordingConfiguration to version 3.0.0+

    main

    In version 3.0.0, VoiceRecordingConfiguration was updated to use RecorderSettings. This new structure encapsulates platform-specific settings for both iOS and Android. The androidOutputFormat property has been removed; the output format is now determined by the encoder used.

    Key changes:

    • Use recorderSettings instead of top-level properties.
    • Use androidEncoderSettings for Android-specific configurations.
    • Use iosEncoderSettings for iOS-specific configurations.
    // New Usage in 3.0.0+
    ChatView(
      sendMessageConfig: SendMessageConfiguration(
        voiceRecordingConfiguration: VoiceRecordingConfiguration(
            recorderSettings: RecorderSettings(
              bitRate: 128000,
              sampleRate: 44100,
              androidEncoderSettings: AndroidEncoderSettings(
                androidEncoder: AndroidEncoder.aacLc,
              ),
              iosEncoderSettings: IosEncoderSetting(
                iosEncoder: IosEncoder.kAudioFormatMPEG4AAC,
              ),
            ),
        ),
      ),
    ),
  8. Customize iOS Launch Screen Assets

    main

    To change the launch screen image for the iOS version of your Flutter application, you can use one of two methods:

    1. Direct File Replacement: Replace the existing image files located in the example/ios/Runner/Assets.xcassets/LaunchImage.imageset/ directory with your own assets.
    2. Xcode Asset Catalog:
      • Open your project's iOS workspace using open ios/Runner.xcworkspace.
      • In the Xcode Project Navigator, navigate to Runner/Assets.xcassets.
      • Drag and drop your desired images into the asset catalog to replace the launch images.
    open ios/Runner.xcworkspace
  9. Internationalize ChatView

    main

    ChatView supports custom locales. To add a new language, use PackageStrings.addLocaleObject with a ChatViewLocale object containing the translated strings, then activate it with PackageStrings.setLocale(localeCode).

    PackageStrings.addLocaleObject(
      'es',
      const ChatViewLocale(
        today: 'Hoy',
        yesterday: 'Ayer',
        repliedToYou: 'Te respondió',
        // ... other keys
      ),
    );
    
    PackageStrings.setLocale('es');
  10. Implement ChatList with basic setup

    main

    To integrate ChatList into your application, follow these three steps:

    1. Create a ChatListController

    Initialize the controller with your initial data and a ScrollController.

    2. Define your Chat List

    Create a list of ChatListItem objects containing user info, unread counts, and last messages.

    3. Add the ChatList Widget

    Pass the controller and configuration to the ChatList widget. You can use menuConfig to handle actions like deleting, muting, or pinning chats via callbacks.

    // 1. Create Controller
    ChatListController chatListController = ChatListController(
      initialChatList: chatList,
      scrollController: ScrollController(),
    );
    
    // 2. Define Data
    List<ChatListItem> chatList = [
      ChatListItem(
        id: '2',
        name: 'Simform',
        unreadCount: 2,
        lastMessage: Message(
          id: '12',
          sentBy: '2',
          message: "🤩🤩",
          createdAt: DateTime.now(),
          status: MessageStatus.delivered,
        ),
        settings: ChatSettings(
          pinTime: DateTime.now(),
          pinStatus: PinStatus.pinned,
        ),
      ),
    ];
    
    // 3. Add Widget
    ChatList(
      controller: chatListController,
      appbar: const ChatListAppBar(title: 'ChatList Demo'),
      menuConfig: ChatMenuConfig(
        deleteCallback: (chat) => chatListController.removeChat(chat.id),
        muteStatusCallback: (result) => chatListController.updateChat(
          result.chat.id,
          (previousChat) => previousChat.copyWith(
            settings: previousChat.settings.copyWith(
              muteStatus: result.status,
            ),
          ),
        ),
        pinStatusCallback: (result) => chatListController.updateChat(
          result.chat.id,
          (previousChat) => previousChat.copyWith(
            settings: previousChat.settings.copyWith(
              pinStatus: result.status,
            ),
          ),
        ),
      ),
      tileConfig: ListTileConfig(onTap: (chat) {}),
    )
  11. Integrate ChatView with a backend using chatview_connect

    main

    To make ChatView backend-ready and avoid boilerplate, use the chatview_connect package. This allows for easy integration with services like Firebase.

    Integration Steps:

    1. Set the Service Type.
    2. Set the User ID.
    3. Obtain the ChatManager.

    Note: This supports 1-on-1 and group chats with media uploads, but audio is not currently supported via this integration method.