From ae44406b96ec39a9cc275c8d51ddf841bf7df9eb Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Mon, 21 Feb 2022 15:31:23 +0530 Subject: [PATCH 1/2] fix(llc): Fix `channelState.copyWith` with respect to pinnedMessages. Signed-off-by: xsahil03x --- packages/stream_chat/CHANGELOG.md | 1 + .../stream_chat/lib/src/core/models/channel_state.dart | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/stream_chat/CHANGELOG.md b/packages/stream_chat/CHANGELOG.md index 82225b27..ef66f835 100644 --- a/packages/stream_chat/CHANGELOG.md +++ b/packages/stream_chat/CHANGELOG.md @@ -10,6 +10,7 @@ - [[#890]](https://github.com/GetStream/stream-chat-flutter/pull/890) Fixed Reactions not updating on thread messages. Thanks [bstolinski](https://github.com/bstolinski). - [[#897]](https://github.com/GetStream/stream-chat-flutter/issues/897) Fixed error type mis-match in `AuthInterceptor`. +- Fix `channelState.copyWith` with respect to pinnedMessages. ## 3.4.0 diff --git a/packages/stream_chat/lib/src/core/models/channel_state.dart b/packages/stream_chat/lib/src/core/models/channel_state.dart index 3ddc2b68..8b500d18 100644 --- a/packages/stream_chat/lib/src/core/models/channel_state.dart +++ b/packages/stream_chat/lib/src/core/models/channel_state.dart @@ -67,9 +67,10 @@ class ChannelState { members: members ?? this.members, // Hack to avoid using the default value in case nothing is provided. // FIXME: Use non-nullable by default instead of empty list. - pinnedMessages: pinnedMessages == _emptyPinnedMessages - ? this.pinnedMessages - : pinnedMessages ?? _emptyPinnedMessages, + pinnedMessages: + pinnedMessages == null || pinnedMessages == _emptyPinnedMessages + ? this.pinnedMessages + : pinnedMessages, watcherCount: watcherCount ?? this.watcherCount, watchers: watchers ?? this.watchers, read: read ?? this.read, From a361e89abad9cc5e70980cf86067518a3392ce3f Mon Sep 17 00:00:00 2001 From: Sahil Kumar Date: Wed, 23 Feb 2022 17:55:34 +0530 Subject: [PATCH 2/2] fix(llc): fix `pinnedMessage` inconsistencies. Signed-off-by: xsahil03x --- .../stream_chat/lib/src/client/channel.dart | 38 +++++++++++-------- .../lib/src/core/models/channel_state.dart | 9 ++--- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/packages/stream_chat/lib/src/client/channel.dart b/packages/stream_chat/lib/src/client/channel.dart index 76fbab7a..dd6fcff1 100644 --- a/packages/stream_chat/lib/src/client/channel.dart +++ b/packages/stream_chat/lib/src/client/channel.dart @@ -1744,15 +1744,6 @@ class ChannelClientState { ownReactions: oldMessage?.ownReactions, ); addMessage(message); - - if (message.pinned) { - _channelState = _channelState.copyWith( - pinnedMessages: [ - ..._channelState.pinnedMessages, - message, - ], - ); - } })); } @@ -1804,8 +1795,24 @@ class ChannelClientState { newMessages.add(message); } + final newPinnedMessages = [...pinnedMessages]; + final oldPinnedIndex = + newPinnedMessages.indexWhere((m) => m.id == message.id); + + // Handle pinned messages + if (message.pinned) { + if (oldPinnedIndex != -1) { + newPinnedMessages[oldPinnedIndex] = message; + } else { + newPinnedMessages.add(message); + } + } else { + newPinnedMessages.removeWhere((m) => m.id == message.id); + } + _channelState = _channelState.copyWith( messages: newMessages..sort(_sortByCreatedAt), + pinnedMessages: newPinnedMessages, channel: _channelState.channel?.copyWith( lastMessageAt: message.createdAt, ), @@ -1898,11 +1905,12 @@ class ChannelClientState { .distinct(const ListEquality().equals); /// Channel pinned message list. - List get pinnedMessages => _channelState.pinnedMessages.toList(); + List get pinnedMessages => _channelState.pinnedMessages; /// Channel pinned message list as a stream. - Stream> get pinnedMessagesStream => - channelStateStream.map((cs) => cs.pinnedMessages.toList()); + Stream> get pinnedMessagesStream => channelStateStream + .map((cs) => cs.pinnedMessages) + .distinct(const ListEquality().equals); /// Get channel last message. Message? get lastMessage => @@ -2213,7 +2221,7 @@ class ChannelClientState { .toList(); updateChannelState(_channelState.copyWith( - pinnedMessages: pinnedMessages.where(_pinIsValid()).toList(), + pinnedMessages: pinnedMessages.where(_pinIsValid).toList(), messages: expiredMessages, )); } @@ -2250,7 +2258,7 @@ class ChannelClientState { } } -bool Function(Message) _pinIsValid() { +bool _pinIsValid(Message message) { final now = DateTime.now(); - return (Message m) => m.pinExpires!.isAfter(now); + return message.pinExpires!.isAfter(now); } diff --git a/packages/stream_chat/lib/src/core/models/channel_state.dart b/packages/stream_chat/lib/src/core/models/channel_state.dart index 8b500d18..17439dc0 100644 --- a/packages/stream_chat/lib/src/core/models/channel_state.dart +++ b/packages/stream_chat/lib/src/core/models/channel_state.dart @@ -56,7 +56,7 @@ class ChannelState { ChannelModel? channel, List? messages, List? members, - List? pinnedMessages, + List pinnedMessages = _emptyPinnedMessages, int? watcherCount, List? watchers, List? read, @@ -67,10 +67,9 @@ class ChannelState { members: members ?? this.members, // Hack to avoid using the default value in case nothing is provided. // FIXME: Use non-nullable by default instead of empty list. - pinnedMessages: - pinnedMessages == null || pinnedMessages == _emptyPinnedMessages - ? this.pinnedMessages - : pinnedMessages, + pinnedMessages: pinnedMessages == _emptyPinnedMessages + ? this.pinnedMessages + : pinnedMessages, watcherCount: watcherCount ?? this.watcherCount, watchers: watchers ?? this.watchers, read: read ?? this.read,