Skip to content

Commit e0a7164

Browse files
Improved read indicator updates
1 parent bb233ee commit e0a7164

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ open class ChatChannelViewModel: ObservableObject, MessagesDataSource {
2626
}
2727

2828
private var isActive = true
29+
private var readsString = ""
2930

3031
private let messageListDateOverlay: DateFormatter = {
3132
let df = DateFormatter()
@@ -195,6 +196,7 @@ open class ChatChannelViewModel: ObservableObject, MessagesDataSource {
195196
didUpdateChannel channel: EntityChange<ChatChannel>,
196197
channelController: ChatChannelController
197198
) {
199+
checkReadIndicators(for: channel)
198200
checkHeaderType()
199201
}
200202

@@ -278,6 +280,23 @@ open class ChatChannelViewModel: ObservableObject, MessagesDataSource {
278280
}
279281
}
280282

283+
private func checkReadIndicators(for channel: EntityChange<ChatChannel>) {
284+
switch channel {
285+
case let .update(chatChannel):
286+
let newReadsString = chatChannel.readsString
287+
if readsString == "" {
288+
readsString = newReadsString
289+
return
290+
}
291+
if readsString != newReadsString && isActive {
292+
messages = channelDataSource.messages
293+
readsString = newReadsString
294+
}
295+
default:
296+
log.debug("skip updating of messages in channel update")
297+
}
298+
}
299+
281300
private func checkNameChange() {
282301
let currentChannelName = channel?.name ?? ""
283302
var nameChanged = false
@@ -470,6 +489,17 @@ extension ChatMessage: Identifiable {
470489
}
471490
}
472491

492+
extension ChatChannel {
493+
494+
var readsString: String {
495+
reads.map { read in
496+
"\(read.user.id)-\(read.lastReadAt)"
497+
}
498+
.sorted()
499+
.joined(separator: "-")
500+
}
501+
}
502+
473503
/// The type of header shown in the chat channel screen.
474504
public enum ChannelHeaderType {
475505
/// The regular header showing the channel name and members.

StreamChatSwiftUITests/Tests/ChatChannel/ChatChannelViewModel_Tests.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,33 @@ class ChatChannelViewModel_Tests: StreamChatTestCase {
294294
XCTAssert(initial.count < after.count)
295295
}
296296

297+
func test_chatChannelVM_updateReadIndicators() {
298+
// Given
299+
let channelController = makeChannelController()
300+
let viewModel = ChatChannelViewModel(channelController: channelController)
301+
let channel = ChatChannel.mockDMChannel()
302+
let read = ChatChannelRead.mock(lastReadAt: Date(), unreadMessagesCount: 1, user: .mock(id: .unique))
303+
let newChannel = ChatChannel.mockDMChannel(reads: [read])
304+
305+
// When
306+
channelController.simulate(
307+
channel: channel,
308+
change: .update(channel),
309+
typingUsers: nil
310+
)
311+
let readsString = channel.readsString
312+
channelController.simulate(
313+
channel: newChannel,
314+
change: .update(newChannel),
315+
typingUsers: nil
316+
)
317+
let newChannelReadsString = newChannel.readsString
318+
319+
// Then
320+
XCTAssert(viewModel.channel! == newChannel)
321+
XCTAssert(readsString != newChannelReadsString)
322+
}
323+
297324
// MARK: - private
298325

299326
private func makeChannelController(

0 commit comments

Comments
 (0)