Product Introduction

You only need to integrate Chat SDK to easily gain chat, conversation, group capabilities, and you can also communicate with other products such as whiteboards through signaling messages. Chat can cover various business scenarios, support the access and use of various platforms, and fully meet the communication needs.

Check Out Our Sample Apps

This document introduces how to quickly run the Chat demo on the iOS platform. For the other platforms, please refer to document:

Introduction to TUIKit

Chat SDK comes with TUIKit, which is an official set of UI components that have chat business logic built-in. TUIKit includes components like conversation, chat, relationship chain, and group. See TUIKit Library Overview for more details.

Developers can use these UI components to quickly and easily add In-APP chat modules to their mobile applications.

Currently, Flutter TUIKit contains the following main components:

  • TIMUIKitCore: Core entry
  • TIMUIKitConversation: Conversation list
  • TIMUIKitChat: Chat module, includes historical message list and message sending area, with some other features like message reaction and URL preview, etc.
  • TIMUIKitContact: Contacts list
  • TIMUIKitProfile: User profile and relationship management
  • TIMUIKitGroupProfile: Group profile and management
  • TIMUIKitGroup: The list of group self joined
  • TIMUIKitBlackList: The list of user been blocked
  • TIMUIKitNewContact: New contacts application list
  • TIMUIKitSearch: Search globally
  • TIMUIKitSearchMsgDetail: Search in specific conversation

In addition to these components, there are other useful components and widgets available to help developers meet their business needs, such as group entry application list and group member list.

Compatible Platforms

The platforms are compatible with the deployment of our Chat UIKit.

  • Android
  • iOS
  • Web (version 0.1.4 and later)
  • Windows (version 2.0.0 and later)
  • macOS (version 2.0.0 and later)

Get Started

Please refer to Run Demo for a complete and detailed guide on getting started.

Directions

The following guide describes how to quickly build a simple chat application using Flutter TUIKit. Refer to the appendix if you want to learn about the details and parameters of each widget.

Step 0: Create two accounts for testing

Sign up and log in to the Chat console.

Create an application and enter it. Click Users and create two accounts.

The correct way to distribute UserSig is to integrate the calculation code for UserSig into your server and provide an application-oriented API. When UserSig is needed, your application can send a request to the business server for a dynamic UserSig. For more information, see How do I calculate UserSig on the server?.

Step 1: Create a Flutter app and add permission configuration

Create a Flutter app quickly by following the Flutter documentation.

TUIKit needs the permissions of shooting/album/recording/network for basic messaging functions. You need to declare these permissions manually to use the relevant capabilities normally.

Android

Open android/app/src/main/AndroidManifest.xml and add the following lines between <manifest> and </manifest>.

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>

iOS

Open ios/Podfile and add the following lines to the end of the file.

post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
    target.build_configurations.each do |config|
            config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64'
            config.build_settings['ENABLE_BITCODE'] = 'NO'
            config.build_settings["ONLY_ACTIVE_ARCH"] = "NO"
        end
    target.build_configurations.each do |config|
          config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
            '$(inherited)',
            'PERMISSION_MICROPHONE=1',
            'PERMISSION_CAMERA=1',
            'PERMISSION_PHOTOS=1',
          ]
        end
  end
end

Step 2: Install dependencies

Add tencent_cloud_chat_uikit under dependencies in the pubspec.yaml file, or run the following command:

flutter pub add tencent_cloud_chat_uikit

It supports Android and iOS by default. If you also want to use it on the web, refer to the following guide.

Web Support

Version 0.1.4 or later is required to support web.

If your existing Flutter project does not support web, run flutter create . in the project root directory to add web support.

Install JavaScript dependencies to web/ using npm or yarn.

cd web

npm init

npm i tim-js-sdk

npm i tim-upload-plugin

Open web/index.html and add the following two lines between <head> and </head> to import them.

