From 4e7fb6123c9e93d13f15007bec358bcfcfff3d7a Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Wed, 30 Dec 2020 14:50:13 +0530 Subject: [PATCH] fixes Signed-off-by: Sahil Kumar --- lib/src/channel_file_display_screen.dart | 4 +- lib/src/channel_list_view.dart | 11 +- lib/src/channel_media_display_screen.dart | 4 +- lib/src/image_footer.dart | 432 +++++++++++----------- 4 files changed, 225 insertions(+), 226 deletions(-) diff --git a/lib/src/channel_file_display_screen.dart b/lib/src/channel_file_display_screen.dart index c319b524..a6b1008e 100644 --- a/lib/src/channel_file_display_screen.dart +++ b/lib/src/channel_file_display_screen.dart @@ -90,9 +90,7 @@ class _ChannelFileDisplayScreenState extends State { builder: (context, snapshot) { if (snapshot.data == null) { return Center( - child: CircularProgressIndicator( - backgroundColor: StreamChatTheme.of(context).accentColor, - ), + child: const CircularProgressIndicator(), ); } diff --git a/lib/src/channel_list_view.dart b/lib/src/channel_list_view.dart index 5efa1e29..126e6d0d 100644 --- a/lib/src/channel_list_view.dart +++ b/lib/src/channel_list_view.dart @@ -75,6 +75,7 @@ class ChannelListView extends StatefulWidget { this.swipeToAction = false, this.pullToRefresh = true, this.crossAxisCount = 1, + this.padding, this.selectedChannels = const [], }) : super(key: key); @@ -139,6 +140,9 @@ class ChannelListView extends StatefulWidget { /// The number of children in the cross axis. final int crossAxisCount; + /// The amount of space by which to inset the children. + final EdgeInsetsGeometry padding; + final List selectedChannels; @override @@ -268,6 +272,7 @@ class _ChannelListViewState extends State if (channels.isNotEmpty) { if (widget.crossAxisCount > 1) { child = GridView.builder( + padding: widget.padding, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: widget.crossAxisCount), itemCount: channels.length, @@ -279,6 +284,7 @@ class _ChannelListViewState extends State ); } else { child = ListView.separated( + padding: widget.padding, physics: AlwaysScrollableScrollPhysics(), itemCount: channels.isNotEmpty ? channels.length + 1 : channels.length, @@ -306,6 +312,7 @@ class _ChannelListViewState extends State Widget _buildLoadingWidget() { return ListView( + padding: widget.padding, physics: AlwaysScrollableScrollPhysics(), children: List.generate( 25, @@ -331,9 +338,7 @@ class _ChannelListViewState extends State highlightColor: Color(0xffffffff), child: Column( children: [ - SizedBox( - height: 4.0, - ), + SizedBox(height: 4.0), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ diff --git a/lib/src/channel_media_display_screen.dart b/lib/src/channel_media_display_screen.dart index 21eeb611..ddf52c66 100644 --- a/lib/src/channel_media_display_screen.dart +++ b/lib/src/channel_media_display_screen.dart @@ -92,9 +92,7 @@ class _ChannelMediaDisplayScreenState extends State { builder: (context, snapshot) { if (snapshot.data == null) { return Center( - child: CircularProgressIndicator( - backgroundColor: StreamChatTheme.of(context).accentColor, - ), + child: const CircularProgressIndicator(), ); } diff --git a/lib/src/image_footer.dart b/lib/src/image_footer.dart index 00b38a90..97e40cba 100644 --- a/lib/src/image_footer.dart +++ b/lib/src/image_footer.dart @@ -16,7 +16,7 @@ import 'package:stream_chat_flutter/src/stream_chat.dart'; import 'package:stream_chat_flutter/src/stream_chat_theme.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; -class ImageFooter extends StatefulWidget { +class ImageFooter extends StatefulWidget implements PreferredSizeWidget { /// Callback to call when pressing the back button. /// By default it calls [Navigator.pop] final VoidCallback onBackPressed; @@ -61,12 +61,12 @@ class ImageFooter extends StatefulWidget { class _ImageFooterState extends State { bool _userSearchMode = false; TextEditingController _searchController; - TextEditingController _messageController = TextEditingController(); - FocusNode _messageFocusNode = FocusNode(); + final TextEditingController _messageController = TextEditingController(); + final FocusNode _messageFocusNode = FocusNode(); String _channelNameQuery; - List _selectedChannels = []; + final List _selectedChannels = []; bool _loading = false; Timer _debounce; @@ -103,52 +103,54 @@ class _ImageFooterState extends State { @override Widget build(BuildContext context) { - return SafeArea( - child: Container( - color: - StreamChatTheme.of(context).channelTheme.channelHeaderTheme.color, - padding: EdgeInsets.symmetric(vertical: 8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - IconButton( - icon: StreamSvgIcon.icon_SHARE( - size: 24.0, - color: Colors.black, + return SizedBox.fromSize( + size: widget.preferredSize, + child: MediaQuery.removePadding( + context: context, + removeTop: true, + child: BottomAppBar( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + IconButton( + icon: StreamSvgIcon.icon_SHARE( + size: 24.0, + color: Colors.black, + ), + onPressed: () { + _buildShareModal(context); + }, ), - onPressed: () { - _buildShareModal(context); - }, - ), - InkWell( - onTap: widget.onTitleTap, - child: Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - Text( - '${widget.currentPage + 1} of ${widget.totalPages}', - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.w700, - color: Colors.black, + InkWell( + onTap: widget.onTitleTap, + child: Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + '${widget.currentPage + 1} of ${widget.totalPages}', + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w700, + color: Colors.black, + ), ), - ), - ], + ], + ), ), ), - ), - IconButton( - icon: StreamSvgIcon.Icon_grid( - color: Colors.black, + IconButton( + icon: StreamSvgIcon.Icon_grid( + color: Colors.black, + ), + onPressed: () { + _buildPhotosModal(context); + }, ), - onPressed: () { - _buildPhotosModal(context); - }, - ), - ], + ], + ), ), ), ); @@ -258,8 +260,8 @@ class _ImageFooterState extends State { ); } - void _buildShareModal(context) { - showDialog( + void _buildShareModal(context) async { + final result = await showDialog( context: context, builder: (context) { return StatefulBuilder(builder: (context, modalSetState) { @@ -282,10 +284,6 @@ class _ImageFooterState extends State { child: Column( children: [ _buildTextInputSection(modalSetState), - if (_userSearchMode) - SizedBox( - height: 22.0, - ), Expanded( child: ChannelsBloc( child: ChannelListView( @@ -302,6 +300,7 @@ class _ImageFooterState extends State { }); } }, + padding: const EdgeInsets.symmetric(vertical: 8), crossAxisCount: 4, pagination: PaginationParams( limit: 25, @@ -342,7 +341,8 @@ class _ImageFooterState extends State { ), ), Text( - 'No chat matches these keywords...'), + 'No chat matches these keywords...', + ), ], ), ), @@ -360,42 +360,30 @@ class _ImageFooterState extends State { Align( alignment: Alignment.bottomCenter, child: Container( - color: Colors.white, - height: 48.0, - child: Material( - child: InkWell( - onTap: () async { - var url = widget - .mediaAttachments[widget.currentPage] - .imageUrl ?? - widget - .mediaAttachments[widget.currentPage] - .assetUrl ?? - widget - .mediaAttachments[widget.currentPage] - .thumbUrl; - - if (widget - .mediaAttachments[widget.currentPage] - .type == - 'video') { + height: kToolbarHeight, + child: SizedBox.expand( + child: RaisedButton( + onPressed: () async { + final attachment = widget + .mediaAttachments[widget.currentPage]; + var url = attachment.imageUrl ?? + attachment.assetUrl ?? + attachment.thumbUrl; + if (attachment.type == 'video') { await _saveVideo(url); - Navigator.pop(context); } else { await _saveImage(url); - Navigator.pop(context); } + Navigator.pop(context); }, - child: SizedBox.expand( - child: Center( - child: Text( - 'Save to Photos', - style: TextStyle( - color: StreamChatTheme.of(context) - .accentColor, - fontWeight: FontWeight.bold, - ), - ), + color: Colors.white, + elevation: 8, + child: Text( + 'Save to Photos', + style: TextStyle( + color: + StreamChatTheme.of(context).accentColor, + fontWeight: FontWeight.bold, ), ), ), @@ -411,62 +399,74 @@ class _ImageFooterState extends State { }); }, ); + if (result == null) { + _selectedChannels.clear(); + } } Widget _buildTextInputSection(modalSetState) { if (_userSearchMode) { return Column( children: [ - SizedBox( - height: 16.0, - ), + SizedBox(height: 16.0), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - SizedBox( - width: 16.0, - ), + SizedBox(width: 8.0), Expanded( - child: TextField( - controller: _searchController, - cursorColor: Colors.black, - autofocus: true, - decoration: InputDecoration( - isDense: true, - prefixIconConstraints: - BoxConstraints.tight(Size(36.0, 44.0)), - prefixIcon: Padding( - padding: const EdgeInsets.symmetric( - vertical: 2.0, horizontal: 6.0), - child: StreamSvgIcon.search( - color: Colors.black, + child: Container( + height: 36, + margin: const EdgeInsets.symmetric( + vertical: 8, + horizontal: 8, + ), + child: TextField( + controller: _searchController, + cursorColor: Colors.black, + autofocus: true, + decoration: InputDecoration( + prefixIconConstraints: BoxConstraints.tight(Size(40, 24)), + prefixIcon: Padding( + padding: const EdgeInsets.only(left: 8, right: 8), + child: StreamSvgIcon.search( + color: Colors.black, + size: 24, + ), ), + hintText: 'Search', + hintStyle: TextStyle( + color: Colors.black.withOpacity(0.5), + fontSize: 14, + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: Colors.black.withOpacity(0.08), + ), + borderRadius: BorderRadius.circular(24), + ), + focusedBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(24.0), + borderSide: BorderSide( + color: Colors.black.withOpacity(0.08), + ), + ), + contentPadding: EdgeInsets.zero, ), - hintText: 'Search', - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(32.0), - borderSide: - BorderSide(color: Colors.black.withOpacity(0.08)), - ), - focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(32.0), - borderSide: - BorderSide(color: Colors.black.withOpacity(0.08)), - ), - contentPadding: EdgeInsets.zero, ), ), ), - SizedBox( - width: 8.0, - ), IconButton( icon: StreamSvgIcon.close_small( color: Colors.black.withOpacity(0.5), ), + splashRadius: 24, onPressed: () { modalSetState(() { - _userSearchMode = false; + if (_searchController.text.isNotEmpty) { + _searchController.text = ''; + } else { + _userSearchMode = false; + } }); setState(() {}); }, @@ -475,80 +475,80 @@ class _ImageFooterState extends State { ), ], ); - } else { - return Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 6.0), - child: IconButton( - icon: StreamSvgIcon.search( - color: Colors.black, - ), - iconSize: 24.0, - onPressed: () { - modalSetState(() { - _userSearchMode = true; - }); - }, - ), - ), - Padding( - padding: const EdgeInsets.all(16.0), - child: Text( - 'Select a Chat to Share', - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.w700, - color: Colors.black, - ), - ), - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 6.0), - child: IconButton( - icon: StreamSvgIcon.share_arrow( - color: Colors.black, - ), - onPressed: () async { - var url = - widget.mediaAttachments[widget.currentPage].imageUrl ?? - widget.mediaAttachments[widget.currentPage].assetUrl ?? - widget.mediaAttachments[widget.currentPage].thumbUrl; - var type = - widget.mediaAttachments[widget.currentPage].type == 'image' - ? 'jpg' - : url?.split('?')?.first?.split('.')?.last ?? 'jpg'; - var request = await HttpClient().getUrl(Uri.parse(url)); - var response = await request.close(); - var bytes = await consolidateHttpClientResponseBytes(response); - await Share.file('File', 'image.$type', bytes, 'image/$type'); - }, - ), - ), - ], - ); } + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 6.0), + child: IconButton( + icon: StreamSvgIcon.search( + color: Colors.black, + ), + iconSize: 24.0, + onPressed: () { + modalSetState(() { + _userSearchMode = true; + }); + }, + ), + ), + Padding( + padding: const EdgeInsets.all(16.0), + child: Text( + 'Select a Chat to Share', + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w700, + color: Colors.black, + ), + ), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 6.0), + child: IconButton( + icon: StreamSvgIcon.share_arrow( + color: Colors.black, + ), + onPressed: () async { + final attachment = widget.mediaAttachments[widget.currentPage]; + var url = attachment.imageUrl ?? + attachment.assetUrl ?? + attachment.thumbUrl; + var type = attachment.type == 'image' + ? 'jpg' + : url?.split('?')?.first?.split('.')?.last ?? 'jpg'; + var request = await HttpClient().getUrl(Uri.parse(url)); + var response = await request.close(); + var bytes = await consolidateHttpClientResponseBytes(response); + await Share.file('File', 'image.$type', bytes, 'image/$type'); + }, + ), + ), + ], + ); } Widget _buildShareTextInputSection(modalSetState) { return Align( alignment: Alignment.bottomCenter, - child: Container( - color: Colors.white, - height: 56.0, - child: _loading - ? Center( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: CircularProgressIndicator(), - ), - ) - : Row( - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.only(left: 8.0), + child: BottomAppBar( + child: Container( + height: 40.0, + margin: const EdgeInsets.symmetric( + vertical: 8, + horizontal: 8, + ), + child: _loading + ? Center( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: CircularProgressIndicator(), + ), + ) + : Row( + children: [ + Expanded( child: TextField( controller: _messageController, focusNode: _messageFocusNode, @@ -560,54 +560,52 @@ class _ImageFooterState extends State { setState(() {}); }, decoration: InputDecoration( - isDense: true, prefixText: ' ', hintText: 'Add a comment', - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(32.0), + enabledBorder: OutlineInputBorder( + borderRadius: BorderRadius.circular(24.0), borderSide: BorderSide( color: Colors.black.withOpacity(0.16), ), ), focusedBorder: OutlineInputBorder( - borderRadius: BorderRadius.circular(32.0), + borderRadius: BorderRadius.circular(24.0), borderSide: BorderSide( color: Colors.black.withOpacity(0.16), )), - contentPadding: EdgeInsets.symmetric(vertical: 12.0), + contentPadding: const EdgeInsets.all(0), ), ), ), - ), - IconTheme( - data: StreamChatTheme.of(context) - .channelTheme - .messageInputButtonIconTheme, - child: Center( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: InkWell( - onTap: () async { - modalSetState(() { - _loading = true; - }); - await sendMessage(); - modalSetState(() { - _loading = false; - }); - }, - child: Transform.rotate( - angle: -pi / 2, - child: StreamSvgIcon.Icon_send_message( - color: StreamChatTheme.of(context).accentColor, - ), + SizedBox(width: 8), + IconTheme( + data: StreamChatTheme.of(context) + .channelTheme + .messageInputButtonIconTheme, + child: IconButton( + onPressed: () async { + modalSetState(() => _loading = true); + await sendMessage(); + modalSetState(() => _loading = false); + }, + splashRadius: 24, + visualDensity: VisualDensity.compact, + constraints: BoxConstraints.tightFor( + height: 24, + width: 24, + ), + padding: EdgeInsets.zero, + icon: Transform.rotate( + angle: -pi / 2, + child: StreamSvgIcon.Icon_send_message( + color: StreamChatTheme.of(context).accentColor, ), ), ), ), - ), - ], - ), + ], + ), + ), ), ); }