From 3a04e4f390631fb24f487ac26217572ea6ee77ab Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Mon, 15 Nov 2021 17:18:30 +0530 Subject: [PATCH 01/10] added customisation options for attachment actions modal and related widgets --- .../lib/src/attachment_actions_modal.dart | 164 ++++++++++-------- .../lib/src/full_screen_media.dart | 20 +++ .../lib/src/gallery_header.dart | 20 +++ 3 files changed, 132 insertions(+), 72 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/attachment_actions_modal.dart b/packages/stream_chat_flutter/lib/src/attachment_actions_modal.dart index f49561aa..96e040fd 100644 --- a/packages/stream_chat_flutter/lib/src/attachment_actions_modal.dart +++ b/packages/stream_chat_flutter/lib/src/attachment_actions_modal.dart @@ -24,6 +24,10 @@ class AttachmentActionsModal extends StatelessWidget { this.onShowMessage, this.imageDownloader, this.fileDownloader, + this.showReply = true, + this.showShowInChat = true, + this.showSave = true, + this.showDelete = true, }) : super(key: key); /// The message containing the attachments @@ -41,6 +45,18 @@ class AttachmentActionsModal extends StatelessWidget { /// Callback to provide download files final AttachmentDownloader? fileDownloader; + /// Show reply option + final bool showReply; + + /// Show show in chat option + final bool showShowInChat; + + /// Show save option + final bool showSave; + + /// Show delete option + final bool showDelete; + @override Widget build(BuildContext context) => GestureDetector( behavior: HitTestBehavior.translucent, @@ -67,82 +83,86 @@ class AttachmentActionsModal extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.end, mainAxisSize: MainAxisSize.min, children: [ - _buildButton( - context, - context.translations.replyLabel, - StreamSvgIcon.iconCurveLineLeftUp( - size: 24, - color: theme.colorTheme.textLowEmphasis, + if (showReply) + _buildButton( + context, + context.translations.replyLabel, + StreamSvgIcon.iconCurveLineLeftUp( + size: 24, + color: theme.colorTheme.textLowEmphasis, + ), + () { + Navigator.pop(context, ReturnActionType.reply); + }, ), - () { - Navigator.pop(context, ReturnActionType.reply); - }, - ), - _buildButton( - context, - context.translations.showInChatLabel, - StreamSvgIcon.eye( - size: 24, - color: theme.colorTheme.textHighEmphasis, + if (showShowInChat) + _buildButton( + context, + context.translations.showInChatLabel, + StreamSvgIcon.eye( + size: 24, + color: theme.colorTheme.textHighEmphasis, + ), + onShowMessage, ), - onShowMessage, - ), - _buildButton( - context, - message.attachments[currentIndex].type == 'video' - ? context.translations.saveVideoLabel - : context.translations.saveImageLabel, - StreamSvgIcon.iconSave( - size: 24, - color: theme.colorTheme.textLowEmphasis, + if (showSave) + _buildButton( + context, + message.attachments[currentIndex].type == 'video' + ? context.translations.saveVideoLabel + : context.translations.saveImageLabel, + StreamSvgIcon.iconSave( + size: 24, + color: theme.colorTheme.textLowEmphasis, + ), + () { + final attachment = message.attachments[currentIndex]; + final isImage = attachment.type == 'image'; + final Future Function( + Attachment, { + void Function(int, int) progressCallback, + }) saveFile = fileDownloader ?? _downloadAttachment; + final Future Function( + Attachment, { + void Function(int, int) progressCallback, + }) saveImage = imageDownloader ?? _downloadAttachment; + final downloader = isImage ? saveImage : saveFile; + + final progressNotifier = + ValueNotifier<_DownloadProgress?>( + _DownloadProgress.initial(), + ); + + downloader( + attachment, + progressCallback: (received, total) { + progressNotifier.value = _DownloadProgress( + total, + received, + ); + }, + ).catchError((e, stk) { + progressNotifier.value = null; + }); + + // Closing attachment actions modal before opening + // attachment download dialog + Navigator.pop(context); + + showDialog( + barrierDismissible: false, + context: context, + barrierColor: theme.colorTheme.overlay, + builder: (context) => _buildDownloadProgressDialog( + context, + progressNotifier, + ), + ); + }, ), - () { - final attachment = message.attachments[currentIndex]; - final isImage = attachment.type == 'image'; - final Future Function( - Attachment, { - void Function(int, int) progressCallback, - }) saveFile = fileDownloader ?? _downloadAttachment; - final Future Function( - Attachment, { - void Function(int, int) progressCallback, - }) saveImage = imageDownloader ?? _downloadAttachment; - final downloader = isImage ? saveImage : saveFile; - - final progressNotifier = - ValueNotifier<_DownloadProgress?>( - _DownloadProgress.initial(), - ); - - downloader( - attachment, - progressCallback: (received, total) { - progressNotifier.value = _DownloadProgress( - total, - received, - ); - }, - ).catchError((e, stk) { - progressNotifier.value = null; - }); - - // Closing attachment actions modal before opening - // attachment download dialog - Navigator.pop(context); - - showDialog( - barrierDismissible: false, - context: context, - barrierColor: theme.colorTheme.overlay, - builder: (context) => _buildDownloadProgressDialog( - context, - progressNotifier, - ), - ); - }, - ), if (StreamChat.of(context).currentUser?.id == - message.user?.id) + message.user?.id && + showDelete) _buildButton( context, context.translations.deleteLabel.capitalize(), diff --git a/packages/stream_chat_flutter/lib/src/full_screen_media.dart b/packages/stream_chat_flutter/lib/src/full_screen_media.dart index 0c47383c..6fe2b2a4 100644 --- a/packages/stream_chat_flutter/lib/src/full_screen_media.dart +++ b/packages/stream_chat_flutter/lib/src/full_screen_media.dart @@ -33,6 +33,10 @@ class FullScreenMedia extends StatefulWidget { this.startIndex = 0, String? userName, this.onShowMessage, + this.showReply = true, + this.showShowInChat = true, + this.showSave = true, + this.showDelete = true, }) : userName = userName ?? '', super(key: key); @@ -51,6 +55,18 @@ class FullScreenMedia extends StatefulWidget { /// Callback for when show message is tapped final ShowMessageCallback? onShowMessage; + /// Show reply option + final bool showReply; + + /// Show show in chat option + final bool showShowInChat; + + /// Show save option + final bool showSave; + + /// Show delete option + final bool showDelete; + @override _FullScreenMediaState createState() => _FullScreenMediaState(); } @@ -196,6 +212,10 @@ class _FullScreenMediaState extends State StreamChannel.of(context).channel, ); }, + showReply: widget.showReply, + showShowInChat: widget.showShowInChat, + showSave: widget.showSave, + showDelete: widget.showDelete, ), if (!widget.message.isEphemeral) GalleryFooter( diff --git a/packages/stream_chat_flutter/lib/src/gallery_header.dart b/packages/stream_chat_flutter/lib/src/gallery_header.dart index fc5f67b4..638375eb 100644 --- a/packages/stream_chat_flutter/lib/src/gallery_header.dart +++ b/packages/stream_chat_flutter/lib/src/gallery_header.dart @@ -21,6 +21,10 @@ class GalleryHeader extends StatelessWidget implements PreferredSizeWidget { this.userName = '', this.sentAt = '', this.backgroundColor, + this.showReply = true, + this.showShowInChat = true, + this.showSave = true, + this.showDelete = true, }) : preferredSize = const Size.fromHeight(kToolbarHeight), super(key: key); @@ -55,6 +59,18 @@ class GalleryHeader extends StatelessWidget implements PreferredSizeWidget { /// The background color of this [GalleryHeader]. final Color? backgroundColor; + /// Show reply option + final bool showReply; + + /// Show show in chat option + final bool showShowInChat; + + /// Show save option + final bool showSave; + + /// Show delete option + final bool showDelete; + @override Widget build(BuildContext context) { final galleryHeaderThemeData = GalleryHeaderTheme.of(context); @@ -133,6 +149,10 @@ class GalleryHeader extends StatelessWidget implements PreferredSizeWidget { message: message, currentIndex: currentIndex, onShowMessage: onShowMessage, + showReply: showReply, + showShowInChat: showShowInChat, + showSave: showSave, + showDelete: showDelete, ), ), ); From 81508ac8baa54139edddc1949cadb139f5ba5a86 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Mon, 15 Nov 2021 17:20:40 +0530 Subject: [PATCH 02/10] added changelog --- packages/stream_chat_flutter/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/stream_chat_flutter/CHANGELOG.md b/packages/stream_chat_flutter/CHANGELOG.md index 00f8412b..c9880c1e 100644 --- a/packages/stream_chat_flutter/CHANGELOG.md +++ b/packages/stream_chat_flutter/CHANGELOG.md @@ -1,3 +1,9 @@ +## Upcoming + +🐞 Fixed + +- [[#766]]`AttachmentActionsModal` now has customisation options for actions. + ## 3.2.0 - Updated Dart SDK constraints to `>=2.14.0 <3.0.0` From 5740e53adad7392a45590f59ae1f20fb1d1d1e0e Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Mon, 15 Nov 2021 18:00:45 +0530 Subject: [PATCH 03/10] added attachment actions modal builder --- .../lib/src/attachment/giphy_attachment.dart | 4 ++ .../lib/src/attachment/image_attachment.dart | 5 ++ .../lib/src/attachment/video_attachment.dart | 5 ++ .../lib/src/attachment_actions_modal.dart | 26 +++++++++++ .../lib/src/full_screen_media.dart | 23 ++-------- .../lib/src/gallery_header.dart | 46 +++++++++---------- .../lib/src/image_group.dart | 5 ++ 7 files changed, 71 insertions(+), 43 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/attachment/giphy_attachment.dart b/packages/stream_chat_flutter/lib/src/attachment/giphy_attachment.dart index fc0fb586..215ada51 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/giphy_attachment.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/giphy_attachment.dart @@ -18,6 +18,7 @@ class GiphyAttachment extends AttachmentWidget { this.onShowMessage, this.onReturnAction, this.onAttachmentTap, + this.attachmentActionsModalBuilder, }) : super( key: key, message: message, @@ -34,6 +35,8 @@ class GiphyAttachment extends AttachmentWidget { /// Callback when attachment is tapped final VoidCallback? onAttachmentTap; + final AttachmentActionsBuilder? attachmentActionsModalBuilder; + @override Widget build(BuildContext context) { final imageUrl = @@ -250,6 +253,7 @@ class GiphyAttachment extends AttachmentWidget { userName: message.user?.name, message: message, onShowMessage: onShowMessage, + attachmentActionsModalBuilder: attachmentActionsModalBuilder, ), ); }, diff --git a/packages/stream_chat_flutter/lib/src/attachment/image_attachment.dart b/packages/stream_chat_flutter/lib/src/attachment/image_attachment.dart index 41b8d039..239cf2a2 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/image_attachment.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/image_attachment.dart @@ -21,6 +21,7 @@ class ImageAttachment extends AttachmentWidget { this.onShowMessage, this.onReturnAction, this.onAttachmentTap, + this.attachmentActionsModalBuilder, }) : super( key: key, message: message, @@ -43,6 +44,8 @@ class ImageAttachment extends AttachmentWidget { /// Callback when attachment is tapped final VoidCallback? onAttachmentTap; + final AttachmentActionsBuilder? attachmentActionsModalBuilder; + @override Widget build(BuildContext context) => source.when( local: () { @@ -145,6 +148,8 @@ class ImageAttachment extends AttachmentWidget { userName: message.user?.name, message: message, onShowMessage: onShowMessage, + attachmentActionsModalBuilder: + attachmentActionsModalBuilder, ), ); }, diff --git a/packages/stream_chat_flutter/lib/src/attachment/video_attachment.dart b/packages/stream_chat_flutter/lib/src/attachment/video_attachment.dart index ce4ac804..40a1bff3 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/video_attachment.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/video_attachment.dart @@ -18,6 +18,7 @@ class VideoAttachment extends AttachmentWidget { this.onShowMessage, this.onReturnAction, this.onAttachmentTap, + this.attachmentActionsModalBuilder, }) : super( key: key, message: message, @@ -37,6 +38,8 @@ class VideoAttachment extends AttachmentWidget { /// Callback when attachment is tapped final VoidCallback? onAttachmentTap; + final AttachmentActionsBuilder? attachmentActionsModalBuilder; + @override Widget build(BuildContext context) => source.when( local: () { @@ -91,6 +94,8 @@ class VideoAttachment extends AttachmentWidget { userName: message.user?.name, message: message, onShowMessage: onShowMessage, + attachmentActionsModalBuilder: + attachmentActionsModalBuilder, ), ), ), diff --git a/packages/stream_chat_flutter/lib/src/attachment_actions_modal.dart b/packages/stream_chat_flutter/lib/src/attachment_actions_modal.dart index 96e040fd..89527a48 100644 --- a/packages/stream_chat_flutter/lib/src/attachment_actions_modal.dart +++ b/packages/stream_chat_flutter/lib/src/attachment_actions_modal.dart @@ -57,6 +57,32 @@ class AttachmentActionsModal extends StatelessWidget { /// Show delete option final bool showDelete; + /// Creates a copy of [MessageWidget] with specified attributes overridden. + AttachmentActionsModal copyWith({ + Key? key, + int? currentIndex, + Message? message, + VoidCallback? onShowMessage, + AttachmentDownloader? imageDownloader, + AttachmentDownloader? fileDownloader, + bool? showReply, + bool? showShowInChat, + bool? showSave, + bool? showDelete, + }) => + AttachmentActionsModal( + key: key ?? this.key, + currentIndex: currentIndex ?? this.currentIndex, + message: message ?? this.message, + onShowMessage: onShowMessage ?? this.onShowMessage, + imageDownloader: imageDownloader ?? this.imageDownloader, + fileDownloader: fileDownloader ?? this.fileDownloader, + showReply: showReply ?? this.showReply, + showShowInChat: showShowInChat ?? this.showShowInChat, + showSave: showSave ?? this.showSave, + showDelete: showDelete ?? this.showDelete, + ); + @override Widget build(BuildContext context) => GestureDetector( behavior: HitTestBehavior.translucent, diff --git a/packages/stream_chat_flutter/lib/src/full_screen_media.dart b/packages/stream_chat_flutter/lib/src/full_screen_media.dart index 6fe2b2a4..566f8f3f 100644 --- a/packages/stream_chat_flutter/lib/src/full_screen_media.dart +++ b/packages/stream_chat_flutter/lib/src/full_screen_media.dart @@ -33,10 +33,7 @@ class FullScreenMedia extends StatefulWidget { this.startIndex = 0, String? userName, this.onShowMessage, - this.showReply = true, - this.showShowInChat = true, - this.showSave = true, - this.showDelete = true, + this.attachmentActionsModalBuilder, }) : userName = userName ?? '', super(key: key); @@ -55,17 +52,7 @@ class FullScreenMedia extends StatefulWidget { /// Callback for when show message is tapped final ShowMessageCallback? onShowMessage; - /// Show reply option - final bool showReply; - - /// Show show in chat option - final bool showShowInChat; - - /// Show save option - final bool showSave; - - /// Show delete option - final bool showDelete; + final AttachmentActionsBuilder? attachmentActionsModalBuilder; @override _FullScreenMediaState createState() => _FullScreenMediaState(); @@ -212,10 +199,8 @@ class _FullScreenMediaState extends State StreamChannel.of(context).channel, ); }, - showReply: widget.showReply, - showShowInChat: widget.showShowInChat, - showSave: widget.showSave, - showDelete: widget.showDelete, + attachmentActionsModalBuilder: + widget.attachmentActionsModalBuilder, ), if (!widget.message.isEphemeral) GalleryFooter( diff --git a/packages/stream_chat_flutter/lib/src/gallery_header.dart b/packages/stream_chat_flutter/lib/src/gallery_header.dart index 638375eb..bc19979e 100644 --- a/packages/stream_chat_flutter/lib/src/gallery_header.dart +++ b/packages/stream_chat_flutter/lib/src/gallery_header.dart @@ -6,6 +6,12 @@ import 'package:stream_chat_flutter/src/stream_svg_icon.dart'; import 'package:stream_chat_flutter/src/theme/themes.dart'; import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; +typedef AttachmentActionsBuilder = Widget Function( + BuildContext context, + Attachment attachment, + AttachmentActionsModal defaultActionsModal, +); + /// Header/AppBar widget for media display screen class GalleryHeader extends StatelessWidget implements PreferredSizeWidget { /// Creates a channel header @@ -21,10 +27,7 @@ class GalleryHeader extends StatelessWidget implements PreferredSizeWidget { this.userName = '', this.sentAt = '', this.backgroundColor, - this.showReply = true, - this.showShowInChat = true, - this.showSave = true, - this.showDelete = true, + this.attachmentActionsModalBuilder, }) : preferredSize = const Size.fromHeight(kToolbarHeight), super(key: key); @@ -59,17 +62,7 @@ class GalleryHeader extends StatelessWidget implements PreferredSizeWidget { /// The background color of this [GalleryHeader]. final Color? backgroundColor; - /// Show reply option - final bool showReply; - - /// Show show in chat option - final bool showShowInChat; - - /// Show save option - final bool showSave; - - /// Show delete option - final bool showDelete; + final AttachmentActionsBuilder? attachmentActionsModalBuilder; @override Widget build(BuildContext context) { @@ -139,21 +132,26 @@ class GalleryHeader extends StatelessWidget implements PreferredSizeWidget { final galleryHeaderThemeData = StreamChatTheme.of(context).galleryHeaderTheme; + final defaultModal = AttachmentActionsModal( + message: message, + currentIndex: currentIndex, + onShowMessage: onShowMessage, + ); + + final effectiveModal = attachmentActionsModalBuilder?.call( + context, + message.attachments[currentIndex], + defaultModal, + ) ?? + defaultModal; + final result = await showDialog( useRootNavigator: false, context: context, barrierColor: galleryHeaderThemeData.bottomSheetBarrierColor, builder: (context) => StreamChannel( channel: channel, - child: AttachmentActionsModal( - message: message, - currentIndex: currentIndex, - onShowMessage: onShowMessage, - showReply: showReply, - showShowInChat: showShowInChat, - showSave: showSave, - showDelete: showDelete, - ), + child: effectiveModal, ), ); diff --git a/packages/stream_chat_flutter/lib/src/image_group.dart b/packages/stream_chat_flutter/lib/src/image_group.dart index 88b309fe..04fe8032 100644 --- a/packages/stream_chat_flutter/lib/src/image_group.dart +++ b/packages/stream_chat_flutter/lib/src/image_group.dart @@ -16,6 +16,7 @@ class ImageGroup extends StatelessWidget { this.onReturnAction, this.onShowMessage, this.onAttachmentTap, + this.attachmentActionsModalBuilder, }) : super(key: key); /// List of attachments to show @@ -39,6 +40,8 @@ class ImageGroup extends StatelessWidget { /// Callback for when show message is tapped final ShowMessageCallback? onShowMessage; + final AttachmentActionsBuilder? attachmentActionsModalBuilder; + @override Widget build(BuildContext context) => ConstrainedBox( constraints: BoxConstraints.loose(size), @@ -138,6 +141,7 @@ class ImageGroup extends StatelessWidget { userName: message.user?.name, message: message, onShowMessage: onShowMessage, + attachmentActionsModalBuilder: attachmentActionsModalBuilder, ), ), ), @@ -151,5 +155,6 @@ class ImageGroup extends StatelessWidget { message: message, messageTheme: messageTheme, onAttachmentTap: () => _onTap(context, index), + attachmentActionsModalBuilder: attachmentActionsModalBuilder, ); } From 5223aa6b4a52776255e53e6f25e8e95fea3726dc Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Mon, 15 Nov 2021 18:04:49 +0530 Subject: [PATCH 04/10] added docs --- .../lib/src/attachment/giphy_attachment.dart | 4 ++++ .../lib/src/attachment/image_attachment.dart | 3 +++ .../lib/src/attachment/video_attachment.dart | 3 +++ packages/stream_chat_flutter/lib/src/full_screen_media.dart | 3 +++ packages/stream_chat_flutter/lib/src/gallery_header.dart | 6 ++++++ packages/stream_chat_flutter/lib/src/image_group.dart | 3 +++ 6 files changed, 22 insertions(+) diff --git a/packages/stream_chat_flutter/lib/src/attachment/giphy_attachment.dart b/packages/stream_chat_flutter/lib/src/attachment/giphy_attachment.dart index 215ada51..7c8ad684 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/giphy_attachment.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/giphy_attachment.dart @@ -2,6 +2,7 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:shimmer/shimmer.dart'; import 'package:stream_chat_flutter/src/attachment/attachment_widget.dart'; +import 'package:stream_chat_flutter/src/attachment_actions_modal.dart'; import 'package:stream_chat_flutter/src/extension.dart'; import 'package:stream_chat_flutter/src/visible_footnote.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -35,6 +36,9 @@ class GiphyAttachment extends AttachmentWidget { /// Callback when attachment is tapped final VoidCallback? onAttachmentTap; + /// Widget builder for attachment actions modal + /// [defaultActionsModal] is the default [AttachmentActionsModal] config + /// Use [defaultActionsModal.copyWith] to easily customize it final AttachmentActionsBuilder? attachmentActionsModalBuilder; @override diff --git a/packages/stream_chat_flutter/lib/src/attachment/image_attachment.dart b/packages/stream_chat_flutter/lib/src/attachment/image_attachment.dart index 239cf2a2..7711ad1f 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/image_attachment.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/image_attachment.dart @@ -44,6 +44,9 @@ class ImageAttachment extends AttachmentWidget { /// Callback when attachment is tapped final VoidCallback? onAttachmentTap; + /// Widget builder for attachment actions modal + /// [defaultActionsModal] is the default [AttachmentActionsModal] config + /// Use [defaultActionsModal.copyWith] to easily customize it final AttachmentActionsBuilder? attachmentActionsModalBuilder; @override diff --git a/packages/stream_chat_flutter/lib/src/attachment/video_attachment.dart b/packages/stream_chat_flutter/lib/src/attachment/video_attachment.dart index 40a1bff3..a712b40b 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/video_attachment.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/video_attachment.dart @@ -38,6 +38,9 @@ class VideoAttachment extends AttachmentWidget { /// Callback when attachment is tapped final VoidCallback? onAttachmentTap; + /// Widget builder for attachment actions modal + /// [defaultActionsModal] is the default [AttachmentActionsModal] config + /// Use [defaultActionsModal.copyWith] to easily customize it final AttachmentActionsBuilder? attachmentActionsModalBuilder; @override diff --git a/packages/stream_chat_flutter/lib/src/full_screen_media.dart b/packages/stream_chat_flutter/lib/src/full_screen_media.dart index 566f8f3f..6547a93d 100644 --- a/packages/stream_chat_flutter/lib/src/full_screen_media.dart +++ b/packages/stream_chat_flutter/lib/src/full_screen_media.dart @@ -52,6 +52,9 @@ class FullScreenMedia extends StatefulWidget { /// Callback for when show message is tapped final ShowMessageCallback? onShowMessage; + /// Widget builder for attachment actions modal + /// [defaultActionsModal] is the default [AttachmentActionsModal] config + /// Use [defaultActionsModal.copyWith] to easily customize it final AttachmentActionsBuilder? attachmentActionsModalBuilder; @override diff --git a/packages/stream_chat_flutter/lib/src/gallery_header.dart b/packages/stream_chat_flutter/lib/src/gallery_header.dart index bc19979e..2325af69 100644 --- a/packages/stream_chat_flutter/lib/src/gallery_header.dart +++ b/packages/stream_chat_flutter/lib/src/gallery_header.dart @@ -6,6 +6,9 @@ import 'package:stream_chat_flutter/src/stream_svg_icon.dart'; import 'package:stream_chat_flutter/src/theme/themes.dart'; import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; +/// Widget builder for attachment actions modal +/// [defaultActionsModal] is the default [AttachmentActionsModal] config +/// Use [defaultActionsModal.copyWith] to easily customize it typedef AttachmentActionsBuilder = Widget Function( BuildContext context, Attachment attachment, @@ -62,6 +65,9 @@ class GalleryHeader extends StatelessWidget implements PreferredSizeWidget { /// The background color of this [GalleryHeader]. final Color? backgroundColor; + /// Widget builder for attachment actions modal + /// [defaultActionsModal] is the default [AttachmentActionsModal] config + /// Use [defaultActionsModal.copyWith] to easily customize it final AttachmentActionsBuilder? attachmentActionsModalBuilder; @override diff --git a/packages/stream_chat_flutter/lib/src/image_group.dart b/packages/stream_chat_flutter/lib/src/image_group.dart index 04fe8032..851b82e4 100644 --- a/packages/stream_chat_flutter/lib/src/image_group.dart +++ b/packages/stream_chat_flutter/lib/src/image_group.dart @@ -40,6 +40,9 @@ class ImageGroup extends StatelessWidget { /// Callback for when show message is tapped final ShowMessageCallback? onShowMessage; + /// Widget builder for attachment actions modal + /// [defaultActionsModal] is the default [AttachmentActionsModal] config + /// Use [defaultActionsModal.copyWith] to easily customize it final AttachmentActionsBuilder? attachmentActionsModalBuilder; @override From 8acc3b9d85fb5486a50c4d1504954182f18321d2 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Mon, 15 Nov 2021 18:57:37 +0530 Subject: [PATCH 05/10] analysis --- packages/stream_chat_flutter/lib/src/gallery_footer.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/stream_chat_flutter/lib/src/gallery_footer.dart b/packages/stream_chat_flutter/lib/src/gallery_footer.dart index dcfa0e29..0acd9b02 100644 --- a/packages/stream_chat_flutter/lib/src/gallery_footer.dart +++ b/packages/stream_chat_flutter/lib/src/gallery_footer.dart @@ -1,7 +1,6 @@ import 'dart:io'; import 'package:cached_network_image/cached_network_image.dart'; -import 'package:dio/dio.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:path_provider/path_provider.dart'; From ba91a0f019a7f65205a89016a13cf7e23193f7cf Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Mon, 15 Nov 2021 19:11:54 +0530 Subject: [PATCH 06/10] added back dio --- packages/stream_chat_flutter/lib/src/gallery_footer.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/stream_chat_flutter/lib/src/gallery_footer.dart b/packages/stream_chat_flutter/lib/src/gallery_footer.dart index 0acd9b02..dcfa0e29 100644 --- a/packages/stream_chat_flutter/lib/src/gallery_footer.dart +++ b/packages/stream_chat_flutter/lib/src/gallery_footer.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:cached_network_image/cached_network_image.dart'; +import 'package:dio/dio.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:path_provider/path_provider.dart'; From f3d4eab1a003bcae3d461c0b300ba54f4c957ac7 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Wed, 17 Nov 2021 13:53:58 +0530 Subject: [PATCH 07/10] removed builders --- .../lib/src/attachment/giphy_attachment.dart | 8 -------- .../lib/src/attachment/image_attachment.dart | 8 -------- .../lib/src/attachment/video_attachment.dart | 8 -------- packages/stream_chat_flutter/lib/src/image_group.dart | 8 -------- 4 files changed, 32 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/attachment/giphy_attachment.dart b/packages/stream_chat_flutter/lib/src/attachment/giphy_attachment.dart index 7c8ad684..fc0fb586 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/giphy_attachment.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/giphy_attachment.dart @@ -2,7 +2,6 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:shimmer/shimmer.dart'; import 'package:stream_chat_flutter/src/attachment/attachment_widget.dart'; -import 'package:stream_chat_flutter/src/attachment_actions_modal.dart'; import 'package:stream_chat_flutter/src/extension.dart'; import 'package:stream_chat_flutter/src/visible_footnote.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; @@ -19,7 +18,6 @@ class GiphyAttachment extends AttachmentWidget { this.onShowMessage, this.onReturnAction, this.onAttachmentTap, - this.attachmentActionsModalBuilder, }) : super( key: key, message: message, @@ -36,11 +34,6 @@ class GiphyAttachment extends AttachmentWidget { /// Callback when attachment is tapped final VoidCallback? onAttachmentTap; - /// Widget builder for attachment actions modal - /// [defaultActionsModal] is the default [AttachmentActionsModal] config - /// Use [defaultActionsModal.copyWith] to easily customize it - final AttachmentActionsBuilder? attachmentActionsModalBuilder; - @override Widget build(BuildContext context) { final imageUrl = @@ -257,7 +250,6 @@ class GiphyAttachment extends AttachmentWidget { userName: message.user?.name, message: message, onShowMessage: onShowMessage, - attachmentActionsModalBuilder: attachmentActionsModalBuilder, ), ); }, diff --git a/packages/stream_chat_flutter/lib/src/attachment/image_attachment.dart b/packages/stream_chat_flutter/lib/src/attachment/image_attachment.dart index 7711ad1f..41b8d039 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/image_attachment.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/image_attachment.dart @@ -21,7 +21,6 @@ class ImageAttachment extends AttachmentWidget { this.onShowMessage, this.onReturnAction, this.onAttachmentTap, - this.attachmentActionsModalBuilder, }) : super( key: key, message: message, @@ -44,11 +43,6 @@ class ImageAttachment extends AttachmentWidget { /// Callback when attachment is tapped final VoidCallback? onAttachmentTap; - /// Widget builder for attachment actions modal - /// [defaultActionsModal] is the default [AttachmentActionsModal] config - /// Use [defaultActionsModal.copyWith] to easily customize it - final AttachmentActionsBuilder? attachmentActionsModalBuilder; - @override Widget build(BuildContext context) => source.when( local: () { @@ -151,8 +145,6 @@ class ImageAttachment extends AttachmentWidget { userName: message.user?.name, message: message, onShowMessage: onShowMessage, - attachmentActionsModalBuilder: - attachmentActionsModalBuilder, ), ); }, diff --git a/packages/stream_chat_flutter/lib/src/attachment/video_attachment.dart b/packages/stream_chat_flutter/lib/src/attachment/video_attachment.dart index a712b40b..ce4ac804 100644 --- a/packages/stream_chat_flutter/lib/src/attachment/video_attachment.dart +++ b/packages/stream_chat_flutter/lib/src/attachment/video_attachment.dart @@ -18,7 +18,6 @@ class VideoAttachment extends AttachmentWidget { this.onShowMessage, this.onReturnAction, this.onAttachmentTap, - this.attachmentActionsModalBuilder, }) : super( key: key, message: message, @@ -38,11 +37,6 @@ class VideoAttachment extends AttachmentWidget { /// Callback when attachment is tapped final VoidCallback? onAttachmentTap; - /// Widget builder for attachment actions modal - /// [defaultActionsModal] is the default [AttachmentActionsModal] config - /// Use [defaultActionsModal.copyWith] to easily customize it - final AttachmentActionsBuilder? attachmentActionsModalBuilder; - @override Widget build(BuildContext context) => source.when( local: () { @@ -97,8 +91,6 @@ class VideoAttachment extends AttachmentWidget { userName: message.user?.name, message: message, onShowMessage: onShowMessage, - attachmentActionsModalBuilder: - attachmentActionsModalBuilder, ), ), ), diff --git a/packages/stream_chat_flutter/lib/src/image_group.dart b/packages/stream_chat_flutter/lib/src/image_group.dart index 851b82e4..88b309fe 100644 --- a/packages/stream_chat_flutter/lib/src/image_group.dart +++ b/packages/stream_chat_flutter/lib/src/image_group.dart @@ -16,7 +16,6 @@ class ImageGroup extends StatelessWidget { this.onReturnAction, this.onShowMessage, this.onAttachmentTap, - this.attachmentActionsModalBuilder, }) : super(key: key); /// List of attachments to show @@ -40,11 +39,6 @@ class ImageGroup extends StatelessWidget { /// Callback for when show message is tapped final ShowMessageCallback? onShowMessage; - /// Widget builder for attachment actions modal - /// [defaultActionsModal] is the default [AttachmentActionsModal] config - /// Use [defaultActionsModal.copyWith] to easily customize it - final AttachmentActionsBuilder? attachmentActionsModalBuilder; - @override Widget build(BuildContext context) => ConstrainedBox( constraints: BoxConstraints.loose(size), @@ -144,7 +138,6 @@ class ImageGroup extends StatelessWidget { userName: message.user?.name, message: message, onShowMessage: onShowMessage, - attachmentActionsModalBuilder: attachmentActionsModalBuilder, ), ), ), @@ -158,6 +151,5 @@ class ImageGroup extends StatelessWidget { message: message, messageTheme: messageTheme, onAttachmentTap: () => _onTap(context, index), - attachmentActionsModalBuilder: attachmentActionsModalBuilder, ); } From 4f1dc72d3a50d27584596756eea9231faaf0d4eb Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Wed, 17 Nov 2021 14:03:03 +0530 Subject: [PATCH 08/10] added custom actions --- .../lib/src/attachment_actions_modal.dart | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/packages/stream_chat_flutter/lib/src/attachment_actions_modal.dart b/packages/stream_chat_flutter/lib/src/attachment_actions_modal.dart index 89527a48..7b9f0d51 100644 --- a/packages/stream_chat_flutter/lib/src/attachment_actions_modal.dart +++ b/packages/stream_chat_flutter/lib/src/attachment_actions_modal.dart @@ -28,6 +28,7 @@ class AttachmentActionsModal extends StatelessWidget { this.showShowInChat = true, this.showSave = true, this.showDelete = true, + this.customActions = const [], }) : super(key: key); /// The message containing the attachments @@ -57,6 +58,9 @@ class AttachmentActionsModal extends StatelessWidget { /// Show delete option final bool showDelete; + /// List of custom actions + final List customActions; + /// Creates a copy of [MessageWidget] with specified attributes overridden. AttachmentActionsModal copyWith({ Key? key, @@ -69,6 +73,7 @@ class AttachmentActionsModal extends StatelessWidget { bool? showShowInChat, bool? showSave, bool? showDelete, + List? customActions, }) => AttachmentActionsModal( key: key ?? this.key, @@ -81,6 +86,7 @@ class AttachmentActionsModal extends StatelessWidget { showShowInChat: showShowInChat ?? this.showShowInChat, showSave: showSave ?? this.showSave, showDelete: showDelete ?? this.showDelete, + customActions: customActions ?? this.customActions, ); @override @@ -217,6 +223,16 @@ class AttachmentActionsModal extends StatelessWidget { }, color: theme.colorTheme.accentError, ), + ...customActions + .map( + (e) => _buildButton( + context, + e.actionTitle, + e.icon, + e.onTap, + ), + ) + .toList(), ] .map((e) => Align( alignment: Alignment.centerRight, @@ -239,7 +255,7 @@ class AttachmentActionsModal extends StatelessWidget { Widget _buildButton( context, String title, - StreamSvgIcon icon, + Widget icon, VoidCallback? onTap, { Color? color, Key? key, @@ -377,3 +393,15 @@ class _DownloadProgress { int get toPercentage => (received * 100) ~/ total; } + +class AttachmentAction { + String actionTitle; + Widget icon; + VoidCallback onTap; + + AttachmentAction({ + required this.actionTitle, + required this.icon, + required this.onTap, + }); +} From ecaba6ebb98b32023cff3b6cf650e9ec2a9984dd Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Wed, 17 Nov 2021 14:04:39 +0530 Subject: [PATCH 09/10] added custom actions --- .../lib/src/attachment_actions_modal.dart | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/stream_chat_flutter/lib/src/attachment_actions_modal.dart b/packages/stream_chat_flutter/lib/src/attachment_actions_modal.dart index 7b9f0d51..0c10ae46 100644 --- a/packages/stream_chat_flutter/lib/src/attachment_actions_modal.dart +++ b/packages/stream_chat_flutter/lib/src/attachment_actions_modal.dart @@ -394,14 +394,21 @@ class _DownloadProgress { int get toPercentage => (received * 100) ~/ total; } +/// Class for custom attachment action class AttachmentAction { - String actionTitle; - Widget icon; - VoidCallback onTap; - + /// Constructor for custom attachment action AttachmentAction({ required this.actionTitle, required this.icon, required this.onTap, }); + + /// Title for the attachment action + String actionTitle; + + /// Icon for the attachment action + Widget icon; + + /// Callback for when the action is tapped + VoidCallback onTap; } From 1c25d415d6e6c1a3a5bd80e8524269da0c335395 Mon Sep 17 00:00:00 2001 From: Salvatore Giordano Date: Wed, 17 Nov 2021 11:31:51 +0100 Subject: [PATCH 10/10] fix(ui): export attachment_actions_modal --- packages/stream_chat_flutter/lib/stream_chat_flutter.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart index 0447fc68..cd0d93a0 100644 --- a/packages/stream_chat_flutter/lib/stream_chat_flutter.dart +++ b/packages/stream_chat_flutter/lib/stream_chat_flutter.dart @@ -2,6 +2,7 @@ export 'package:jiffy/jiffy.dart'; export 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; export 'src/attachment/attachment.dart'; +export 'src/attachment_actions_modal.dart'; export 'src/back_button.dart'; export 'src/channel_avatar.dart'; export 'src/channel_header.dart';