<script src="./node_modules/tim-upload-plugin/index.js"></script>
<script src="./node_modules/tim-js-sdk/tim-js-friendship.js"></script>

Step 3: Initialize TUIKit

Initialize TUIKit when your app starts. You only need to perform the initialization once for the project to start.

Get the instance of TUIKit first using TIMUIKitCore.getInstance(), followed by initializing it with your sdkAppID.

/// main.dart
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';

final CoreServicesImpl _coreInstance = TIMUIKitCore.getInstance();

@override
void initState() {
  _coreInstance.init(
      sdkAppID: 0, // Replace 0 with the SDKAppID of your Tencent Cloud Chat application
      loglevel: LogLevelEnum.V2TIM_LOG_DEBUG,
      listener: V2TimSDKListener());
  super.initState();
}}

You may also want to register a callback function for onTUIKitCallbackListener here. Refer to the appendix.

Step 4: Get the signature and log in

You can now log in one of the testing accounts generated in Step 0 to start the Tencent Cloud Chat module.

Log in using _coreInstance.login.

/// main.dart
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';

final CoreServicesImpl _coreInstance = TIMUIKitCore.getInstance();
_coreInstance.login(userID: userID, userSig: userSig);

Note: Importing UserSig to your application is only for debugging purposes and cannot be used for the release version. Before publishing your app, you should generate your UserSig from your server. Refer to: Generate Signature.

Step 5. Implementing the conversation list page

You can use the conversation (channel) list page as the homepage of your Chat module, which includes all conversations with users and groups that have chat records.

You can create a Conversation class, with TIMUIKitConversation as its body, to render the conversation list. You only need to provide the onTapItem callback, which allows users to navigate to the Chat page for each conversation. In the next step, we'll introduce the Chat class.

import 'package:flutter/material.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text(
          "Message",
          style: TextStyle(color: Colors.black),
        ),
      ),
      body: TIMUIKitConversation(
        onTapItem: (selectedConv) {
          Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) =>
                    Chat(
                      selectedConversation: selectedConv,
                    ),
              ));
        },
      ),
    );
  }
}

Step 6. Implementing the chat page

The chat page consists of the main message list and a message sending bar at the bottom.

You can create a Chat class, with TIMUIKitChat as its body, to render the chat page. We recommend providing an onTapAvatar callback function to navigate to the profile page for the current contact, which we'll introduce in the next step.

import 'package:flutter/material.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';

class Chat extends StatelessWidget {
  final V2TimConversation selectedConversation;

  const Chat({Key? key, required this.selectedConversation}) : super(key: key);

  String? _getConvID() {
    return selectedConversation.type == 1
        ? selectedConversation.userID
        : selectedConversation.groupID;
  }

  @override
  Widget build(BuildContext context) {
    return TIMUIKitChat(
      conversationID: _getConvID() ?? '', 
      conversationType: selectedConversation.type ?? 1, 
      conversationShowName: selectedConversation.showName ?? "", 
      onTapAvatar: (_) {
        Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) => UserProfile(userID: userID),
            ));
      }, 
    );
  }

Step 7. Implementing the user profile page

This page shows the profile of a specific user and maintains the relationship between the current logged-in user and the other user.

You can create a UserProfile class, with TIMUIKitProfile as its body, to render the user profile page.

The only parameter you have to provide is userID, while this component automatically generates the profile and relationship maintenance page based on the existence of friendship.

TIP: Please use profileWidgetBuilder first to customize some profile widgets and determine their vertical sequence using profileWidgetsOrder if you want to customize this page. If this method cannot meet your business needs, you may consider using builder instead.

import 'package:flutter/material.dart';
import 'package:tencent_cloud_chat_uikit/tencent_cloud_chat_uikit.dart';

class UserProfile extends StatelessWidget {
  final String userID;

  const UserProfile({required this.userID, Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text(
          "Message",
          style: TextStyle(color: Colors.black),
        ),
      ),
      body: TIMUIKitProfile(
        userID: widget.userID,
      ),
    );
  }
}

