[core]: move .of calls to didChangeDependencies

This commit is contained in:
Salvatore Giordano
2021-05-06 13:25:41 +02:00
parent b3ec54ae48
commit 9392d150c0
9 changed files with 170 additions and 120 deletions
@@ -119,12 +119,11 @@ class ChannelListCore extends StatefulWidget {
/// The current state of the [ChannelListCore]. /// The current state of the [ChannelListCore].
class ChannelListCoreState extends State<ChannelListCore> { class ChannelListCoreState extends State<ChannelListCore> {
@override late final ChannelsBlocState _channelsBloc;
Widget build(BuildContext context) { late final StreamChatCoreState _streamChatCoreState;
final channelsBloc = ChannelsBloc.of(context);
return _buildListView(channelsBloc); @override
} Widget build(BuildContext context) => _buildListView(_channelsBloc);
StreamBuilder<List<Channel>> _buildListView( StreamBuilder<List<Channel>> _buildListView(
ChannelsBlocState channelsBlocState, ChannelsBlocState channelsBlocState,
@@ -147,36 +146,42 @@ class ChannelListCoreState extends State<ChannelListCore> {
); );
/// Fetches initial channels and updates the widget /// Fetches initial channels and updates the widget
Future<void> loadData() { Future<void> loadData() => _channelsBloc.queryChannels(
final channelsBloc = ChannelsBloc.of(context); filter: widget.filter,
return channelsBloc.queryChannels( sortOptions: widget.sort,
filter: widget.filter, paginationParams: widget.pagination,
sortOptions: widget.sort, options: widget.options,
paginationParams: widget.pagination, );
options: widget.options,
);
}
/// Fetches more channels with updated pagination and updates the widget /// Fetches more channels with updated pagination and updates the widget
Future<void> paginateData() { Future<void> paginateData() => _channelsBloc.queryChannels(
final channelsBloc = ChannelsBloc.of(context); filter: widget.filter,
return channelsBloc.queryChannels( sortOptions: widget.sort,
filter: widget.filter, paginationParams: widget.pagination.copyWith(
sortOptions: widget.sort, offset: _channelsBloc.channels?.length ?? 0,
paginationParams: widget.pagination.copyWith( ),
offset: channelsBloc.channels?.length ?? 0, options: widget.options,
), );
options: widget.options,
);
}
late StreamSubscription<Event> _subscription; StreamSubscription<Event>? _subscription;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
loadData(); _setupController();
final client = StreamChatCore.of(context).client; }
@override
void didChangeDependencies() {
_channelsBloc = ChannelsBloc.of(context);
_streamChatCoreState = StreamChatCore.of(context);
if (_subscription == null) {
loadData();
}
final client = _streamChatCoreState.client;
_subscription?.cancel();
_subscription = client _subscription = client
.on( .on(
EventType.connectionRecovered, EventType.connectionRecovered,
@@ -186,10 +191,7 @@ class ChannelListCoreState extends State<ChannelListCore> {
) )
.listen((event) => loadData()); .listen((event) => loadData());
if (widget.channelListController != null) { super.didChangeDependencies();
widget.channelListController!.loadData = loadData;
widget.channelListController!.paginateData = paginateData;
}
} }
@override @override
@@ -203,11 +205,22 @@ class ChannelListCoreState extends State<ChannelListCore> {
oldWidget.pagination.toJson().toString()) { oldWidget.pagination.toJson().toString()) {
loadData(); loadData();
} }
if (widget.channelListController != oldWidget.channelListController) {
_setupController();
}
}
void _setupController() {
if (widget.channelListController != null) {
widget.channelListController!.loadData = loadData;
widget.channelListController!.paginateData = paginateData;
}
} }
@override @override
void dispose() { void dispose() {
_subscription.cancel(); _subscription?.cancel();
super.dispose(); super.dispose();
} }
} }
@@ -50,17 +50,20 @@ class ChannelsBloc extends StatefulWidget {
streamChatState = context.findAncestorStateOfType<ChannelsBlocState>(); streamChatState = context.findAncestorStateOfType<ChannelsBlocState>();
if (streamChatState == null) { assert(
throw Exception('You must have a ChannelsBloc widget as ancestor'); streamChatState != null,
} 'You must have a ChannelsBloc widget as ancestor',
);
return streamChatState; return streamChatState!;
} }
} }
/// The current state of the [ChannelsBloc]. /// The current state of the [ChannelsBloc].
class ChannelsBlocState extends State<ChannelsBloc> class ChannelsBlocState extends State<ChannelsBloc>
with AutomaticKeepAliveClientMixin { with AutomaticKeepAliveClientMixin {
late final StreamChatCoreState _streamChatCoreState;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
super.build(context); super.build(context);
@@ -86,6 +89,8 @@ class ChannelsBlocState extends State<ChannelsBloc>
bool _paginationEnded = false; bool _paginationEnded = false;
final List<StreamSubscription> _subscriptions = [];
/// Calls [client.queryChannels] updating [queryChannelsLoading] stream /// Calls [client.queryChannels] updating [queryChannelsLoading] stream
Future<void> queryChannels({ Future<void> queryChannels({
Filter? filter, Filter? filter,
@@ -93,7 +98,7 @@ class ChannelsBlocState extends State<ChannelsBloc>
PaginationParams paginationParams = const PaginationParams(limit: 30), PaginationParams paginationParams = const PaginationParams(limit: 30),
Map<String, dynamic>? options, Map<String, dynamic>? options,
}) async { }) async {
final client = StreamChatCore.of(context).client; final client = _streamChatCoreState.client;
final clear = paginationParams.offset == 0; final clear = paginationParams.offset == 0;
@@ -139,14 +144,12 @@ class ChannelsBlocState extends State<ChannelsBloc>
} }
} }
final List<StreamSubscription> _subscriptions = [];
@override @override
void initState() { void didChangeDependencies() {
super.initState(); _streamChatCoreState = StreamChatCore.of(context);
final client = _streamChatCoreState.client;
final client = StreamChatCore.of(context).client;
_cancelSubscriptions();
if (!widget.lockChannelsOrder) { if (!widget.lockChannelsOrder) {
_subscriptions.add(client _subscriptions.add(client
.on( .on(
@@ -179,37 +182,44 @@ class ChannelsBlocState extends State<ChannelsBloc>
})); }));
} }
_subscriptions.add(client.on(EventType.channelHidden).listen((event) async { _subscriptions
final newChannels = List<Channel>.from(channels ?? []); ..add(client.on(EventType.channelHidden).listen((event) async {
final channelIndex = newChannels.indexWhere((c) => c.cid == event.cid); final newChannels = List<Channel>.from(channels ?? []);
if (channelIndex > -1) { final channelIndex = newChannels.indexWhere((c) => c.cid == event.cid);
final channel = newChannels.removeAt(channelIndex); if (channelIndex > -1) {
_hiddenChannels.add(channel); final channel = newChannels.removeAt(channelIndex);
_channelsController.add(newChannels); _hiddenChannels.add(channel);
} _channelsController.add(newChannels);
})); }
// ignore: cascade_invocations }))
_subscriptions.add(client ..add(client
.on( .on(
EventType.channelDeleted, EventType.channelDeleted,
EventType.notificationRemovedFromChannel, EventType.notificationRemovedFromChannel,
) )
.listen((e) { .listen((e) {
// ignore: cascade_invocations final channel = e.channel;
final channel = e.channel; _channelsController.add(List.from(
_channelsController.add(List.from( (channels ?? [])..removeWhere((c) => c.cid == channel?.cid)));
(channels ?? [])..removeWhere((c) => c.cid == channel?.cid))); }));
}));
super.didChangeDependencies();
} }
@override @override
void dispose() { void dispose() {
_channelsController.close(); _channelsController.close();
_queryChannelsLoadingController.close(); _queryChannelsLoadingController.close();
_subscriptions.forEach((s) => s.cancel()); _cancelSubscriptions();
super.dispose(); super.dispose();
} }
void _cancelSubscriptions() {
_subscriptions
..forEach((s) => s.cancel())
..clear();
}
@override @override
bool get wantKeepAlive => true; bool get wantKeepAlive => true;
} }
@@ -109,7 +109,7 @@ class MessageListCore extends StatefulWidget {
/// The current state of the [MessageListCore]. /// The current state of the [MessageListCore].
class MessageListCoreState extends State<MessageListCore> { class MessageListCoreState extends State<MessageListCore> {
late StreamChannelState _streamChannel; late final StreamChannelState _streamChannel;
bool get _upToDate => _streamChannel.channel.state?.isUpToDate ?? true; bool get _upToDate => _streamChannel.channel.state?.isUpToDate ?? true;
@@ -174,18 +174,34 @@ class MessageListCoreState extends State<MessageListCore> {
} }
@override @override
void initState() { void didChangeDependencies() {
_streamChannel = StreamChannel.of(context); _streamChannel = StreamChannel.of(context);
if (_isThreadConversation) { if (_isThreadConversation) {
_streamChannel.getReplies(widget.parentMessage!.id); _streamChannel.getReplies(widget.parentMessage!.id);
} }
super.didChangeDependencies();
}
@override
void didUpdateWidget(covariant MessageListCore oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.messageListController != oldWidget.messageListController) {
_setupController();
}
}
@override
void initState() {
_setupController();
super.initState();
}
void _setupController() {
if (widget.messageListController != null) { if (widget.messageListController != null) {
widget.messageListController!.paginateData = paginateData; widget.messageListController!.paginateData = paginateData;
} }
super.initState();
} }
@override @override
@@ -29,17 +29,20 @@ class MessageSearchBloc extends StatefulWidget {
state = context.findAncestorStateOfType<MessageSearchBlocState>(); state = context.findAncestorStateOfType<MessageSearchBlocState>();
if (state == null) { assert(
throw Exception('You must have a MessageSearchBloc widget as ancestor'); state != null,
} 'You must have a MessageSearchBloc widget as ancestor',
);
return state; return state!;
} }
} }
/// The current state of the [MessageSearchBloc] /// The current state of the [MessageSearchBloc]
class MessageSearchBlocState extends State<MessageSearchBloc> class MessageSearchBlocState extends State<MessageSearchBloc>
with AutomaticKeepAliveClientMixin { with AutomaticKeepAliveClientMixin {
late final StreamChatCoreState _streamChatCoreState;
/// The current messages list /// The current messages list
List<GetMessageResponse>? get messageResponses => _messageResponses.value; List<GetMessageResponse>? get messageResponses => _messageResponses.value;
@@ -64,7 +67,7 @@ class MessageSearchBlocState extends State<MessageSearchBloc>
String? query, String? query,
PaginationParams? pagination, PaginationParams? pagination,
}) async { }) async {
final client = StreamChatCore.of(context).client; final client = _streamChatCoreState.client;
if (_queryMessagesLoadingController.value == true) return; if (_queryMessagesLoadingController.value == true) return;
@@ -109,6 +112,12 @@ class MessageSearchBlocState extends State<MessageSearchBloc>
return widget.child; return widget.child;
} }
@override
void didChangeDependencies() {
_streamChatCoreState = StreamChatCore.of(context);
super.didChangeDependencies();
}
@override @override
void dispose() { void dispose() {
_messageResponses.close(); _messageResponses.close();
@@ -105,21 +105,21 @@ class MessageSearchListCore extends StatefulWidget {
/// The current state of the [MessageSearchListCore]. /// The current state of the [MessageSearchListCore].
class MessageSearchListCoreState extends State<MessageSearchListCore> { class MessageSearchListCoreState extends State<MessageSearchListCore> {
late final MessageSearchBlocState messageSearchBloc;
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies(); messageSearchBloc = MessageSearchBloc.of(context);
loadData(); loadData();
if (widget.messageSearchListController != null) { if (widget.messageSearchListController != null) {
widget.messageSearchListController!.loadData = loadData; widget.messageSearchListController!.loadData = loadData;
widget.messageSearchListController!.paginateData = paginateData; widget.messageSearchListController!.paginateData = paginateData;
} }
super.didChangeDependencies();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) => _buildListView(messageSearchBloc);
final messageSearchBloc = MessageSearchBloc.of(context);
return _buildListView(messageSearchBloc);
}
Widget _buildListView(MessageSearchBlocState messageSearchBloc) => Widget _buildListView(MessageSearchBlocState messageSearchBloc) =>
StreamBuilder<List<GetMessageResponse>>( StreamBuilder<List<GetMessageResponse>>(
@@ -140,30 +140,24 @@ class MessageSearchListCoreState extends State<MessageSearchListCore> {
); );
/// Fetches initial messages and updates the widget /// Fetches initial messages and updates the widget
Future<void> loadData() { Future<void> loadData() => messageSearchBloc.search(
final messageSearchBloc = MessageSearchBloc.of(context); filter: widget.filters,
return messageSearchBloc.search( sort: widget.sortOptions,
filter: widget.filters, query: widget.messageQuery,
sort: widget.sortOptions, pagination: widget.paginationParams,
query: widget.messageQuery, messageFilter: widget.messageFilters,
pagination: widget.paginationParams, );
messageFilter: widget.messageFilters,
);
}
/// Fetches more messages with updated pagination and updates the widget /// Fetches more messages with updated pagination and updates the widget
Future<void> paginateData() { Future<void> paginateData() => messageSearchBloc.search(
final messageSearchBloc = MessageSearchBloc.of(context); filter: widget.filters,
return messageSearchBloc.search( sort: widget.sortOptions,
filter: widget.filters, pagination: widget.paginationParams!.copyWith(
sort: widget.sortOptions, offset: messageSearchBloc.messageResponses?.length ?? 0,
pagination: widget.paginationParams!.copyWith( ),
offset: messageSearchBloc.messageResponses?.length ?? 0, query: widget.messageQuery,
), messageFilter: widget.messageFilters,
query: widget.messageQuery, );
messageFilter: widget.messageFilters,
);
}
@override @override
void didUpdateWidget(MessageSearchListCore oldWidget) { void didUpdateWidget(MessageSearchListCore oldWidget) {
@@ -47,13 +47,12 @@ class StreamChannel extends StatefulWidget {
streamChannelState = context.findAncestorStateOfType<StreamChannelState>(); streamChannelState = context.findAncestorStateOfType<StreamChannelState>();
if (streamChannelState == null) { assert(
throw Exception( streamChannelState != null,
'You must have a StreamChannel widget at the top of your widget tree', 'You must have a StreamChannel widget at the top of your widget tree',
); );
}
return streamChannelState; return streamChannelState!;
} }
@override @override
@@ -70,12 +70,12 @@ class StreamChatCore extends StatefulWidget {
streamChatState = context.findAncestorStateOfType<StreamChatCoreState>(); streamChatState = context.findAncestorStateOfType<StreamChatCoreState>();
if (streamChatState == null) { assert(
throw Exception( streamChatState != null,
'You must have a StreamChat widget at the top of your widget tree'); 'You must have a StreamChat widget at the top of your widget tree',
} );
return streamChatState; return streamChatState!;
} }
} }
@@ -124,12 +124,12 @@ class UserListCoreState extends State<UserListCore>
with WidgetsBindingObserver { with WidgetsBindingObserver {
@override @override
void didChangeDependencies() { void didChangeDependencies() {
super.didChangeDependencies();
loadData(); loadData();
if (widget.userListController != null) { if (widget.userListController != null) {
widget.userListController!.loadData = loadData; widget.userListController!.loadData = loadData;
widget.userListController!.paginateData = paginateData; widget.userListController!.paginateData = paginateData;
} }
super.didChangeDependencies();
} }
@override @override
@@ -30,11 +30,12 @@ class UsersBloc extends StatefulWidget {
state = context.findAncestorStateOfType<UsersBlocState>(); state = context.findAncestorStateOfType<UsersBlocState>();
if (state == null) { assert(
throw Exception('You must have a UsersBloc widget as ancestor'); state != null,
} 'You must have a UsersBloc widget as ancestor',
);
return state; return state!;
} }
} }
@@ -54,6 +55,8 @@ class UsersBlocState extends State<UsersBloc>
/// The stream notifying the state of queryUsers call /// The stream notifying the state of queryUsers call
Stream<bool> get queryUsersLoading => _queryUsersLoadingController.stream; Stream<bool> get queryUsersLoading => _queryUsersLoadingController.stream;
late final StreamChatCoreState _streamChatCore;
/// The Query Users method allows you to search for users and see if they are /// The Query Users method allows you to search for users and see if they are
/// online/offline. /// online/offline.
/// [API Reference](https://getstream.io/chat/docs/flutter-dart/query_users/?language=dart) /// [API Reference](https://getstream.io/chat/docs/flutter-dart/query_users/?language=dart)
@@ -63,7 +66,7 @@ class UsersBlocState extends State<UsersBloc>
Map<String, dynamic>? options, Map<String, dynamic>? options,
PaginationParams? pagination, PaginationParams? pagination,
}) async { }) async {
final client = StreamChatCore.of(context).client; final client = _streamChatCore.client;
if (_queryUsersLoadingController.value == true) return; if (_queryUsersLoadingController.value == true) return;
@@ -101,6 +104,12 @@ class UsersBlocState extends State<UsersBloc>
} }
} }
@override
void didChangeDependencies() {
_streamChatCore = StreamChatCore.of(context);
super.didChangeDependencies();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
super.build(context); super.build(context);