diff --git a/packages/stream_chat/CHANGELOG.md b/packages/stream_chat/CHANGELOG.md index 37e45f9e..1017ec7d 100644 --- a/packages/stream_chat/CHANGELOG.md +++ b/packages/stream_chat/CHANGELOG.md @@ -1,3 +1,9 @@ +## Upcoming + +🐞 Fixed + +- Remove disposed channel clients from the client state. + ## 5.0.0 - Included the changes from version [4.5.0](#450). diff --git a/packages/stream_chat/lib/src/client/channel.dart b/packages/stream_chat/lib/src/client/channel.dart index d2d854a8..cc2550f7 100644 --- a/packages/stream_chat/lib/src/client/channel.dart +++ b/packages/stream_chat/lib/src/client/channel.dart @@ -1237,7 +1237,7 @@ class Channel { state = ChannelClientState(this, channelState); if (cid != null) { - client.state.channels = {cid!: this}; + client.state.addChannels({cid!: this}); } if (!_initializedCompleter.isCompleted) { _initializedCompleter.complete(true); @@ -1544,6 +1544,7 @@ class Channel { /// Call this method to dispose the channel client. void dispose() { + client.state.removeChannel('$cid'); state?.dispose(); _keyStrokeHandler.cancel(); } diff --git a/packages/stream_chat/lib/src/client/client.dart b/packages/stream_chat/lib/src/client/client.dart index 2a33bd35..1ab85e94 100644 --- a/packages/stream_chat/lib/src/client/client.dart +++ b/packages/stream_chat/lib/src/client/client.dart @@ -665,7 +665,7 @@ class StreamChatClient { clearQueryCache: paginationParams.offset == 0, ); - this.state.channels = updateData.key; + this.state.addChannels(updateData.key); return updateData.value; } @@ -682,7 +682,7 @@ class StreamChatClient { )) ?? []; final updatedData = _mapChannelStateToChannel(offlineChannels); - state.channels = updatedData.key; + state.addChannels(updatedData.key); return updatedData.value; } @@ -1549,7 +1549,6 @@ class ClientState { final eventChannel = event.channel!; await _client.chatPersistenceClient?.deleteChannels([eventChannel.cid]); channels[eventChannel.cid]?.dispose(); - channels = channels..remove(eventChannel.cid); }), ); } @@ -1589,7 +1588,6 @@ class ClientState { final eventChannel = event.channel!; await _client.chatPersistenceClient?.deleteChannels([eventChannel.cid]); channels[eventChannel.cid]?.dispose(); - channels = channels..remove(eventChannel.cid); }), ); } @@ -1648,11 +1646,24 @@ class ClientState { /// The current list of channels in memory Map get channels => _channelsController.value; - set channels(Map channelMap) { - final newChannels = {...channels, ...channelMap}; + set channels(Map newChannels) { _channelsController.add(newChannels); } + /// Adds a list of channels to the current list of cached channels + void addChannels(Map channelMap) { + final newChannels = { + ...channels, + ...channelMap, + }; + channels = newChannels; + } + + /// Removes the channel from the cached list of [channels] + void removeChannel(String channelCid) { + channels = channels..remove(channelCid); + } + /// Used internally for optimistic update of unread count set totalUnreadCount(int unreadCount) { _totalUnreadCountController.add(unreadCount); @@ -1682,7 +1693,11 @@ class ClientState { _currentUserController.close(); _unreadChannelsController.close(); _totalUnreadCountController.close(); - channels.values.forEach((c) => c.dispose()); + + final channels = this.channels.values.toList(); + for (final channel in channels) { + channel.dispose(); + } _channelsController.close(); } } diff --git a/packages/stream_chat/test/src/client/channel_test.dart b/packages/stream_chat/test/src/client/channel_test.dart index c2f7490e..12a35629 100644 --- a/packages/stream_chat/test/src/client/channel_test.dart +++ b/packages/stream_chat/test/src/client/channel_test.dart @@ -50,6 +50,10 @@ void main() { // client logger when(() => client.logger).thenReturn(_createLogger('mock-client-logger')); + + // fake clientState + final clientState = FakeClientState(); + when(() => client.state).thenReturn(clientState); }); setUp(() { diff --git a/packages/stream_chat/test/src/fakes.dart b/packages/stream_chat/test/src/fakes.dart index ddbf4887..53ef2aed 100644 --- a/packages/stream_chat/test/src/fakes.dart +++ b/packages/stream_chat/test/src/fakes.dart @@ -91,6 +91,11 @@ class FakeClientState extends Fake implements ClientState { @override int totalUnreadCount = 0; + + @override + void removeChannel(String channelCid) { + return; + } } class FakeMessage extends Fake implements Message {}