Now your app can send and receive messages, display the conversation list, and manage contact friendships. You can use other components from TUIKit to quickly and easily implement the complete Chat module.

FAQs

Do I need to integrate Chat SDK after integrating TUIKit?

No. You don't need to integrate Chat SDK again. If you want to use Chat SDK related APIs, you can get them via TIMUIKitCore.getSDKInstance(). This method is recommended to ensure Chat SDK version consistency.

Why did force quit occur when I sent voice, image, file or other messages?

Check whether you have enabled the camera, mic, album, or other related permissions.

Refers to Step 1 above.

What should I do if clicking Build And Run for an Android device triggers an error, stating no available device is found?

Check that the device is not occupied by other resources. Alternatively, click Build to generate an APK package, drag it to the simulator, and run it.

What should I do if an error occurs during the first run for an iOS device?

If an error occurs after the configuration, click Product > Clean Build Folder , clean the product, and run pod install or flutter run again.

What should I do if an error occurs during debugging on a real iOS device when I am wearing an Apple Watch?

Turn on Airplane Mode on your Apple Watch, and go to Settings > Bluetooth on your iPhone to turn off Bluetooth.

Restart Xcode (if opened) and run flutter run again.

What should I do when an error occurs on an Android device after TUIKit is imported into the application automatically generated by Flutter?

  1. Open android\app\src\main\AndroidManifest.xml and complete xmlns:tools="http://schemas.android.com/tools" / android:label="@string/android_label" / tools:replace="android:label" as follows.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="Replace it with your Android package name"
    xmlns:tools="http://schemas.android.com/tools">
    <application android:label="@string/android_label" tools:replace="android:label"
        android:icon="@mipmap/ic_launcher"
    // Specify an icon path
    android:usesCleartextTraffic="true"
    android:requestLegacyExternalStorage="true">
  1. Open android\app\build.gradle and complete minSdkVersion and targetSdkVersion in defaultConfig.
defaultConfig {
  applicationId "" // Replace it with your Android package name
  minSdkVersion 21
  targetSdkVersion 30
}

For those who require real-time voice and video call capabilities alongside our Chat UIKit, we highly recommend our dedicated voice and video call UI component package, tencent_calls_uikit. This robust and feature-rich package is specifically designed to complement our existing solution and seamlessly integrate with it, providing a comprehensive, unified communication experience for your users.

Libraries

