Skip to content

4.84.0 Release #3770

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Aug 7, 2025
Merged

4.84.0 Release #3770

merged 15 commits into from
Aug 7, 2025

Conversation

Stream-SDK-Bot
Copy link
Collaborator

StreamChat

βœ… Added

  • Add pending messages support #3754
  • Add new lightweight LivestreamChannelController that improves performance for live chats #3750

🐞 Fixed

  • Fix ChatClient.currentUserId not removed instantly after calling logout() #3766

StreamChatUI

🐞 Fixed

  • Fix the height of the attachment view in the composer when using larger dynamic type 3762
  • Remove animation in message reactions when opening a sheet in the channel view #3763

Stream Bot and others added 12 commits July 29, 2025 10:39
…ogout()` (#3766)

* Fix `ChatClient.currentUserId` not removed instantly after calling `logout()`

* Update CHANGELOG.md
* Set FileAttachmentView's min height to default 54, but allow it to grow with dynamic type

* Update snapshot tests to take into account the correct sizing
* 1st WIP

* Handle more mapping

* Make message list diff kit to support updating from Array instead of LazyCollection

* Handle events in LivestreamChannelController

* fixup message list view

* Add reads and attachments

* Forward live stream events and don't save them into the DB

* Use currentUserId and channel from DB for now (Maybe implement caching later)

* Simplify model mapping

* Fix current user reactions

* Improve how event notification center knows when to do manually event handling

* Do WIP on reads

* Remove reads since it is not needed for live streams

* Add DemoLivestreamChannelVC to the DemoApp

* Remove unread stuff from LivestreamChannelController

* Add ChatLivestreamChannelVC to be able to test

* Handle message errors

* Fix regular controller not working after showing as livestream

* Fix sometimes messages disappearing from the view

* Quick jumps fix for Live Stream

* Fix some minor typos

* Move Payload to asModel() to seperate files

* Handling new messages while first page is not loaded

* Remove atomics

* Add API only message actions to the livestream controller

- deleteMessages
- loadReactins
- flag
- unflag
- addReaction
- deleteReaction
- pin
- unpin

* Add createNewMessage to `LivestreamChannelController`

* Remove markRead from livestream controller

* Load initial page from cache

* Add reaction groups and moderation details to Message Payload model mapping

* If event is not handled, fallback to middlewares

* Add Combine support for livestream controller

* Handle channel update events and make it easier to notify delegates

* Cache local channels when handling manual events

* Fix not loading older pages when in skip logic

* Add slow mode support to Livestream Controller

* Extract manual event handling logic to a ManualEventHandler

* Fix merge conflict

* CodeRabit review feedback changes

* Cleanuo livestream channel controller

* Cleanup model mapping

* Move livestream UI to the demo app

* Quick fix typo

* Handle pagination with willDisplayAt

* Log a warning instead of a error when a feature is disabled

* Do not use channel controller in the composer

* Fix message actions on livestream demo UI

* Fix minor warning

* Add  support for setting max number of messages in livestream controller

* Add a way to check how much messages were skipped when the controller was paused

* Add `isPause` publisher

* Disable the discarding of messages by default

* Reset the live stream channel controller when memory warning is received

* Fix attachments not working

* Explicitly disable commands

* Fix access control of livestream channel view

* Use reactions from livestream controller in the demo app livestream UI

* Display list of reaction authors when tapping the reactions in the message list

* Change the thread to utility in the Manual Event Handler

* Do not copy the current message everytime when doing in-memory message updates

* Improve doc of livestream channel controller message capping

* Print whenever the livestream messages are updated

* Only count skipped messages if enabled

* Make the completion blocks and delegates as main actors

* Fix loadReactions completion not in the MainActor

* Fix thread-safeness when fetching cached channel in manual event handler

* Remove cooldown protections

* Fix creating a new message not resuming the controller

* Save the channel to the DB on the first page fetch

* Remove unnecessary isBounce in live reactions view

* Add loadPinnedMessage to livestream controller

* Handle channel updates through the DB

* Update CHANGELOG.md

* Fix existing tests

* Remove ChannelDetailPayload as model since it is not used

* Fix tests related to pending messages

* Add test coverage to user payload model conversion

* Add test coverage to message payload model conversion

* Add test coverage to channel payload model conversion

* Add missing tests to disable slow mode

* Add test coverage to LivestreamChannelController

* Fix UI Tests not compiling

* Add combine test coverage

* Add memory warning test coverage

* Add missing test coverage to the event notification centre

* Add test coverage to ManualEventHandler
@Stream-SDK-Bot Stream-SDK-Bot requested a review from a team as a code owner August 6, 2025 10:04
Copy link

coderabbitai bot commented Aug 6, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

✨ Finishing Touches
πŸ§ͺ Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch release/4.84.0

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❀️ Share
πŸͺ§ Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

github-actions bot commented Aug 6, 2025

Build for regression testing β„–123457082 has been uploaded to TestFlight 🎁

@Stream-SDK-Bot
Copy link
Collaborator Author

SDK Performance

target metric benchmark branch performance status
MessageList Hitches total duration 10 ms 28.37 ms -183.7% πŸ”½ πŸ”΄
Duration 2.6 s 2.55 s 1.92% πŸ”Ό 🟒
Hitch time ratio 4 ms per s 11.13 ms per s -178.25% πŸ”½ πŸ”΄
Frame rate 75 fps 78.94 fps 5.25% πŸ”Ό 🟒
Number of hitches 1 2.0 -100.0% πŸ”½ πŸ”΄

Copy link

github-actions bot commented Aug 6, 2025

1 Warning
⚠️ Big PR

Generated by 🚫 Danger

Copy link

github-actions bot commented Aug 6, 2025

Public Interface

+ public extension LivestreamChannelControllerDelegate

+ extension LivestreamChannelController  
+ 
+   public var channelChangePublisher: AnyPublisher<ChatChannel?, Never>
+   public var messagesChangesPublisher: AnyPublisher<[ChatMessage], Never>
+   public var isPausedPublisher: AnyPublisher<Bool, Never>
+   public var skippedMessagesAmountPublisher: AnyPublisher<Int, Never>

+ public extension ChatMessageListVC

+ @MainActor public protocol LivestreamChannelControllerDelegate: AnyObject

+ public class LivestreamChannelController: DataStoreProvider, EventsControllerDelegate, AppStateObserverDelegate  
+ 
+   public private var channelQuery: ChannelQuery
+   public var cid: ChannelId?
+   public let client: ChatClient
+   public private var channel: ChatChannel?
+   public private var messages: [ChatMessage]
+   public private var isPaused: Bool
+   public private var skippedMessagesAmount: Int
+   public var hasLoadedAllPreviousMessages: Bool
+   public var hasLoadedAllNextMessages: Bool
+   public var isLoadingPreviousMessages: Bool
+   public var isLoadingNextMessages: Bool
+   public var isLoadingMiddleMessages: Bool
+   public var isJumpingToMessage: Bool
+   public var loadInitialMessagesFromCache: Bool
+   public var countSkippedMessagesWhenPaused: Bool
+   public var maxMessageLimitOptions: MaxMessageLimitOptions?
+   public var delegate: LivestreamChannelControllerDelegate?
+   
+ 
+   public func synchronize(_ completion: (@MainActor(_ error: Error?) -> Void)? = nil)
+   public func loadPreviousMessages(before messageId: MessageId? = nil,limit: Int? = nil,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func loadNextMessages(after messageId: MessageId? = nil,limit: Int? = nil,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func loadPageAroundMessageId(_ messageId: MessageId,limit: Int? = nil,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func loadFirstPage(_ completion: (@MainActor(_ error: Error?) -> Void)? = nil)
+   public func createNewMessage(messageId: MessageId? = nil,text: String,pinning: MessagePinning? = nil,isSilent: Bool = false,attachments: [AnyAttachmentPayload] = [],mentionedUserIds: [UserId] = [],quotedMessageId: MessageId? = nil,skipPush: Bool = false,skipEnrichUrl: Bool = false,restrictedVisibility: [UserId] = [],location: NewLocationInfo? = nil,extraData: [String: RawJSON] = [:],completion: (@MainActor(Result<MessageId, Error>) -> Void)? = nil)
+   public func deleteMessage(messageId: MessageId,hard: Bool = false,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func loadReactions(for messageId: MessageId,limit: Int = 25,offset: Int = 0,completion: @escaping @MainActor(Result<[ChatMessageReaction], Error>) -> Void)
+   public func flag(messageId: MessageId,reason: String? = nil,extraData: [String: RawJSON]? = nil,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func unflag(messageId: MessageId,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func addReaction(_ type: MessageReactionType,to messageId: MessageId,score: Int = 1,enforceUnique: Bool = false,skipPush: Bool = false,pushEmojiCode: String? = nil,extraData: [String: RawJSON] = [:],completion: (@MainActor(Error?) -> Void)? = nil)
+   public func deleteReaction(_ type: MessageReactionType,from messageId: MessageId,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func pin(messageId: MessageId,pinning: MessagePinning = .noExpiration,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func unpin(messageId: MessageId,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func loadPinnedMessages(pageSize: Int = .messagesPageSize,sorting: [Sorting<PinnedMessagesSortingKey>] = [],pagination: PinnedMessagesPagination? = nil,completion: @escaping @MainActor(Result<[ChatMessage], Error>) -> Void)
+   public func currentCooldownTime()-> Int
+   public func enableSlowMode(cooldownDuration: Int,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func disableSlowMode(completion: (@MainActor(Error?) -> Void)? = nil)
+   public func pause()
+   public func resume()
+   public func eventsController(_ controller: EventsController,didReceiveEvent event: Event)
+   public func applicationDidReceiveMemoryWarning()

+ extension AppStateObserverDelegate  
+ 
+   public func applicationDidMoveToBackground()
+   public func applicationDidMoveToForeground()
+   public func applicationDidReceiveMemoryWarning()

+ public struct MaxMessageLimitOptions  
+ 
+   public let maxLimit: Int
+   public let discardAmount: Int
+   public static let recommended
+   
+ 
+   public init(maxLimit: Int = 200,discardAmount: Int = 50)



- public struct NewMessagePendingEvent: Event  
+ public struct NewMessagePendingEvent: ChannelSpecificEvent  
+   public var cid: ChannelId

 public struct ChatMessage  
-   public func changing(text: String? = nil,type: MessageType? = nil,state: LocalMessageState? = nil,command: String? = nil,arguments: String? = nil,attachments: [AnyChatMessageAttachment]? = nil,translations: [TranslationLanguage: String]? = nil,originalLanguage: TranslationLanguage? = nil,moderationDetails: MessageModerationDetails? = nil,extraData: [String: RawJSON]? = nil)-> ChatMessage
+   public func changing(text: String? = nil,type: MessageType? = nil,state: LocalMessageState? = nil,command: String? = nil,arguments: String? = nil,attachments: [AnyChatMessageAttachment]? = nil,translations: [TranslationLanguage: String]? = nil,originalLanguage: TranslationLanguage? = nil,moderationDetails: MessageModerationDetails? = nil,readBy: Set<ChatUser>? = nil,extraData: [String: RawJSON]? = nil)-> ChatMessage

- public struct ChatMessageReactionData  
+ public struct ChatMessageReactionData: Equatable  

- public struct NewMessageErrorEvent: Event  
+ public struct NewMessageErrorEvent: ChannelSpecificEvent  
-   public let error: Error
+   public let cid: ChannelId
+   public let error: Error

 public struct ChatChannel  
-   public let reads: [ChatChannelRead]
+   public let pendingMessages: [ChatMessage]
-   public let muteDetails: MuteDetails?
+   public let reads: [ChatChannelRead]
-   public var isMuted: Bool
+   public let muteDetails: MuteDetails?
-   public let cooldownDuration: Int
+   public var isMuted: Bool
-   public let extraData: [String: RawJSON]
+   public let cooldownDuration: Int
-   public let previewMessage: ChatMessage?
+   public let extraData: [String: RawJSON]
-   public let draftMessage: DraftMessage?
+   public let previewMessage: ChatMessage?
-   public let activeLiveLocations: [SharedLocation]
+   public let draftMessage: DraftMessage?
-   
+   public let activeLiveLocations: [SharedLocation]
- 
+   
-   public func replacing(name: String?,imageURL: URL?,extraData: [String: RawJSON]?)-> ChatChannel
+ 
+   public func replacing(name: String?,imageURL: URL?,extraData: [String: RawJSON]?)-> ChatChannel
+   public func changing(name: String? = nil,imageURL: URL? = nil,reads: [ChatChannelRead]? = nil,extraData: [String: RawJSON]? = nil)-> ChatChannel

 open class ScrollToBottomButton: _Button, ThemeProvider  
-   open private lazy var unreadCountView: ChatMessageListUnreadCountView
+   public var content: ChannelUnreadCount
-   
+   open private lazy var unreadCountView: ChatMessageListUnreadCountView
- 
+   
-   override open func layoutSubviews()
+ 
-   override open func setUpAppearance()
+   override open func layoutSubviews()
-   override open func setUpLayout()
+   override open func setUpAppearance()
-   override open func updateContent()
+   override open func setUpLayout()
+   override open func updateContent()

@Stream-SDK-Bot
Copy link
Collaborator Author

SDK Size

title previous release current release diff status
StreamChat 7.92 MB 8.04 MB +125 KB 🟒
StreamChatUI 4.84 MB 4.86 MB +17 KB 🟒

@Stream-SDK-Bot
Copy link
Collaborator Author

SDK Performance

target metric benchmark branch performance status
MessageList Hitches total duration 10 ms 23.36 ms -133.6% πŸ”½ πŸ”΄
Duration 2.6 s 2.55 s 1.92% πŸ”Ό 🟒
Hitch time ratio 4 ms per s 9.18 ms per s -129.5% πŸ”½ πŸ”΄
Frame rate 75 fps 78.86 fps 5.15% πŸ”Ό 🟒
Number of hitches 1 1.6 -60.0% πŸ”½ πŸ”΄

@Stream-SDK-Bot
Copy link
Collaborator Author

Stream-SDK-Bot commented Aug 6, 2025

SDK Size

title previous release current release diff status
StreamChat 8.04 MB 8.04 MB 0 KB 🟒
StreamChatUI 4.86 MB 4.86 MB 0 KB 🟒

Copy link

github-actions bot commented Aug 6, 2025

Build for regression testing β„–123457083 has been uploaded to TestFlight 🎁

Copy link

github-actions bot commented Aug 6, 2025

Public Interface

+ extension LivestreamChannelController  
+ 
+   public var channelChangePublisher: AnyPublisher<ChatChannel?, Never>
+   public var messagesChangesPublisher: AnyPublisher<[ChatMessage], Never>
+   public var isPausedPublisher: AnyPublisher<Bool, Never>
+   public var skippedMessagesAmountPublisher: AnyPublisher<Int, Never>

+ extension AppStateObserverDelegate  
+ 
+   public func applicationDidMoveToBackground()
+   public func applicationDidMoveToForeground()
+   public func applicationDidReceiveMemoryWarning()

+ public class LivestreamChannelController: DataStoreProvider, EventsControllerDelegate, AppStateObserverDelegate  
+ 
+   public private var channelQuery: ChannelQuery
+   public var cid: ChannelId?
+   public let client: ChatClient
+   public private var channel: ChatChannel?
+   public private var messages: [ChatMessage]
+   public private var isPaused: Bool
+   public private var skippedMessagesAmount: Int
+   public var hasLoadedAllPreviousMessages: Bool
+   public var hasLoadedAllNextMessages: Bool
+   public var isLoadingPreviousMessages: Bool
+   public var isLoadingNextMessages: Bool
+   public var isLoadingMiddleMessages: Bool
+   public var isJumpingToMessage: Bool
+   public var loadInitialMessagesFromCache: Bool
+   public var countSkippedMessagesWhenPaused: Bool
+   public var maxMessageLimitOptions: MaxMessageLimitOptions?
+   public var delegate: LivestreamChannelControllerDelegate?
+   
+ 
+   public func synchronize(_ completion: (@MainActor(_ error: Error?) -> Void)? = nil)
+   public func loadPreviousMessages(before messageId: MessageId? = nil,limit: Int? = nil,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func loadNextMessages(after messageId: MessageId? = nil,limit: Int? = nil,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func loadPageAroundMessageId(_ messageId: MessageId,limit: Int? = nil,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func loadFirstPage(_ completion: (@MainActor(_ error: Error?) -> Void)? = nil)
+   public func createNewMessage(messageId: MessageId? = nil,text: String,pinning: MessagePinning? = nil,isSilent: Bool = false,attachments: [AnyAttachmentPayload] = [],mentionedUserIds: [UserId] = [],quotedMessageId: MessageId? = nil,skipPush: Bool = false,skipEnrichUrl: Bool = false,restrictedVisibility: [UserId] = [],location: NewLocationInfo? = nil,extraData: [String: RawJSON] = [:],completion: (@MainActor(Result<MessageId, Error>) -> Void)? = nil)
+   public func deleteMessage(messageId: MessageId,hard: Bool = false,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func loadReactions(for messageId: MessageId,limit: Int = 25,offset: Int = 0,completion: @escaping @MainActor(Result<[ChatMessageReaction], Error>) -> Void)
+   public func flag(messageId: MessageId,reason: String? = nil,extraData: [String: RawJSON]? = nil,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func unflag(messageId: MessageId,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func addReaction(_ type: MessageReactionType,to messageId: MessageId,score: Int = 1,enforceUnique: Bool = false,skipPush: Bool = false,pushEmojiCode: String? = nil,extraData: [String: RawJSON] = [:],completion: (@MainActor(Error?) -> Void)? = nil)
+   public func deleteReaction(_ type: MessageReactionType,from messageId: MessageId,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func pin(messageId: MessageId,pinning: MessagePinning = .noExpiration,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func unpin(messageId: MessageId,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func loadPinnedMessages(pageSize: Int = .messagesPageSize,sorting: [Sorting<PinnedMessagesSortingKey>] = [],pagination: PinnedMessagesPagination? = nil,completion: @escaping @MainActor(Result<[ChatMessage], Error>) -> Void)
+   public func currentCooldownTime()-> Int
+   public func enableSlowMode(cooldownDuration: Int,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func disableSlowMode(completion: (@MainActor(Error?) -> Void)? = nil)
+   public func pause()
+   public func resume()
+   public func eventsController(_ controller: EventsController,didReceiveEvent event: Event)
+   public func applicationDidReceiveMemoryWarning()

+ public struct MaxMessageLimitOptions  
+ 
+   public let maxLimit: Int
+   public let discardAmount: Int
+   public static let recommended
+   
+ 
+   public init(maxLimit: Int = 200,discardAmount: Int = 50)

+ @MainActor public protocol LivestreamChannelControllerDelegate: AnyObject

+ public extension LivestreamChannelControllerDelegate

+ public extension ChatMessageListVC



- public struct NewMessagePendingEvent: Event  
+ public struct NewMessagePendingEvent: ChannelSpecificEvent  
+   public var cid: ChannelId

 public struct ChatMessage  
-   public func changing(text: String? = nil,type: MessageType? = nil,state: LocalMessageState? = nil,command: String? = nil,arguments: String? = nil,attachments: [AnyChatMessageAttachment]? = nil,translations: [TranslationLanguage: String]? = nil,originalLanguage: TranslationLanguage? = nil,moderationDetails: MessageModerationDetails? = nil,extraData: [String: RawJSON]? = nil)-> ChatMessage
+   public func changing(text: String? = nil,type: MessageType? = nil,state: LocalMessageState? = nil,command: String? = nil,arguments: String? = nil,attachments: [AnyChatMessageAttachment]? = nil,translations: [TranslationLanguage: String]? = nil,originalLanguage: TranslationLanguage? = nil,moderationDetails: MessageModerationDetails? = nil,readBy: Set<ChatUser>? = nil,extraData: [String: RawJSON]? = nil)-> ChatMessage

 open class ScrollToBottomButton: _Button, ThemeProvider  
-   open private lazy var unreadCountView: ChatMessageListUnreadCountView
+   public var content: ChannelUnreadCount
-   
+   open private lazy var unreadCountView: ChatMessageListUnreadCountView
- 
+   
-   override open func layoutSubviews()
+ 
-   override open func setUpAppearance()
+   override open func layoutSubviews()
-   override open func setUpLayout()
+   override open func setUpAppearance()
-   override open func updateContent()
+   override open func setUpLayout()
+   override open func updateContent()

- public struct NewMessageErrorEvent: Event  
+ public struct NewMessageErrorEvent: ChannelSpecificEvent  
-   public let error: Error
+   public let cid: ChannelId
+   public let error: Error

 public struct ChatChannel  
-   public let reads: [ChatChannelRead]
+   public let pendingMessages: [ChatMessage]
-   public let muteDetails: MuteDetails?
+   public let reads: [ChatChannelRead]
-   public var isMuted: Bool
+   public let muteDetails: MuteDetails?
-   public let cooldownDuration: Int
+   public var isMuted: Bool
-   public let extraData: [String: RawJSON]
+   public let cooldownDuration: Int
-   public let previewMessage: ChatMessage?
+   public let extraData: [String: RawJSON]
-   public let draftMessage: DraftMessage?
+   public let previewMessage: ChatMessage?
-   public let activeLiveLocations: [SharedLocation]
+   public let draftMessage: DraftMessage?
-   
+   public let activeLiveLocations: [SharedLocation]
- 
+   
-   public func replacing(name: String?,imageURL: URL?,extraData: [String: RawJSON]?)-> ChatChannel
+ 
+   public func replacing(name: String?,imageURL: URL?,extraData: [String: RawJSON]?)-> ChatChannel
+   public func changing(name: String? = nil,imageURL: URL? = nil,reads: [ChatChannelRead]? = nil,extraData: [String: RawJSON]? = nil)-> ChatChannel

- public struct ChatMessageReactionData  
+ public struct ChatMessageReactionData: Equatable  

Copy link

github-actions bot commented Aug 6, 2025

Build for regression testing β„–123457084 has been uploaded to TestFlight 🎁

* Fix video player not playing when GalleryVC is opened

* Update CHANGELOG.md

* Fix swift format
Copy link

github-actions bot commented Aug 6, 2025

Public Interface

+ extension LivestreamChannelController  
+ 
+   public var channelChangePublisher: AnyPublisher<ChatChannel?, Never>
+   public var messagesChangesPublisher: AnyPublisher<[ChatMessage], Never>
+   public var isPausedPublisher: AnyPublisher<Bool, Never>
+   public var skippedMessagesAmountPublisher: AnyPublisher<Int, Never>

+ public struct MaxMessageLimitOptions  
+ 
+   public let maxLimit: Int
+   public let discardAmount: Int
+   public static let recommended
+   
+ 
+   public init(maxLimit: Int = 200,discardAmount: Int = 50)

+ extension AppStateObserverDelegate  
+ 
+   public func applicationDidMoveToBackground()
+   public func applicationDidMoveToForeground()
+   public func applicationDidReceiveMemoryWarning()

+ public extension LivestreamChannelControllerDelegate

+ public class LivestreamChannelController: DataStoreProvider, EventsControllerDelegate, AppStateObserverDelegate  
+ 
+   public private var channelQuery: ChannelQuery
+   public var cid: ChannelId?
+   public let client: ChatClient
+   public private var channel: ChatChannel?
+   public private var messages: [ChatMessage]
+   public private var isPaused: Bool
+   public private var skippedMessagesAmount: Int
+   public var hasLoadedAllPreviousMessages: Bool
+   public var hasLoadedAllNextMessages: Bool
+   public var isLoadingPreviousMessages: Bool
+   public var isLoadingNextMessages: Bool
+   public var isLoadingMiddleMessages: Bool
+   public var isJumpingToMessage: Bool
+   public var loadInitialMessagesFromCache: Bool
+   public var countSkippedMessagesWhenPaused: Bool
+   public var maxMessageLimitOptions: MaxMessageLimitOptions?
+   public var delegate: LivestreamChannelControllerDelegate?
+   
+ 
+   public func synchronize(_ completion: (@MainActor(_ error: Error?) -> Void)? = nil)
+   public func loadPreviousMessages(before messageId: MessageId? = nil,limit: Int? = nil,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func loadNextMessages(after messageId: MessageId? = nil,limit: Int? = nil,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func loadPageAroundMessageId(_ messageId: MessageId,limit: Int? = nil,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func loadFirstPage(_ completion: (@MainActor(_ error: Error?) -> Void)? = nil)
+   public func createNewMessage(messageId: MessageId? = nil,text: String,pinning: MessagePinning? = nil,isSilent: Bool = false,attachments: [AnyAttachmentPayload] = [],mentionedUserIds: [UserId] = [],quotedMessageId: MessageId? = nil,skipPush: Bool = false,skipEnrichUrl: Bool = false,restrictedVisibility: [UserId] = [],location: NewLocationInfo? = nil,extraData: [String: RawJSON] = [:],completion: (@MainActor(Result<MessageId, Error>) -> Void)? = nil)
+   public func deleteMessage(messageId: MessageId,hard: Bool = false,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func loadReactions(for messageId: MessageId,limit: Int = 25,offset: Int = 0,completion: @escaping @MainActor(Result<[ChatMessageReaction], Error>) -> Void)
+   public func flag(messageId: MessageId,reason: String? = nil,extraData: [String: RawJSON]? = nil,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func unflag(messageId: MessageId,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func addReaction(_ type: MessageReactionType,to messageId: MessageId,score: Int = 1,enforceUnique: Bool = false,skipPush: Bool = false,pushEmojiCode: String? = nil,extraData: [String: RawJSON] = [:],completion: (@MainActor(Error?) -> Void)? = nil)
+   public func deleteReaction(_ type: MessageReactionType,from messageId: MessageId,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func pin(messageId: MessageId,pinning: MessagePinning = .noExpiration,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func unpin(messageId: MessageId,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func loadPinnedMessages(pageSize: Int = .messagesPageSize,sorting: [Sorting<PinnedMessagesSortingKey>] = [],pagination: PinnedMessagesPagination? = nil,completion: @escaping @MainActor(Result<[ChatMessage], Error>) -> Void)
+   public func currentCooldownTime()-> Int
+   public func enableSlowMode(cooldownDuration: Int,completion: (@MainActor(Error?) -> Void)? = nil)
+   public func disableSlowMode(completion: (@MainActor(Error?) -> Void)? = nil)
+   public func pause()
+   public func resume()
+   public func eventsController(_ controller: EventsController,didReceiveEvent event: Event)
+   public func applicationDidReceiveMemoryWarning()

+ @MainActor public protocol LivestreamChannelControllerDelegate: AnyObject

+ public extension ChatMessageListVC



- public struct NewMessagePendingEvent: Event  
+ public struct NewMessagePendingEvent: ChannelSpecificEvent  
+   public var cid: ChannelId

 public struct ChatChannel  
-   public let reads: [ChatChannelRead]
+   public let pendingMessages: [ChatMessage]
-   public let muteDetails: MuteDetails?
+   public let reads: [ChatChannelRead]
-   public var isMuted: Bool
+   public let muteDetails: MuteDetails?
-   public let cooldownDuration: Int
+   public var isMuted: Bool
-   public let extraData: [String: RawJSON]
+   public let cooldownDuration: Int
-   public let previewMessage: ChatMessage?
+   public let extraData: [String: RawJSON]
-   public let draftMessage: DraftMessage?
+   public let previewMessage: ChatMessage?
-   public let activeLiveLocations: [SharedLocation]
+   public let draftMessage: DraftMessage?
-   
+   public let activeLiveLocations: [SharedLocation]
- 
+   
-   public func replacing(name: String?,imageURL: URL?,extraData: [String: RawJSON]?)-> ChatChannel
+ 
+   public func replacing(name: String?,imageURL: URL?,extraData: [String: RawJSON]?)-> ChatChannel
+   public func changing(name: String? = nil,imageURL: URL? = nil,reads: [ChatChannelRead]? = nil,extraData: [String: RawJSON]? = nil)-> ChatChannel

 open class ScrollToBottomButton: _Button, ThemeProvider  
-   open private lazy var unreadCountView: ChatMessageListUnreadCountView
+   public var content: ChannelUnreadCount
-   
+   open private lazy var unreadCountView: ChatMessageListUnreadCountView
- 
+   
-   override open func layoutSubviews()
+ 
-   override open func setUpAppearance()
+   override open func layoutSubviews()
-   override open func setUpLayout()
+   override open func setUpAppearance()
-   override open func updateContent()
+   override open func setUpLayout()
+   override open func updateContent()

- public struct NewMessageErrorEvent: Event  
+ public struct NewMessageErrorEvent: ChannelSpecificEvent  
-   public let error: Error
+   public let cid: ChannelId
+   public let error: Error

- public struct ChatMessageReactionData  
+ public struct ChatMessageReactionData: Equatable  

 public struct ChatMessage  
-   public func changing(text: String? = nil,type: MessageType? = nil,state: LocalMessageState? = nil,command: String? = nil,arguments: String? = nil,attachments: [AnyChatMessageAttachment]? = nil,translations: [TranslationLanguage: String]? = nil,originalLanguage: TranslationLanguage? = nil,moderationDetails: MessageModerationDetails? = nil,extraData: [String: RawJSON]? = nil)-> ChatMessage
+   public func changing(text: String? = nil,type: MessageType? = nil,state: LocalMessageState? = nil,command: String? = nil,arguments: String? = nil,attachments: [AnyChatMessageAttachment]? = nil,translations: [TranslationLanguage: String]? = nil,originalLanguage: TranslationLanguage? = nil,moderationDetails: MessageModerationDetails? = nil,readBy: Set<ChatUser>? = nil,extraData: [String: RawJSON]? = nil)-> ChatMessage

Copy link

github-actions bot commented Aug 6, 2025

Build for regression testing β„–123457085 has been uploaded to TestFlight 🎁

Copy link

sonarqubecloud bot commented Aug 6, 2025

@testableapple
Copy link
Contributor

/merge release

@testableapple
Copy link
Contributor

Publication of the release has been launched πŸ‘

@github-actions github-actions bot merged commit 487d3d2 into main Aug 7, 2025
15 checks passed
@github-actions github-actions bot deleted the release/4.84.0 branch August 7, 2025 10:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants