From dc141a9d303d1c25d8145b55e683db8851569699 Mon Sep 17 00:00:00 2001 From: Toomas Vahter Date: Wed, 12 Jun 2024 11:34:03 +0300 Subject: [PATCH] Reload messages when author name or profile picture changes --- CHANGELOG.md | 3 +- .../ChatChannel/ChatChannelViewModel.swift | 2 + .../MessageList/MessageIdBuilder.swift | 12 +++++- .../ChatChannelViewModel_Tests.swift | 41 +++++++++++++++++++ 4 files changed, 55 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34c60c47..7389cf7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). # Upcoming -### 🔄 Changed +### 🐞 Fixed +- Reload messages when author name or profile picture changes [#514](https://github.com/GetStream/stream-chat-swiftui/pull/514) # [4.57.0](https://github.com/GetStream/stream-chat-swiftui/releases/tag/4.57.0) _June 07, 2024_ diff --git a/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift b/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift index a3e1200e..716abb5a 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift @@ -391,6 +391,8 @@ open class ChatChannelViewModel: ObservableObject, MessagesDataSource { if !isActive { return } + // Message data can change with every callback + utils.messageCachingUtils.clearCache() let animationState = shouldAnimate(changes: changes) if animationState == .animated { diff --git a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageIdBuilder.swift b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageIdBuilder.swift index 86b53751..0bbeb989 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageIdBuilder.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageIdBuilder.swift @@ -23,7 +23,15 @@ public class DefaultMessageIdBuilder: MessageIdBuilder { if message.textUpdatedAt != nil { statesId = "edited" } - return message.baseId + statesId + message.reactionScoresId - + message.repliesCountId + "\(message.updatedAt)" + message.pinStateId + let authorDisplayInfo = message.authorDisplayInfo + let author = authorDisplayInfo.name + String(authorDisplayInfo.imageURL?.hashValue ?? 0) + + return message.baseId + + statesId + + message.reactionScoresId + + message.repliesCountId + + "\(message.updatedAt)" + + message.pinStateId + + author } } diff --git a/StreamChatSwiftUITests/Tests/ChatChannel/ChatChannelViewModel_Tests.swift b/StreamChatSwiftUITests/Tests/ChatChannel/ChatChannelViewModel_Tests.swift index ba1d9c24..045922d5 100644 --- a/StreamChatSwiftUITests/Tests/ChatChannel/ChatChannelViewModel_Tests.swift +++ b/StreamChatSwiftUITests/Tests/ChatChannel/ChatChannelViewModel_Tests.swift @@ -469,6 +469,47 @@ class ChatChannelViewModel_Tests: StreamChatTestCase { // Then XCTAssert(shouldJump == false) } + + func test_chatChannelVM_messageAuthorChanged() { + // Given + let channelId = ChannelId.unique + let channelController = makeChannelController(messages: [ + ChatMessage.mock( + id: "1", + cid: channelId, + text: "A", + author: .mock(id: "a1", name: "Name") + ) + ]) + let viewModel = ChatChannelViewModel(channelController: channelController) + let initialMesssageIds = viewModel.messages.map(\.messageId) + + // When + channelController.messages_mock = [ + ChatMessage.mock( + id: "1", + cid: channelId, + text: "A", + author: .mock(id: "a1", name: "Name Updated") + ) + ] + let changes = channelController.messages + .enumerated() + .map { + ListChange.update( + $0.element, + index: IndexPath(item: $0.offset, section: 0) + ) + } + viewModel.dataSource( + channelDataSource: ChatChannelDataSource(controller: channelController), + didUpdateMessages: channelController.messages, + changes: changes + ) + // Then + let updatedMessageIds = viewModel.messages.map(\.messageId) + XCTAssertNotEqual(initialMesssageIds, updatedMessageIds, "Message id should not be cached when author changes") + } // MARK: - private