### Install ChatView dependency Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/README.md Add the package to your pubspec.yaml file to begin using ChatView in your Flutter project. ```yaml dependencies: chatview: ``` -------------------------------- ### Implement Custom Message Builder in ChatView Source: https://context7.com/simformsolutionspvtltd/chatview/llms.txt Use `customMessageBuilder` to define how different custom message types are rendered. This example shows how to handle 'location', 'contact', and 'unavailable' message types, parsing JSON data to display relevant information and actions. Ensure the `MessageConfiguration` is passed to the `ChatView` widget. ```dart ChatView( chatController: chatController, chatViewState: ChatViewState.hasMessages, onSendTap: onSendTap, messageConfig: MessageConfiguration( customMessageBuilder: (Message message) { // Parse custom message data final data = jsonDecode(message.message); switch (data['type']) { case 'location': return Container( width: 200, padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.grey.shade200, borderRadius: BorderRadius.circular(12), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Icon(Icons.location_on, color: Colors.red), const SizedBox(height: 4), Text( data['address'], style: const TextStyle(fontWeight: FontWeight.bold), ), Text( '${data['latitude']}, ${data['longitude']}', style: TextStyle(color: Colors.grey.shade600, fontSize: 12), ), TextButton( onPressed: () => openMaps(data['latitude'], data['longitude']), child: const Text('Open in Maps'), ), ], ), ); case 'contact': return Container( width: 220, padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.grey.shade300), ), child: Row( children: [ CircleAvatar( backgroundImage: NetworkImage(data['avatar']), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(data['name'], style: const TextStyle(fontWeight: FontWeight.bold)), Text(data['phone'], style: TextStyle(color: Colors.grey.shade600)), ], ), ), ], ), ); case 'unavailable': return Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.grey.shade200, borderRadius: BorderRadius.circular(12), ), child: const Text( 'This message is no longer available', style: TextStyle(fontStyle: FontStyle.italic, color: Colors.grey), ), ); default: return const SizedBox.shrink(); } }, customMessageReplyViewBuilder: (ReplyMessage replyMessage) { // Custom view for replied custom messages final data = jsonDecode(replyMessage.message); return Row( children: [ Icon( data['type'] == 'location' ? Icons.location_on : Icons.person, size: 16, ), const SizedBox(width: 4), Text( data['type'] == 'location' ? 'Location' : 'Contact', style: const TextStyle(fontSize: 12), ), ], ); }, ), ) ``` -------------------------------- ### Configure Project Dependencies and Permissions Source: https://context7.com/simformsolutionspvtltd/chatview/llms.txt Add the package to pubspec.yaml and configure platform-specific permissions for media and audio access. ```yaml # pubspec.yaml dependencies: chatview: ^3.0.0 # For iOS - add to ios/Runner/Info.plist: # NSCameraUsageDescription # Used for taking photos # NSMicrophoneUsageDescription # Used for voice messages # NSPhotoLibraryUsageDescription # Used for selecting photos # For Android - add to android/app/build.gradle: # minSdkVersion 21 # And in AndroidManifest.xml: # ``` -------------------------------- ### Initialize ChatController Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Create a controller to manage the chat state, including current and other users. ```dart final chatController = ChatController( initialMessageList: messageList, scrollController: ScrollController(), currentUser: ChatUser(id: '1', name: 'Flutter'), otherUsers: [ChatUser(id: '2', name: 'Simform')], ); ``` -------------------------------- ### Initialize ChatList Controller Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Create a ChatListController instance, providing an initial list of chats and a ScrollController for managing scroll behavior. ```dart ChatListController chatListController = ChatListController( initialChatList: chatList, scrollController: ScrollController(), ); ``` -------------------------------- ### Import ChatView Package Source: https://context7.com/simformsolutionspvtltd/chatview/llms.txt Include the necessary import statement to access ChatView classes. ```dart import 'package:chatview/chatview.dart'; ``` -------------------------------- ### Implement ChatView Widget Source: https://context7.com/simformsolutionspvtltd/chatview/llms.txt Initializes the main ChatView widget with message handling, feature toggles, app bar customization, and pagination logic. ```dart ChatView( chatController: chatController, chatViewState: ChatViewState.hasMessages, onSendTap: (String message, ReplyMessage replyMessage, MessageType messageType) { final newMessage = Message( id: DateTime.now().millisecondsSinceEpoch.toString(), message: message, createdAt: DateTime.now(), sentBy: chatController.currentUser.id, replyMessage: replyMessage, messageType: messageType, status: MessageStatus.pending, ); chatController.addMessage(newMessage); // Simulate message delivery Future.delayed(const Duration(seconds: 1), () { newMessage.setStatus = MessageStatus.delivered; }); }, featureActiveConfig: const FeatureActiveConfig( enableSwipeToReply: true, enableReactionPopup: true, enablePagination: true, enableScrollToBottomButton: true, enableTextSelection: true, enableOtherUserProfileAvatar: true, enableDoubleTapToLike: true, ), appBar: ChatViewAppBar( chatTitle: 'Jane Doe', userStatus: 'Online', profilePicture: 'https://example.com/jane.jpg', backGroundColor: Colors.white, chatTitleTextStyle: const TextStyle( fontSize: 18, fontWeight: FontWeight.w600, ), actions: [ IconButton( icon: const Icon(Icons.call), onPressed: () => print('Call pressed'), ), IconButton( icon: const Icon(Icons.videocam), onPressed: () => print('Video call pressed'), ), ], ), chatBackgroundConfig: ChatBackgroundConfiguration( backgroundColor: Colors.grey.shade100, backgroundImage: 'assets/chat_bg.png', // Optional background ), loadMoreData: (ChatPaginationDirection direction, Message referenceMessage) async { // Fetch more messages from your backend final messages = await fetchMessages( beforeId: direction.isPrevious ? referenceMessage.id : null, afterId: direction.isNext ? referenceMessage.id : null, ); chatController.loadMoreData(messages, direction: direction); }, isLastPage: () => noMoreMessagesAvailable, loadingWidget: const Center(child: CircularProgressIndicator()), ) ``` -------------------------------- ### Implement ChatList Widget Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Basic implementation of the ChatList widget with controller, app bar, and menu configuration. ```dart 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) { // Handle chat tile tap }, ), ) ``` -------------------------------- ### Initialize ChatListController Source: https://context7.com/simformsolutionspvtltd/chatview/llms.txt Initialize ChatListController with an initial list of chats and a ScrollController. Manages chat operations like search and updates. ```dart // Initialize ChatListController final chatListController = ChatListController( initialChatList: [ ChatListItem( id: '1', name: 'John Doe', imageUrl: 'https://example.com/john.jpg', unreadCount: 3, userActiveStatus: UserActiveStatus.online, lastMessage: Message( id: 'msg-1', sentBy: '2', message: 'Hey, are you coming to the meeting?', createdAt: DateTime.now().subtract(const Duration(minutes: 5)), status: MessageStatus.delivered, ), settings: ChatSettings( pinStatus: PinStatus.unpinned, muteStatus: MuteStatus.unmuted, ), ), ChatListItem( id: '2', name: 'Jane Smith', imageUrl: 'https://example.com/jane.jpg', unreadCount: 0, lastMessage: Message( id: 'msg-2', sentBy: '1', message: 'Thanks for the update!', createdAt: DateTime.now().subtract(const Duration(hours: 2)), status: MessageStatus.read, ), settings: ChatSettings( pinStatus: PinStatus.pinned, pinTime: DateTime.now(), ), ), ], scrollController: ScrollController(), ); ``` -------------------------------- ### Configure Link Previews Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Customize the appearance and error handling of link previews within chat bubbles using LinkPreviewConfiguration. ```dart ChatView( // ... chatBubbleConfig: ChatBubbleConfiguration( linkPreviewConfig: LinkPreviewConfiguration( linkStyle: const TextStyle( color: Colors.white, decoration: TextDecoration.underline, ), backgroundColor: Colors.grey, bodyStyle: const TextStyle( color: Colors.grey.shade200, fontSize: 16, ), titleStyle: const TextStyle( color: Colors.black, fontSize: 20, ), errorBody: 'Error encountered while parsing the link for preview' ), ), // ... ) ``` -------------------------------- ### Implement ChatList Widget Source: https://context7.com/simformsolutionspvtltd/chatview/llms.txt Configures a ChatList with custom app bar, search functionality, menu actions, and tile styling. Requires a ChatListController to manage state and data updates. ```dart ChatList( controller: chatListController, backgroundColor: Colors.white, enablePagination: true, appbar: ChatListAppBar( titleText: 'Messages', backgroundColor: Colors.white, centerTitle: false, titleTextStyle: const TextStyle( fontSize: 24, fontWeight: FontWeight.bold, color: Colors.black, ), actions: [ IconButton( icon: const Icon(Icons.edit_square), onPressed: () => print('New chat'), ), ], ), header: Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Row( children: [ FilterChip( label: Text('All (${chatListController.chatListMap.length})'), onSelected: (_) => chatListController.clearSearch(), ), const SizedBox(width: 8), FilterChip( label: const Text('Unread'), onSelected: (_) { final unread = chatListController.chatListMap.values .where((c) => (c.unreadCount ?? 0) > 0) .toList(); chatListController.setSearchChats(unread); }, ), ], ), ), searchConfig: SearchConfig( textEditingController: TextEditingController(), hintText: 'Search conversations...', borderRadius: BorderRadius.circular(24), textFieldBackgroundColor: Colors.grey.shade100, prefixIcon: const Icon(Icons.search), clearIcon: const Icon(Icons.clear), onSearch: (String query) { if (query.isEmpty) return null; return chatListController.chatListMap.values .where((chat) => chat.name.toLowerCase().contains(query.toLowerCase())) .toList(); }, ), menuConfig: ChatMenuConfig( enabled: true, deleteCallback: (ChatListItem chat) { chatListController.removeChat(chat.id); deleteConversation(chat.id); // Backend call }, pinStatusCallback: (result) { chatListController.updateChat( result.chat.id, (chat) => chat.copyWith( settings: chat.settings.copyWith(pinStatus: result.status), ), ); }, muteStatusCallback: (result) { chatListController.updateChat( result.chat.id, (chat) => chat.copyWith( settings: chat.settings.copyWith(muteStatus: result.status), ), ); }, ), tileConfig: ListTileConfig( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), onTap: (ChatListItem chat) { Navigator.push( context, MaterialPageRoute(builder: (_) => ChatScreen(chat: chat)), ); }, userAvatarConfig: UserAvatarConfig( radius: 28, backgroundColor: Colors.grey.shade300, ), userActiveStatusConfig: UserActiveStatusConfig( alignment: UserActiveStatusAlignment.bottomRight, color: (status) => status.isOnline ? Colors.green : Colors.grey, ), unreadCountConfig: const UnreadCountConfig( backgroundColor: Colors.blue, style: UnreadCountStyle.count, ), typingStatusConfig: TypingStatusConfig( textBuilder: (chat) => '${chat.typingUsers.first.name} is typing...', textStyle: const TextStyle( fontStyle: FontStyle.italic, color: Colors.grey, ), ), ), loadMoreChats: () async { final moreChats = await fetchMoreConversations(offset: currentOffset); for (final chat in moreChats) { chatListController.addChat(chat); } }, isLastPage: () => noMoreChatsAvailable, loadMoreConfig: const LoadMoreConfig( size: 24, color: Colors.blue, ), ) ``` -------------------------------- ### Define Message List Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Create the initial list of messages to display in the chat. ```dart List messageList = [ Message( id: '1', message: "Hi", createdAt: DateTime.now(), sentBy: userId, ), Message( id: '2', message: "Hello", createdAt: DateTime.now(), sentBy: userId, ), ]; ``` -------------------------------- ### Implement ChatView Widget Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Integrate the main ChatView widget with the required controller and state. ```dart ChatView( chatController: chatController, onSendTap: onSendTap, chatViewState: ChatViewState.hasMessages, // Add this state once data is available ) ``` -------------------------------- ### Configure Swipe to Reply Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Implement swipe gestures to trigger reply actions using SwipeToReplyConfiguration. ```dart ChatView( // ... swipeToReplyConfig: SwipeToReplyConfiguration( onLeftSwipe: (message, sentBy) { // Your code here }, onRightSwipe: (message, sentBy) { // Your code here }, ), // ... ) ``` -------------------------------- ### iOS Info.plist Configuration for Image Picker Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Configure your Info.plist file on iOS to grant necessary permissions for the image picker functionality. ```xml NSCameraUsageDescription Used to demonstrate image picker plugin NSMicrophoneUsageDescription Used to capture audio for image picker plugin NSPhotoLibraryUsageDescription Used to demonstrate image picker plugin ``` -------------------------------- ### Initialize Flutter Web App with Service Worker Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/example/web/index.html This JavaScript code initializes the Flutter web application by loading the main entry point and setting up the service worker. It's typically found in the index.html file for Flutter web projects. ```javascript const serviceWorkerVersion = null; window.addEventListener('load', function(ev) { // Download main.dart.js _flutter.loader.loadEntrypoint({ serviceWorker: { serviceWorkerVersion: serviceWorkerVersion, }, onEntrypointLoaded: function(engineInitializer) { engineInitializer.initializeEngine().then(function(appRunner) { appRunner.runApp(); }); } }); }); ``` -------------------------------- ### Add Custom AppBar Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Customize the ChatView header with profile information and actions. ```dart ChatView( // ... appBar: ChatViewAppBar( profilePicture: profileImage, chatTitle: "Simform", userStatus: "online", actions: [ Icon(Icons.more_vert), ], defaultAvatarImage: defaultAvatar, imageType: ImageType.network, networkImageErrorBuilder: (context, url, error) { return Center( child: Text('Error $error'), ); }, ), // ... ) ``` -------------------------------- ### Configure Load More Behavior Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Set the pagination size and color for the load more indicator. ```dart ChatList( // ... loadMoreConfig: LoadMoreConfig( size: 30, color: Colors.blue, ), // ... ) ``` -------------------------------- ### Configure Message Reactions Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Enable and style the reaction popup for messages. ```dart ChatView( // ... reactionPopupConfig: ReactionPopupConfiguration( backgroundColor: Colors.white, userReactionCallback: (message, emoji) { // Your code here }, padding: EdgeInsets.all(12), shadow: BoxShadow( color: Colors.black54, blurRadius: 20, ), ), // ... ) ``` -------------------------------- ### Define Chat List Items Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Initializes a list of ChatListItem objects to populate the chat interface. ```dart List 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, ), ), ChatListItem( id: '1', name: 'Flutter', userActiveStatus: UserActiveStatus.online, typingUsers: {const ChatUser(id: '1', name: 'Simform')}, ), ]; ``` -------------------------------- ### Add Custom Actions to Chat Menu Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Define custom actions for the chat context menu by providing a list of actions to the `menuConfig.actions` property. Use `CupertinoContextMenuAction` for menu items. ```dart ChatList( // ... menuConfig: ChatMenuConfig( actions: (chat) => [ CupertinoContextMenuAction( trailingIcon: Icons.favorite_outline_rounded, child: const Text( 'Add to Favorite', maxLines: 1, overflow: TextOverflow.ellipsis, ), onPressed: () { Future.delayed( const Duration(milliseconds: 800), () { // YOUR CODE HERE }, ); Navigator.pop(context); }, ), ], 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, ), ), ), // ... ), // ... ) ``` -------------------------------- ### Manage Reply Suggestions Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Add, remove, and configure the UI for reply suggestion chips within the chat interface. ```dart // Add reply suggestions _chatController.addReplySuggestions([ SuggestionItemData(text: 'Thanks.'), SuggestionItemData(text: 'Thank you very much.'), SuggestionItemData(text: 'Great.') ]); // Remove reply suggestions _chatController.removeReplySuggestions(); // Reply suggestions configuration ChatView( // ... replySuggestionsConfig: ReplySuggestionsConfig( itemConfig: SuggestionItemConfig( decoration: BoxDecoration(), textStyle: TextStyle(), padding: EdgeInsets.all(8), ), listConfig: SuggestionListConfig( decoration: BoxDecoration(), padding: EdgeInsets.all(8), itemSeparatorWidth: 8, axisAlignment: SuggestionListAlignment.left ), onTap: (item) => _onSendTap(item.text, const ReplyMessage(), MessageType.text), autoDismissOnSelection: true, suggestionItemType: SuggestionItemsType.multiline, ), // ... ) ``` -------------------------------- ### Configure Reaction Popup Source: https://context7.com/simformsolutionspvtltd/chatview/llms.txt Customize the emoji reaction popup with options for background, padding, shadow, and glass morphism effects. Handles user reactions via a callback. ```dart ChatView( chatController: chatController, chatViewState: ChatViewState.hasMessages, onSendTap: onSendTap, reactionPopupConfig: ReactionPopupConfiguration( backgroundColor: Colors.white, padding: const EdgeInsets.all(12), margin: const EdgeInsets.symmetric(horizontal: 16), maxWidth: 300, shadow: const BoxShadow( color: Colors.black26, blurRadius: 12, offset: Offset(0, 4), ), animationDuration: const Duration(milliseconds: 200), emojiConfig: const EmojiConfiguration( emojiList: ['👍', '❤️', '😂', '😮', '😢', '🙏'], size: 28, ), showGlassMorphismEffect: true, glassMorphismConfig: const GlassMorphismConfiguration( backgroundColor: Colors.white70, borderColor: Colors.white24, strokeWidth: 1, borderRadius: 16, ), userReactionCallback: (Message message, String emoji) { // Handle reaction - update backend and local state print('User reacted with $emoji on message ${message.id}'); updateMessageReaction(message.id, emoji); }, ), ) ``` -------------------------------- ### Set iOS Platform Version Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Ensure your Podfile specifies iOS 13.0 or higher for voice message functionality. ```ruby platform :ios, '13.0' ``` -------------------------------- ### Configure ChatList States Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Define custom widgets for empty chat or empty search result states within the ChatList. ```dart ChatList( // ... stateConfig: const ListStateConfig( noChatsWidgetConfig: ChatViewStateWidgetConfiguration( title: 'No Chats', subTitle: 'Start a new chat now!', showDefaultReloadButton: false, ), noSearchChatsWidgetConfig: ChatViewStateWidgetConfiguration( title: 'No Chats Found', subTitle: 'Try searching with different keywords.', showDefaultReloadButton: false, ), // ... ), // ... ) ``` -------------------------------- ### Manage Chat State with ChatController Source: https://context7.com/simformsolutionspvtltd/chatview/llms.txt Initialize and interact with the ChatController to handle messages, typing indicators, suggestions, and pagination. ```dart // Initialize ChatController with users and messages final chatController = ChatController( initialMessageList: [ Message( id: '1', message: 'Hello!', createdAt: DateTime.now().subtract(const Duration(minutes: 5)), sentBy: '2', // Other user status: MessageStatus.read, ), Message( id: '2', message: 'Hi there! How are you?', createdAt: DateTime.now().subtract(const Duration(minutes: 3)), sentBy: '1', // Current user status: MessageStatus.delivered, ), ], scrollController: ScrollController(), currentUser: const ChatUser(id: '1', name: 'John'), otherUsers: [const ChatUser(id: '2', name: 'Jane', profilePhoto: 'https://example.com/jane.jpg')], ); // Add a new message chatController.addMessage( Message( id: DateTime.now().millisecondsSinceEpoch.toString(), message: 'New message content', createdAt: DateTime.now(), sentBy: chatController.currentUser.id, messageType: MessageType.text, status: MessageStatus.pending, ), ); // Show/hide typing indicator chatController.setTypingIndicator = true; // Add reply suggestions after receiving a message chatController.addReplySuggestions([ const SuggestionItemData(text: 'Thanks!'), const SuggestionItemData(text: 'Sounds good!'), const SuggestionItemData(text: 'Let me check.'), ]); // Remove reply suggestions chatController.removeReplySuggestions(); // Load more messages for pagination chatController.loadMoreData( [ Message( id: 'old-1', message: 'Older message', createdAt: DateTime.now().subtract(const Duration(days: 1)), sentBy: '2', status: MessageStatus.read, ), ], direction: ChatPaginationDirection.previous, ); // Scroll to the last message chatController.scrollToLastMessage(); // Dispose when done chatController.dispose(); ``` -------------------------------- ### Implement onSendTap Callback Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Handle the logic for sending a new message and updating the controller. ```dart void onSendTap(String message, ReplyMessage replyMessage, MessageType messageType) { // Create a new message final newMessage = Message( id: '3', message: message, createdAt: DateTime.now(), sentBy: currentUser.id, replyMessage: replyMessage, messageType: messageType, ); // Add message to chat controller chatController.addMessage(newMessage); } ``` -------------------------------- ### Configure Reply Messages Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Set up behavior for replied messages, including auto-scroll and loading historical data. ```dart ChatView( // ... repliedMessageConfig: RepliedMessageConfiguration( loadOldReplyMessage: (messageId) async { // Load older messages that contain the replied message await _loadMessagesAround(messageId); }, backgroundColor: Colors.blue, verticalBarColor: Colors.black, repliedMsgAutoScrollConfig: RepliedMsgAutoScrollConfig( enableHighlightRepliedMsg: true, highlightColor: Colors.grey, highlightScale: 1.1, ), ), // ... ) ``` -------------------------------- ### Configure Chat Tile Appearance Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Customize the appearance and behavior of individual chat tiles using `tileConfig`. This includes handling taps, setting padding, and defining text styles. ```dart ChatList( // ... tileConfig: ListTileConfig( // ... onTap: (chat) { // Handle chat tile tap }, // Custom padding for chat tile padding: const EdgeInsets.all(12), middleWidgetPadding: const EdgeInsets.symmetric(horizontal: 12), // Custom text styles for chat tile lastMessageTextStyle: const TextStyle(color: Colors.red), userNameTextStyle: const TextStyle(fontWeight: FontWeight.bold), // Custom builders for various parts of the chat tile trailingBuilder: (chat) => const Placeholder(fallbackWidth: 40, fallbackHeight: 40), userNameBuilder: (chat) => const Placeholder(fallbackHeight: 20), lastMessageTileBuilder: (message) => const Placeholder(fallbackHeight: 20), // ... ), // ... ) ``` -------------------------------- ### Configure Replied Message Loading Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Use RepliedMessageConfiguration to define the logic for fetching and displaying historical messages when a reply is triggered. ```dart repliedMessageConfig: RepliedMessageConfiguration( loadOldReplyMessage: (messageId) async { try { // 1. Fetch historical messages containing the target message // Ensure to handle loading UI state till messages are fetched final historicalMessages = await _apiService.getMessagesAroundId( messageId: messageId, limit: 20, // Load messages around the target ); // 2. Update the message list with historical data _chatController.replaceMessageList(historicalMessages); } catch (error) { // Handle errors gracefully debugPrint('Failed to load old reply message: $error'); // Optionally show user-friendly error message } }, // Other configuration options... ), ``` -------------------------------- ### Implement Two-Way Pagination Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Enable bidirectional pagination to load older or newer messages dynamically based on scroll direction. ```dart @override Widget build(BuildContext context) { return Scaffold( body: ChatView( chatController: _chatController, // Enable pagination featureActiveConfig: FeatureActiveConfig( enablePagination: true, ), // Prevent further pagination when no more data is available. isLastPage: () => _messageCount >= _totalMessageCount, // Customize the loading indicator shown during pagination. loadingWidget: Column( mainAxisSize: MainAxisSize.min, children: [ CircularProgressIndicator(), SizedBox(height: 8), Text('Loading messages...'), ], ), // Handle loading more data for pagination. loadMoreData: (ChatPaginationDirection direction, Message referenceMessage) async { // Call your API service to load messages based on the direction and reference message final newMessages = switch (direction) { // Load older messages (when user scrolls to top) // referenceMessage is the first message in the current list ChatPaginationDirection.previous => await _apiService.getOlderMessages( beforeMessageId: referenceMessage.id, limit: 20, ), // Load newer messages (when user scrolls to bottom) // referenceMessage is the last message in the current list ChatPaginationDirection.next => await _apiService.getNewerMessages( afterMessageId: referenceMessage.id, limit: 20, ), }; // Add the loaded messages to the chat controller _chatController.loadMoreData( newMessages, direction: direction, ); }, ), ); } ``` -------------------------------- ### Configure Voice Message Recording and Playback Source: https://context7.com/simformsolutionspvtltd/chatview/llms.txt Set up voice message recording with custom recorder settings, waveform styles, and player configurations for incoming and outgoing messages. Ensure `allowRecordingVoice` is set to true in `SendMessageConfiguration` to enable voice message functionality. ```dart ChatView( chatController: chatController, chatViewState: ChatViewState.hasMessages, onSendTap: onSendTap, sendMessageConfig: SendMessageConfiguration( allowRecordingVoice: true, voiceRecordingConfiguration: VoiceRecordingConfiguration( recorderSettings: RecorderSettings( bitRate: 128000, sampleRate: 44100, androidEncoderSettings: AndroidEncoderSettings( androidEncoder: AndroidEncoder.aacLc, ), iosEncoderSettings: IosEncoderSetting( iosEncoder: IosEncoder.kAudioFormatMPEG4AAC, ), ), waveStyle: WaveStyle( showMiddleLine: false, waveColor: Colors.white, extendWaveform: true, backgroundColor: Colors.transparent, scaleFactor: 60, waveThickness: 3, spacing: 4, ), backgroundColor: Colors.blue, recorderIconColor: Colors.white, micIcon: const Icon(Icons.mic, color: Colors.white), stopIcon: const Icon(Icons.stop, color: Colors.white), ), cancelRecordConfiguration: CancelRecordConfiguration( icon: const Icon(Icons.delete_outline), iconColor: Colors.red, onCancel: () => print('Recording cancelled'), ), ), messageConfig: MessageConfiguration( voiceMessageConfig: VoiceMessageConfiguration( playerMode: PlayerMode.single, // Only one audio plays at a time margin: const EdgeInsets.symmetric(vertical: 4), padding: const EdgeInsets.all(8), playIcon: (bool isMessageBySender) => Icon( Icons.play_arrow, color: isMessageBySender ? Colors.white : Colors.black87, ), pauseIcon: (bool isMessageBySender) => Icon( Icons.pause, color: isMessageBySender ? Colors.white : Colors.black87, ), inComingPlayerWaveStyle: PlayerWaveStyle( fixedWaveColor: Colors.grey.shade400, liveWaveColor: Colors.blue, backgroundColor: Colors.transparent, scaleFactor: 60, waveThickness: 3, spacing: 4, ), outgoingPlayerWaveStyle: PlayerWaveStyle( fixedWaveColor: Colors.white54, liveWaveColor: Colors.white, backgroundColor: Colors.transparent, scaleFactor: 60, waveThickness: 3, spacing: 4, ), ), ), ) ``` -------------------------------- ### Add Custom Appbar Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Configures a custom app bar with specific title alignment and action buttons. ```dart ChatList( // ... appbar: ChatListAppBar( title: 'ChatList Demo', centerTitle: false, actions: [ IconButton( icon: const Icon(Icons.search), onPressed: () { // Handle search action }, ), ], ), // ... ) ``` -------------------------------- ### Configure Voice Messages Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Set up audio recording parameters, cancellation behavior, and playback modes for voice messages. ```dart ChatView( // ... sendMessageConfig: SendMessageConfiguration( voiceRecordingConfiguration: VoiceRecordingConfiguration( iosEncoder: IosEncoder.kAudioFormatMPEG4AAC, androidOutputFormat: AndroidOutputFormat.mpeg4, androidEncoder: AndroidEncoder.aac, bitRate: 128000, sampleRate: 44100, waveStyle: WaveStyle( showMiddleLine: false, waveColor: Colors.white, extendWaveform: true, ), ), cancelRecordConfiguration: CancelRecordConfiguration( icon: const Icon( Icons.cancel_outlined, ), onCancel: () { debugPrint('Voice recording cancelled'); }, iconColor: Colors.black, ), voiceMessageConfig: VoiceMessageConfiguration( // Determines whether single or multi player mode is enabled for audio playback. // Note: Defaults to multi-player mode. // // PlayerMode.single: // - Only one audio can be played at a time. // - Starting recording will stop any currently playing audio. // // PlayerMode.multi: // - Multiple audios can be played simultaneously. // - Starting recording will not affect any currently playing audio. playerMode: PlayerMode.single, ) ), // ... ) ``` -------------------------------- ### Add Search Functionality Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Integrates search capabilities using a TextEditingController and a debounce duration. ```dart ChatList( // ... searchConfig: SearchConfig( textEditingController: TextEditingController(), debounceDuration: const Duration(milliseconds: 300), onSearch: (value) async { if (value.isEmpty) { return null; } final list = chatListController?.chatListMap.values .where((chat) => chat.name.toLowerCase().contains(value.toLowerCase())) .toList(); return list; }, border: const OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(10)), ) ), // ... ) ``` -------------------------------- ### Configure User Avatar Display Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Customize the user avatar display using `userAvatarConfig`. Set the background color, radius, and define a callback for profile taps. ```dart ChatList( // ... tileConfig: ListTileConfig( // ... userAvatarConfig: UserAvatarConfig( backgroundColor: Colors.blue, radius: 20, onProfileTap: (value) { // Your code here }, ), // ... ), // ... ) ``` -------------------------------- ### Create Message with Reactions Source: https://context7.com/simformsolutionspvtltd/chatview/llms.txt Define a message that includes user reactions. Reactions are represented by a list of emojis and the user IDs who reacted. ```dart final messageWithReactions = Message( id: '6', message: 'Great news!', createdAt: DateTime.now(), sentBy: otherUserId, reaction: Reaction( reactions: ['👍', '❤️'], reactedUserIds: ['user1', 'user2'], ), ); ``` -------------------------------- ### Build Custom Message Views Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Implement a custom builder for displaying custom messages within ChatView. This allows for unique message rendering, such as displaying text with specific styling and truncation. ```dart ChatView( // ... messageConfig: MessageConfiguration( // by default, true showReactionsOnCustomMessages: false, customMessageBuilder: (ReplyMessage state) { return Text( state.message, maxLines: 1, overflow: TextOverflow.ellipsis, style: const TextStyle( fontSize: 12, color: Colors.black, ), ); }, ), // ... ) ``` -------------------------------- ### Configure ChatView Message Input Source: https://context7.com/simformsolutionspvtltd/chatview/llms.txt Use SendMessageConfiguration to define the behavior and styling of the input field, including voice recording settings and custom action buttons for media. ```dart ChatView( chatController: chatController, chatViewState: ChatViewState.hasMessages, onSendTap: onSendTap, sendMessageConfig: SendMessageConfiguration( textFieldBackgroundColor: Colors.grey.shade100, defaultSendButtonColor: Colors.blue, replyDialogColor: Colors.white, replyTitleColor: Colors.black87, replyMessageColor: Colors.grey, allowRecordingVoice: true, shouldSendImageWithText: true, voiceRecordingConfiguration: VoiceRecordingConfiguration( recorderSettings: RecorderSettings( bitRate: 128000, sampleRate: 44100, androidEncoderSettings: AndroidEncoderSettings( androidEncoder: AndroidEncoder.aacLc, ), iosEncoderSettings: IosEncoderSetting( iosEncoder: IosEncoder.kAudioFormatMPEG4AAC, ), ), waveStyle: WaveStyle( showMiddleLine: false, waveColor: Colors.blue, extendWaveform: true, ), recorderIconColor: Colors.blue, ), cancelRecordConfiguration: CancelRecordConfiguration( icon: const Icon(Icons.delete), iconColor: Colors.red, onCancel: () => print('Recording cancelled'), ), textFieldConfig: TextFieldConfiguration( hintText: 'Type a message...', maxLines: 5, minLines: 1, textStyle: const TextStyle(fontSize: 16), borderRadius: BorderRadius.circular(24), contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), onMessageTyping: (TypeWriterStatus status) { // Notify backend about typing status if (status == TypeWriterStatus.typing) { sendTypingIndicator(isTyping: true); } else { sendTypingIndicator(isTyping: false); } }, leadingActions: (context, controller) => [ CameraActionButton( icon: const Icon(Icons.camera_alt, color: Colors.blue), onPressed: (String? imagePath, ReplyMessage? replyMessage) { if (imagePath != null) { chatController.addMessage(Message( id: DateTime.now().millisecondsSinceEpoch.toString(), message: imagePath, createdAt: DateTime.now(), messageType: MessageType.image, sentBy: chatController.currentUser.id, replyMessage: replyMessage ?? const ReplyMessage(), )); } }, ), ], trailingActions: (context, controller) => [ GalleryActionButton( icon: const Icon(Icons.photo, color: Colors.grey), onPressed: (String? imagePath, ReplyMessage? replyMessage) { if (imagePath != null) { chatController.addMessage(Message( id: DateTime.now().millisecondsSinceEpoch.toString(), message: imagePath, createdAt: DateTime.now(), messageType: MessageType.image, sentBy: chatController.currentUser.id, replyMessage: replyMessage ?? const ReplyMessage(), )); } }, ), EmojiPickerActionButton( context: context, icon: const Icon(Icons.emoji_emotions, color: Colors.grey), onPressed: (String? emoji, ReplyMessage? replyMessage) { if (emoji != null) { chatController.addMessage(Message( id: DateTime.now().millisecondsSinceEpoch.toString(), message: emoji, createdAt: DateTime.now(), sentBy: chatController.currentUser.id, replyMessage: replyMessage ?? const ReplyMessage(), )); } }, ), ], ), ), ) ``` -------------------------------- ### Create Message with Reply Source: https://context7.com/simformsolutionspvtltd/chatview/llms.txt Construct a message that includes a reply to another message. The reply details include the original message ID, content, sender, and type. ```dart final replyMessage = Message( id: '5', message: 'This is my reply', createdAt: DateTime.now(), sentBy: currentUserId, messageType: MessageType.text, replyMessage: ReplyMessage( messageId: '1', message: 'Hello, how are you?', replyTo: otherUserId, replyBy: currentUserId, messageType: MessageType.text, ), ); ``` -------------------------------- ### Update Voice Recording Configuration in ChatView Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Migrate from previous voice recording configurations to the new RecorderSettings in ChatView 3.0.0. The androidOutputFormat property has been removed. ```dart ChatView( sendMessageConfig: SendMessageConfiguration( voiceRecordingConfiguration: VoiceRecordingConfiguration( sampleRate: 44100, bitRate: 128000, iosEncoder: IosEncoder.kAudioFormatMPEG4AAC, androidEncoder: AndroidEncoder.aacLc, androidOutputFormat: AndroidOutputFormat.mpeg4, ), ), ) ``` ```dart ChatView( sendMessageConfig: SendMessageConfiguration( voiceRecordingConfiguration: VoiceRecordingConfiguration( recorderSettings: RecorderSettings( bitRate: 128000, sampleRate: 44100, androidEncoderSettings: AndroidEncoderSettings( androidEncoder: AndroidEncoder.aacLc, ), iosEncoderSettings: IosEncoderSetting( iosEncoder: IosEncoder.kAudioFormatMPEG4AAC, ), ), ), ), ) ``` -------------------------------- ### Build Custom Reply Message View Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Define a custom UI for the reply message section in ChatView. This builder allows for complete control over the appearance and behavior of the reply message display, including a close button. ```dart ChatView( // ... replyMessageBuilder: (context, state) { return Container( decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.vertical( top: Radius.circular(14), ), ), margin: const EdgeInsets.only( bottom: 17, right: 0.4, left: 0.4, ), padding: const EdgeInsets.fromLTRB(10, 10, 10, 30), child: Container( padding: const EdgeInsets.symmetric( horizontal: 6, ), decoration: BoxDecoration( color: Colors.grey.shade200, borderRadius: BorderRadius.circular(12), ), child: Column( mainAxisSize: MainAxisSize.min, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Text( state.message, maxLines: 1, overflow: TextOverflow.ellipsis, style: const TextStyle( fontWeight: FontWeight.bold, ), ), ), IconButton( constraints: const BoxConstraints(), padding: EdgeInsets.zero, icon: const Icon( Icons.close, size: 16, ), onPressed: () => ChatView.closeReplyMessageView(context), ), ], ), ], ), ), ); }, // ... ) ``` -------------------------------- ### iOS Info.plist Configuration for Voice Messages Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Add the NSMicrophoneUsageDescription key to your iOS Info.plist for voice message recording. ```xml NSMicrophoneUsageDescription This app requires Mic permission. ``` -------------------------------- ### Configure Typing Indicator Colors and Custom Indicator Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Customize the colors of the typing indicator's flashing circles or provide a completely custom widget for the indicator. Use `setTypingIndicator` on the `_chatController` to show or hide it. ```dart ChatView( // ... typeIndicatorConfig: TypeIndicatorConfiguration( flashingCircleBrightColor: Colors.grey, flashingCircleDarkColor: Colors.black, // For custom indicator // padding: const EdgeInsets.only(left: 12), // customIndicator: Container( // margin: const EdgeInsets.only(left: 8), // decoration: const BoxDecoration( // color: Colors.white, // borderRadius: BorderRadius.all(Radius.circular(30)), // ), // padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), // child: const Text('Typing...'), // ), ), // ... ) // Show/hide typing indicator _chatController.setTypingIndicator = true; // Show indicator _chatController.setTypingIndicator = false; // Hide indicator ``` -------------------------------- ### Add Android RECORD_AUDIO Permission Source: https://github.com/simformsolutionspvtltd/chatview/blob/main/doc/documentation.md Include the RECORD_AUDIO permission in your AndroidManifest.xml to enable voice message recording. ```xml ``` -------------------------------- ### Create Different Message Types Source: https://context7.com/simformsolutionspvtltd/chatview/llms.txt Instantiate various message types including text, image, voice, and custom messages. Supports setting message ID, content, timestamp, sender, type, and status. Custom messages can hold JSON data. ```dart final textMessage = Message( id: '1', message: 'Hello, how are you?', createdAt: DateTime.now(), sentBy: currentUserId, messageType: MessageType.text, status: MessageStatus.pending, ); ``` ```dart final imageMessage = Message( id: '2', message: '/path/to/image.jpg', // Local path or URL createdAt: DateTime.now(), sentBy: currentUserId, messageType: MessageType.image, status: MessageStatus.pending, ); ``` ```dart final voiceMessage = Message( id: '3', message: '/path/to/audio.m4a', createdAt: DateTime.now(), sentBy: currentUserId, messageType: MessageType.voice, voiceMessageDuration: const Duration(seconds: 15), status: MessageStatus.pending, ); ``` ```dart final customMessage = Message( id: '4', message: 'custom_data_json', createdAt: DateTime.now(), sentBy: currentUserId, messageType: MessageType.custom, status: MessageStatus.pending, ); ```