Nexconn Chat UI SDK for Flutter
ai_nexconn_chatui_plugin provides ready-to-use Flutter UI for Nexconn Chat:
channel list, chat page, message list, input bar, message bubbles, and
preview pages.
The package exposes Nexconn SDK objects directly. Public APIs use
BaseChannel, Message, MessageType, ChannelType, NCEngine, and other
types from ai_nexconn_chat_plugin as the customer-facing API.
User profile features are exposed through the Nexconn-named UI layer:
NexconnUserProfilePage, NexconnUserProfileProvider, and
NexconnUserProfilePageConfig.
Quick Start
import 'package:ai_nexconn_chatui_plugin/ai_nexconn_chatui_plugin.dart';
final engineProvider = EngineProvider();
await engineProvider.initialize(InitParams(appKey: 'YOUR_APP_KEY'));
await engineProvider.connect(
ConnectParams(token: 'USER_TOKEN'),
);
runApp(
ChatUIProviders(
engineProvider: engineProvider,
child: const MaterialApp(
home: ChannelPage(),
),
),
);
Open a chat page with any Nexconn channel:
ChannelPage(
onItemTap: (channel, index, context) {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => ChatPage(channel: channel),
),
);
},
);
Channel List Customization
ChannelPage(
config: ChannelConfig(
listConfig: const ChannelListConfig(
pageSize: 30,
showNetworkStatusTip: true,
),
itemConfig: ChannelItemConfig(
avatarShape: ChannelAvatarShape.circle,
showDirectChannelOnlineStatus: true,
onlineStatusProvider: (channel) => ChannelOnlineStatus.online,
),
longPressMenuConfig: const ChannelLongPressMenuConfig(
cancelText: 'Close',
),
),
headerBuilder: (_) => const Text('Channel Header'),
footerBuilder: (_) => const Text('Channel Footer'),
emptyBuilder: (_) => const Text('No channels'),
);
Chat Page Customization
ChatPage(
channel: channel,
config: const ChatPageConfig(
messageListConfig: MessageListConfig(
historyMessageCount: 30,
maxSelectedMessages: 20,
showSenderName: false,
showNetworkStatusTip: true,
),
bubbleConfig: BubbleConfig(
avatarConfig: ChatAvatarConfig(
size: 44,
shape: ChatAvatarShape.roundedRectangle,
),
),
longPressMenuConfig: ChatMessageLongPressMenuConfig(
showMoreButton: false,
deleteBehavior: ChatMessageDeleteBehavior.forAll,
),
),
headerBuilder: (_) => const Text('Chat Header'),
footerBuilder: (_) => const Text('Chat Footer'),
emptyBuilder: (_) => const Text('No messages'),
onMessageTap: (message) {},
onMessageLongPress: (message) {},
onMessageAvatarTap: (message) {},
onMessageAvatarLongPress: (message) {},
);
Input Area
Configure the input bar controls and extension panel from ChatPageConfig.
Controls can be reordered or hidden, and extension plugins can be replaced at
runtime by rebuilding with a new MessageInputConfig.
ChatPage(
channel: channel,
config: ChatPageConfig(
inputConfig: MessageInputConfig(
enableEmojiPanel: false,
toolbarControls: [
MessageInputBarControl.extension,
MessageInputBarControl.voice,
],
extensionPlugins: [
const MessageInputExtensionPlugin.voiceToText(),
MessageInputExtensionPlugin(
id: 'scan',
title: 'Scan',
icon: Icons.qr_code_scanner,
onTap: (context, plugin) {
// Connect your own Nexconn business flow here.
},
),
],
),
),
);
MessageInputExtensionPlugin.voiceToText() is a configurable entry point only.
It is disabled by default until the app wires a real speech-to-text capability
and explicitly enables it.
Built-in media entries such as photo, camera, file, and location are
also callback entry points only. They stay disabled until your app supplies the
real picker or capture flow and enables them explicitly.
Media Send Helpers
ChatProvider now exposes a generic media sending entry point plus
type-specific helpers. The UI layer only forwards message params, so your app
can plug in any real picker or recorder before calling these helpers.
For image messages, the helper currently accepts the selected file path only;
original-image switching should still be handled by your picker layer when the
underlying SDK exposes it.
context.read<ChatProvider>().sendImageMessage('/tmp/photo.jpg');
context.read<ChatProvider>().sendGifMessage('/tmp/anim.gif');
context.read<ChatProvider>().sendVoiceMessage('/tmp/voice.aac', 12);
context.read<ChatProvider>().sendShortVideoMessage('/tmp/video.mp4', 30);
context.read<ChatProvider>().sendFileMessage('/tmp/report.pdf');
If you want to keep the input UI fully custom, use the extension panel builder
or onTap callback to bridge your picker into the helper:
MessageInputExtensionPlugin.photo(
enabled: true,
onTap: (context, plugin) async {
final provider = context.read<ChatProvider>();
await provider.sendImageMessage('/tmp/photo.jpg');
},
);
User Profile
Use the built-in page to display the current user or any other user profile.
By default it resolves data through NCEngine.user.getMyUserProfile and
NCEngine.user.getUserProfiles, but you can inject your own resolver through
NexconnUserProfileProviderConfig.
NexconnUserProfilePage(
userId: 'target-user-id',
config: NexconnUserProfilePageConfig(
providerConfig: NexconnUserProfileProviderConfig(
profileResolver: (userId) async {
// Return a NexconnUserProfile from your own cache or backend.
return null;
},
),
),
);
Migration Notes
The public naming strategy intentionally uses generic UI names such as
ChannelPage and ChatPage, while the data and event objects remain the
Nexconn SDK types.
Libraries
- ai_nexconn_chatui_plugin
- Unified export entry for the Nexconn Chat UI SDK.
- ai_nexconn_chatui_plugin_method_channel
- ai_nexconn_chatui_plugin_platform_interface
- app_providers
- l10n/nexconn_chat_ui_l10n
- l10n/nexconn_chat_ui_localizations
- l10n/nexconn_chat_ui_localizations_en
- l10n/nexconn_chat_ui_localizations_zh
- models/chat_profile_info
- models/nexconn_user_profile
- models/user_at_info
- providers/audio_player_provider
- providers/channel_provider
- providers/chat_provider
- providers/engine_provider
- providers/message_input_provider
- providers/theme_provider
- providers/user_profile_provider
- routes/nexconn_chat_ui_routes
- ui_config/channel/channel_app_bar_config
- ui_config/channel/channel_config
- ui_config/chat/bubble/bubble_config
- ui_config/chat/bubble/message_style_config
- ui_config/chat/input/input_config_exports
- ui_config/chat/input/message_input_config
- ui_config/chat/page/chat_page_config
- ui_config/user/user_profile_page_config
- ui_config/user/user_profile_provider_config
- utils/chatui_asset
- utils/chatui_image_util
- utils/constants
- utils/message_content_util
- utils/message_type_util
- utils/system_ui_overlay
- utils/time_util
- utils/video_playback_backend
- utils/voice_message_layout
- views/channel/item/channel_item
- views/channel/page/channel_app_bar_widget
- views/channel/page/channel_page
- views/chat/bubble/message_bubble
- views/chat/input/message_input_widget
- views/chat/page/chat_app_bar_widget
- views/chat/page/chat_page
- views/chat/page/message_list_controller
- views/chat/page/message_list_widget
- views/chat_extras/chat_message_search_page
- views/chat_extras/chat_message_search_result_page
- views/chat_extras/combine_message_detail_page
- views/chat_extras/file_preview_page
- views/chat_extras/forward_select_page
- views/chat_extras/photo_preview_page
- views/chat_extras/read_receipt_users_sheet
- views/chat_extras/short_video_preview_page
- views/common/im_kit_profile_widgets
- views/common/kit_page_widgets
- views/user/user_profile_page