From a688ab3a1097426a33a3c2d31ad8a217a3fb2e28 Mon Sep 17 00:00:00 2001 From: Deven Joshi Date: Wed, 5 May 2021 14:59:21 +0530 Subject: [PATCH] lint changes image --- .../lib/src/attachment_actions_modal.dart | 43 +-- .../lib/src/back_button.dart | 63 +++-- .../lib/src/channel_image.dart | 50 ++-- .../lib/src/channel_list_header.dart | 99 +++---- .../lib/src/channel_list_view.dart | 1 - .../lib/src/channel_name.dart | 6 +- .../lib/src/channel_preview.dart | 1 - .../lib/src/date_divider.dart | 1 - .../lib/src/deleted_message.dart | 69 +++-- .../lib/src/full_screen_media.dart | 9 +- .../lib/src/image_footer.dart | 262 ++++++++---------- .../lib/src/image_group.dart | 153 +++++----- .../lib/src/image_header.dart | 160 +++++------ .../lib/src/message_input.dart | 213 +++++++------- 14 files changed, 561 insertions(+), 569 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 a8d1bddd..a9ea651b 100644 --- a/packages/stream_chat_flutter/lib/src/attachment_actions_modal.dart +++ b/packages/stream_chat_flutter/lib/src/attachment_actions_modal.dart @@ -192,29 +192,30 @@ class AttachmentActionsModal extends StatelessWidget { VoidCallback? onTap, { Color? color, Key? key, - }) => Material( - key: key, - color: StreamChatTheme.of(context).colorTheme.white, - child: InkWell( - onTap: onTap, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), - child: Row( - children: [ - icon, - SizedBox(width: 16), - Text( - title, - style: StreamChatTheme.of(context) - .textTheme - .body - .copyWith(color: color), - ), - ], + }) => + Material( + key: key, + color: StreamChatTheme.of(context).colorTheme.white, + child: InkWell( + onTap: onTap, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), + child: Row( + children: [ + icon, + SizedBox(width: 16), + Text( + title, + style: StreamChatTheme.of(context) + .textTheme + .body + .copyWith(color: color), + ), + ], + ), ), ), - ), - ); + ); Widget _buildDownloadProgressDialog( BuildContext context, diff --git a/packages/stream_chat_flutter/lib/src/back_button.dart b/packages/stream_chat_flutter/lib/src/back_button.dart index acb3d1ec..e8fe7e31 100644 --- a/packages/stream_chat_flutter/lib/src/back_button.dart +++ b/packages/stream_chat_flutter/lib/src/back_button.dart @@ -5,7 +5,6 @@ import 'package:stream_chat_flutter/stream_chat_flutter.dart'; /// Back button implementation class StreamBackButton extends StatelessWidget { - /// Constructor for creating back button const StreamBackButton({ Key? key, @@ -25,37 +24,37 @@ class StreamBackButton extends StatelessWidget { @override Widget build(BuildContext context) => Stack( - alignment: Alignment.center, - children: [ - RawMaterialButton( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(4), - ), - elevation: 0, - highlightElevation: 0, - focusElevation: 0, - hoverElevation: 0, - onPressed: () { - if (onPressed != null) { - onPressed!(); - } else { - Navigator.maybePop(context); - } - }, - padding: const EdgeInsets.all(14), - child: StreamSvgIcon.left( - size: 24, - color: StreamChatTheme.of(context).colorTheme.black, - ), - ), - if (showUnreads) - Positioned( - top: 7, - right: 7, - child: UnreadIndicator( - cid: cid, + alignment: Alignment.center, + children: [ + RawMaterialButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(4), + ), + elevation: 0, + highlightElevation: 0, + focusElevation: 0, + hoverElevation: 0, + onPressed: () { + if (onPressed != null) { + onPressed!(); + } else { + Navigator.maybePop(context); + } + }, + padding: const EdgeInsets.all(14), + child: StreamSvgIcon.left( + size: 24, + color: StreamChatTheme.of(context).colorTheme.black, ), ), - ], - ); + if (showUnreads) + Positioned( + top: 7, + right: 7, + child: UnreadIndicator( + cid: cid, + ), + ), + ], + ); } diff --git a/packages/stream_chat_flutter/lib/src/channel_image.dart b/packages/stream_chat_flutter/lib/src/channel_image.dart index 3f3a38be..8116ca83 100644 --- a/packages/stream_chat_flutter/lib/src/channel_image.dart +++ b/packages/stream_chat_flutter/lib/src/channel_image.dart @@ -98,23 +98,23 @@ class ChannelImage extends StatelessWidget { (users) => users[otherMember?.userId] ?? otherMember!.user!), initialData: otherMember!.user, builder: (context, snapshot) => UserAvatar( - borderRadius: borderRadius ?? - StreamChatTheme.of(context) - .channelPreviewTheme - .avatarTheme - ?.borderRadius, - user: snapshot.data ?? otherMember.user!, - constraints: constraints ?? - StreamChatTheme.of(context) - .channelPreviewTheme - .avatarTheme - ?.constraints, - onTap: onTap != null ? (_) => onTap!() : null, - selected: selected, - selectionColor: selectionColor ?? - StreamChatTheme.of(context).colorTheme.accentBlue, - selectionThickness: selectionThickness, - )); + borderRadius: borderRadius ?? + StreamChatTheme.of(context) + .channelPreviewTheme + .avatarTheme + ?.borderRadius, + user: snapshot.data ?? otherMember.user!, + constraints: constraints ?? + StreamChatTheme.of(context) + .channelPreviewTheme + .avatarTheme + ?.constraints, + onTap: onTap != null ? (_) => onTap!() : null, + selected: selected, + selectionColor: selectionColor ?? + StreamChatTheme.of(context).colorTheme.accentBlue, + selectionThickness: selectionThickness, + )); } else { final images = channel.state?.members .where((member) => @@ -167,16 +167,16 @@ class ChannelImage extends StatelessWidget { CachedNetworkImage( imageUrl: image, errorWidget: (_, __, ___) => Center( - child: Text( - snapshot.data?.containsKey('name') ?? false - ? snapshot.data!['name'][0] - : '', - style: TextStyle( - color: StreamChatTheme.of(context).colorTheme.white, - fontWeight: FontWeight.bold, - ), + child: Text( + snapshot.data?.containsKey('name') ?? false + ? snapshot.data!['name'][0] + : '', + style: TextStyle( + color: StreamChatTheme.of(context).colorTheme.white, + fontWeight: FontWeight.bold, ), ), + ), fit: BoxFit.cover, ) else diff --git a/packages/stream_chat_flutter/lib/src/channel_list_header.dart b/packages/stream_chat_flutter/lib/src/channel_list_header.dart index c8d2aa69..afc1884c 100644 --- a/packages/stream_chat_flutter/lib/src/channel_list_header.dart +++ b/packages/stream_chat_flutter/lib/src/channel_list_header.dart @@ -217,64 +217,65 @@ class ChannelListHeader extends StatelessWidget implements PreferredSizeWidget { ); Widget _buildConnectingTitleState(BuildContext context) => Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const SizedBox( - height: 16, - width: 16, - child: Center( - child: CircularProgressIndicator(), + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const SizedBox( + height: 16, + width: 16, + child: Center( + child: CircularProgressIndicator(), + ), ), - ), - const SizedBox(width: 10), - Text( - 'Searching for Network', - style: StreamChatTheme.of(context) - .channelListHeaderTheme - .title - ?.copyWith( - fontSize: 16, - fontWeight: FontWeight.bold, - ), - ), - ], - ); - - Widget _buildDisconnectedTitleState( - BuildContext context, - StreamChatClient client, - ) => Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'Offline...', - style: StreamChatTheme.of(context) - .channelListHeaderTheme - .title - ?.copyWith( - fontSize: 16, - fontWeight: FontWeight.bold, - ), - ), - TextButton( - onPressed: () async { - await client.disconnect(); - await client.connect(); - }, - child: Text( - 'Try Again', + const SizedBox(width: 10), + Text( + 'Searching for Network', style: StreamChatTheme.of(context) .channelListHeaderTheme .title ?.copyWith( fontSize: 16, fontWeight: FontWeight.bold, - color: StreamChatTheme.of(context).colorTheme.accentBlue, ), ), - ), - ], - ); + ], + ); + + Widget _buildDisconnectedTitleState( + BuildContext context, + StreamChatClient client, + ) => + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Offline...', + style: StreamChatTheme.of(context) + .channelListHeaderTheme + .title + ?.copyWith( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + TextButton( + onPressed: () async { + await client.disconnect(); + await client.connect(); + }, + child: Text( + 'Try Again', + style: StreamChatTheme.of(context) + .channelListHeaderTheme + .title + ?.copyWith( + fontSize: 16, + fontWeight: FontWeight.bold, + color: StreamChatTheme.of(context).colorTheme.accentBlue, + ), + ), + ), + ], + ); @override Size get preferredSize => const Size.fromHeight(kToolbarHeight); diff --git a/packages/stream_chat_flutter/lib/src/channel_list_view.dart b/packages/stream_chat_flutter/lib/src/channel_list_view.dart index c58ed42f..fb713ea8 100644 --- a/packages/stream_chat_flutter/lib/src/channel_list_view.dart +++ b/packages/stream_chat_flutter/lib/src/channel_list_view.dart @@ -9,7 +9,6 @@ import 'package:stream_chat_flutter/src/utils.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; - /// Callback called when tapping on a channel typedef ChannelTapCallback = void Function(Channel, Widget?); diff --git a/packages/stream_chat_flutter/lib/src/channel_name.dart b/packages/stream_chat_flutter/lib/src/channel_name.dart index d76bca0c..1cc510af 100644 --- a/packages/stream_chat_flutter/lib/src/channel_name.dart +++ b/packages/stream_chat_flutter/lib/src/channel_name.dart @@ -3,7 +3,6 @@ import 'package:flutter/rendering.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; - /// It shows the current [Channel] name using a [Text] widget. /// /// The widget uses a [StreamBuilder] to render the channel information @@ -60,9 +59,8 @@ class ChannelName extends StatelessWidget { final exceedingMembers = otherMembers.length - currentMembers.length; - title = - '${currentMembers.map((e) => e.user?.name).join(', ')} ' - '${exceedingMembers > 0 ? '+ $exceedingMembers' : ''}'; + title = '${currentMembers.map((e) => e.user?.name).join(', ')} ' + '${exceedingMembers > 0 ? '+ $exceedingMembers' : ''}'; } else { title = 'No title'; } diff --git a/packages/stream_chat_flutter/lib/src/channel_preview.dart b/packages/stream_chat_flutter/lib/src/channel_preview.dart index 9c793ba6..70ad0e3f 100644 --- a/packages/stream_chat_flutter/lib/src/channel_preview.dart +++ b/packages/stream_chat_flutter/lib/src/channel_preview.dart @@ -21,7 +21,6 @@ import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; /// [StreamChatTheme]. /// Modify it to change the widget appearance. class ChannelPreview extends StatelessWidget { - /// Constructor for creating [ChannelPreview] const ChannelPreview({ required this.channel, diff --git a/packages/stream_chat_flutter/lib/src/date_divider.dart b/packages/stream_chat_flutter/lib/src/date_divider.dart index e1b9cfea..f409872b 100644 --- a/packages/stream_chat_flutter/lib/src/date_divider.dart +++ b/packages/stream_chat_flutter/lib/src/date_divider.dart @@ -4,7 +4,6 @@ import 'package:stream_chat_flutter/src/stream_chat_theme.dart'; /// It shows a date divider depending on the date difference class DateDivider extends StatelessWidget { - /// Constructor for creating a [DateDivider] const DateDivider({ Key? key, diff --git a/packages/stream_chat_flutter/lib/src/deleted_message.dart b/packages/stream_chat_flutter/lib/src/deleted_message.dart index 47a5f2ee..96f5606a 100644 --- a/packages/stream_chat_flutter/lib/src/deleted_message.dart +++ b/packages/stream_chat_flutter/lib/src/deleted_message.dart @@ -5,7 +5,6 @@ import 'package:stream_chat_flutter/src/stream_chat_theme.dart'; /// Widget to display deleted message class DeletedMessage extends StatelessWidget { - /// Constructor to create [DeletedMessage] const DeletedMessage({ Key? key, @@ -33,43 +32,43 @@ class DeletedMessage extends StatelessWidget { @override Widget build(BuildContext context) => Transform( - transform: Matrix4.rotationY(reverse ? pi : 0), - alignment: Alignment.center, - child: Material( - color: messageTheme.messageBackgroundColor, - shape: shape ?? - RoundedRectangleBorder( - borderRadius: borderRadiusGeometry ?? BorderRadius.zero, - side: borderSide ?? - BorderSide( - color: Theme.of(context).brightness == Brightness.dark - ? StreamChatTheme.of(context) - .colorTheme - .white - .withAlpha(24) - : StreamChatTheme.of(context) - .colorTheme - .black - .withAlpha(24), - ), + transform: Matrix4.rotationY(reverse ? pi : 0), + alignment: Alignment.center, + child: Material( + color: messageTheme.messageBackgroundColor, + shape: shape ?? + RoundedRectangleBorder( + borderRadius: borderRadiusGeometry ?? BorderRadius.zero, + side: borderSide ?? + BorderSide( + color: Theme.of(context).brightness == Brightness.dark + ? StreamChatTheme.of(context) + .colorTheme + .white + .withAlpha(24) + : StreamChatTheme.of(context) + .colorTheme + .black + .withAlpha(24), + ), + ), + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 8, + horizontal: 16, ), - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 8, - horizontal: 16, - ), - child: Transform( - transform: Matrix4.rotationY(reverse ? pi : 0), - alignment: Alignment.center, - child: Text( - 'Message deleted', - style: messageTheme.messageText?.copyWith( - fontStyle: FontStyle.italic, - color: messageTheme.createdAt?.color, + child: Transform( + transform: Matrix4.rotationY(reverse ? pi : 0), + alignment: Alignment.center, + child: Text( + 'Message deleted', + style: messageTheme.messageText?.copyWith( + fontStyle: FontStyle.italic, + color: messageTheme.createdAt?.color, + ), ), ), ), ), - ), - ); + ); } 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 edebfa09..f86ac60b 100644 --- a/packages/stream_chat_flutter/lib/src/full_screen_media.dart +++ b/packages/stream_chat_flutter/lib/src/full_screen_media.dart @@ -13,7 +13,6 @@ import 'package:video_player/video_player.dart'; /// Return action for coming back from pages enum ReturnActionType { - /// No return action none, @@ -252,10 +251,10 @@ class _FullScreenMediaState extends State class VideoPackage { /// Constructor for creating [VideoPackage] VideoPackage( - Attachment attachment, { - bool showControls = false, - bool autoInitialize = true, - }) : _showControls = showControls, + Attachment attachment, { + bool showControls = false, + bool autoInitialize = true, + }) : _showControls = showControls, _autoInitialize = autoInitialize, _videoPlayerController = attachment.localUri != null ? VideoPlayerController.file(File.fromUri(attachment.localUri!)) diff --git a/packages/stream_chat_flutter/lib/src/image_footer.dart b/packages/stream_chat_flutter/lib/src/image_footer.dart index f660bad7..9298e73b 100644 --- a/packages/stream_chat_flutter/lib/src/image_footer.dart +++ b/packages/stream_chat_flutter/lib/src/image_footer.dart @@ -12,7 +12,22 @@ import 'package:stream_chat_flutter/src/video_thumbnail_image.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; +/// Footer widget for media display class ImageFooter extends StatefulWidget implements PreferredSizeWidget { + /// Creates a channel header + const ImageFooter({ + Key? key, + required this.message, + this.onBackPressed, + this.onTitleTap, + this.onImageTap, + this.currentPage = 0, + this.totalPages = 0, + this.mediaAttachments = const [], + this.mediaSelectedCallBack, + }) : preferredSize = const Size.fromHeight(kToolbarHeight), + super(key: key); + /// Callback to call when pressing the back button. /// By default it calls [Navigator.pop] final VoidCallback? onBackPressed; @@ -23,28 +38,21 @@ class ImageFooter extends StatefulWidget implements PreferredSizeWidget { /// Callback to call when the image is tapped. final VoidCallback? onImageTap; + /// Stores the current index of media shown final int currentPage; + + /// Total number of pages of media final int totalPages; + /// All attachments to show final List mediaAttachments; + + /// Message which attachments are attached to final Message message; + /// Callback when media is selected final ValueChanged? mediaSelectedCallBack; - /// Creates a channel header - ImageFooter({ - Key? key, - required this.message, - this.onBackPressed, - this.onTitleTap, - this.onImageTap, - this.currentPage = 0, - this.totalPages = 0, - this.mediaAttachments = const [], - this.mediaSelectedCallBack, - }) : preferredSize = Size.fromHeight(kToolbarHeight), - super(key: key); - @override _ImageFooterState createState() => _ImageFooterState(); @@ -119,7 +127,7 @@ class _ImageFooterState extends State { ), InkWell( onTap: widget.onTitleTap, - child: Container( + child: SizedBox( child: Column( mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min, @@ -169,115 +177,115 @@ class _ImageFooterState extends State { expand: false, initialChildSize: initialChildSize / size.height, minChildSize: initialChildSize / size.height, - builder: (context, scrollController) { - return SingleChildScrollView( - controller: scrollController, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Stack( - children: [ - Center( - child: Padding( - padding: const EdgeInsets.all(16), - child: Text( - 'Photos', - style: StreamChatTheme.of(context) - .textTheme - .headlineBold, - ), + builder: (context, scrollController) => SingleChildScrollView( + controller: scrollController, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Stack( + children: [ + Center( + child: Padding( + padding: const EdgeInsets.all(16), + child: Text( + 'Photos', + style: StreamChatTheme.of(context) + .textTheme + .headlineBold, ), ), - Align( - alignment: Alignment.centerRight, - child: IconButton( - icon: StreamSvgIcon.close( - color: StreamChatTheme.of(context).colorTheme.black, - ), - onPressed: () => Navigator.maybePop(context), + ), + Align( + alignment: Alignment.centerRight, + child: IconButton( + icon: StreamSvgIcon.close( + color: StreamChatTheme.of(context).colorTheme.black, ), + onPressed: () => Navigator.maybePop(context), ), - ], - ), - Flexible( - child: GridView.builder( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemCount: widget.mediaAttachments.length, - padding: const EdgeInsets.all(1), - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: crossAxisCount, - mainAxisSpacing: 2, - crossAxisSpacing: 2, - ), - itemBuilder: (context, index) { - Widget media; - final attachment = widget.mediaAttachments[index]; - if (attachment.type == 'video') { - media = InkWell( - onTap: () => widget.mediaSelectedCallBack!(index), - child: FittedBox( + ), + ], + ), + Flexible( + child: GridView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: widget.mediaAttachments.length, + padding: const EdgeInsets.all(1), + // ignore: lines_longer_than_80_chars + gridDelegate: + const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: crossAxisCount, + mainAxisSpacing: 2, + crossAxisSpacing: 2, + ), + itemBuilder: (context, index) { + Widget media; + final attachment = widget.mediaAttachments[index]; + if (attachment.type == 'video') { + media = InkWell( + onTap: () => widget.mediaSelectedCallBack!(index), + child: FittedBox( + fit: BoxFit.cover, + child: VideoThumbnailImage( + video: (attachment.file?.path ?? + attachment.assetUrl)!, + ), + ), + ); + } else { + media = InkWell( + onTap: () => widget.mediaSelectedCallBack!(index), + child: AspectRatio( + aspectRatio: 1, + child: CachedNetworkImage( + imageUrl: attachment.imageUrl ?? + attachment.assetUrl ?? + attachment.thumbUrl!, fit: BoxFit.cover, - child: VideoThumbnailImage( - video: (attachment.file?.path ?? - attachment.assetUrl)!, - ), ), - ); - } else { - media = InkWell( - onTap: () => widget.mediaSelectedCallBack!(index), - child: AspectRatio( - aspectRatio: 1, - child: CachedNetworkImage( - imageUrl: attachment.imageUrl ?? - attachment.assetUrl ?? - attachment.thumbUrl!, - fit: BoxFit.cover, - ), - ), - ); - } + ), + ); + } - return Stack( - children: [ - media, - if (widget.message.user != null) - Padding( - padding: EdgeInsets.all(8), - child: Container( - clipBehavior: Clip.antiAlias, - decoration: BoxDecoration( - shape: BoxShape.circle, - color: Colors.white.withOpacity(0.6), - boxShadow: [ - BoxShadow( - blurRadius: 8, - color: StreamChatTheme.of(context) - .colorTheme - .black - .withOpacity(0.3), - ), - ], - ), - padding: const EdgeInsets.all(2), - child: UserAvatar( - user: widget.message.user!, - constraints: - BoxConstraints.tight(Size(24, 24)), - showOnlineStatus: false, - ), + return Stack( + children: [ + media, + if (widget.message.user != null) + Padding( + padding: const EdgeInsets.all(8), + child: Container( + clipBehavior: Clip.antiAlias, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.white.withOpacity(0.6), + boxShadow: [ + BoxShadow( + blurRadius: 8, + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(0.3), + ), + ], + ), + padding: const EdgeInsets.all(2), + child: UserAvatar( + user: widget.message.user!, + constraints: + BoxConstraints.tight(const Size(24, 24)), + showOnlineStatus: false, ), ), - ], - ); - }, - ), + ), + ], + ); + }, ), - ], - ), - ); - }, + ), + ], + ), + ), ); }, ); @@ -304,29 +312,3 @@ class _ImageFooterState extends State { Navigator.pop(context); } } - -/// Used for clipping textfield prefix icon -class IconClipper extends CustomClipper { - @override - Path getClip(Size size) { - final leftX = size.width / 5; - final rightX = 4 * size.width / 5; - final topY = size.height / 5; - final bottomY = 4 * size.height / 5; - - final path = Path(); - path.moveTo(leftX, topY); - path.lineTo(leftX, bottomY); - path.lineTo(rightX, bottomY); - path.lineTo(rightX, topY); - path.lineTo(leftX, topY); - path.lineTo(0, 0); - path.close(); - return path; - } - - @override - bool shouldReclip(CustomClipper oldClipper) { - return false; - } -} diff --git a/packages/stream_chat_flutter/lib/src/image_group.dart b/packages/stream_chat_flutter/lib/src/image_group.dart index 600b7867..51c686c3 100644 --- a/packages/stream_chat_flutter/lib/src/image_group.dart +++ b/packages/stream_chat_flutter/lib/src/image_group.dart @@ -3,7 +3,9 @@ import 'package:stream_chat_flutter/src/full_screen_media.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; +/// Widget for constructing a group of images in message class ImageGroup extends StatelessWidget { + /// Constructor for creating [ImageGroup] widget const ImageGroup({ Key? key, required this.images, @@ -13,91 +15,98 @@ class ImageGroup extends StatelessWidget { this.onShowMessage, }) : super(key: key); + /// List of attachments to show final List images; + + /// Message which images are attached to final Message message; + + /// [MessageTheme] to apply to message final MessageTheme messageTheme; + + /// Size of iamges final Size size; + + /// Callback for when show message is tapped final ShowMessageCallback? onShowMessage; @override - Widget build(BuildContext context) { - return ConstrainedBox( - constraints: BoxConstraints.loose(size), - child: Flex( - direction: Axis.vertical, - children: [ - Flexible( - fit: FlexFit.tight, - child: Flex( - crossAxisAlignment: CrossAxisAlignment.stretch, - direction: Axis.horizontal, - children: [ - Flexible( - fit: FlexFit.tight, - child: _buildImage(context, 0), - ), - Flexible( - fit: FlexFit.tight, - child: Padding( - padding: const EdgeInsets.only(left: 2), - child: _buildImage(context, 1), - ), - ), - ], - ), - ), - if (images.length >= 3) + Widget build(BuildContext context) => ConstrainedBox( + constraints: BoxConstraints.loose(size), + child: Flex( + direction: Axis.vertical, + children: [ Flexible( fit: FlexFit.tight, - child: Padding( - padding: const EdgeInsets.only(top: 2), - child: Flex( - direction: Axis.horizontal, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Flexible( - fit: FlexFit.tight, - child: _buildImage(context, 2), + child: Flex( + crossAxisAlignment: CrossAxisAlignment.stretch, + direction: Axis.horizontal, + children: [ + Flexible( + fit: FlexFit.tight, + child: _buildImage(context, 0), + ), + Flexible( + fit: FlexFit.tight, + child: Padding( + padding: const EdgeInsets.only(left: 2), + child: _buildImage(context, 1), ), - if (images.length >= 4) + ), + ], + ), + ), + if (images.length >= 3) + Flexible( + fit: FlexFit.tight, + child: Padding( + padding: const EdgeInsets.only(top: 2), + child: Flex( + direction: Axis.horizontal, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ Flexible( fit: FlexFit.tight, - child: Padding( - padding: const EdgeInsets.only(left: 2), - child: Stack( - fit: StackFit.expand, - children: [ - _buildImage(context, 3), - if (images.length > 4) - Positioned.fill( - child: GestureDetector( - onTap: () => _onTap(context, 3), - child: Material( - color: Colors.black38, - child: Center( - child: Text( - '+ ${images.length - 4}', - style: TextStyle( - color: Colors.white, - fontSize: 26, + child: _buildImage(context, 2), + ), + if (images.length >= 4) + Flexible( + fit: FlexFit.tight, + child: Padding( + padding: const EdgeInsets.only(left: 2), + child: Stack( + fit: StackFit.expand, + children: [ + _buildImage(context, 3), + if (images.length > 4) + Positioned.fill( + child: GestureDetector( + onTap: () => _onTap(context, 3), + child: Material( + color: Colors.black38, + child: Center( + child: Text( + '+ ${images.length - 4}', + style: const TextStyle( + color: Colors.white, + fontSize: 26, + ), ), ), ), ), ), - ), - ], + ], + ), ), ), - ), - ], + ], + ), ), ), - ), - ], - ), - ); - } + ], + ), + ); void _onTap( BuildContext context, @@ -122,13 +131,11 @@ class ImageGroup extends StatelessWidget { ); } - Widget _buildImage(BuildContext context, int index) { - return ImageAttachment( - attachment: images[index], - size: size, - message: message, - messageTheme: messageTheme, - onAttachmentTap: () => _onTap(context, index), - ); - } + Widget _buildImage(BuildContext context, int index) => ImageAttachment( + attachment: images[index], + size: size, + message: message, + messageTheme: messageTheme, + onAttachmentTap: () => _onTap(context, index), + ); } diff --git a/packages/stream_chat_flutter/lib/src/image_header.dart b/packages/stream_chat_flutter/lib/src/image_header.dart index 18c78770..0b876aa1 100644 --- a/packages/stream_chat_flutter/lib/src/image_header.dart +++ b/packages/stream_chat_flutter/lib/src/image_header.dart @@ -1,11 +1,26 @@ import 'package:flutter/material.dart'; +import 'package:stream_chat_flutter/src/attachment_actions_modal.dart'; import 'package:stream_chat_flutter/src/stream_chat_theme.dart'; import 'package:stream_chat_flutter/src/stream_svg_icon.dart'; import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart'; -import 'attachment_actions_modal.dart'; - +/// Header/AppBar widget for media display screen class ImageHeader extends StatelessWidget implements PreferredSizeWidget { + /// Creates a channel header + const ImageHeader({ + Key? key, + required this.message, + this.currentIndex = 0, + this.showBackButton = true, + this.onBackPressed, + this.onShowMessage, + this.onTitleTap, + this.onImageTap, + this.userName = '', + this.sentAt = '', + }) : preferredSize = const Size.fromHeight(kToolbarHeight), + super(key: key); + /// True if this header shows the leading back button final bool showBackButton; @@ -22,83 +37,72 @@ class ImageHeader extends StatelessWidget implements PreferredSizeWidget { /// Callback to call when the image is tapped. final VoidCallback? onImageTap; + /// Message which attachments are attached to final Message message; + /// Username of sender final String userName; + + /// Text which connotes the time the message was sent final String sentAt; + /// Stores the current index of media shown final int currentIndex; - /// Creates a channel header - ImageHeader({ - Key? key, - required this.message, - this.currentIndex = 0, - this.showBackButton = true, - this.onBackPressed, - this.onShowMessage, - this.onTitleTap, - this.onImageTap, - this.userName = '', - this.sentAt = '', - }) : preferredSize = Size.fromHeight(kToolbarHeight), - super(key: key); - @override - Widget build(BuildContext context) { - return AppBar( - brightness: Theme.of(context).brightness, - elevation: 1, - leading: showBackButton - ? IconButton( - icon: StreamSvgIcon.close( - color: StreamChatTheme.of(context).colorTheme.black, - size: 24, - ), - onPressed: onBackPressed, - ) - : SizedBox(), - backgroundColor: - StreamChatTheme.of(context).channelTheme.channelHeaderTheme.color, - actions: [ - if (message.type != 'ephemeral') - IconButton( - icon: StreamSvgIcon.iconMenuPoint( - color: StreamChatTheme.of(context).colorTheme.black, - ), - onPressed: () { - _showMessageActionModalBottomSheet(context); - }, - ), - ], - centerTitle: true, - title: message.type != 'ephemeral' - ? InkWell( - onTap: onTitleTap, - child: Container( - height: preferredSize.height, - width: preferredSize.width, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - Text( - userName, - style: StreamChatTheme.of(context).textTheme.headlineBold, - ), - Text( - sentAt, - style: StreamChatTheme.of(context) - .channelPreviewTheme - .subtitle, - ), - ], + Widget build(BuildContext context) => AppBar( + brightness: Theme.of(context).brightness, + elevation: 1, + leading: showBackButton + ? IconButton( + icon: StreamSvgIcon.close( + color: StreamChatTheme.of(context).colorTheme.black, + size: 24, ), + onPressed: onBackPressed, + ) + : const SizedBox(), + backgroundColor: + StreamChatTheme.of(context).channelTheme.channelHeaderTheme.color, + actions: [ + if (message.type != 'ephemeral') + IconButton( + icon: StreamSvgIcon.iconMenuPoint( + color: StreamChatTheme.of(context).colorTheme.black, ), - ) - : SizedBox(), - ); - } + onPressed: () { + _showMessageActionModalBottomSheet(context); + }, + ), + ], + centerTitle: true, + title: message.type != 'ephemeral' + ? InkWell( + onTap: onTitleTap, + child: SizedBox( + height: preferredSize.height, + width: preferredSize.width, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + userName, + style: + StreamChatTheme.of(context).textTheme.headlineBold, + ), + Text( + sentAt, + style: StreamChatTheme.of(context) + .channelPreviewTheme + .subtitle, + ), + ], + ), + ), + ) + : const SizedBox(), + ); @override final Size preferredSize; @@ -109,16 +113,14 @@ class ImageHeader extends StatelessWidget implements PreferredSizeWidget { final result = await showDialog( context: context, barrierColor: StreamChatTheme.of(context).colorTheme.overlay, - builder: (context) { - return StreamChannel( - channel: channel, - child: AttachmentActionsModal( - message: message, - currentIndex: currentIndex, - onShowMessage: onShowMessage, - ), - ); - }, + builder: (context) => StreamChannel( + channel: channel, + child: AttachmentActionsModal( + message: message, + currentIndex: currentIndex, + onShowMessage: onShowMessage, + ), + ), ); if (result != null) { diff --git a/packages/stream_chat_flutter/lib/src/message_input.dart b/packages/stream_chat_flutter/lib/src/message_input.dart index b0335e52..638c7769 100644 --- a/packages/stream_chat_flutter/lib/src/message_input.dart +++ b/packages/stream_chat_flutter/lib/src/message_input.dart @@ -812,116 +812,123 @@ class MessageInputState extends State { final renderBox = context.findRenderObject() as RenderBox; final size = renderBox.size; - return OverlayEntry(builder: (context) => Positioned( - bottom: size.height + MediaQuery.of(context).viewInsets.bottom, - left: 0, - right: 0, - child: TweenAnimationBuilder( - tween: Tween(begin: 0, end: 1), - duration: Duration(milliseconds: 300), - curve: Curves.easeInOutExpo, - builder: (context, val, wid) => Transform.scale( - scale: val, - child: Padding( - padding: const EdgeInsets.all(8), - child: Card( - elevation: 2, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), - color: StreamChatTheme.of(context).colorTheme.white, - clipBehavior: Clip.antiAlias, - child: Container( - constraints: BoxConstraints.loose(Size.fromHeight(400)), - decoration: BoxDecoration( - color: StreamChatTheme.of(context).colorTheme.white, - borderRadius: BorderRadius.circular(8)), - child: ListView( - padding: const EdgeInsets.all(0), - shrinkWrap: true, - children: [ - if (commands.isNotEmpty) - Padding( - padding: const EdgeInsets.only(top: 8), - child: Row( + return OverlayEntry( + builder: (context) => Positioned( + bottom: size.height + MediaQuery.of(context).viewInsets.bottom, + left: 0, + right: 0, + child: TweenAnimationBuilder( + tween: Tween(begin: 0, end: 1), + duration: Duration(milliseconds: 300), + curve: Curves.easeInOutExpo, + builder: (context, val, wid) => Transform.scale( + scale: val, + child: Padding( + padding: const EdgeInsets.all(8), + child: Card( + elevation: 2, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + color: StreamChatTheme.of(context).colorTheme.white, + clipBehavior: Clip.antiAlias, + child: Container( + constraints: + BoxConstraints.loose(Size.fromHeight(400)), + decoration: BoxDecoration( + color: StreamChatTheme.of(context) + .colorTheme + .white, + borderRadius: BorderRadius.circular(8)), + child: ListView( + padding: const EdgeInsets.all(0), + shrinkWrap: true, children: [ - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 8, - ), - child: StreamSvgIcon.lightning( - color: StreamChatTheme.of(context) - .colorTheme - .accentBlue, + if (commands.isNotEmpty) + Padding( + padding: const EdgeInsets.only(top: 8), + child: Row( + children: [ + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 8, + ), + child: StreamSvgIcon.lightning( + color: StreamChatTheme.of(context) + .colorTheme + .accentBlue, + ), + ), + Text( + 'Instant Commands', + style: TextStyle( + color: StreamChatTheme.of(context) + .colorTheme + .black + .withOpacity(.5), + ), + ) + ], + ), ), + const SizedBox( + height: 10, ), - Text( - 'Instant Commands', - style: TextStyle( - color: StreamChatTheme.of(context) - .colorTheme - .black - .withOpacity(.5), - ), - ) + ...commands + .map( + (c) => InkWell( + onTap: () { + _setCommand(c); + }, + child: SizedBox( + height: 40, + child: Row( + children: [ + const SizedBox( + width: 16, + ), + _buildCommandIcon(c.name), + const SizedBox( + width: 8, + ), + Text.rich( + TextSpan( + text: c.name.capitalize(), + style: const TextStyle( + fontWeight: + FontWeight.bold), + children: [ + TextSpan( + text: + ' /${c.name} ${c.args}', + style: + StreamChatTheme.of( + context) + .textTheme + .body + .copyWith( + color: StreamChatTheme.of( + context) + .colorTheme + .grey, + ), + ), + ], + ), + ), + ], + ), + ), + ), + ) + .toList(), ], ), ), - const SizedBox( - height: 10, ), - ...commands - .map( - (c) => InkWell( - onTap: () { - _setCommand(c); - }, - child: SizedBox( - height: 40, - child: Row( - children: [ - const SizedBox( - width: 16, - ), - _buildCommandIcon(c.name), - const SizedBox( - width: 8, - ), - Text.rich( - TextSpan( - text: c.name.capitalize(), - style: const TextStyle( - fontWeight: FontWeight.bold), - children: [ - TextSpan( - text: ' /${c.name} ${c.args}', - style: - StreamChatTheme.of(context) - .textTheme - .body - .copyWith( - color: StreamChatTheme - .of(context) - .colorTheme - .grey, - ), - ), - ], - ), - ), - ], - ), - ), - ), - ) - .toList(), - ], - ), - ), - ), - ), - )), - )); + ), + )), + )); } Widget _buildFilePickerSection() {