From bc9d53624f3b930e409daa36acf61fc1d1f3a878 Mon Sep 17 00:00:00 2001 From: RaulRodrigo06 Date: Fri, 20 Oct 2023 15:16:14 -0300 Subject: [PATCH 1/9] feat: adding reply container --- .../controllers/chat/ds_reply.controller.dart | 15 +++ lib/src/themes/colors/ds_colors.theme.dart | 2 + .../audio/ds_audio_message_bubble.widget.dart | 3 + .../ds_application_json_bubble.widget.dart | 4 + .../ds_contact_message_bubble.widget.dart | 3 + .../chat/ds_file_message_bubble.widget.dart | 3 + .../chat/ds_image_message_bubble.widget.dart | 3 + .../ds_location_message_bubble.widget.dart | 3 + .../chat/ds_message_bubble.widget.dart | 17 ++- .../chat/ds_reply_container.widget.dart | 116 ++++++++++++++++++ .../ds_request_location_bubble.widget.dart | 3 + .../chat/ds_text_message_bubble.widget.dart | 3 + ...pported_content_message_bubble.widget.dart | 3 + lib/src/widgets/chat/ds_weblink.widget.dart | 5 + .../video/ds_video_message_bubble.widget.dart | 5 + lib/src/widgets/utils/ds_card.widget.dart | 16 +++ .../widgets/utils/ds_group_card.widget.dart | 8 ++ 17 files changed, 211 insertions(+), 1 deletion(-) create mode 100644 lib/src/controllers/chat/ds_reply.controller.dart create mode 100644 lib/src/widgets/chat/ds_reply_container.widget.dart diff --git a/lib/src/controllers/chat/ds_reply.controller.dart b/lib/src/controllers/chat/ds_reply.controller.dart new file mode 100644 index 00000000..0586f3fb --- /dev/null +++ b/lib/src/controllers/chat/ds_reply.controller.dart @@ -0,0 +1,15 @@ +import 'package:get/get.dart'; + +import '../../models/ds_message_item.model.dart'; + +class DSReplyController extends GetxController { + final List messages = []; + + void addMessages(List newMessages) { + messages.addAll(newMessages); + } + + DSMessageItemModel? getMessageById(String id) { + return messages.firstWhereOrNull((element) => element.id == id); + } +} diff --git a/lib/src/themes/colors/ds_colors.theme.dart b/lib/src/themes/colors/ds_colors.theme.dart index a8bcf7c2..dbc496c4 100644 --- a/lib/src/themes/colors/ds_colors.theme.dart +++ b/lib/src/themes/colors/ds_colors.theme.dart @@ -51,6 +51,8 @@ abstract class DSColors { static const Color surface1 = Color(0xFFF6F6F6); static const Color surface3 = Color(0xFFC7C7C7); static const Color contentDefault = Color(0xFF454545); + static const Color contentGhost = Color(0xFF949494); + static const Color disabledText = Color(0xFF637798); static const Color disabledBg = Color(0xFFE8F2FF); diff --git a/lib/src/widgets/chat/audio/ds_audio_message_bubble.widget.dart b/lib/src/widgets/chat/audio/ds_audio_message_bubble.widget.dart index e1c955d4..aa01d4b4 100644 --- a/lib/src/widgets/chat/audio/ds_audio_message_bubble.widget.dart +++ b/lib/src/widgets/chat/audio/ds_audio_message_bubble.widget.dart @@ -15,6 +15,7 @@ class DSAudioMessageBubble extends StatelessWidget { final String? uniqueId; final String audioType; final bool shouldAuthenticate; + final String? replyId; DSAudioMessageBubble({ super.key, @@ -22,6 +23,7 @@ class DSAudioMessageBubble extends StatelessWidget { required this.align, required this.audioType, this.uniqueId, + this.replyId, this.borderRadius = const [DSBorderRadius.all], this.shouldAuthenticate = false, final DSMessageBubbleStyle? style, @@ -35,6 +37,7 @@ class DSAudioMessageBubble extends StatelessWidget { return DSMessageBubble( borderRadius: borderRadius, align: align, + replyId: replyId, style: style, padding: const EdgeInsets.only( left: 4.0, diff --git a/lib/src/widgets/chat/ds_application_json_bubble.widget.dart b/lib/src/widgets/chat/ds_application_json_bubble.widget.dart index 2463c596..2ec30d9c 100644 --- a/lib/src/widgets/chat/ds_application_json_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_application_json_bubble.widget.dart @@ -15,12 +15,14 @@ class DSApplicationJsonMessageBubble extends StatelessWidget { required this.borderRadius, required this.content, this.status, + this.replyId, DSMessageBubbleStyle? style, }) : style = style ?? DSMessageBubbleStyle(); final DSAlign align; final List borderRadius; final Map content; + final String? replyId; final DSDeliveryReportStatus? status; final DSMessageBubbleStyle style; @@ -31,6 +33,7 @@ class DSApplicationJsonMessageBubble extends StatelessWidget { opacity: status == DSDeliveryReportStatus.failed ? .3 : 1, child: DSUnsupportedContentMessageBubble( align: align, + replyId: replyId, borderRadius: borderRadius, style: style, overflow: TextOverflow.visible, @@ -50,6 +53,7 @@ class DSApplicationJsonMessageBubble extends StatelessWidget { align: align, borderRadius: borderRadius, style: style, + replyId: replyId, ); } } diff --git a/lib/src/widgets/chat/ds_contact_message_bubble.widget.dart b/lib/src/widgets/chat/ds_contact_message_bubble.widget.dart index 5cdbb064..664ca2d1 100644 --- a/lib/src/widgets/chat/ds_contact_message_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_contact_message_bubble.widget.dart @@ -6,6 +6,7 @@ class DSContactMessageBubble extends StatelessWidget { final String? phone; final String? email; final String? address; + final String? replyId; final DSAlign align; final List borderRadius; final DSMessageBubbleStyle style; @@ -17,6 +18,7 @@ class DSContactMessageBubble extends StatelessWidget { required this.address, required this.email, required this.align, + this.replyId, this.borderRadius = const [DSBorderRadius.all], DSMessageBubbleStyle? style, }) : style = style ?? DSMessageBubbleStyle(); @@ -29,6 +31,7 @@ class DSContactMessageBubble extends StatelessWidget { padding: const EdgeInsets.all(16.0), shouldUseDefaultSize: true, style: style, + replyId: replyId, child: _buildContactCard(), ); } diff --git a/lib/src/widgets/chat/ds_file_message_bubble.widget.dart b/lib/src/widgets/chat/ds_file_message_bubble.widget.dart index 5f605fab..21b63e25 100644 --- a/lib/src/widgets/chat/ds_file_message_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_file_message_bubble.widget.dart @@ -22,6 +22,7 @@ class DSFileMessageBubble extends StatelessWidget { final List borderRadius; final DSMessageBubbleStyle style; final bool shouldAuthenticate; + final String? replyId; /// Creates a Design System's [DSMessageBubble] used on files other than image, audio, or video DSFileMessageBubble({ @@ -30,6 +31,7 @@ class DSFileMessageBubble extends StatelessWidget { required this.url, required this.size, required this.filename, + this.replyId, this.borderRadius = const [DSBorderRadius.all], this.shouldAuthenticate = false, DSMessageBubbleStyle? style, @@ -46,6 +48,7 @@ class DSFileMessageBubble extends StatelessWidget { ), child: DSMessageBubble( borderRadius: borderRadius, + replyId: replyId, padding: EdgeInsets.zero, align: align, style: style, diff --git a/lib/src/widgets/chat/ds_image_message_bubble.widget.dart b/lib/src/widgets/chat/ds_image_message_bubble.widget.dart index 51759838..e266ead7 100644 --- a/lib/src/widgets/chat/ds_image_message_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_image_message_bubble.widget.dart @@ -29,6 +29,7 @@ class DSImageMessageBubble extends StatefulWidget { this.showSelect = false, this.onSelected, this.onOpenLink, + this.replyId, this.shouldAuthenticate = false, }) : style = style ?? DSMessageBubbleStyle(); @@ -40,6 +41,7 @@ class DSImageMessageBubble extends StatefulWidget { final String? text; final String appBarText; final Uri? appBarPhotoUri; + final String? replyId; final DSMessageBubbleStyle style; final List selectOptions; final bool showSelect; @@ -73,6 +75,7 @@ class _DSImageMessageBubbleState extends State defaultMaxSize: 360.0, shouldUseDefaultSize: true, align: widget.align, + replyId:widget.replyId, borderRadius: widget.borderRadius, padding: EdgeInsets.zero, hasSpacer: widget.hasSpacer, diff --git a/lib/src/widgets/chat/ds_location_message_bubble.widget.dart b/lib/src/widgets/chat/ds_location_message_bubble.widget.dart index a838ca8c..688361b9 100644 --- a/lib/src/widgets/chat/ds_location_message_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_location_message_bubble.widget.dart @@ -16,6 +16,7 @@ class DSLocationMessageBubble extends StatelessWidget { final DSAlign align; final DSMessageBubbleStyle style; final String? title; + final String? replyId; final String latitude; final String longitude; final List borderRadius; @@ -25,6 +26,7 @@ class DSLocationMessageBubble extends StatelessWidget { required this.align, required this.latitude, required this.longitude, + this.replyId, this.borderRadius = const [DSBorderRadius.all], DSMessageBubbleStyle? style, this.title, @@ -56,6 +58,7 @@ class DSLocationMessageBubble extends StatelessWidget { defaultMaxSize: 240.0, defaultMinSize: 240.0, borderRadius: borderRadius, + replyId: replyId, padding: EdgeInsets.zero, align: align, style: style, diff --git a/lib/src/widgets/chat/ds_message_bubble.widget.dart b/lib/src/widgets/chat/ds_message_bubble.widget.dart index cb1a62c5..bcea3632 100644 --- a/lib/src/widgets/chat/ds_message_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_message_bubble.widget.dart @@ -1,3 +1,4 @@ +import 'package:blip_ds/src/widgets/chat/ds_reply_container.widget.dart'; import 'package:flutter/material.dart'; import '../../enums/ds_align.enum.dart'; @@ -10,6 +11,7 @@ import '../animations/ds_animated_size.widget.dart'; class DSMessageBubble extends StatelessWidget { final DSAlign align; final Widget child; + final String? replyId; final List borderRadius; final EdgeInsets padding; final bool shouldUseDefaultSize; @@ -22,6 +24,7 @@ class DSMessageBubble extends StatelessWidget { Key? key, required this.align, required this.child, + this.replyId, this.borderRadius = const [DSBorderRadius.all], this.padding = const EdgeInsets.symmetric( vertical: 8.0, @@ -60,7 +63,19 @@ class DSMessageBubble extends StatelessWidget { : null, padding: padding, color: style.bubbleBackgroundColor(align), - child: child, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (replyId != null) + DSReplyContainer( + replyId: replyId!, + style: style, + align: align, + ), + child, + ], + ), ), ), ), diff --git a/lib/src/widgets/chat/ds_reply_container.widget.dart b/lib/src/widgets/chat/ds_reply_container.widget.dart new file mode 100644 index 00000000..a4528871 --- /dev/null +++ b/lib/src/widgets/chat/ds_reply_container.widget.dart @@ -0,0 +1,116 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; + +import '../../controllers/chat/ds_reply.controller.dart'; +import '../../enums/ds_align.enum.dart'; +import '../../models/ds_message_bubble_style.model.dart'; +import '../../themes/colors/ds_colors.theme.dart'; +import '../../themes/icons/ds_icons.dart'; +import '../../utils/ds_message_content_type.util.dart'; +import '../texts/ds_body_text.widget.dart'; + +class DSReplyContainer extends StatelessWidget { + const DSReplyContainer({ + super.key, + required this.replyId, + required this.style, + required this.align, + }); + + final DSAlign align; + final String replyId; + final DSMessageBubbleStyle style; + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.only( + top: 8.0, + left: 8.0, + right: 8.0, + ), + child: DecoratedBox( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4.0), + border: Border.all( + color: style.isLightBubbleBackground(align) + ? DSColors.contentGhost + : DSColors.contentDisable, + ), + color: style.isLightBubbleBackground(align) + ? DSColors.surface3 + : DSColors.contentDefault, + ), + child: IntrinsicHeight( + child: Row( + children: [ + Container( + decoration: const ShapeDecoration( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(8.0), + bottomLeft: Radius.circular(8.0), + ), + ), + color: DSColors.primary, + ), + width: 4.0, + ), + Flexible( + child: Padding( + padding: const EdgeInsets.only( + top: 8.0, + left: 8.0, + bottom: 8.0, + ), + child: _replyWidget(replyId, style, align), + ), + ), + ], + ), + ), + ), + ); + } +} + +Widget _replyWidget( + String id, + DSMessageBubbleStyle style, + DSAlign align, +) { + final replyController = Get.find(); + final message = replyController.getMessageById(id); + + switch (message?.type) { + case DSMessageContentType.textPlain: + return DSBodyText( + message?.content is String ? message?.content : '**********', + color: style.isLightBubbleBackground(align) + ? DSColors.contentDefault + : DSColors.neutralLightSnow, + ); + default: + return Row( + mainAxisSize: MainAxisSize.max, + children: [ + Icon( + DSIcons.warning_outline, + color: style.isLightBubbleBackground(align) + ? DSColors.contentDefault + : DSColors.neutralLightSnow, + ), + const SizedBox(width: 8), + Flexible( + child: DSBodyText( + 'Falha ao carregar mensagem', + overflow: TextOverflow.visible, + color: style.isLightBubbleBackground(align) + ? DSColors.contentDefault + : DSColors.neutralLightSnow, + ), + ), + ], + ); + } +} diff --git a/lib/src/widgets/chat/ds_request_location_bubble.widget.dart b/lib/src/widgets/chat/ds_request_location_bubble.widget.dart index 511b7923..d8ceba85 100644 --- a/lib/src/widgets/chat/ds_request_location_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_request_location_bubble.widget.dart @@ -14,6 +14,7 @@ class DSRequestLocationBubble extends StatelessWidget { required this.label, required this.value, required this.align, + this.replyId, this.type = DSMessageContentType.textPlain, this.borderRadius = const [DSBorderRadius.all], this.showRequestLocationButton = false, @@ -23,6 +24,7 @@ class DSRequestLocationBubble extends StatelessWidget { final String? label; final String type; final String? value; + final String? replyId; final DSAlign align; final List borderRadius; final bool showRequestLocationButton; @@ -45,6 +47,7 @@ class DSRequestLocationBubble extends StatelessWidget { ), child: DSTextMessageBubble( text: value!, + replyId: replyId, align: align, borderRadius: borderRadius, style: style, diff --git a/lib/src/widgets/chat/ds_text_message_bubble.widget.dart b/lib/src/widgets/chat/ds_text_message_bubble.widget.dart index b82d4a50..35faf79d 100644 --- a/lib/src/widgets/chat/ds_text_message_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_text_message_bubble.widget.dart @@ -16,6 +16,7 @@ class DSTextMessageBubble extends StatefulWidget { final bool hasSpacer; final List borderRadius; final dynamic selectContent; + final String? replyId; final bool showSelect; final void Function(String, Map)? onSelected; final DSMessageBubbleStyle style; @@ -24,6 +25,7 @@ class DSTextMessageBubble extends StatefulWidget { Key? key, required this.text, required this.align, + this.replyId, this.borderRadius = const [DSBorderRadius.all], this.selectContent, this.hasSpacer = true, @@ -61,6 +63,7 @@ class _DSTextMessageBubbleState extends State { padding: EdgeInsets.zero, style: widget.style, hasSpacer: widget.hasSpacer, + replyId: widget.replyId, child: _buildText(), ); } diff --git a/lib/src/widgets/chat/ds_unsupported_content_message_bubble.widget.dart b/lib/src/widgets/chat/ds_unsupported_content_message_bubble.widget.dart index 34f16cc6..6ef590b7 100644 --- a/lib/src/widgets/chat/ds_unsupported_content_message_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_unsupported_content_message_bubble.widget.dart @@ -11,6 +11,7 @@ import 'ds_message_bubble.widget.dart'; class DSUnsupportedContentMessageBubble extends StatelessWidget { final DSAlign align; final Widget? leftWidget; + final String? replyId; final String? text; final TextOverflow overflow; final List borderRadius; @@ -21,6 +22,7 @@ class DSUnsupportedContentMessageBubble extends StatelessWidget { required this.align, this.leftWidget, this.text, + this.replyId, this.overflow = TextOverflow.ellipsis, this.borderRadius = const [DSBorderRadius.all], DSMessageBubbleStyle? style, @@ -37,6 +39,7 @@ class DSUnsupportedContentMessageBubble extends StatelessWidget { borderRadius: borderRadius, align: align, style: style, + replyId: replyId, child: Row( mainAxisSize: MainAxisSize.min, children: [ diff --git a/lib/src/widgets/chat/ds_weblink.widget.dart b/lib/src/widgets/chat/ds_weblink.widget.dart index 0bd3689f..96f81a32 100644 --- a/lib/src/widgets/chat/ds_weblink.widget.dart +++ b/lib/src/widgets/chat/ds_weblink.widget.dart @@ -29,12 +29,16 @@ class DSWeblink extends StatelessWidget { /// Card styling to adjust custom colors final DSMessageBubbleStyle style; + /// replyId + final String? replyId; + DSWeblink({ Key? key, required this.title, required this.text, required this.align, required this.url, + this.replyId, this.borderRadius = const [DSBorderRadius.all], DSMessageBubbleStyle? style, }) : style = style ?? DSMessageBubbleStyle(), @@ -50,6 +54,7 @@ class DSWeblink extends StatelessWidget { return DSMessageBubble( align: align, + replyId: replyId, borderRadius: borderRadius, style: style, child: Column( diff --git a/lib/src/widgets/chat/video/ds_video_message_bubble.widget.dart b/lib/src/widgets/chat/video/ds_video_message_bubble.widget.dart index 24129f8c..01ad15b1 100644 --- a/lib/src/widgets/chat/video/ds_video_message_bubble.widget.dart +++ b/lib/src/widgets/chat/video/ds_video_message_bubble.widget.dart @@ -42,6 +42,9 @@ class DSVideoMessageBubble extends StatefulWidget { // Unique id to message bubble final String uniqueId; + // reply id message + final String? replyId; + /// The video size final int mediaSize; @@ -61,6 +64,7 @@ class DSVideoMessageBubble extends StatefulWidget { required this.uniqueId, required this.mediaSize, this.appBarPhotoUri, + this.replyId, this.text, this.borderRadius = const [DSBorderRadius.all], this.shouldAuthenticate = false, @@ -121,6 +125,7 @@ class _DSVideoMessageBubbleState extends State borderRadius: widget.borderRadius, padding: EdgeInsets.zero, style: widget.style, + replyId: widget.replyId, child: LayoutBuilder( builder: (_, constraints) => Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/src/widgets/utils/ds_card.widget.dart b/lib/src/widgets/utils/ds_card.widget.dart index 596ce460..026fd9dd 100644 --- a/lib/src/widgets/utils/ds_card.widget.dart +++ b/lib/src/widgets/utils/ds_card.widget.dart @@ -43,6 +43,7 @@ class DSCard extends StatelessWidget { this.customer, this.showQuickReplyOptions = false, this.showRequestLocationButton = false, + this.replyId, }) : style = style ?? DSMessageBubbleStyle(); final String type; @@ -58,6 +59,7 @@ class DSCard extends StatelessWidget { final Map? customer; final bool showQuickReplyOptions; final bool showRequestLocationButton; + final String? replyId; @override Widget build(BuildContext context) { @@ -73,6 +75,7 @@ class DSCard extends StatelessWidget { align: align, borderRadius: borderRadius, style: style, + replyId: replyId, ); case DSMessageContentType.contact: @@ -91,6 +94,7 @@ class DSCard extends StatelessWidget { onOpenLink: onOpenLink, messageId: messageId, customer: customer, + replyId: content['inReplyTo']['id'], ); case DSMessageContentType.mediaLink: @@ -119,6 +123,7 @@ class DSCard extends StatelessWidget { text: content['text'], url: content['uri'], align: align, + replyId: replyId, borderRadius: borderRadius, style: style, ); @@ -131,6 +136,7 @@ class DSCard extends StatelessWidget { borderRadius: borderRadius, align: align, style: style, + replyId: replyId, ); case DSMessageContentType.ticket: return DSTicketMessage( @@ -154,6 +160,7 @@ class DSCard extends StatelessWidget { default: return DSUnsupportedContentMessageBubble( align: align, + replyId: replyId, borderRadius: borderRadius, style: style, ); @@ -178,6 +185,7 @@ class DSCard extends StatelessWidget { selectOptions: documentSelectModel.options, borderRadius: borderRadius, style: style, + replyId: replyId, showSelect: true, onSelected: onSelected, onOpenLink: onOpenLink, @@ -195,6 +203,7 @@ class DSCard extends StatelessWidget { child: DSTextMessageBubble( align: align, text: content['text'], + replyId: replyId, borderRadius: borderRadius, style: style, ), @@ -216,6 +225,7 @@ class DSCard extends StatelessWidget { borderRadius: borderRadius, selectContent: content, showSelect: true, + replyId: replyId, onSelected: onSelected, style: style, ); @@ -228,6 +238,7 @@ class DSCard extends StatelessWidget { address: content['address'], email: content['email'], align: align, + replyId: replyId, style: style, borderRadius: borderRadius, ); @@ -253,6 +264,7 @@ class DSCard extends StatelessWidget { align: align, borderRadius: borderRadius, style: style, + replyId: replyId, uniqueId: messageId, audioType: media.type, shouldAuthenticate: shouldAuthenticate, @@ -270,6 +282,7 @@ class DSCard extends StatelessWidget { : avatarConfig.sentAvatar, text: media.text, title: media.title, + replyId: replyId, borderRadius: borderRadius, style: style, shouldAuthenticate: shouldAuthenticate, @@ -286,6 +299,7 @@ class DSCard extends StatelessWidget { ? avatarConfig.receivedAvatar : avatarConfig.sentAvatar, text: media.text, + replyId: replyId, borderRadius: borderRadius, style: style, uniqueId: messageId ?? DateTime.now().toIso8601String(), @@ -296,6 +310,7 @@ class DSCard extends StatelessWidget { return DSFileMessageBubble( align: align, url: media.uri, + replyId: replyId, size: size, filename: media.title ?? '${media.uri.hashCode}.${DSFileService.getFileExtensionFromMime(media.type)}', @@ -313,6 +328,7 @@ class DSCard extends StatelessWidget { return DSRequestLocationBubble( label: 'Send location', + replyId: replyId, type: type, value: value, align: align, diff --git a/lib/src/widgets/utils/ds_group_card.widget.dart b/lib/src/widgets/utils/ds_group_card.widget.dart index 2e6dee95..7c8cc3fe 100644 --- a/lib/src/widgets/utils/ds_group_card.widget.dart +++ b/lib/src/widgets/utils/ds_group_card.widget.dart @@ -1,3 +1,4 @@ +import 'package:blip_ds/src/controllers/chat/ds_reply.controller.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -89,6 +90,7 @@ class DSGroupCard extends StatefulWidget { class _DSGroupCardState extends State { final List widgets = []; final showScrollBottomButton = false.obs; + final DSReplyController replyController = Get.put(DSReplyController()); @override void initState() { @@ -211,6 +213,12 @@ class _DSGroupCardState extends State { }; } } + + final listOfDSMessageItemModelList = groups.map((e) => e['msgs']).toList(); + replyController.messages.clear(); + for (List items in listOfDSMessageItemModelList) { + replyController.addMessages(items); + } groups.add(group); return groups; } From f5522198a95546ae05e8d6257cdc50d3a642e030 Mon Sep 17 00:00:00 2001 From: RaulRodrigo06 Date: Fri, 20 Oct 2023 15:35:23 -0300 Subject: [PATCH 2/9] chore: adding reply --- .../chat/ds_reply_container.widget.dart | 104 ++++++++++-------- 1 file changed, 59 insertions(+), 45 deletions(-) diff --git a/lib/src/widgets/chat/ds_reply_container.widget.dart b/lib/src/widgets/chat/ds_reply_container.widget.dart index a4528871..74d6f3ff 100644 --- a/lib/src/widgets/chat/ds_reply_container.widget.dart +++ b/lib/src/widgets/chat/ds_reply_container.widget.dart @@ -8,6 +8,7 @@ import '../../themes/colors/ds_colors.theme.dart'; import '../../themes/icons/ds_icons.dart'; import '../../utils/ds_message_content_type.util.dart'; import '../texts/ds_body_text.widget.dart'; +import '../texts/ds_caption_text.widget.dart'; class DSReplyContainer extends StatelessWidget { const DSReplyContainer({ @@ -29,46 +30,59 @@ class DSReplyContainer extends StatelessWidget { left: 8.0, right: 8.0, ), - child: DecoratedBox( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(4.0), - border: Border.all( - color: style.isLightBubbleBackground(align) - ? DSColors.contentGhost - : DSColors.contentDisable, - ), - color: style.isLightBubbleBackground(align) - ? DSColors.surface3 - : DSColors.contentDefault, - ), - child: IntrinsicHeight( - child: Row( + child: Column( + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.center, children: [ - Container( - decoration: const ShapeDecoration( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(8.0), - bottomLeft: Radius.circular(8.0), + const Icon(DSIcons.undo_outline), + const SizedBox(width: 8.0), + DSCaptionText('Reply', fontStyle: FontStyle.italic), + ], + ), + const SizedBox(height: 4.0), + DecoratedBox( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4.0), + border: Border.all( + color: style.isLightBubbleBackground(align) + ? DSColors.contentGhost + : DSColors.contentDisable, + ), + color: style.isLightBubbleBackground(align) + ? DSColors.surface3 + : DSColors.contentDefault, + ), + child: IntrinsicHeight( + child: Row( + children: [ + Container( + decoration: const ShapeDecoration( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(8.0), + bottomLeft: Radius.circular(8.0), + ), + ), + color: DSColors.primary, ), + width: 4.0, ), - color: DSColors.primary, - ), - width: 4.0, - ), - Flexible( - child: Padding( - padding: const EdgeInsets.only( - top: 8.0, - left: 8.0, - bottom: 8.0, + Flexible( + child: Padding( + padding: const EdgeInsets.only( + top: 8.0, + left: 8.0, + bottom: 8.0, + ), + child: _replyWidget(replyId, style, align), + ), ), - child: _replyWidget(replyId, style, align), - ), + ], ), - ], + ), ), - ), + ], ), ); } @@ -86,9 +100,7 @@ Widget _replyWidget( case DSMessageContentType.textPlain: return DSBodyText( message?.content is String ? message?.content : '**********', - color: style.isLightBubbleBackground(align) - ? DSColors.contentDefault - : DSColors.neutralLightSnow, + color: _color(align, style), ); default: return Row( @@ -96,21 +108,23 @@ Widget _replyWidget( children: [ Icon( DSIcons.warning_outline, - color: style.isLightBubbleBackground(align) - ? DSColors.contentDefault - : DSColors.neutralLightSnow, + color: _color(align, style), ), - const SizedBox(width: 8), + const SizedBox(width: 8.0), Flexible( child: DSBodyText( - 'Falha ao carregar mensagem', + 'Failed to load message', overflow: TextOverflow.visible, - color: style.isLightBubbleBackground(align) - ? DSColors.contentDefault - : DSColors.neutralLightSnow, + color: _color(align, style), ), ), ], ); } } + +Color _color(DSAlign align, DSMessageBubbleStyle style) { + return style.isLightBubbleBackground(align) + ? DSColors.contentDefault + : DSColors.surface1; +} From a4bb774eae47adbf259e2dbf63ff68d82ea2f3fb Mon Sep 17 00:00:00 2001 From: RaulRodrigo06 Date: Fri, 20 Oct 2023 15:40:33 -0300 Subject: [PATCH 3/9] fix: fixing color reply icon and text based on bubble color --- .../widgets/chat/ds_reply_container.widget.dart | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/src/widgets/chat/ds_reply_container.widget.dart b/lib/src/widgets/chat/ds_reply_container.widget.dart index 74d6f3ff..7d2b4cdc 100644 --- a/lib/src/widgets/chat/ds_reply_container.widget.dart +++ b/lib/src/widgets/chat/ds_reply_container.widget.dart @@ -35,9 +35,20 @@ class DSReplyContainer extends StatelessWidget { Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ - const Icon(DSIcons.undo_outline), + Icon( + DSIcons.undo_outline, + color: style.isLightBubbleBackground(align) + ? DSColors.neutralDarkCity + : DSColors.neutralLightSnow, + ), const SizedBox(width: 8.0), - DSCaptionText('Reply', fontStyle: FontStyle.italic), + DSCaptionText( + 'Reply', + fontStyle: FontStyle.italic, + color: style.isLightBubbleBackground(align) + ? DSColors.neutralDarkCity + : DSColors.neutralLightSnow, + ), ], ), const SizedBox(height: 4.0), From 5fa169642f0654607d9344531024890980d5ed9c Mon Sep 17 00:00:00 2001 From: RaulRodrigo06 Date: Mon, 23 Oct 2023 13:26:19 -0300 Subject: [PATCH 4/9] fix: fixing padding and text overflow on ds reply container --- lib/src/widgets/chat/ds_reply_container.widget.dart | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/src/widgets/chat/ds_reply_container.widget.dart b/lib/src/widgets/chat/ds_reply_container.widget.dart index 7d2b4cdc..8dbc1d9f 100644 --- a/lib/src/widgets/chat/ds_reply_container.widget.dart +++ b/lib/src/widgets/chat/ds_reply_container.widget.dart @@ -25,10 +25,8 @@ class DSReplyContainer extends StatelessWidget { @override Widget build(BuildContext context) { return Padding( - padding: const EdgeInsets.only( - top: 8.0, - left: 8.0, - right: 8.0, + padding: const EdgeInsets.all( + 8.0, ), child: Column( children: [ @@ -112,6 +110,7 @@ Widget _replyWidget( return DSBodyText( message?.content is String ? message?.content : '**********', color: _color(align, style), + overflow: TextOverflow.visible, ); default: return Row( From 5b289057690820219f34589423d1530decb5326f Mon Sep 17 00:00:00 2001 From: RaulRodrigo06 Date: Mon, 23 Oct 2023 14:25:25 -0300 Subject: [PATCH 5/9] chore: removing empty line --- lib/src/themes/colors/ds_colors.theme.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/src/themes/colors/ds_colors.theme.dart b/lib/src/themes/colors/ds_colors.theme.dart index dbc496c4..e7dfd5d5 100644 --- a/lib/src/themes/colors/ds_colors.theme.dart +++ b/lib/src/themes/colors/ds_colors.theme.dart @@ -53,7 +53,6 @@ abstract class DSColors { static const Color contentDefault = Color(0xFF454545); static const Color contentGhost = Color(0xFF949494); - static const Color disabledText = Color(0xFF637798); static const Color disabledBg = Color(0xFFE8F2FF); static const Color contentDisable = Color(0xFF636363); From cdaac639e1133a3cbeaabb056bc7f5cf787fa415 Mon Sep 17 00:00:00 2001 From: RaulRodrigo06 Date: Thu, 26 Oct 2023 19:52:53 -0300 Subject: [PATCH 6/9] fix: passing reply content to ds card --- .../controllers/chat/ds_reply.controller.dart | 15 --------- lib/src/models/ds_message_item.model.dart | 5 +++ .../audio/ds_audio_message_bubble.widget.dart | 6 ++-- .../ds_application_json_bubble.widget.dart | 8 ++--- .../ds_contact_message_bubble.widget.dart | 7 ++-- .../chat/ds_file_message_bubble.widget.dart | 6 ++-- .../chat/ds_image_message_bubble.widget.dart | 6 ++-- .../ds_location_message_bubble.widget.dart | 6 ++-- .../chat/ds_message_bubble.widget.dart | 8 ++--- .../chat/ds_reply_container.widget.dart | 21 ++++++------ .../ds_request_location_bubble.widget.dart | 6 ++-- .../chat/ds_text_message_bubble.widget.dart | 6 ++-- ...pported_content_message_bubble.widget.dart | 6 ++-- lib/src/widgets/chat/ds_weblink.widget.dart | 8 ++--- .../video/ds_video_message_bubble.widget.dart | 8 ++--- lib/src/widgets/utils/ds_card.widget.dart | 32 +++++++++---------- .../widgets/utils/ds_group_card.widget.dart | 10 ++---- 17 files changed, 75 insertions(+), 89 deletions(-) delete mode 100644 lib/src/controllers/chat/ds_reply.controller.dart diff --git a/lib/src/controllers/chat/ds_reply.controller.dart b/lib/src/controllers/chat/ds_reply.controller.dart deleted file mode 100644 index 0586f3fb..00000000 --- a/lib/src/controllers/chat/ds_reply.controller.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'package:get/get.dart'; - -import '../../models/ds_message_item.model.dart'; - -class DSReplyController extends GetxController { - final List messages = []; - - void addMessages(List newMessages) { - messages.addAll(newMessages); - } - - DSMessageItemModel? getMessageById(String id) { - return messages.firstWhereOrNull((element) => element.id == id); - } -} diff --git a/lib/src/models/ds_message_item.model.dart b/lib/src/models/ds_message_item.model.dart index 856119b8..4dde23bf 100644 --- a/lib/src/models/ds_message_item.model.dart +++ b/lib/src/models/ds_message_item.model.dart @@ -26,6 +26,9 @@ class DSMessageItemModel { /// Customer data Map? customer; + /// The message content + dynamic replyContent; + /// Used to define if a message detail (typicament a messages date and time) should be displayed or not bool? hideMessageDetail; @@ -40,6 +43,7 @@ class DSMessageItemModel { this.content, this.customer, this.hideMessageDetail, + this.replyContent, }); factory DSMessageItemModel.fromJson(Map json) { @@ -52,6 +56,7 @@ class DSMessageItemModel { content: json['content'], status: DSDeliveryReportStatus.unknown.getValue(json['status']), hideMessageDetail: json['hideMessageDetail'], + replyContent: json['replyContent'], ); if (json.containsKey('customer')) { diff --git a/lib/src/widgets/chat/audio/ds_audio_message_bubble.widget.dart b/lib/src/widgets/chat/audio/ds_audio_message_bubble.widget.dart index aa01d4b4..e7193f6c 100644 --- a/lib/src/widgets/chat/audio/ds_audio_message_bubble.widget.dart +++ b/lib/src/widgets/chat/audio/ds_audio_message_bubble.widget.dart @@ -15,7 +15,7 @@ class DSAudioMessageBubble extends StatelessWidget { final String? uniqueId; final String audioType; final bool shouldAuthenticate; - final String? replyId; + final dynamic replyContent; DSAudioMessageBubble({ super.key, @@ -23,7 +23,7 @@ class DSAudioMessageBubble extends StatelessWidget { required this.align, required this.audioType, this.uniqueId, - this.replyId, + this.replyContent, this.borderRadius = const [DSBorderRadius.all], this.shouldAuthenticate = false, final DSMessageBubbleStyle? style, @@ -37,7 +37,7 @@ class DSAudioMessageBubble extends StatelessWidget { return DSMessageBubble( borderRadius: borderRadius, align: align, - replyId: replyId, + replyContent: replyContent, style: style, padding: const EdgeInsets.only( left: 4.0, diff --git a/lib/src/widgets/chat/ds_application_json_bubble.widget.dart b/lib/src/widgets/chat/ds_application_json_bubble.widget.dart index 2ec30d9c..307f3fbf 100644 --- a/lib/src/widgets/chat/ds_application_json_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_application_json_bubble.widget.dart @@ -15,14 +15,14 @@ class DSApplicationJsonMessageBubble extends StatelessWidget { required this.borderRadius, required this.content, this.status, - this.replyId, + this.replyContent, DSMessageBubbleStyle? style, }) : style = style ?? DSMessageBubbleStyle(); final DSAlign align; final List borderRadius; final Map content; - final String? replyId; + final dynamic replyContent; final DSDeliveryReportStatus? status; final DSMessageBubbleStyle style; @@ -33,7 +33,7 @@ class DSApplicationJsonMessageBubble extends StatelessWidget { opacity: status == DSDeliveryReportStatus.failed ? .3 : 1, child: DSUnsupportedContentMessageBubble( align: align, - replyId: replyId, + replyContent: replyContent, borderRadius: borderRadius, style: style, overflow: TextOverflow.visible, @@ -53,7 +53,7 @@ class DSApplicationJsonMessageBubble extends StatelessWidget { align: align, borderRadius: borderRadius, style: style, - replyId: replyId, + replyContent: replyContent, ); } } diff --git a/lib/src/widgets/chat/ds_contact_message_bubble.widget.dart b/lib/src/widgets/chat/ds_contact_message_bubble.widget.dart index 664ca2d1..80b83553 100644 --- a/lib/src/widgets/chat/ds_contact_message_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_contact_message_bubble.widget.dart @@ -6,7 +6,7 @@ class DSContactMessageBubble extends StatelessWidget { final String? phone; final String? email; final String? address; - final String? replyId; + final dynamic replyContent; final DSAlign align; final List borderRadius; final DSMessageBubbleStyle style; @@ -18,7 +18,7 @@ class DSContactMessageBubble extends StatelessWidget { required this.address, required this.email, required this.align, - this.replyId, + this.replyContent, this.borderRadius = const [DSBorderRadius.all], DSMessageBubbleStyle? style, }) : style = style ?? DSMessageBubbleStyle(); @@ -31,7 +31,7 @@ class DSContactMessageBubble extends StatelessWidget { padding: const EdgeInsets.all(16.0), shouldUseDefaultSize: true, style: style, - replyId: replyId, + replyContent: replyContent, child: _buildContactCard(), ); } @@ -53,6 +53,7 @@ class DSContactMessageBubble extends StatelessWidget { ), ), const SizedBox(height: 16.0), + /// TODO(format): Format phone number if (phone != null) Padding( diff --git a/lib/src/widgets/chat/ds_file_message_bubble.widget.dart b/lib/src/widgets/chat/ds_file_message_bubble.widget.dart index 21b63e25..6c6a0e5a 100644 --- a/lib/src/widgets/chat/ds_file_message_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_file_message_bubble.widget.dart @@ -22,7 +22,7 @@ class DSFileMessageBubble extends StatelessWidget { final List borderRadius; final DSMessageBubbleStyle style; final bool shouldAuthenticate; - final String? replyId; + final dynamic replyContent; /// Creates a Design System's [DSMessageBubble] used on files other than image, audio, or video DSFileMessageBubble({ @@ -31,7 +31,7 @@ class DSFileMessageBubble extends StatelessWidget { required this.url, required this.size, required this.filename, - this.replyId, + this.replyContent, this.borderRadius = const [DSBorderRadius.all], this.shouldAuthenticate = false, DSMessageBubbleStyle? style, @@ -48,7 +48,7 @@ class DSFileMessageBubble extends StatelessWidget { ), child: DSMessageBubble( borderRadius: borderRadius, - replyId: replyId, + replyContent: replyContent, padding: EdgeInsets.zero, align: align, style: style, diff --git a/lib/src/widgets/chat/ds_image_message_bubble.widget.dart b/lib/src/widgets/chat/ds_image_message_bubble.widget.dart index d558f00d..d97bf801 100644 --- a/lib/src/widgets/chat/ds_image_message_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_image_message_bubble.widget.dart @@ -29,7 +29,7 @@ class DSImageMessageBubble extends StatefulWidget { this.showSelect = false, this.onSelected, this.onOpenLink, - this.replyId, + this.replyContent, this.shouldAuthenticate = false, this.mediaType, this.imageMaxHeight, @@ -44,7 +44,7 @@ class DSImageMessageBubble extends StatefulWidget { final String? text; final String appBarText; final Uri? appBarPhotoUri; - final String? replyId; + final dynamic replyContent; final DSMessageBubbleStyle style; final List selectOptions; final bool showSelect; @@ -86,7 +86,7 @@ class _DSImageMessageBubbleState extends State defaultMaxSize: 360.0, shouldUseDefaultSize: true, align: widget.align, - replyId:widget.replyId, + replyContent: widget.replyContent, borderRadius: widget.borderRadius, padding: EdgeInsets.zero, hasSpacer: widget.hasSpacer, diff --git a/lib/src/widgets/chat/ds_location_message_bubble.widget.dart b/lib/src/widgets/chat/ds_location_message_bubble.widget.dart index 688361b9..924e666e 100644 --- a/lib/src/widgets/chat/ds_location_message_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_location_message_bubble.widget.dart @@ -16,7 +16,7 @@ class DSLocationMessageBubble extends StatelessWidget { final DSAlign align; final DSMessageBubbleStyle style; final String? title; - final String? replyId; + final dynamic replyContent; final String latitude; final String longitude; final List borderRadius; @@ -26,7 +26,7 @@ class DSLocationMessageBubble extends StatelessWidget { required this.align, required this.latitude, required this.longitude, - this.replyId, + this.replyContent, this.borderRadius = const [DSBorderRadius.all], DSMessageBubbleStyle? style, this.title, @@ -58,7 +58,7 @@ class DSLocationMessageBubble extends StatelessWidget { defaultMaxSize: 240.0, defaultMinSize: 240.0, borderRadius: borderRadius, - replyId: replyId, + replyContent: replyContent, padding: EdgeInsets.zero, align: align, style: style, diff --git a/lib/src/widgets/chat/ds_message_bubble.widget.dart b/lib/src/widgets/chat/ds_message_bubble.widget.dart index bcea3632..07f27c9e 100644 --- a/lib/src/widgets/chat/ds_message_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_message_bubble.widget.dart @@ -11,7 +11,7 @@ import '../animations/ds_animated_size.widget.dart'; class DSMessageBubble extends StatelessWidget { final DSAlign align; final Widget child; - final String? replyId; + final dynamic replyContent; final List borderRadius; final EdgeInsets padding; final bool shouldUseDefaultSize; @@ -24,7 +24,7 @@ class DSMessageBubble extends StatelessWidget { Key? key, required this.align, required this.child, - this.replyId, + this.replyContent, this.borderRadius = const [DSBorderRadius.all], this.padding = const EdgeInsets.symmetric( vertical: 8.0, @@ -67,9 +67,9 @@ class DSMessageBubble extends StatelessWidget { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - if (replyId != null) + if (replyContent != null) DSReplyContainer( - replyId: replyId!, + replyContent: replyContent!, style: style, align: align, ), diff --git a/lib/src/widgets/chat/ds_reply_container.widget.dart b/lib/src/widgets/chat/ds_reply_container.widget.dart index 8dbc1d9f..ff0fb12e 100644 --- a/lib/src/widgets/chat/ds_reply_container.widget.dart +++ b/lib/src/widgets/chat/ds_reply_container.widget.dart @@ -1,7 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:get/get.dart'; -import '../../controllers/chat/ds_reply.controller.dart'; import '../../enums/ds_align.enum.dart'; import '../../models/ds_message_bubble_style.model.dart'; import '../../themes/colors/ds_colors.theme.dart'; @@ -13,13 +11,13 @@ import '../texts/ds_caption_text.widget.dart'; class DSReplyContainer extends StatelessWidget { const DSReplyContainer({ super.key, - required this.replyId, + required this.replyContent, required this.style, required this.align, }); final DSAlign align; - final String replyId; + final dynamic replyContent; final DSMessageBubbleStyle style; @override @@ -84,7 +82,7 @@ class DSReplyContainer extends StatelessWidget { left: 8.0, bottom: 8.0, ), - child: _replyWidget(replyId, style, align), + child: _replyWidget(replyContent, style, align), ), ), ], @@ -98,17 +96,18 @@ class DSReplyContainer extends StatelessWidget { } Widget _replyWidget( - String id, + dynamic replyContent, DSMessageBubbleStyle style, DSAlign align, ) { - final replyController = Get.find(); - final message = replyController.getMessageById(id); - - switch (message?.type) { + final replyType = + replyContent != '' ? replyContent['content']['replied']['type'] : ''; + switch (replyType) { case DSMessageContentType.textPlain: return DSBodyText( - message?.content is String ? message?.content : '**********', + replyContent['content']['replied']['value'] is String + ? replyContent['content']['replied']['value'] + : '**********', color: _color(align, style), overflow: TextOverflow.visible, ); diff --git a/lib/src/widgets/chat/ds_request_location_bubble.widget.dart b/lib/src/widgets/chat/ds_request_location_bubble.widget.dart index d8ceba85..b43455d6 100644 --- a/lib/src/widgets/chat/ds_request_location_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_request_location_bubble.widget.dart @@ -14,7 +14,7 @@ class DSRequestLocationBubble extends StatelessWidget { required this.label, required this.value, required this.align, - this.replyId, + this.replyContent, this.type = DSMessageContentType.textPlain, this.borderRadius = const [DSBorderRadius.all], this.showRequestLocationButton = false, @@ -24,7 +24,7 @@ class DSRequestLocationBubble extends StatelessWidget { final String? label; final String type; final String? value; - final String? replyId; + final dynamic replyContent; final DSAlign align; final List borderRadius; final bool showRequestLocationButton; @@ -47,7 +47,7 @@ class DSRequestLocationBubble extends StatelessWidget { ), child: DSTextMessageBubble( text: value!, - replyId: replyId, + replyContent: replyContent, align: align, borderRadius: borderRadius, style: style, diff --git a/lib/src/widgets/chat/ds_text_message_bubble.widget.dart b/lib/src/widgets/chat/ds_text_message_bubble.widget.dart index 35faf79d..a1c5c98b 100644 --- a/lib/src/widgets/chat/ds_text_message_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_text_message_bubble.widget.dart @@ -16,7 +16,7 @@ class DSTextMessageBubble extends StatefulWidget { final bool hasSpacer; final List borderRadius; final dynamic selectContent; - final String? replyId; + final dynamic replyContent; final bool showSelect; final void Function(String, Map)? onSelected; final DSMessageBubbleStyle style; @@ -25,7 +25,7 @@ class DSTextMessageBubble extends StatefulWidget { Key? key, required this.text, required this.align, - this.replyId, + this.replyContent, this.borderRadius = const [DSBorderRadius.all], this.selectContent, this.hasSpacer = true, @@ -63,7 +63,7 @@ class _DSTextMessageBubbleState extends State { padding: EdgeInsets.zero, style: widget.style, hasSpacer: widget.hasSpacer, - replyId: widget.replyId, + replyContent: widget.replyContent, child: _buildText(), ); } diff --git a/lib/src/widgets/chat/ds_unsupported_content_message_bubble.widget.dart b/lib/src/widgets/chat/ds_unsupported_content_message_bubble.widget.dart index 6ef590b7..160b4d5f 100644 --- a/lib/src/widgets/chat/ds_unsupported_content_message_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_unsupported_content_message_bubble.widget.dart @@ -11,7 +11,7 @@ import 'ds_message_bubble.widget.dart'; class DSUnsupportedContentMessageBubble extends StatelessWidget { final DSAlign align; final Widget? leftWidget; - final String? replyId; + final dynamic replyContent; final String? text; final TextOverflow overflow; final List borderRadius; @@ -22,7 +22,7 @@ class DSUnsupportedContentMessageBubble extends StatelessWidget { required this.align, this.leftWidget, this.text, - this.replyId, + this.replyContent, this.overflow = TextOverflow.ellipsis, this.borderRadius = const [DSBorderRadius.all], DSMessageBubbleStyle? style, @@ -39,7 +39,7 @@ class DSUnsupportedContentMessageBubble extends StatelessWidget { borderRadius: borderRadius, align: align, style: style, - replyId: replyId, + replyContent: replyContent, child: Row( mainAxisSize: MainAxisSize.min, children: [ diff --git a/lib/src/widgets/chat/ds_weblink.widget.dart b/lib/src/widgets/chat/ds_weblink.widget.dart index 96f81a32..1bcb3953 100644 --- a/lib/src/widgets/chat/ds_weblink.widget.dart +++ b/lib/src/widgets/chat/ds_weblink.widget.dart @@ -29,8 +29,8 @@ class DSWeblink extends StatelessWidget { /// Card styling to adjust custom colors final DSMessageBubbleStyle style; - /// replyId - final String? replyId; + /// replyContent + final dynamic replyContent; DSWeblink({ Key? key, @@ -38,7 +38,7 @@ class DSWeblink extends StatelessWidget { required this.text, required this.align, required this.url, - this.replyId, + this.replyContent, this.borderRadius = const [DSBorderRadius.all], DSMessageBubbleStyle? style, }) : style = style ?? DSMessageBubbleStyle(), @@ -54,7 +54,7 @@ class DSWeblink extends StatelessWidget { return DSMessageBubble( align: align, - replyId: replyId, + replyContent: replyContent, borderRadius: borderRadius, style: style, child: Column( diff --git a/lib/src/widgets/chat/video/ds_video_message_bubble.widget.dart b/lib/src/widgets/chat/video/ds_video_message_bubble.widget.dart index ea037bad..b5e9afaa 100644 --- a/lib/src/widgets/chat/video/ds_video_message_bubble.widget.dart +++ b/lib/src/widgets/chat/video/ds_video_message_bubble.widget.dart @@ -39,8 +39,8 @@ class DSVideoMessageBubble extends StatefulWidget { /// Style for bubble final DSMessageBubbleStyle style; - // reply id message - final String? replyId; + // reply id message + final dynamic replyContent; /// The video size final int mediaSize; @@ -63,7 +63,7 @@ class DSVideoMessageBubble extends StatefulWidget { required this.appBarText, required this.mediaSize, this.appBarPhotoUri, - this.replyId, + this.replyContent, this.type = 'video/mp4', this.text, this.borderRadius = const [DSBorderRadius.all], @@ -125,7 +125,7 @@ class _DSVideoMessageBubbleState extends State borderRadius: widget.borderRadius, padding: EdgeInsets.zero, style: widget.style, - replyId: widget.replyId, + replyContent: widget.replyContent, child: LayoutBuilder( builder: (_, constraints) => Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/src/widgets/utils/ds_card.widget.dart b/lib/src/widgets/utils/ds_card.widget.dart index 6532b391..2c2d3966 100644 --- a/lib/src/widgets/utils/ds_card.widget.dart +++ b/lib/src/widgets/utils/ds_card.widget.dart @@ -43,7 +43,7 @@ class DSCard extends StatelessWidget { this.customer, this.showQuickReplyOptions = false, this.showRequestLocationButton = false, - this.replyId, + this.replyContent, }) : style = style ?? DSMessageBubbleStyle(); final String type; @@ -59,7 +59,7 @@ class DSCard extends StatelessWidget { final Map? customer; final bool showQuickReplyOptions; final bool showRequestLocationButton; - final String? replyId; + final dynamic replyContent; @override Widget build(BuildContext context) { @@ -75,7 +75,7 @@ class DSCard extends StatelessWidget { align: align, borderRadius: borderRadius, style: style, - replyId: replyId, + replyContent: replyContent, ); case DSMessageContentType.contact: @@ -94,7 +94,7 @@ class DSCard extends StatelessWidget { onOpenLink: onOpenLink, messageId: messageId, customer: customer, - replyId: content['inReplyTo']['id'], + replyContent: replyContent, ); case DSMessageContentType.mediaLink: @@ -123,7 +123,7 @@ class DSCard extends StatelessWidget { text: content['text'], url: content['uri'], align: align, - replyId: replyId, + replyContent: replyContent, borderRadius: borderRadius, style: style, ); @@ -136,7 +136,7 @@ class DSCard extends StatelessWidget { borderRadius: borderRadius, align: align, style: style, - replyId: replyId, + replyContent: replyContent, ); case DSMessageContentType.ticket: return DSTicketMessage( @@ -160,7 +160,7 @@ class DSCard extends StatelessWidget { default: return DSUnsupportedContentMessageBubble( align: align, - replyId: replyId, + replyContent: replyContent, borderRadius: borderRadius, style: style, ); @@ -185,7 +185,7 @@ class DSCard extends StatelessWidget { selectOptions: documentSelectModel.options, borderRadius: borderRadius, style: style, - replyId: replyId, + replyContent: replyContent, showSelect: true, onSelected: onSelected, onOpenLink: onOpenLink, @@ -204,7 +204,7 @@ class DSCard extends StatelessWidget { child: DSTextMessageBubble( align: align, text: content['text'], - replyId: replyId, + replyContent: replyContent, borderRadius: borderRadius, style: style, ), @@ -226,7 +226,7 @@ class DSCard extends StatelessWidget { borderRadius: borderRadius, selectContent: content, showSelect: true, - replyId: replyId, + replyContent: replyContent, onSelected: onSelected, style: style, ); @@ -239,7 +239,7 @@ class DSCard extends StatelessWidget { address: content['address'], email: content['email'], align: align, - replyId: replyId, + replyContent: replyContent, style: style, borderRadius: borderRadius, ); @@ -265,7 +265,7 @@ class DSCard extends StatelessWidget { align: align, borderRadius: borderRadius, style: style, - replyId: replyId, + replyContent: replyContent, uniqueId: messageId, audioType: media.type, shouldAuthenticate: shouldAuthenticate, @@ -283,7 +283,7 @@ class DSCard extends StatelessWidget { : avatarConfig.sentAvatar, text: media.text, title: media.title, - replyId: replyId, + replyContent: replyContent, borderRadius: borderRadius, style: style, shouldAuthenticate: shouldAuthenticate, @@ -302,7 +302,7 @@ class DSCard extends StatelessWidget { ? avatarConfig.receivedAvatar : avatarConfig.sentAvatar, text: media.text, - replyId: replyId, + replyContent: replyContent, borderRadius: borderRadius, style: style, mediaSize: size, @@ -312,7 +312,7 @@ class DSCard extends StatelessWidget { return DSFileMessageBubble( align: align, url: media.uri, - replyId: replyId, + replyContent: replyContent, size: size, filename: media.title ?? '${media.uri.hashCode}.${DSFileService.getFileExtensionFromMime(media.type)}', @@ -330,7 +330,7 @@ class DSCard extends StatelessWidget { return DSRequestLocationBubble( label: 'Send location', - replyId: replyId, + replyContent: replyContent, type: type, value: value, align: align, diff --git a/lib/src/widgets/utils/ds_group_card.widget.dart b/lib/src/widgets/utils/ds_group_card.widget.dart index 7c8cc3fe..db26e6bd 100644 --- a/lib/src/widgets/utils/ds_group_card.widget.dart +++ b/lib/src/widgets/utils/ds_group_card.widget.dart @@ -1,4 +1,3 @@ -import 'package:blip_ds/src/controllers/chat/ds_reply.controller.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -54,6 +53,7 @@ class DSGroupCard extends StatefulWidget { super.key, required this.documents, required this.isComposing, + this.ticketId, this.sortMessages = true, this.onSelected, this.onOpenLink, @@ -73,6 +73,7 @@ class DSGroupCard extends StatefulWidget { final bool Function(DSMessageItemModel, DSMessageItemModel) compareMessages; final bool isComposing; final bool sortMessages; + final String? ticketId; final void Function(String, Map)? onSelected; final void Function(Map)? onOpenLink; final bool hideOptions; @@ -90,7 +91,6 @@ class DSGroupCard extends StatefulWidget { class _DSGroupCardState extends State { final List widgets = []; final showScrollBottomButton = false.obs; - final DSReplyController replyController = Get.put(DSReplyController()); @override void initState() { @@ -214,11 +214,6 @@ class _DSGroupCardState extends State { } } - final listOfDSMessageItemModelList = groups.map((e) => e['msgs']).toList(); - replyController.messages.clear(); - for (List items in listOfDSMessageItemModelList) { - replyController.addMessages(items); - } groups.add(group); return groups; } @@ -268,6 +263,7 @@ class _DSGroupCardState extends State { onOpenLink: widget.onOpenLink, messageId: message.id, customer: message.customer, + replyContent: message.replyContent, ); final isLastMsg = msgCount == length; From 71d7247b512567346d019f03d8212dbc90cee924 Mon Sep 17 00:00:00 2001 From: RaulRodrigo06 Date: Thu, 26 Oct 2023 20:00:27 -0300 Subject: [PATCH 7/9] fix: removing unused attributte --- lib/src/widgets/utils/ds_group_card.widget.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/src/widgets/utils/ds_group_card.widget.dart b/lib/src/widgets/utils/ds_group_card.widget.dart index db26e6bd..4d5b81ee 100644 --- a/lib/src/widgets/utils/ds_group_card.widget.dart +++ b/lib/src/widgets/utils/ds_group_card.widget.dart @@ -53,7 +53,6 @@ class DSGroupCard extends StatefulWidget { super.key, required this.documents, required this.isComposing, - this.ticketId, this.sortMessages = true, this.onSelected, this.onOpenLink, @@ -73,7 +72,6 @@ class DSGroupCard extends StatefulWidget { final bool Function(DSMessageItemModel, DSMessageItemModel) compareMessages; final bool isComposing; final bool sortMessages; - final String? ticketId; final void Function(String, Map)? onSelected; final void Function(Map)? onOpenLink; final bool hideOptions; From ef5ab9ce048faf010dc0415a562d4c6354bdfbc9 Mon Sep 17 00:00:00 2001 From: RaulRodrigo06 Date: Thu, 16 Nov 2023 16:47:05 -0300 Subject: [PATCH 8/9] fix: removing unecessary reply content and fixing return --- lib/src/models/ds_message_item.model.dart | 5 ----- lib/src/widgets/chat/ds_reply_container.widget.dart | 8 ++------ lib/src/widgets/utils/ds_card.widget.dart | 2 +- lib/src/widgets/utils/ds_group_card.widget.dart | 1 - 4 files changed, 3 insertions(+), 13 deletions(-) diff --git a/lib/src/models/ds_message_item.model.dart b/lib/src/models/ds_message_item.model.dart index aeaf1ebf..e4d01fcf 100644 --- a/lib/src/models/ds_message_item.model.dart +++ b/lib/src/models/ds_message_item.model.dart @@ -27,9 +27,6 @@ class DSMessageItemModel { /// Customer data Map? customer; - /// The message content - dynamic replyContent; - /// Used to define if a message detail (typicament a messages date and time) should be displayed or not bool? hideMessageDetail; @@ -44,7 +41,6 @@ class DSMessageItemModel { this.content, this.customer, this.hideMessageDetail, - this.replyContent, }); factory DSMessageItemModel.fromJson(Map json) { @@ -57,7 +53,6 @@ class DSMessageItemModel { content: json['content'], status: DSDeliveryReportStatus.unknown.getValue(json['status']), hideMessageDetail: json['hideMessageDetail'], - replyContent: json['replyContent'], ); if (json.containsKey('customer')) { diff --git a/lib/src/widgets/chat/ds_reply_container.widget.dart b/lib/src/widgets/chat/ds_reply_container.widget.dart index ff0fb12e..83199263 100644 --- a/lib/src/widgets/chat/ds_reply_container.widget.dart +++ b/lib/src/widgets/chat/ds_reply_container.widget.dart @@ -100,14 +100,10 @@ Widget _replyWidget( DSMessageBubbleStyle style, DSAlign align, ) { - final replyType = - replyContent != '' ? replyContent['content']['replied']['type'] : ''; - switch (replyType) { + switch (replyContent['type']) { case DSMessageContentType.textPlain: return DSBodyText( - replyContent['content']['replied']['value'] is String - ? replyContent['content']['replied']['value'] - : '**********', + replyContent['value'] is String ? replyContent['value'] : '**********', color: _color(align, style), overflow: TextOverflow.visible, ); diff --git a/lib/src/widgets/utils/ds_card.widget.dart b/lib/src/widgets/utils/ds_card.widget.dart index b0f996fb..c2120496 100644 --- a/lib/src/widgets/utils/ds_card.widget.dart +++ b/lib/src/widgets/utils/ds_card.widget.dart @@ -94,7 +94,7 @@ class DSCard extends StatelessWidget { onOpenLink: onOpenLink, messageId: messageId, customer: customer, - replyContent: replyContent, + replyContent: content['inReplyTo'], ); case DSMessageContentType.mediaLink: diff --git a/lib/src/widgets/utils/ds_group_card.widget.dart b/lib/src/widgets/utils/ds_group_card.widget.dart index b4f94dbb..c74dd0ed 100644 --- a/lib/src/widgets/utils/ds_group_card.widget.dart +++ b/lib/src/widgets/utils/ds_group_card.widget.dart @@ -261,7 +261,6 @@ class _DSGroupCardState extends State { onOpenLink: widget.onOpenLink, messageId: message.id, customer: message.customer, - replyContent: message.replyContent, ); final isLastMsg = msgCount == length; From cb0323c04b2eb2ae7d0a87a6f68f127ecc978fca Mon Sep 17 00:00:00 2001 From: Andre Rossi Date: Wed, 22 Nov 2023 13:15:59 -0300 Subject: [PATCH 9/9] fix: set manually extension for ppt --- lib/src/services/ds_file.service.dart | 7 ++- .../chat/ds_file_message_bubble.widget.dart | 1 - .../chat/ds_message_bubble.widget.dart | 44 +++++++++---------- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/lib/src/services/ds_file.service.dart b/lib/src/services/ds_file.service.dart index c4eeb2ef..0809f1e0 100644 --- a/lib/src/services/ds_file.service.dart +++ b/lib/src/services/ds_file.service.dart @@ -102,6 +102,9 @@ abstract class DSFileService { return null; } - static String getFileExtensionFromMime(String? mimeType) => - extensionFromMime(mimeType ?? ''); + static String getFileExtensionFromMime(String? mimeType) { + return mimeType == 'application/vnd.ms-powerpoint' + ? 'ppt' + : extensionFromMime(mimeType ?? ''); + } } diff --git a/lib/src/widgets/chat/ds_file_message_bubble.widget.dart b/lib/src/widgets/chat/ds_file_message_bubble.widget.dart index 21afe492..9007c39b 100644 --- a/lib/src/widgets/chat/ds_file_message_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_file_message_bubble.widget.dart @@ -108,7 +108,6 @@ class DSFileMessageBubble extends StatelessWidget { filename, color: color, textAlign: TextAlign.center, - isSelectable: true, shouldLinkify: false, ), Visibility( diff --git a/lib/src/widgets/chat/ds_message_bubble.widget.dart b/lib/src/widgets/chat/ds_message_bubble.widget.dart index 07f27c9e..c977fa6e 100644 --- a/lib/src/widgets/chat/ds_message_bubble.widget.dart +++ b/lib/src/widgets/chat/ds_message_bubble.widget.dart @@ -1,4 +1,3 @@ -import 'package:blip_ds/src/widgets/chat/ds_reply_container.widget.dart'; import 'package:flutter/material.dart'; import '../../enums/ds_align.enum.dart'; @@ -7,6 +6,7 @@ import '../../models/ds_message_bubble_style.model.dart'; import '../../utils/ds_bubble.util.dart'; import '../../utils/ds_utils.util.dart'; import '../animations/ds_animated_size.widget.dart'; +import 'ds_reply_container.widget.dart'; class DSMessageBubble extends StatelessWidget { final DSAlign align; @@ -37,12 +37,21 @@ class DSMessageBubble extends StatelessWidget { this.hasSpacer = true, }) : super(key: key); - BorderRadius _getBorderRadius() { - return borderRadius.getCircularBorderRadius( - maxRadius: 22.0, - minRadius: 2.0, - ); - } + @override + Widget build(BuildContext context) => Column( + children: [ + Row( + mainAxisAlignment: align == DSAlign.right + ? MainAxisAlignment.end + : MainAxisAlignment.start, + children: DSBubbleUtils.addSpacer( + align: align, + hasSpacer: hasSpacer, + child: _messageContainer(), + ), + ), + ], + ); Widget _messageContainer() { return DSAnimatedSize( @@ -82,19 +91,10 @@ class DSMessageBubble extends StatelessWidget { ); } - @override - Widget build(BuildContext context) => Column( - children: [ - Row( - mainAxisAlignment: align == DSAlign.right - ? MainAxisAlignment.end - : MainAxisAlignment.start, - children: DSBubbleUtils.addSpacer( - align: align, - hasSpacer: hasSpacer, - child: _messageContainer(), - ), - ), - ], - ); + BorderRadius _getBorderRadius() { + return borderRadius.getCircularBorderRadius( + maxRadius: 22.0, + minRadius: 2.0, + ); + } }