diff --git a/packages/stream_chat_v1/lib/channel_list.dart b/packages/stream_chat_v1/lib/channel_list.dart index d675fba..a1a6879 100644 --- a/packages/stream_chat_v1/lib/channel_list.dart +++ b/packages/stream_chat_v1/lib/channel_list.dart @@ -4,6 +4,7 @@ import 'package:example/localizations.dart'; import 'package:example/routes/routes.dart'; import 'package:example/search_text_field.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'channel_page.dart'; @@ -16,6 +17,8 @@ class ChannelList extends StatefulWidget { } class _ChannelList extends State { + ScrollController _scrollController = ScrollController(); + TextEditingController? _controller; String _channelQuery = ''; @@ -46,6 +49,7 @@ class _ChannelList extends State { void dispose() { _controller?.removeListener(_channelQueryListener); _controller?.dispose(); + _scrollController.dispose(); super.dispose(); } @@ -61,143 +65,144 @@ class _ChannelList extends State { } return true; }, - child: NestedScrollView( - floatHeaderSlivers: true, - headerSliverBuilder: (_, __) => [ - SliverToBoxAdapter( - child: SearchTextField( - controller: _controller, - showCloseButton: _isSearchActive, - hintText: AppLocalizations.of(context).search, + child: NotificationListener( + onNotification: (ScrollNotification scrollInfo) { + if (_scrollController.position.userScrollDirection == + ScrollDirection.reverse) { + FocusScope.of(context).unfocus(); + } + return true; + }, + child: NestedScrollView( + controller: _scrollController, + floatHeaderSlivers: false, + headerSliverBuilder: (_, __) => [ + SliverToBoxAdapter( + child: SearchTextField( + controller: _controller, + showCloseButton: _isSearchActive, + hintText: AppLocalizations.of(context).search, + ), ), - ), - ], - body: AnimatedSwitcher( - duration: const Duration(milliseconds: 350), - child: GestureDetector( - behavior: HitTestBehavior.opaque, - onPanDown: (_) => FocusScope.of(context).unfocus(), + ], + body: MessageSearchBloc( child: _isSearchActive - ? MessageSearchBloc( - child: MessageSearchListView( - showErrorTile: true, - messageQuery: _channelQuery, - filters: Filter.in_('members', [user!.id]), - sortOptions: [ - SortOption( - 'created_at', - direction: SortOption.ASC, + ? MessageSearchListView( + showErrorTile: true, + messageQuery: _channelQuery, + filters: Filter.in_('members', [user!.id]), + sortOptions: [ + SortOption( + 'created_at', + direction: SortOption.ASC, + ), + ], + pullToRefresh: false, + limit: 30, + emptyBuilder: (_) { + return LayoutBuilder( + builder: (context, viewportConstraints) { + return SingleChildScrollView( + physics: AlwaysScrollableScrollPhysics(), + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: viewportConstraints.maxHeight, + ), + child: Center( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.all(24), + child: StreamSvgIcon.search( + size: 96, + color: Colors.grey, + ), + ), + Text( + AppLocalizations.of(context).noResults, + ), + ], + ), + ), + ), + ); + }, + ); + }, + onItemTap: (messageResponse) async { + FocusScope.of(context).requestFocus(FocusNode()); + final client = StreamChat.of(context).client; + final message = messageResponse.message; + final channel = client.channel( + messageResponse.channel!.type, + id: messageResponse.channel!.id, + ); + if (channel.state == null) { + await channel.watch(); + } + Navigator.pushNamed( + context, + Routes.CHANNEL_PAGE, + arguments: ChannelPageArgs( + channel: channel, + initialMessage: message, ), - ], - pullToRefresh: false, - limit: 20, - emptyBuilder: (_) { - return LayoutBuilder( - builder: (context, viewportConstraints) { - return SingleChildScrollView( - physics: AlwaysScrollableScrollPhysics(), - child: ConstrainedBox( - constraints: BoxConstraints( - minHeight: viewportConstraints.maxHeight, - ), - child: Center( - child: Column( - children: [ - Padding( - padding: const EdgeInsets.all(24), - child: StreamSvgIcon.search( - size: 96, - color: Colors.grey, - ), - ), - Text( - AppLocalizations.of(context).noResults, - ), - ], - ), - ), - ), - ); - }, - ); - }, - onItemTap: (messageResponse) async { - FocusScope.of(context).requestFocus(FocusNode()); - final client = StreamChat.of(context).client; - final message = messageResponse.message; - final channel = client.channel( - messageResponse.channel!.type, - id: messageResponse.channel!.id, - ); - if (channel.state == null) { - await channel.watch(); - } - Navigator.pushNamed( - context, - Routes.CHANNEL_PAGE, - arguments: ChannelPageArgs( - channel: channel, - initialMessage: message, - ), - ); - }, - ), + ); + }, ) - : ChannelsBloc( - child: ChannelListView( - onChannelTap: (channel, _) { - Navigator.pushNamed( + : ChannelListView( + onChannelTap: (channel, _) { + Navigator.pushNamed( + context, + Routes.CHANNEL_PAGE, + arguments: ChannelPageArgs( + channel: channel, + ), + ); + }, + onStartChatPressed: () { + Navigator.pushNamed(context, Routes.NEW_CHAT); + }, + swipeToAction: true, + filter: Filter.in_('members', [user!.id]), + presence: true, + limit: 30, + onViewInfoTap: (channel) { + Navigator.pop(context); + if (channel.memberCount == 2 && channel.isDistinct) { + Navigator.push( context, - Routes.CHANNEL_PAGE, - arguments: ChannelPageArgs( - channel: channel, + MaterialPageRoute( + builder: (context) => StreamChannel( + channel: channel, + child: ChatInfoScreen( + messageTheme: + StreamChatTheme.of(context).ownMessageTheme, + user: channel.state!.members + .where((m) => + m.userId != + channel.client.state.currentUser!.id) + .first + .user, + ), + ), ), ); - }, - onStartChatPressed: () { - Navigator.pushNamed(context, Routes.NEW_CHAT); - }, - swipeToAction: true, - filter: Filter.in_('members', [user!.id]), - presence: true, - limit: 20, - onViewInfoTap: (channel) { - Navigator.pop(context); - if (channel.memberCount == 2 && channel.isDistinct) { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => StreamChannel( - channel: channel, - child: ChatInfoScreen( - messageTheme: StreamChatTheme.of(context) - .ownMessageTheme, - user: channel.state!.members - .where((m) => - m.userId != - channel.client.state.currentUser!.id) - .first - .user, - ), + } else { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => StreamChannel( + channel: channel, + child: GroupInfoScreen( + messageTheme: + StreamChatTheme.of(context).ownMessageTheme, ), ), - ); - } else { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => StreamChannel( - channel: channel, - child: GroupInfoScreen( - messageTheme: StreamChatTheme.of(context) - .ownMessageTheme, - ), - ), - ), - ); - } - }, - ), + ), + ); + } + }, ), ), ), diff --git a/packages/stream_chat_v1/lib/channel_list_page.dart b/packages/stream_chat_v1/lib/channel_list_page.dart index f29f96a..928df1b 100644 --- a/packages/stream_chat_v1/lib/channel_list_page.dart +++ b/packages/stream_chat_v1/lib/channel_list_page.dart @@ -100,7 +100,7 @@ class _ChannelListPageState extends State { body: IndexedStack( index: _currentIndex, children: [ - ChannelList(), + ChannelsBloc(child: ChannelList()), UserMentionsPage(), ], ),