In-app Chat Kit
  • iOS
  • Android
  • Web
  • Flutter : Dart
  • React Native
  • Overview
  • Quick start
  • UI components
    • Overview
    • Conversation component
    • Message component
  • Advanced features

Message component

Last updated:2023-09-23 00:57

The message component of the In-app Chat Kit provides the message list and message transmission features.

  • Message list: Allow you to view the message history of a chat.
  • Message transmission: Allow you to send or receive one-to-one messages and group messages.

Integrate the message component into your project

Prerequisites

Integrate the In-app Chat Kit SDK into your project (finished the initialization and login are required). For more information, see Quick start.

Add the MessageList component

In the file that needs to use the MessageList component, use the ZIMKitMessageListPage widget.

(The ZIMKitMessageListPage widget consists of the appBar, ZIMKitMessageListView component, and the ZIMKitMessageInput component.)

import 'package:zego_zimkit/zego_zimkit.dart';

class YourMessagePage extends StatelessWidget {
  const YourMessagePage({Key? key, required this.conversationID, required this.conversationType})
      : super(key: key);

  final String conversationID;
  final ZIMConversationType conversationType;

  @override
  Widget build(BuildContext context) {
    return ZIMKitMessageListPage(
      conversationID: conversationID,
      conversationType: conversationType,
    );
  }
}

Customize features/UI

If the default message-relevant features, behaviors or UI don’t fully meet your needs, we allow you to flexibly customize those through the parameters provided by the ZIMKitMessageListView and ZIMKitMessageInput mentioned in this section.

ZIMKitMessageListPage has all the parameters of ZIMKitMessageListView and ZIMKitMessageInput, so you can pass any parameters to ZIMKitMessageListView and ZIMKitMessageInput through ZIMKitMessageListPage.

The usage of commonly used parameters is as follows:

1. Custom message UI

The UI of each message can be customized, to do so, you can use the messageItemBuilder. The parameter types are as follows:

final Widget Function(BuildContext context, ZIMKitMessage message, Widget defaultWidget)? messageItemBuilder;

In addition to fully customizing the message item, you can also change the primaryColor of the default message widget to yellow. The code is as follows:

ZIMKitMessageListPage(
  conversationID: conversation.id,
  conversationType: conversation.type,

  messageItemBuilder: (context, message, defaultWidget) {
    return Theme(
      data: ThemeData(primaryColor: Colors.yellow),
      child: defaultWidget,
    );
  },
);
2. Custom press and long press events

To customize the press and long press events for a message, use the onMessageItemPressd and onMessageItemLongPress. The parameter types are as follows:

final void Function(BuildContext context, ZIMKitMessage message, Function defaultAction)? onMessageItemPressd;
final void Function(BuildContext context, ZIMKitMessage message, Function defaultAction)? onMessageItemLongPress;

For example, you can implement functions such as a full-screen preview of images and file download by customizing click and long-press events like this:

ZIMKitMessageListPage(
  conversationID: conversation.id,
  conversationType: conversation.type,

  onMessageItemLongPress: (context, message, defaultAction) {
    debugPrint('onMessageItemLongPress: ${message.hashCode}');
    defaultAction();
  },
  onMessageItemPressd: (context, message, defaultAction) {
    debugPrint('onMessageItemPressd: ${message.hashCode}');
    defaultAction();
  },
);
3. Custom app bar of message list page

To customize the app bar, you can use appBarActions or appBarBuilder. The parameter types are as follows:

final List<Widget>? appBarActions;
final AppBar? Function(BuildContext context, AppBar defaultAppBar)? appBarBuilder;

For example, adding a call button to the app bar, and the preview effect is as follows:

Here are two ways to achieve this:

  1. To add a few buttons to the app bar, use the appBarActions parameter. The sample code is as follows:
ZIMKitMessageListPage(
  conversationID: conversation.id,
  conversationType: conversation.type,
  appBarActions: [
    IconButton(icon: const Icon(Icons.local_phone), onPressed: () {}),
    IconButton(icon: const Icon(Icons.videocam), onPressed: () {}),
  ],
);
  1. To fully customize the app bar, use the appBarBuilder parameter. The sample code is as follows:
ZIMKitMessageListPage(
  conversationID: conversation.id,
  conversationType: conversation.type,
  appBarBuilder: (context, defaultAppBar) {
    return AppBar(
      title: Row(
        children: [
          CircleAvatar(child: conversation.icon),
          const SizedBox(width: 15),
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text(conversation.name, style: const TextStyle(fontSize: 16), overflow: TextOverflow.clip),
              Text(conversation.id, style: const TextStyle(fontSize: 12), overflow: TextOverflow.clip)
            ],
          )
        ],
      ),
      actions: [
        IconButton(icon: const Icon(Icons.local_phone), onPressed: () {}),
        IconButton(icon: const Icon(Icons.videocam), onPressed: () {}),
      ],
    );
  },
);
  • If you don't need to show the app bar, you can return null in the appBarBuilder.
ZIMKitMessageListPage(
  conversationID: conversation.id,
  conversationType: conversation.type,
  appBarBuilder: (context, defaultAppBar) {
    return null;
  },
);
4. Custom input field style

The input field uses the TextField component in Flutter. To customize the style of the TextField, pass the InputDecoration parameter to the component through the MessageListPage. The following shows the sample code and effect:

ZIMKitMessageListPage(
  conversationID: conversation.id,
  conversationType: conversation.type,
  inputDecoration: const InputDecoration(hintText: 'Type message here...'),
);
5. Custom input background style

You can customize the input background style using inputBackgroundDecoration.

The following shows the sample code:

ZIMKitMessageListPage(
  conversationID: conversation.id,
  conversationType: conversation.type,
  inputBackgroundDecoration: BoxDecoration(borderRadius: BorderRadius.circular(40)),
);
6. Custom input field buttons
  1. To hide the default buttons, use the following:
  • showPickFileButton: whether to show the PickFileButton, which is shown by default.
  • showPickMediaButton: whether to show the PickMediaButton, which is shown by default.

Sample code:

ZIMKitMessageListPage(
  conversationID: conversation.id,
  conversationType: conversation.type,
  showPickFileButton: false,
  showPickMediaButton: true,
);
  1. To customize the style of default buttons, use the following:
  • sendButtonWidget: customize the style of the send button.
  • pickMediaButtonWidget: customize the style of the media pick button.
  • pickFileButtonWidget: customize the style of the file pick button.

Sample code:

ZIMKitMessageListPage(
  conversationID: conversation.id,
  conversationType: conversation.type,
  showPickFileButton: true,
  showPickMediaButton: true,
  sendButtonWidget: const Icon(Icons.send),
  pickMediaButtonWidget: const Icon(Icons.photo_library),
  pickFileButtonWidget: const Icon(Icons.attach_file),
);
  1. To add your customized buttons, use the messageInputActions. For example, to add a microphone button and an emoji button on the left side of the input field, use the following sample code:
ZIMKitMessageListPage(
  conversationID: conversation.id,
  conversationType: conversation.type,
  messageInputActions: [
    ZIMKitMessageInputAction.left(
      IconButton(icon: const Icon(Icons.mic), onPressed: () {}),
    ),
    ZIMKitMessageInputAction.leftInside(
      IconButton(icon: const Icon(Icons.sentiment_satisfied_alt_outlined), onPressed: () {}),
    ),
  ],
);

As shown in the sample code, you can specify the position of the custom button relative to the TextField by using ZIMKitMessageInputAction.left, ZIMKitMessageInputAction.right, ZIMKitMessageInputAction.leftInside, and ZIMKitMessageInputAction.rightInside. Its position is as follows:

7. Custom message list background

You can customize the message list background using inputBackgroundDecoration.

The following shows the sample code:

ZIMKitMessageListPage(
  conversationID: conversation.id,
  conversationType: conversation.type,
  messageListBackgroundBuilder: (context, defaultWidget) {
    return YourCustomBackgroundWidget();
  },
);
Click to view the full interface list
  1. messageListErrorBuilder: this can be used to customize the UI when error loading the message list.

  2. messageListLoadingBuilder: this can be used to customize the UI when loading the message list.

  3. preMessageSending: callback for the message not sent yet.

The following methods can be called using ZIMKit() syntax, such as ZIMKit().deleteMessage().

Delete Messages & Recall Messages
  1. deleteMessage: Only delete local messages, after deletion, you cannot see the message yourself.
  2. recallMessage: Recall messages, can only recall messages sent by yourself, after recall, users in the conversation cannot see the message anymore.

By default, In-app Chat Kit supports recalling messages sent in 2 minutes. If you want to modify the configuration (you can recall messages sent in up to 24 hours), contact ZEGOCLOUD technical support.

Refer to the example code in _onMessageItemLongPress:

class ZIMKitDemoHomePage extends StatelessWidget {
  const ZIMKitDemoHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async => false,
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Conversations'),
          actions: const [HomePagePopupMenuButton()],
        ),
        body: ZIMKitConversationListView(
          onPressed: (context, conversation, defaultAction) {
            Navigator.push(context, MaterialPageRoute(
              builder: (context) {
                return ZIMKitMessageListPage(
                  conversationID: conversation.id,
                  conversationType: conversation.type,
                  onMessageItemLongPress: _onMessageItemLongPress,
                );
              },
            ));
          },
        ),
      ),
    );
  }

  Future<void> _onMessageItemLongPress(
    BuildContext context,
    LongPressStartDetails details,
    ZIMKitMessage message,
    Function defaultAction,
  ) async {
    showCupertinoDialog(
      context: context,
      barrierDismissible: true,
      builder: (context) {
        return CupertinoAlertDialog(
          title: const Text('Confirme'),
          content: const Text('Delete or recall this message?'),
          actions: [
            CupertinoDialogAction(
              onPressed: Navigator.of(context).pop,
              child: const Text('Cancel'),
            ),
            CupertinoDialogAction(
              onPressed: () {
                ZIMKit().deleteMessage([message]);
                Navigator.pop(context);
              },
              child: const Text('Delete'),
            ),
            CupertinoDialogAction(
              onPressed: () {
                ZIMKit().recallMessage(message).catchError((error) {
                  ScaffoldMessenger.of(context).showSnackBar(
                    SnackBar(content: Text(error.toString())),
                  );
                });
                Navigator.pop(context);
              },
              child: const Text('Recall'),
            ),
          ],
        );
      },
    );
  }
}

The default effect when a message is recalled:

To hide the prompt for a recalled message ("Recalled a message" in the above image) or to customize the prompt style for recalling messages, you can use messageItemBuilder for customization. Here is an example code snippet to hide the display of recalled messages:

class ZIMKitDemoHomePage extends StatelessWidget {
  const ZIMKitDemoHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async => false,
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Conversations'),
          actions: const [HomePagePopupMenuButton()],
        ),
        body: ZIMKitConversationListView(
          onPressed: (context, conversation, defaultAction) {
            Navigator.push(context, MaterialPageRoute(
              builder: (context) {
                return ZIMKitMessageListPage(
                  conversationID: conversation.id,
                  conversationType: conversation.type,
                  messageItemBuilder: (context, message, defaultWidget) {
                    // *****  hide the display of recalled messages
                    if (message.type == ZIMMessageType.revoke) {
                      return const SizedBox.shrink();
                    } else {
                      return defaultWidget;
                    }
                  },
                );
              },
            ));
          },
        ),
      ),
    );
  }
}
Page Directory