fix: channel list performance

This commit is contained in:
Gordon Hayes
2021-12-07 16:17:36 +01:00
parent cc4fd9361d
commit 2ceab092e4
2 changed files with 134 additions and 129 deletions
+133 -128
View File
@@ -4,6 +4,7 @@ import 'package:example/localizations.dart';
import 'package:example/routes/routes.dart'; import 'package:example/routes/routes.dart';
import 'package:example/search_text_field.dart'; import 'package:example/search_text_field.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart'; import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'channel_page.dart'; import 'channel_page.dart';
@@ -16,6 +17,8 @@ class ChannelList extends StatefulWidget {
} }
class _ChannelList extends State<ChannelList> { class _ChannelList extends State<ChannelList> {
ScrollController _scrollController = ScrollController();
TextEditingController? _controller; TextEditingController? _controller;
String _channelQuery = ''; String _channelQuery = '';
@@ -46,6 +49,7 @@ class _ChannelList extends State<ChannelList> {
void dispose() { void dispose() {
_controller?.removeListener(_channelQueryListener); _controller?.removeListener(_channelQueryListener);
_controller?.dispose(); _controller?.dispose();
_scrollController.dispose();
super.dispose(); super.dispose();
} }
@@ -61,143 +65,144 @@ class _ChannelList extends State<ChannelList> {
} }
return true; return true;
}, },
child: NestedScrollView( child: NotificationListener<ScrollUpdateNotification>(
floatHeaderSlivers: true, onNotification: (ScrollNotification scrollInfo) {
headerSliverBuilder: (_, __) => [ if (_scrollController.position.userScrollDirection ==
SliverToBoxAdapter( ScrollDirection.reverse) {
child: SearchTextField( FocusScope.of(context).unfocus();
controller: _controller, }
showCloseButton: _isSearchActive, return true;
hintText: AppLocalizations.of(context).search, },
child: NestedScrollView(
controller: _scrollController,
floatHeaderSlivers: false,
headerSliverBuilder: (_, __) => [
SliverToBoxAdapter(
child: SearchTextField(
controller: _controller,
showCloseButton: _isSearchActive,
hintText: AppLocalizations.of(context).search,
),
), ),
), ],
], body: MessageSearchBloc(
body: AnimatedSwitcher(
duration: const Duration(milliseconds: 350),
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onPanDown: (_) => FocusScope.of(context).unfocus(),
child: _isSearchActive child: _isSearchActive
? MessageSearchBloc( ? MessageSearchListView(
child: MessageSearchListView( showErrorTile: true,
showErrorTile: true, messageQuery: _channelQuery,
messageQuery: _channelQuery, filters: Filter.in_('members', [user!.id]),
filters: Filter.in_('members', [user!.id]), sortOptions: [
sortOptions: [ SortOption(
SortOption( 'created_at',
'created_at', direction: SortOption.ASC,
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( : ChannelListView(
child: ChannelListView( onChannelTap: (channel, _) {
onChannelTap: (channel, _) { Navigator.pushNamed(
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, context,
Routes.CHANNEL_PAGE, MaterialPageRoute(
arguments: ChannelPageArgs( builder: (context) => StreamChannel(
channel: channel, 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 {
onStartChatPressed: () { Navigator.push(
Navigator.pushNamed(context, Routes.NEW_CHAT); context,
}, MaterialPageRoute(
swipeToAction: true, builder: (context) => StreamChannel(
filter: Filter.in_('members', [user!.id]), channel: channel,
presence: true, child: GroupInfoScreen(
limit: 20, messageTheme:
onViewInfoTap: (channel) { StreamChatTheme.of(context).ownMessageTheme,
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,
),
),
),
);
}
},
),
), ),
), ),
), ),
@@ -100,7 +100,7 @@ class _ChannelListPageState extends State<ChannelListPage> {
body: IndexedStack( body: IndexedStack(
index: _currentIndex, index: _currentIndex,
children: [ children: [
ChannelList(), ChannelsBloc(child: ChannelList()),
UserMentionsPage(), UserMentionsPage(),
], ],
), ),