em_chat_uikit 1.0.0 copy "em_chat_uikit: ^1.0.0" to clipboard
em_chat_uikit: ^1.0.0 copied to clipboard

A set of ui components adapted to the chat sdk can quickly build a chat page and chat through the chat sdk by invoking the ui components.

Get Started with Chat UIKit for Flutter #

Overview #

Instant messaging connects people wherever they are and allows them to communicate with others in real time. With built-in user interfaces (UI) for the message list, the Chat UI Samples enables you to quickly embed real-time messaging into your app without requiring extra effort on the UI.

This page shows a sample code to add one-to-one chat and group chat messaging into your app by using the Flutter Chat UI Samples. 'em_chat_uikit' currently has two modular widgets:

ChatConversationsView ChatConversationsView lists the existing conversations. The avatar and nickname displayed on the conversation view can be returned through callbacks.

ChatMessagesView ChatMessagesView lists messages in the current conversation, including text, image, voice, and file messages. The avatar and nickname displayed on the message view can be returned through callbacks.

easemob offers an open-source em_chat_uikit project on GitHub. You can clone and run the project or refer to the logic in it to create projects integrating em_chat_uikit.

Source code URL of em_chat_uikit for Flutter:

https://github.com/easemob/em_chat_uikit

Function #

The em_chat_uikit library provides the following functions:

  • Sends and receives messages, displays messages, shows the unread message count, and clears messages. The text, image, emoji, file, and audio messages are supported.
  • Deletes conversations and messages.
  • Customizes the UI.
Widget Function Description
ChatUIKit The root of all widgets in ChatUIKit.
ChatConversationsView Conversation list Presents the conversation information, including the user's avatar and nickname, content of the last message, unread message count, and the time when the last message is sent or received.
Delete conversation Deletes the conversation from the conversation list.
ChatMessagesView Message sender Sends text, emoji, image, file, and voice messages.
Delete messages Deletes messages.
Recall message Recalls message that are sent within 120 seconds.
Display message Displays one-to-one messages and group messages, including the user's avatar and nickname and the message's content, sending time or reception time, sending status, and read status. The text, image, emoji, file, voice, and video messages can be displayed.

Dependencies #

The following third-party UI libraries are used in em_chat_uikit:

dependencies:
  im_flutter_sdk: 4.0.2
  image_picker: 0.8.6+4
  file_picker: 4.6.1
  record: 4.4.4
  audioplayers: 3.0.1
  common_utils: 2.1.0

Permissions #

Android #

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>

iOS #

In Info.plist, add the following permissions:

Key Type Value
Privacy - Microphone Usage Description String For microphone access
Privacy - Camera Usage Description String For camera access
Privacy - Photo Library Usage Description String For photo library access

Prevent code obfuscation #

In the example/android/app/proguard-rules.pro file, add the following lines to prevent code obfuscation:

-keep class com.hyphenate.** {*;}
-dontwarn  com.hyphenate.**

Integrate the UIKit #

pub.dev integration #

flutter pub add em_chat_uikit
flutter pub get

Local integration #

You can download the project to your computer and execute it.

dependencies:
    em_chat_uikit:
        path: `<#uikit path#>`

Usage #

Before calling ChatUIKit, you need to make sure that the flutter chat SDK is initialized and the ChatUIKit widget is at the top of you widget tree. You can add it in the MaterialApp builder.

ChatUIKit #

You must have a ChatUIKit widget at the top of you widget tree.

Prop Description
theme Chat UIKit theme for setting component styles. If this prop is not set, the default style will be used.
import 'package:em_chat_uikit/em_chat_uikit.dart';

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      builder: (context, child){
        return ChatUIKit(child: child!);
      },
      home: const MyHomePage(title: 'Flutter Demo'),
    );
  }
}

ChatConversationsView #

The 'ChatConversationsView' allows you to quickly display and manage the current conversations.

Prop Description
controller The ScrollController for the conversation list.
itemBuilder Conversation list item builder. Return a widget if you need to customize it.
avatarBuilder Avatar builder. If this prop is not implemented or you return null, the default avatar will be used.
nicknameBuilder Nickname builder. If you don't set this prop or return null, the conversation ID is displayed.
onItemTap The callback of the click event of the conversation list item.
class _ConversationsPageState extends State<ConversationsPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Conversations")),
      body: ChatConversationsView(
        onItemTap: (conversation) {
          Navigator.of(context)
              .push(
                MaterialPageRoute(
                  builder: (ctx) => ChatPage(conversation),
                ),
              )
              .then((value) => ChatUIKit.of(context)
                  .conversationsController
                  .loadAllConversations());
        },
      ),
    );
  }
}

