Skip to content

Conversation

nuno-vieira
Copy link
Member

@nuno-vieira nuno-vieira commented Oct 1, 2025

🔗 Issue Links

IOS-968
IOS-909
IOS-426

🎯 Goal

Fix multiple issues around mark unread of messages.

📝 Summary

  • Fix unread messages banner not shown for small channels
  • Fix the unread banner not shown if the whole channel is unread
  • Fix channel not marking read when passing by the unread message
  • Fix marking a message unread causing the message list to randomly scroll
  • Fix channel marking read when the user scrolls to the bottom after marking a message as unread
  • Fix new messages ignoring mark unread message state
  • Fix replying to unread messages marking them instantly as read

🛠 Implementation

One of the main issues was related to channelController.firstUnreadMessageId. In the LLC SDK, we already have logic in case the whole channel is unread. But on SwiftUI, we heavily use the firstUnreadMessageId before the channel has been remotely fetched, and the channelController.firstUnreadMessageId depends on the hasLoadedAllPreviousMessages. Because of this, I had to duplicate the logic in the SwiftUI view to avoid too many risky changes.

While doing all these tests, some times whenever I marked a message as unread, I noticed that it would randomly jump to somewhere else. So now, whenever we mark a message as unread, we force it to jump to the unread message.

🧪 Manual Testing Notes

⚠️ Besides all the tests below, we should do a smoke test around the unread and channel reads feature.

Fix unread messages banner not shown for small channels

  1. Open a channel with 6/7 messages
  2. Mark a message in the middle as unread
  3. The "New Messages" banner should be shown
  4. Leave the channel
  5. Open the channel
  6. The "New Messages" banner should be shown
  7. Leave the channel
  8. Open the channel
  9. No banner should be shown

Fix the unread banner not shown if the whole channel is unread

  1. Open a channel with 6/7 messages
  2. Mark the first message (oldest message) as unread
  3. The "New Messages" banner should be shown
  4. Leave the channel
  5. Open the channel
  6. The "New Messages" banner should be shown
  7. Leave the channel
  8. Open the channel
  9. No banner should be shown

Fix channel not marking read when passing by the unread message

  1. Open a channel with multiple messages
  2. Scroll up to older messages
  3. Mark a message as unread
  4. The "New Messages" banner should be shown
  5. Leave the channel
  6. Open the channel
  7. Scroll to the unread message
  8. The "New Messages" banner should be shown
  9. Leave the channel
  10. Open the channel
  11. Scroll to the previous unread message
  12. No banner should be shown anymore

Fix channel marking read when the user scrolls to the bottom after marking a message as unread

  1. Open a channel with multiple messages
  2. Scroll up to older messages
  3. Mark a message as unread
  4. The "New Messages" banner should be shown
  5. Scroll to the bottom of all messages
  6. Scroll again to the unread message
  7. The "New Messages" banner should be shown
  8. Leave the channel
  9. Open the channel
  10. The channel should be still unread

Fix marking a message unread causing the message list to randomly scroll

  1. Open a channel
  2. Scroll up to older pages
  3. Mark a message as unread
  4. It should not jump to somewhere else random

Fix new messages ignoring mark unread message state

Follow the steps in IOS-909

Fix replying to unread messages marking them instantly as read

Follow the steps in IOS-426

☑️ Contributor Checklist

  • I have signed the Stream CLA (required)
  • This change should be manually QAed
  • Changelog is updated with client-facing changes
  • Changelog is updated with new localization keys
  • New code is covered by unit tests
  • Documentation has been updated in the docs-content repo

@nuno-vieira nuno-vieira requested a review from a team as a code owner October 1, 2025 21:19
Copy link

github-actions bot commented Oct 1, 2025

Public Interface

 open class ChatChannelViewModel: ObservableObject, MessagesDataSource  
-   @Published public private var channel: ChatChannel?
+   public var currentUserMarkedMessageUnread: Bool
-   public var isMessageThread: Bool
+   @Published public private var channel: ChatChannel?
-   
+   public var isMessageThread: Bool
- 
+   
-   public init(channelController: ChatChannelController,messageController: ChatMessageController? = nil,scrollToMessage: ChatMessage? = nil)
+ 
-   
+   public init(channelController: ChatChannelController,messageController: ChatMessageController? = nil,scrollToMessage: ChatMessage? = nil)
- 
+   
-   public func scrollToLastMessage()
+ 
-   public func messageSentTapped()
+   public func scrollToLastMessage()
-   public func jumpToMessage(messageId: String)-> Bool
+   public func messageSentTapped()
-   open func handleMessageAppear(index: Int,scrollDirection: ScrollDirection)
+   public func jumpToMessage(messageId: String)-> Bool
-   open func groupMessages()
+   open func handleMessageAppear(index: Int,scrollDirection: ScrollDirection)
-   public func showReactionOverlay(for view: AnyView)
+   open func groupMessages()
-   public func showBouncedActionsView(for message: ChatMessage)
+   public func showReactionOverlay(for view: AnyView)
-   public func deleteMessage(_ message: ChatMessage)
+   public func showBouncedActionsView(for message: ChatMessage)
-   public func resendMessage(_ message: ChatMessage)
+   public func deleteMessage(_ message: ChatMessage)
-   public func editMessage(_ message: ChatMessage)
+   public func resendMessage(_ message: ChatMessage)
-   open func messageActionExecuted(_ messageActionInfo: MessageActionInfo)
+   public func editMessage(_ message: ChatMessage)
-   @objc public func onViewAppear()
+   open func messageActionExecuted(_ messageActionInfo: MessageActionInfo)
-   @objc public func onViewDissappear()
+   @objc public func onViewAppear()
-   public func setActive()
+   @objc public func onViewDissappear()
+   public func setActive()

@Stream-SDK-Bot
Copy link
Collaborator

Stream-SDK-Bot commented Oct 1, 2025

SDK Size

title develop branch diff status
StreamChatSwiftUI 9.48 MB 9.48 MB 0 KB 🟢

@nuno-vieira nuno-vieira force-pushed the fix/unread-message-banner-for-small-channels branch from ecbef3f to ccfef78 Compare October 1, 2025 23:15
@nuno-vieira nuno-vieira changed the title Fix unread message banner for small channels + Improve mark unread stability Fix multiple issues around mark unread and unread banner Oct 1, 2025
Copy link
Contributor

@martinmitrevski martinmitrevski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM ✅ Good if @testableapple runs a QA on this one.

Copy link

sonarqubecloud bot commented Oct 2, 2025

@nuno-vieira nuno-vieira merged commit 5beb176 into develop Oct 2, 2025
11 checks passed
@nuno-vieira nuno-vieira deleted the fix/unread-message-banner-for-small-channels branch October 2, 2025 14:56
@Stream-SDK-Bot Stream-SDK-Bot mentioned this pull request Oct 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants