Skip to content

Commit 571a488

Browse files
authored
Fix marking channel read when scrolling to bottom without unread count (#3881)
* Fix marking channel read when scrolling to bottom without unread count * Update CHANGELOG.md
1 parent e275c6b commit 571a488

File tree

3 files changed

+28
-3
lines changed

3 files changed

+28
-3
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
33

44
# Upcoming
55

6-
### 🔄 Changed
6+
## StreamChatUI
7+
### 🐞 Fixed
8+
- Fix marking channel read when scrolling to the bottom without unread counts [#3881](https://github.com/GetStream/stream-chat-swift/pull/3881)
79

810
# [4.93.0](https://github.com/GetStream/stream-chat-swift/releases/tag/4.93.0)
911
_November 18, 2025_

Sources/StreamChatUI/ChatChannel/ChatChannelVC.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,12 @@ open class ChatChannelVC: _ViewController,
8989
return isLastMessageFullyVisible && isFirstPageLoaded
9090
}
9191

92-
return isLastMessageVisibleOrSeen && hasSeenFirstUnreadMessage && isFirstPageLoaded && !hasMarkedMessageAsUnread
92+
let unreadMessageCount = channelController.channel?.unreadCount.messages ?? 0
93+
return isLastMessageVisibleOrSeen
94+
&& hasSeenFirstUnreadMessage
95+
&& isFirstPageLoaded
96+
&& !hasMarkedMessageAsUnread
97+
&& unreadMessageCount > 0
9398
}
9499

95100
private var isLastMessageVisibleOrSeen: Bool {

Tests/StreamChatUITests/SnapshotTests/ChatChannel/ChatChannelVC_Tests.swift

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -904,11 +904,12 @@ final class ChatChannelVC_Tests: XCTestCase {
904904
XCTAssertTrue(vc.shouldMarkChannelRead)
905905
}
906906

907-
func test_shouldMarkChannelRead_jumpToUnreadEnabled_viewIsVisible_remoteDataFetched_lastMessageVisible_hasLoadedAllNextMessages_hasNotMarkedMessageAsUnread_shouldReturnTrue() {
907+
func test_shouldMarkChannelRead_jumpToUnreadEnabled_viewIsVisible_remoteDataFetched_lastMessageVisible_hasLoadedAllNextMessages_hasNotMarkedMessageAsUnread_withUnreads_shouldReturnTrue() {
908908
let mockedListView = makeMockMessageListView()
909909
vc.mockIsViewVisible(true)
910910
vc.components.isJumpToUnreadEnabled = true
911911
channelControllerMock.state_mock = .remoteDataFetched
912+
channelControllerMock.channel_mock = .mock(cid: .unique, unreadCount: ChannelUnreadCount(messages: 1, mentions: 0))
912913
mockedListView.mockIsLastCellFullyVisible = true
913914
channelControllerMock.hasLoadedAllNextMessages_mock = true
914915
channelControllerMock.markedAsUnread_mock = false
@@ -919,6 +920,23 @@ final class ChatChannelVC_Tests: XCTestCase {
919920

920921
XCTAssertTrue(vc.shouldMarkChannelRead)
921922
}
923+
924+
func test_shouldMarkChannelRead_jumpToUnreadEnabled_viewIsVisible_remoteDataFetched_lastMessageVisible_hasLoadedAllNextMessages_hasNotMarkedMessageAsUnread_withoutUnreads_shouldReturnFalse() {
925+
let mockedListView = makeMockMessageListView()
926+
vc.mockIsViewVisible(true)
927+
vc.components.isJumpToUnreadEnabled = true
928+
channelControllerMock.state_mock = .remoteDataFetched
929+
channelControllerMock.channel_mock = .mock(cid: .unique, unreadCount: ChannelUnreadCount(messages: 0, mentions: 0))
930+
mockedListView.mockIsLastCellFullyVisible = true
931+
channelControllerMock.hasLoadedAllNextMessages_mock = true
932+
channelControllerMock.markedAsUnread_mock = false
933+
934+
// Simulate display to update hasSeenLastMessage && hasSeenFirstUnreadMessage
935+
vc.chatMessageListVC(ChatMessageListVC_Mock(), willDisplayMessageAt: IndexPath(item: 0, section: 0))
936+
vc.chatMessageListVC(ChatMessageListVC_Mock(), scrollViewDidScroll: UIScrollView())
937+
938+
XCTAssertFalse(vc.shouldMarkChannelRead)
939+
}
922940

923941
func test_shouldMarkChannelRead_jumpToUnreadEnabled_whenNotSeenLastMessage_whenNotSeenFirstUnreadMessage_shouldReturnFalse() {
924942
let mockedListView = makeMockMessageListView()

0 commit comments

Comments
 (0)