For more information, see ChatConversationsView.

  const ChatConversationsView({
    super.key,
    this.onItemTap,
    this.controller,
    this.reverse = false,
    this.primary,
    this.physics,
    this.shrinkWrap = false,
    this.padding,
    this.cacheExtent,
    this.dragStartBehavior = DragStartBehavior.down,
    this.keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
    this.restorationId,
    this.clipBehavior = Clip.hardEdge,
    this.itemBuilder,
    this.avatarBuilder,
    this.nicknameBuilder,
  });

ChatMessagesView #

ChatMessagesView is used to manage text, image, emoji, file, and voice messages:

  • Sends and receives messages.
  • Deletes messages.
  • Recalls messages.
Prop Prop Description
inputBar Text input component. If you don't pass in this prop, ChatInputBar will be used by default.
conversation The conversation to which the messages belong.
onTap Message bubble click callback.
onBubbleLongPress Callback for holding a message bubble.
onBubbleDoubleTap Callback for double-clicking a message bubble.
avatarBuilder Avatar component builder.
nicknameBuilder Nickname component builder.
itemBuilder Message bubble. If you don't set this prop, the default bubble will be used.
moreItems Action items displayed after a message bubble is held down. If you return null in onBubbleLongPress, moreItems will be used. This prop involves three default actions: copy, delete, and recall.
messageListViewController Message list controller. You are advised to use the default value. For details, see ChatMessageListController.
willSendMessage Text message pre-sending callback. This callback needs to return a ChatMessage object.
onError Error callbacks, such as no permissions.
enableScrollBar Whether to enable the scroll bar. The scroll bar is enabled by default.
needDismissInputWidget Callback for dismissing the input widget. If you use a custom input widget, dismiss the input widget when you receive this callback, for example, by calling FocusNode.unfocus. See ChatInputBar.
inputBarMoreActionsOnTap The callback for clicking the plus symbol next to the input box. You need to return the ChatBottomSheetItems list.
class _ChatPageState extends State<ChatPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(widget.conversation.id)),
      body: SafeArea(
        child: ChatMessagesView(conversation: widget.conversation),
      ),
    );
  }
}

For more information, see ChatMessagesView.

  const ChatMessagesView({
    super.key,
    this.inputBar,
    required this.conversation,
    this.onTap,
    this.onBubbleLongPress,
    this.onBubbleDoubleTap,
    this.avatarBuilder,
    this.nicknameBuilder,
    this.titleAvatarBuilder,
    this.moreItems,
    this.messageListViewController,
    this.willSendMessage,
  });

Customize colors

You can set the color when adding ChatUIKit. See ChatUIKitTheme.

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      builder: (context, child) => ChatUIKit(
        theme: ChatUIKitTheme(),
        child: child!,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

Add an avatar

class _MessagesPageState extends State<MessagesPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(widget.conversation.id)),
      body: SafeArea(
        child: ChatMessagesView(
          conversation: widget.conversation,
          avatarBuilder: (context, userId) {
            // Returns the avatar widget that you want to display.
            return Container(
              width: 30,
              height: 30,
              color: Colors.red,
            );
          },
        ),
      ),
    );
  }
}

Add a nickname

class _MessagesPageState extends State<MessagesPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(widget.conversation.id)),
      body: SafeArea(
        child: ChatMessagesView(
          conversation: widget.conversation,
          // Returns the nickname widget that you want to display.
          nicknameBuilder: (context, userId) {
            return Text(userId);
          },
        ),
      ),
    );
  }
}

Add the bubble click event

class _MessagesPageState extends State<MessagesPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(widget.conversation.id)),
      body: SafeArea(
        child: ChatMessagesView(
          conversation: widget.conversation,
          onTap: (context, message) {
            bubbleClicked(message);
            return true;
          },
        ),
      ),
    );
  }

  void bubbleClicked(ChatMessage message) {
    debugPrint('bubble clicked');
  }
}

Customize the message item widget #

class _MessagesPageState extends State<MessagesPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(widget.conversation.id)),
      body: SafeArea(
        child: ChatMessagesView(
          conversation: widget.conversation,
          itemBuilder: (context, model) {
            if (model.message.body.type == MessageType.TXT) {
              return CustomTextItemWidget(
                model: model,
                onTap: (context, message) {
                  bubbleClicked(message);
                  return true;
                },
              );
            }
          },
        ),
      ),
    );
  }

  void bubbleClicked(ChatMessage message) {
    debugPrint('bubble clicked');
  }
}

class CustomTextItemWidget extends ChatMessageListItem {
  const CustomTextItemWidget({super.key, required super.model, super.onTap});

  @override
  Widget build(BuildContext context) {
    ChatTextMessageBody body = model.message.body as ChatTextMessageBody;

    Widget content = Text(
      body.content,
      style: const TextStyle(
        color: Colors.black,
        fontSize: 50,
        fontWeight: FontWeight.w400,
      ),
    );
    return getBubbleWidget(content);
  }
}

Customize the input widget #

class _MessagesPageState extends State<MessagesPage> {
  late ChatMessageListController _msgController;
  final TextEditingController _textController = TextEditingController();
  final FocusNode _focusNode = FocusNode();
  @override
  void initState() {
    super.initState();
    _msgController = ChatMessageListController(widget.conversation);
  }

  @override
  void dispose() {
    _focusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(widget.conversation.id)),
      body: SafeArea(
        child: ChatMessagesView(
          conversation: widget.conversation,
          messageListViewController: _msgController,
          inputBar: inputWidget(),
          needDismissInputWidget: () {
            _focusNode.unfocus();
          },
        ),
      ),
    );
  }

  Widget inputWidget() {
    return SizedBox(
      height: 50,
      child: Row(
        children: [
          Expanded(
            child: TextField(
              focusNode: _focusNode,
              controller: _textController,
            ),
          ),
          ElevatedButton(
              onPressed: () {
                final msg = ChatMessage.createTxtSendMessage(
                    targetId: widget.conversation.id,
                    content: _textController.text);
                _textController.text = '';
                _msgController.sendMessage(msg);
              },
              child: const Text('Send'))
        ],
      ),
    );
  }
}

Delete all Messages in the current conversation #

class _MessagesPageState extends State<MessagesPage> {
  late ChatMessageListController _msgController;

  @override
  void initState() {
    super.initState();
    _msgController = ChatMessageListController(widget.conversation);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.conversation.id),
        actions: [
          TextButton(
              onPressed: () {
                _msgController.deleteAllMessages();
              },
              child: const Text(
                'Clear',
                style: TextStyle(color: Colors.white),
              ))
        ],
      ),
      body: SafeArea(
        child: ChatMessagesView(
          conversation: widget.conversation,
          messageListViewController: _msgController,
        ),
      ),
    );
  }
}

Customize actions displayed upon a click of the plus symbol in the conversation #

class _MessagesPageState extends State<MessagesPage> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.conversation.id),
      ),
      body: SafeArea(
        child: ChatMessagesView(
          conversation: widget.conversation,
          inputBarMoreActionsOnTap: (items) {
            ChatBottomSheetItem item =
                ChatBottomSheetItem('more', onTap: customMoreAction);

            return items + [item];
          },
        ),
      ),
    );
  }

  void customMoreAction() {
    debugPrint('custom action');
    Navigator.of(context).pop();
  }
}

Sample Project #

If the demo is required, configure the following information in the example/lib/main.dart file:

Replaces <#Your app key#>, <#Your created user#>, and <#User password#> and with your own App Key, user ID, and user token generated in easemob Console.

class ChatConfig {
  static String appkey = <#Your app key#>;
  static String userId = <#Your created user#>;
  static String password = <#User password#>;
}

License #

The sample projects are under the MIT license.

1
likes
50
points
55
downloads

Publisher

unverified uploader

Weekly Downloads

A set of ui components adapted to the chat sdk can quickly build a chat page and chat through the chat sdk by invoking the ui components.

Homepage

License

MIT (license)

Dependencies

audioplayers, file_picker, flutter, flutter_localizations, im_flutter_sdk, image_picker, intl, record

More

Packages that depend on em_chat_uikit