Skip to content

Commit 15e0665

Browse files
committed
feat: ✨ Add support for plus icon and action items in chat text field
1 parent 39d1adf commit 15e0665

17 files changed

+581
-316
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
## [2.4.2] (unreleased)
22

3+
* **Breaking**: [318](https://github.com/SimformSolutionsPvtLtd/flutter_chatview/issues/318)
4+
Provide support for action item widgets on the chat text field with position options leading and trailing.
5+
Also, provide a way to add plus/attach button to open the overlay for action items.
36
* **Fix**: [266](https://github.com/SimformSolutionsPvtLtd/flutter_chatview/issues/266)
47
Fix the keyboard overlapping the text field
58
* **Feat**: [296](https://github.com/SimformSolutionsPvtLtd/flutter_chatview/issues/296)

doc/documentation.md

Lines changed: 61 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -530,182 +530,83 @@ real-time messaging with supporting media uploads.
530530

531531
# Migration Guide
532532

533-
## Migration Guide for ChatView 2.0.0
534-
This guide will help you migrate your code from previous versions of ChatView to version 2.0.0.
533+
## Migration Guide for ChatView 3.0.0
534+
This guide will help you migrate your code from previous versions of ChatView to version 3.0.0.
535535

536536
## Key Changes
537537

538-
### Renamed Properties
538+
### Add action item widgets list for text field
539539

540-
- Renamed `sendBy` field to `sentBy` in `Message` class.
541-
- Renamed `chatUsers` field to `otherUsers` in `ChatController` class.
540+
- In this version, we have introduced a new way to add action items to the text field.
541+
- There are two ways you can add action items at leading and trailing positions of the text field.
542+
- `textFieldLeadingActionWidgetBuilder`: This builder allows you to add list of action widgets at the leading position of the text field.
543+
- `textFieldTrailingActionWidgetBuilder`: This builder allows you to add list of action widgets at the trailing position of the text field.
544+
- Add `CameraActionButton` and `GalleryActionButton` widgets as list to leading and trailing builder fo the text field for camera and gallery actions.
545+
- Now, you can add overlay action button to show overlay action items in the text field.
546+
- With multiple action items
542547

543-
### Moved Properties
548+
To show camera and gallery action items in the text field at leading position, you can use `textFieldLeadingActionWidgetBuilder`.
544549

545-
- Moved `currentUser` field from `ChatView` widget to `ChatController` class.
546-
547-
### Updated Methods
548-
549-
- Updated `id` value in `copyWith` method of `Message` to have correct value.
550-
- Removed `showTypingIndicator` field from `ChatView` and replaced it with `ChatController.showTypingIndicator`.
551-
552-
### JSON Serialization Changes
553-
554-
The format for `fromJson` and `toJson` methods changed for several classes:
555-
556-
#### ChatUser
557-
558-
**Before (`ChatUser.fromJson`):**
559-
```dart
560-
ChatUser.fromJson(
561-
{
562-
...
563-
'imageType': ImageType.asset,
564-
...
565-
},
566-
),
567-
```
568-
569-
**After (`ChatUser.fromJson`):**
570550
```dart
571-
ChatUser.fromJson(
572-
{
573-
...
574-
'imageType': 'asset',
575-
...
576-
},
577-
),
578-
```
579-
580-
**Before (`ChatUser.toJson`):**
581-
```dart
582-
{
583-
...
584-
imageType: ImageType.asset,
585-
...
586-
}
587-
```
588-
589-
**After (`ChatUser.toJson`):**
590-
```dart
591-
{
592-
...
593-
imageType: asset,
594-
...
595-
}
596-
```
597-
598-
#### Message
599-
600-
**Before (`Message.fromJson`):**
601-
```dart
602-
Message.fromJson(
603-
{
604-
...
605-
'createdAt': DateTime.now(),
606-
'message_type': MessageType.text,
607-
'voice_message_duration': Duration(seconds: 5),
608-
...
609-
}
610-
)
611-
```
612-
613-
**After (`Message.fromJson`):**
614-
```dart
615-
Message.fromJson(
616-
{
617-
...
618-
'createdAt': '2024-06-13T17:32:19.586412',
619-
'message_type': 'text',
620-
'voice_message_duration': '5000000',
621-
...
551+
textFieldConfig: TextFieldConfiguration(
552+
textFieldLeadingActionWidgetBuilder: (context, controller) {
553+
return [
554+
CameraActionButton(
555+
icon: const Icon(
556+
Icons.camera_alt,
557+
),
558+
onPressed: (path) {
559+
if (path != null) {
560+
_onSendTap(path, const ReplyMessage(), MessageType.image);
561+
}
562+
},
563+
),
564+
GalleryActionButton(
565+
icon: const Icon(
566+
Icons.photo_library,
567+
),
568+
onPressed: (path) {
569+
if (path != null) {
570+
_onSendTap(path, const ReplyMessage(), MessageType.image);
571+
}
572+
},
573+
),
574+
];
622575
}
623-
)
624-
```
625-
626-
**Before (`Message.toJson`):**
627-
```dart
628-
{
629-
...
630-
createdAt: 2024-06-13 17:23:19.454789,
631-
message_type: MessageType.text,
632-
voice_message_duration: 0:00:05.000000,
633-
...
634-
}
635-
```
636-
637-
**After (`Message.toJson`):**
638-
```dart
639-
{
640-
...
641-
createdAt: 2024-06-13T17:32:19.586412,
642-
message_type: text,
643-
voice_message_duration: 5000000,
644-
...
645-
}
576+
),
646577
```
647578

648-
#### ReplyMessage
579+
The same way you can add action items at trailing position of the text field using `textFieldTrailingActionWidgetBuilder`.
649580

650-
**Before (`ReplyMessage.fromJson`):**
651581
```dart
652-
ReplyMessage.fromJson(
653-
{
654-
...
655-
'message_type': MessageType.text,
656-
'voiceMessageDuration': Duration(seconds: 5),
657-
...
658-
}
659-
)
660-
```
661-
662-
**After (`ReplyMessage.fromJson`):**
663-
```dart
664-
ReplyMessage.fromJson(
665-
{
666-
...
667-
'message_type': 'text',
668-
'voiceMessageDuration': '5000000',
669-
...
582+
textFieldConfig: TextFieldConfiguration(
583+
textFieldTrailingActionWidgetBuilder: (context, controller) {
584+
return [
585+
CameraActionButton(
586+
icon: const Icon(
587+
Icons.camera_alt,
588+
),
589+
onPressed: (path) {
590+
if (path != null) {
591+
_onSendTap(path, const ReplyMessage(), MessageType.image);
592+
}
593+
},
594+
),
595+
GalleryActionButton(
596+
icon: const Icon(
597+
Icons.photo_library,
598+
),
599+
onPressed: (path) {
600+
if (path != null) {
601+
_onSendTap(path, const ReplyMessage(), MessageType.image);
602+
}
603+
},
604+
),
605+
];
670606
}
671-
)
672-
```
673-
674-
**Before (`ReplyMessage.toJson`):**
675-
```dart
676-
{
677-
...
678-
message_type: MessageType.text,
679-
voiceMessageDuration: 0:00:05.000000,
680-
...
681-
}
682-
```
683-
684-
**After (`ReplyMessage.toJson`):**
685-
```dart
686-
{
687-
...
688-
message_type: text,
689-
voiceMessageDuration: 5000000,
690-
...
691-
}
692-
```
693-
694-
## Typing Indicator Changes
695-
696-
**Before:**
697-
```dart
698-
ChatView(
699-
showTypingIndicator: false,
700607
),
701608
```
702609

703-
**After:**
704-
```dart
705-
// Use it with your ChatController instance
706-
_chatController.setTypingIndicator = true; // for showing indicator
707-
_chatController.setTypingIndicator = false; // for hiding indicator
708-
```
709610

710611
# Contributors
711612

example/lib/main.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,28 +43,28 @@ class _ChatScreenState extends State<ChatScreen> {
4343
_chatController = ChatController(
4444
initialMessageList: Data.messageList,
4545
scrollController: ScrollController(),
46-
currentUser: ChatUser(
46+
currentUser: const ChatUser(
4747
id: '1',
4848
name: 'Flutter',
4949
profilePhoto: Data.profileImage,
5050
),
5151
otherUsers: [
52-
ChatUser(
52+
const ChatUser(
5353
id: '2',
5454
name: 'Simform',
5555
profilePhoto: Data.profileImage,
5656
),
57-
ChatUser(
57+
const ChatUser(
5858
id: '3',
5959
name: 'Jhon',
6060
profilePhoto: Data.profileImage,
6161
),
62-
ChatUser(
62+
const ChatUser(
6363
id: '4',
6464
name: 'Mike',
6565
profilePhoto: Data.profileImage,
6666
),
67-
ChatUser(
67+
const ChatUser(
6868
id: '5',
6969
name: 'Rich',
7070
profilePhoto: Data.profileImage,

lib/chatview.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,9 @@ export 'src/utils/chat_view_locale.dart';
3939
export 'src/utils/package_strings.dart';
4040
export 'src/values/enumeration.dart';
4141
export 'src/values/typedefs.dart';
42+
export 'src/widgets/action_widgets/camera_action_button.dart';
43+
export 'src/widgets/action_widgets/gallery_action_button.dart';
44+
export 'src/widgets/action_widgets/overlay_action_button.dart';
45+
export 'src/widgets/action_widgets/text_field_action_button.dart';
4246
export 'src/widgets/chat_view.dart';
4347
export 'src/widgets/chat_view_appbar.dart';

lib/src/models/config_models/send_message_configuration.dart

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121
*/
2222

2323
import 'package:audio_waveforms/audio_waveforms.dart';
24+
import 'package:chatview_utils/chatview_utils.dart';
2425
import 'package:flutter/material.dart';
2526
import 'package:flutter/services.dart';
26-
import 'package:chatview_utils/chatview_utils.dart';
2727
import 'package:image_picker/image_picker.dart';
2828

2929
import '../../values/typedefs.dart';
@@ -62,12 +62,6 @@ class SendMessageConfiguration {
6262
/// Enable/disable voice recording. Enabled by default.
6363
final bool allowRecordingVoice;
6464

65-
/// Enable/disable image picker from gallery. Enabled by default.
66-
final bool enableGalleryImagePicker;
67-
68-
/// Enable/disable send image from camera. Enabled by default.
69-
final bool enableCameraImagePicker;
70-
7165
/// Color of mic icon when replying to some voice message.
7266
final Color? micIconColor;
7367

@@ -89,8 +83,6 @@ class SendMessageConfiguration {
8983
this.replyMessageColor,
9084
this.closeIconColor,
9185
this.allowRecordingVoice = true,
92-
this.enableCameraImagePicker = true,
93-
this.enableGalleryImagePicker = true,
9486
this.voiceRecordingConfiguration,
9587
this.micIconColor,
9688
this.cancelRecordConfiguration,
@@ -168,6 +160,19 @@ class TextFieldConfiguration {
168160
/// Default is [true].
169161
final bool enabled;
170162

163+
/// List of widgets to be shown as action widget in text field.
164+
final TextFieldTrailingActionWidgetBuilder?
165+
textFieldTrailingActionWidgetBuilder;
166+
167+
/// List of widgets to be shown as leading action widget in text field.
168+
final TextFieldLeadingActionWidgetBuilder?
169+
textFieldLeadingActionWidgetBuilder;
170+
171+
/// hint text max lines in text field.
172+
final int? hintMaxLines;
173+
174+
final bool hideLeadingActionsOnType;
175+
171176
const TextFieldConfiguration({
172177
this.contentPadding,
173178
this.maxLines,
@@ -184,6 +189,10 @@ class TextFieldConfiguration {
184189
this.inputFormatters,
185190
this.textCapitalization,
186191
this.enabled = true,
192+
this.textFieldTrailingActionWidgetBuilder,
193+
this.textFieldLeadingActionWidgetBuilder,
194+
this.hintMaxLines,
195+
this.hideLeadingActionsOnType = true,
187196
});
188197
}
189198

lib/src/models/models.dart

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,25 @@
2020
* SOFTWARE.
2121
*/
2222
export 'chat_bubble.dart';
23+
export 'config_models/chat_bubble_configuration.dart';
24+
export 'config_models/chat_view_states_configuration.dart';
25+
export 'config_models/emoji_message_configuration.dart';
26+
export 'config_models/feature_active_config.dart';
2327
export 'config_models/image_message_configuration.dart';
28+
export 'config_models/link_preview_configuration.dart';
29+
export 'config_models/message_configuration.dart';
30+
export 'config_models/message_list_configuration.dart';
2431
export 'config_models/message_reaction_configuration.dart';
2532
export 'config_models/profile_circle_configuration.dart';
26-
export 'config_models/chat_bubble_configuration.dart';
27-
export 'config_models/replied_message_configuration.dart';
28-
export 'config_models/swipe_to_reply_configuration.dart';
29-
export 'config_models/reply_popup_configuration.dart';
3033
export 'config_models/reaction_popup_configuration.dart';
31-
export 'config_models/message_list_configuration.dart';
32-
export 'config_models/emoji_message_configuration.dart';
33-
export 'config_models/message_configuration.dart';
34-
export 'config_models/send_message_configuration.dart';
35-
export 'config_models/link_preview_configuration.dart';
36-
export 'config_models/type_indicator_configuration.dart';
37-
export 'config_models/chat_view_states_configuration.dart';
34+
export 'config_models/replied_message_configuration.dart';
3835
export 'config_models/replied_msg_auto_scroll_config.dart';
39-
export 'config_models/feature_active_config.dart';
36+
export 'config_models/reply_popup_configuration.dart';
4037
export 'config_models/reply_suggestions_config.dart';
41-
export 'config_models/suggestion_list_config.dart';
4238
export 'config_models/scroll_to_bottom_button_config.dart';
39+
export 'config_models/send_message_configuration.dart';
40+
export 'config_models/suggestion_list_config.dart';
41+
export 'config_models/swipe_to_reply_configuration.dart';
42+
export 'config_models/type_indicator_configuration.dart';
4343
export 'config_models/voice_message_configuration.dart';
44+
export 'overlay_action_widget.dart';

0 commit comments

Comments
 (0)