base_widgets/tim_ui_kit_base
base_widgets/tim_ui_kit_class
base_widgets/tim_ui_kit_state
base_widgets/tim_ui_kit_statelesswidget
business_logic/life_cycle/add_friend_life_cycle
business_logic/life_cycle/add_group_life_cycle
business_logic/life_cycle/base_life_cycle
business_logic/life_cycle/block_list_life_cycle
business_logic/life_cycle/chat_life_cycle
business_logic/life_cycle/conversation_life_cycle
business_logic/life_cycle/friend_list_life_cycle
business_logic/life_cycle/group_profile_life_cycle
business_logic/life_cycle/new_contact_life_cycle
business_logic/life_cycle/profile_life_cycle
business_logic/listener_model/tui_group_listener_model
business_logic/model/profile_model
business_logic/separate_models/tui_chat_model_tools
business_logic/separate_models/tui_chat_separate_view_model
business_logic/separate_models/tui_group_profile_model
business_logic/separate_models/tui_profile_view_model
business_logic/view_models/tui_chat_global_model
business_logic/view_models/tui_conversation_view_model
business_logic/view_models/tui_friendship_view_model
business_logic/view_models/tui_search_view_model
business_logic/view_models/tui_self_info_view_model
business_logic/view_models/tui_setting_model
data_services/conversation/conversation_services
data_services/conversation/conversation_services_implements
data_services/core/core_services
data_services/core/core_services_implements
data_services/core/tim_uikit_config
data_services/core/tim_uikit_wide_modal_operation_key
data_services/core/web_support/uikit_web_support
data_services/core/web_support/uikit_web_support_implement
data_services/friendShip/friendship_services
data_services/friendShip/friendship_services_implements
data_services/group/group_services
data_services/group/group_services_implement
data_services/message/message_service_implement
data_services/message/message_services
data_services/services_locatar
import_proxy/general
import_proxy/import_proxy
import_proxy/platform/native_import
import_proxy/platform/web_import
tencent_cloud_chat_uikit
ui/constants/history_message_constant
ui/constants/time
ui/controller/tim_uikit_chat_controller
ui/controller/tim_uikit_conversation_controller
ui/controller/tim_uikit_profile_controller
ui/theme/tim_uikit_avatar_theme
ui/theme/tim_uikit_message_theme
ui/utils/common_utils
ui/utils/custom_sticker
ui/utils/frame
ui/utils/logger
ui/utils/message
ui/utils/optimize_utils
ui/utils/permission
ui/utils/platform
ui/utils/route
ui/utils/screen_shot
ui/utils/screen_utils
ui/utils/sound_record
ui/utils/time_ago
ui/views/TIMUIKitAddFriend/tim_uikit_add_friend
ui/views/TIMUIKitAddFriend/tim_uikit_send_application
ui/views/TIMUIKitAddGroup/tim_uikit_add_group
ui/views/TIMUIKitAddGroup/tim_uikit_send_application
ui/views/TIMUIKitBlackList/tim_uikit_black_list
ui/views/TIMUIKitChat/tim_uikit_chat
ui/views/TIMUIKitChat/tim_uikit_chat_config
ui/views/TIMUIKitChat/tim_uikit_cloud_custom_data
ui/views/TIMUIKitChat/tim_uikit_multi_select_panel
ui/views/TIMUIKitChat/tim_uikit_send_file
ui/views/TIMUIKitChat/TIMUIKitAppBar/tim_uikit_appbar
ui/views/TIMUIKitChat/TIMUIKitAppBar/tim_uikit_appbar_title
ui/views/TIMUIKitChat/TIMUIKitMessageItem/main
ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_custom_elem
ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_face_elem
ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_file_elem
ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_file_icon
ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_group_tips_elem
ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_image_elem
ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_reply_elem
ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_sound_elem
ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_text_elem
ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_text_translate_elem
ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_chat_video_elem
ui/views/TIMUIKitChat/TIMUIKitMessageItem/tim_uikit_merger_message_elem
ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/message_reaction_emoji
ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_detail
ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_select_emoji
ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_show_item
ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_show_panel
ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_utils
ui/views/TIMUIKitChat/TIMUIKitMessageItem/TIMUIKitMessageReaction/tim_uikit_message_reaction_wrapper
ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list
ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_config
ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_history_message_list_item
ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_chat_message_tooltip
ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_history_message_list_container
ui/views/TIMUIKitChat/TIMUIKItMessageList/tim_uikit_message_read_receipt
ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue
ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_chat_history_message_list_tongue_container
ui/views/TIMUIKitChat/TIMUIKItMessageList/TIMUIKitTongue/tim_uikit_tongue_item
ui/views/TIMUIKitChat/TIMUIKItMessageList/utils
ui/views/TIMUIKitChat/TIMUIKitTextField/at_member_panel
ui/views/TIMUIKitChat/TIMUIKitTextField/intl_camer_picker
ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/DefaultSpecialTextSpanBuilder
ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/emoji_text
ui/views/TIMUIKitChat/TIMUIKitTextField/special_text/http_text
ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_at_text
ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_call_invite_list
ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_emoji_panel
ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_more_panel
ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_send_sound_message
ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field
ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_controller
ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/narrow
ui/views/TIMUIKitChat/TIMUIKitTextField/tim_uikit_text_field_layout/wide
ui/views/TIMUIKitContact/tim_uikit_contact
ui/views/TIMUIKitConversation/tim_ui_kit_conversation_total_unread
ui/views/TIMUIKitConversation/tim_uikit_conversation
ui/views/TIMUIKitConversation/tim_uikit_conversation_draft_text
ui/views/TIMUIKitConversation/tim_uikit_conversation_item
ui/views/TIMUIKitConversation/tim_uikit_conversation_last_msg
ui/views/TIMUIKitGroup/tim_uikit_group
ui/views/TIMUIKitGroup/tim_uikit_group_application_list
ui/views/TIMUIKitGroup/tim_uikit_group_application_list_item
ui/views/TIMUIKitGroupProfile/group_member/tui_add_group_member
ui/views/TIMUIKitGroupProfile/group_member/tui_delete_group_member
ui/views/TIMUIKitGroupProfile/group_member/tui_group_member_list
ui/views/TIMUIKitGroupProfile/group_profile_widget
ui/views/TIMUIKitGroupProfile/shared_data_widget
ui/views/TIMUIKitGroupProfile/tim_uikit_group_profile
ui/views/TIMUIKitGroupProfile/widgets/tim_ui_group_profile_widget
ui/views/TIMUIKitGroupProfile/widgets/tim_ui_group_search_msg
ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_add_opt
ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_button_area
ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_detail_card
ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_manage
ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_member_tile
ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_message_disturb
ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_name_card
ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_notification
ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_pin_conversation
ui/views/TIMUIKitGroupProfile/widgets/tim_uikit_group_type
ui/views/TIMUIKitNewContact/tim_uikit_new_contact
ui/views/TIMUIKitNewContact/tim_uikit_unread_count
ui/views/TIMUIKitProfile/profile_widget
ui/views/TIMUIKitProfile/tim_uikit_profile
ui/views/TIMUIKitProfile/widget/tim_uikit_operation_item
ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card/tim_uikit_profile_userinfo_card
ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card/tim_uikit_profile_userinfo_card_narrow
ui/views/TIMUIKitProfile/widget/tim_uikit_profile_userinfo_card/tim_uikit_profile_userinfo_card_wide
ui/views/TIMUIKitProfile/widget/tim_uikit_profile_widget
ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_folder
ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_indicator
ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_input
ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_item
ui/views/TIMUIKitSearch/pureUI/tim_uikit_search_showAll
ui/views/TIMUIKitSearch/tim_uikit_search_friend
ui/views/TIMUIKitSearch/tim_uikit_search_group
ui/views/TIMUIKitSearch/tim_uikit_search_item_wide
ui/views/TIMUIKitSearch/tim_uikit_search_msg
ui/views/TIMUIKitSearch/tim_uikit_search_msg_detail
ui/views/TIMUIKitSearch/tim_uikit_search_not_support
ui/widgets/avatar
ui/widgets/az_list_view
ui/widgets/center_play_button
ui/widgets/column_menu
ui/widgets/contact_list
ui/widgets/customize_ball_pulse_header
ui/widgets/drag_widget
ui/widgets/emoji
ui/widgets/extended_wrap/extended_render_wrap
ui/widgets/extended_wrap/extended_wrap
ui/widgets/forward_message_screen
ui/widgets/gestured_image
ui/widgets/group_member_list
ui/widgets/image_hero
ui/widgets/image_screen
ui/widgets/keepalive_wrapper
ui/widgets/link_preview/common/extensions
ui/widgets/link_preview/common/utils
ui/widgets/link_preview/compiler/md_text
ui/widgets/link_preview/link_preview_entry
ui/widgets/loading
ui/widgets/merger_message_screen
ui/widgets/message_read_receipt
ui/widgets/radio_button
ui/widgets/recent_conversation_list
ui/widgets/text_input_bottom_sheet
ui/widgets/textSize
ui/widgets/transimit_group_owner_select
ui/widgets/unread_message
ui/widgets/video_custom_control
ui/widgets/video_screen
ui/widgets/wide_popup