fix: channel list performance
This commit is contained in:
@@ -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<ChannelList> {
|
||||
ScrollController _scrollController = ScrollController();
|
||||
|
||||
TextEditingController? _controller;
|
||||
|
||||
String _channelQuery = '';
|
||||
@@ -46,6 +49,7 @@ class _ChannelList extends State<ChannelList> {
|
||||
void dispose() {
|
||||
_controller?.removeListener(_channelQueryListener);
|
||||
_controller?.dispose();
|
||||
_scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -61,143 +65,144 @@ class _ChannelList extends State<ChannelList> {
|
||||
}
|
||||
return true;
|
||||
},
|
||||
child: NestedScrollView(
|
||||
floatHeaderSlivers: true,
|
||||
headerSliverBuilder: (_, __) => [
|
||||
SliverToBoxAdapter(
|
||||
child: SearchTextField(
|
||||
controller: _controller,
|
||||
showCloseButton: _isSearchActive,
|
||||
hintText: AppLocalizations.of(context).search,
|
||||
child: NotificationListener<ScrollUpdateNotification>(
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -100,7 +100,7 @@ class _ChannelListPageState extends State<ChannelListPage> {
|
||||
body: IndexedStack(
|
||||
index: _currentIndex,
|
||||
children: [
|
||||
ChannelList(),
|
||||
ChannelsBloc(child: ChannelList()),
|
||||
UserMentionsPage(),
|
||||
],
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user