Skip to content

Commit

Permalink
Fix marking channel read when isJumpToUnread is disabled (#2902)
Browse files Browse the repository at this point in the history
* Fix not being able to mark channel read when `isJumpToUnread` is disabled

* Update CHANGELOG.md
  • Loading branch information
nuno-vieira committed Nov 17, 2023
1 parent 7f261a9 commit ec8c625
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ _November 17, 2023_
### 🐞 Fixed
- Fix Message List UI not updated when message.updatedAt changes [#2884](https://github.com/GetStream/stream-chat-swift/pull/2884)
- Fix jump to unread button showing "0" unread counts [#2894](https://github.com/GetStream/stream-chat-swift/pull/2894)
- Fix not able to mark channel read when isJumpToUnread is disabled [#2902](https://github.com/GetStream/stream-chat-swift/pull/2902)

# [4.42.0](https://github.com/GetStream/stream-chat-swift/releases/tag/4.42.0)
_November 14, 2023_
Expand Down
6 changes: 5 additions & 1 deletion Sources/StreamChatUI/ChatChannel/ChatChannelVC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,11 @@ open class ChatChannelVC: _ViewController,
return false
}

return isLastMessageVisibleOrSeen && hasSeenFirstUnreadMessage && channelController.hasLoadedAllNextMessages && !hasMarkedMessageAsUnread
guard components.isJumpToUnreadEnabled else {
return isLastMessageFullyVisible && isFirstPageLoaded
}

return isLastMessageVisibleOrSeen && hasSeenFirstUnreadMessage && isFirstPageLoaded && !hasMarkedMessageAsUnread
}

private var isLastMessageVisibleOrSeen: Bool {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -760,9 +760,22 @@ final class ChatChannelVC_Tests: XCTestCase {

// MARK: Channel read

func test_shouldMarkChannelRead_viewIsVisible_remoteDataFetched_lastMessageVisible_hasLoadedAllNextMessages_hasNotMarkedMessageAsUnread_shouldReturnTrue() {
func test_shouldMarkChannelRead_jumpToUnreadDisabled_viewIsVisible_remoteDataFetched_lastMessageVisible_hasLoadedAllNextMessages_hasNotMarkedMessageAsUnread_shouldReturnTrue() {
let mockedListView = makeMockMessageListView()
vc.isViewVisible = { _ in true }
vc.components.isJumpToUnreadEnabled = false
channelControllerMock.state_mock = .remoteDataFetched
mockedListView.mockIsLastCellFullyVisible = true
channelControllerMock.hasLoadedAllNextMessages_mock = true
channelControllerMock.markedAsUnread_mock = false

XCTAssertTrue(vc.shouldMarkChannelRead)
}

func test_shouldMarkChannelRead_jumpToUnreadEnabled_viewIsVisible_remoteDataFetched_lastMessageVisible_hasLoadedAllNextMessages_hasNotMarkedMessageAsUnread_shouldReturnTrue() {
let mockedListView = makeMockMessageListView()
vc.isViewVisible = { _ in true }
vc.components.isJumpToUnreadEnabled = true
channelControllerMock.state_mock = .remoteDataFetched
mockedListView.mockIsLastCellFullyVisible = true
channelControllerMock.hasLoadedAllNextMessages_mock = true
Expand All @@ -775,6 +788,18 @@ final class ChatChannelVC_Tests: XCTestCase {
XCTAssertTrue(vc.shouldMarkChannelRead)
}

func test_shouldMarkChannelRead_jumpToUnreadEnabled_whenNotSeenLastMessage_whenNotSeenFirstUnreadMessage_shouldReturnFalse() {
let mockedListView = makeMockMessageListView()
vc.isViewVisible = { _ in true }
vc.components.isJumpToUnreadEnabled = true
channelControllerMock.state_mock = .remoteDataFetched
mockedListView.mockIsLastCellFullyVisible = true
channelControllerMock.hasLoadedAllNextMessages_mock = true
channelControllerMock.markedAsUnread_mock = false

XCTAssertFalse(vc.shouldMarkChannelRead)
}

func test_shouldMarkChannelRead_viewIsNotVisible_remoteDataNotFetched_lastMessageNotVisible_hasNotLoadedAllNextMessages_hasMarkedMessageAsUnread_shouldReturnFalse() {
let mockedListView = makeMockMessageListView()
vc.isViewVisible = { _ in false }
Expand All @@ -789,10 +814,15 @@ final class ChatChannelVC_Tests: XCTestCase {
XCTAssertFalse(vc.shouldMarkChannelRead)
}

func test_shouldMarkChannelRead_otherCombinations_shouldReturnFalse() {
func test_shouldMarkChannelRead_whenJumpToUnreadDisabled_otherCombinations_shouldReturnFalse() {
struct MarkUnreadStatePreconditions {
let isViewVisible: Bool, state: DataController.State, isLastCellFullyVisible: Bool, hasLoadedAllNextMessages: Bool, markedAsUnread: Bool
let isViewVisible: Bool
let state: DataController.State
let isLastCellFullyVisible: Bool
let hasLoadedAllNextMessages: Bool
let markedAsUnread: Bool
}

let options: [MarkUnreadStatePreconditions] = [
.init(isViewVisible: false, state: .remoteDataFetched, isLastCellFullyVisible: true, hasLoadedAllNextMessages: true, markedAsUnread: false),
.init(isViewVisible: true, state: .initialized, isLastCellFullyVisible: true, hasLoadedAllNextMessages: true, markedAsUnread: false),
Expand All @@ -806,9 +836,10 @@ final class ChatChannelVC_Tests: XCTestCase {
let vc = ChatChannelVC()
vc.isViewVisible = { _ in true }
vc.components = self.vc.components
vc.components.isJumpToUnreadEnabled = true
vc.channelController = self.vc.channelController

let mockedListView = makeMockMessageListView()
let mockedListView = makeMockMessageListView(channelVC: vc)
vc.isViewVisible = { _ in option.isViewVisible }
channelControllerMock.state_mock = option.state
mockedListView.mockIsLastCellFullyVisible = option.isLastCellFullyVisible
Expand All @@ -818,9 +849,44 @@ final class ChatChannelVC_Tests: XCTestCase {
// Simulate display to update hasSeenLastMessage
vc.chatMessageListVC(ChatMessageListVC_Mock(), willDisplayMessageAt: IndexPath(item: 0, section: 0))

if vc.shouldMarkChannelRead {
debugPrint(option)
}
XCTAssertFalse(vc.shouldMarkChannelRead)
}
}

func test_shouldMarkChannelRead_whenJumpToUnreadDisabled_whenMarkedAsUnreadTrueOrFalse_shouldReturnTrue() {
struct MarkUnreadStatePreconditions {
let isViewVisible: Bool
let state: DataController.State
let isLastCellFullyVisible: Bool
let hasLoadedAllNextMessages: Bool
let markedAsUnread: Bool
}

let options: [MarkUnreadStatePreconditions] = [
.init(isViewVisible: true, state: .remoteDataFetched, isLastCellFullyVisible: true, hasLoadedAllNextMessages: true, markedAsUnread: false),
.init(isViewVisible: true, state: .remoteDataFetched, isLastCellFullyVisible: true, hasLoadedAllNextMessages: true, markedAsUnread: true)
]

options.forEach { option in
let vc = ChatChannelVC()
vc.isViewVisible = { _ in true }
vc.components = self.vc.components
vc.components.isJumpToUnreadEnabled = false
vc.channelController = self.vc.channelController

let mockedListView = makeMockMessageListView(channelVC: vc)
vc.isViewVisible = { _ in option.isViewVisible }
channelControllerMock.state_mock = option.state
mockedListView.mockIsLastCellFullyVisible = option.isLastCellFullyVisible
channelControllerMock.hasLoadedAllNextMessages_mock = option.hasLoadedAllNextMessages
channelControllerMock.markedAsUnread_mock = option.markedAsUnread

XCTAssertTrue(vc.shouldMarkChannelRead)
}
}

func test_viewDidAppear_whenShouldMarkChannelRead_thenMarkRead() {
let mockedListView = makeMockMessageListView()
Expand Down Expand Up @@ -1300,7 +1366,8 @@ private extension ChatChannelVC_Tests {
)
}

func makeMockMessageListView() -> ChatMessageListView_Mock {
func makeMockMessageListView(channelVC: ChatChannelVC? = nil) -> ChatMessageListView_Mock {
let vc = channelVC ?? self.vc!
vc.messageListVC.components.messageListView = ChatMessageListView_Mock.self
return vc.messageListVC.listView as! ChatMessageListView_Mock
}
Expand Down

0 comments on commit ec8c625

Please sign in to comment.