diff --git a/Examples/YouTubeClone/ChatClient.swift b/Examples/YouTubeClone/ChatClient.swift index daf31f05d4d..54020dc7c4e 100644 --- a/Examples/YouTubeClone/ChatClient.swift +++ b/Examples/YouTubeClone/ChatClient.swift @@ -18,7 +18,7 @@ extension ChatClient { components.messageListVC = YTLiveChatMessageListViewController.self components.messageComposerVC = YTChatComposerViewController.self components.messageComposerView = YTChatMessageComposerView.self - components.scrollToLatestMessageButton = YTScrollToLatestMessageButton.self + components.scrollToBottomButton = YTScrollToLatestMessageButton.self components.sendButton = YTSendButton.self components.inputMessageView = YTInputChatMessageView.self diff --git a/Examples/YouTubeClone/ScrollToLatestMessageButton/YTScrollToLatestMessageButton.swift b/Examples/YouTubeClone/ScrollToLatestMessageButton/YTScrollToLatestMessageButton.swift index f1dc08aedd5..fd2b6a53e36 100644 --- a/Examples/YouTubeClone/ScrollToLatestMessageButton/YTScrollToLatestMessageButton.swift +++ b/Examples/YouTubeClone/ScrollToLatestMessageButton/YTScrollToLatestMessageButton.swift @@ -7,7 +7,7 @@ import StreamChatUI import UIKit /// A button which appears at the bottom of the chat list when the user is not viewing the latest messages. Tapping on this button scrolls to the latest messages. -final class YTScrollToLatestMessageButton: ScrollToLatestMessageButton { +final class YTScrollToLatestMessageButton: ScrollToBottomButton { override func setUpAppearance() { // Customise the appearance to make it look like the YouTube scroll to bottom button tintColor = .white diff --git a/Examples/YouTubeClone/YTLiveChatViewController.swift b/Examples/YouTubeClone/YTLiveChatViewController.swift index ff2154c15cf..e553afe0bad 100644 --- a/Examples/YouTubeClone/YTLiveChatViewController.swift +++ b/Examples/YouTubeClone/YTLiveChatViewController.swift @@ -24,9 +24,9 @@ final class YTLiveChatMessageListViewController: ChatMessageListVC { override func setUpLayout() { super.setUpLayout() NSLayoutConstraint.activate([ - scrollToLatestMessageButton.centerXAnchor.constraint(equalTo: view.layoutMarginsGuide.centerXAnchor), - scrollToLatestMessageButton.widthAnchor.constraint(equalToConstant: 30), - scrollToLatestMessageButton.heightAnchor.constraint(equalToConstant: 30) + scrollToBottomButton.centerXAnchor.constraint(equalTo: view.layoutMarginsGuide.centerXAnchor), + scrollToBottomButton.widthAnchor.constraint(equalToConstant: 30), + scrollToBottomButton.heightAnchor.constraint(equalToConstant: 30) ]) dateOverlayView.removeFromSuperview() diff --git a/Sources/StreamChat/APIClient/Endpoints/Payloads/RawJSON.swift b/Sources/StreamChat/APIClient/Endpoints/Payloads/RawJSON.swift index af77a2f7c91..fe7a8e9136c 100644 --- a/Sources/StreamChat/APIClient/Endpoints/Payloads/RawJSON.swift +++ b/Sources/StreamChat/APIClient/Endpoints/Payloads/RawJSON.swift @@ -337,14 +337,3 @@ extension RawJSON { } } } - -// MARK: Deprecations - -public extension RawJSON { - @available(*, deprecated, message: "dictionaryValue property should be used instead.") - func dictionary(with value: RawJSON?, forKey key: String) -> RawJSON? { - guard case var .dictionary(content) = self else { return nil } - content[key] = value - return .dictionary(content) - } -} diff --git a/Sources/StreamChat/ChatClient.swift b/Sources/StreamChat/ChatClient.swift index 3691a3318ee..11a170f8db8 100644 --- a/Sources/StreamChat/ChatClient.swift +++ b/Sources/StreamChat/ChatClient.swift @@ -477,13 +477,6 @@ public class ChatClient: @unchecked Sendable { authenticationRepository.setToken(token: token, completeTokenWaiters: true) } - /// Disconnects the chat client from the chat servers. No further updates from the servers - /// are received. - @available(*, deprecated, message: "Use the asynchronous version of `disconnect` for increased safety") - public func disconnect() { - disconnect {} - } - /// Disconnects the chat client from the chat servers. No further updates from the servers /// are received. public func disconnect(completion: @escaping @MainActor() -> Void) { @@ -506,12 +499,6 @@ public class ChatClient: @unchecked Sendable { } } } - - /// Disconnects the chat client from the chat servers and removes all the local data related. - @available(*, deprecated, message: "Use the asynchronous version of `logout` for increased safety") - public func logout() { - logout {} - } /// Disconnects the chat client from the chat servers and removes all the local data related. /// - Parameters: diff --git a/Sources/StreamChat/Config/ChatClientConfig.swift b/Sources/StreamChat/Config/ChatClientConfig.swift index 49f97f81d48..7443dc6f44b 100644 --- a/Sources/StreamChat/Config/ChatClientConfig.swift +++ b/Sources/StreamChat/Config/ChatClientConfig.swift @@ -81,20 +81,6 @@ public struct ChatClientConfig: Sendable { /// **Warning**: There should be at max 1 active client at the same time, else it can lead to undefined behavior. public var isClientInActiveMode: Bool - /// If set to `true` the `ChatClient` will automatically establish a web-socket - /// connection to listen to the updates when `refreshToken` is called. - /// - /// If set to `false` the connection won't be established automatically - /// but has to be initiated manually by calling `connect`. - /// - /// Is `true` by default. - @available( - *, - deprecated, - message: "This flag has no effect anymore. The flow for setting and for connecting the user has been unified to the `connectUser` set of methods." - ) - public var shouldConnectAutomatically = true - /// If set to `true`, the `ChatClient` will try to stay connected while app is backgrounded. /// If set to `false`, websocket disconnects immediately when app is backgrounded. /// diff --git a/Sources/StreamChat/Config/Token.swift b/Sources/StreamChat/Config/Token.swift index 11c797c9d92..29a429beb3a 100644 --- a/Sources/StreamChat/Config/Token.swift +++ b/Sources/StreamChat/Config/Token.swift @@ -10,16 +10,6 @@ public struct Token: Decodable, Equatable, ExpressibleByStringLiteral, Sendable public let userId: UserId public let expiration: Date? - @available( - *, - deprecated, - - message: "It is not a good practice to check expiration client side since the user can change the device's time." - ) - public var isExpired: Bool { - expiration.map { $0 < Date() } ?? false - } - /// Created a new `Token` instance. /// - Parameter value: The JWT string value. It must be in valid format and contain `user_id` in payload. public init(stringLiteral value: StringLiteralType) { diff --git a/Sources/StreamChat/Controllers/ChannelController/ChannelController.swift b/Sources/StreamChat/Controllers/ChannelController/ChannelController.swift index fcf4e8948f6..0f2568a3021 100644 --- a/Sources/StreamChat/Controllers/ChannelController/ChannelController.swift +++ b/Sources/StreamChat/Controllers/ChannelController/ChannelController.swift @@ -2101,80 +2101,6 @@ extension ClientError { final class ChannelFeatureDisabled: ClientError, @unchecked Sendable {} } -// MARK: - Deprecations - -public extension ChatChannelController { - /// Indicates whether the channel has typing events enabled. - @available(*, deprecated, message: "`channel.canSendTypingEvents` should be used instead.") - var areTypingEventsEnabled: Bool { - channel?.canSendTypingEvents == true - } - - /// Indicates whether the channel has reactions enabled. - @available(*, deprecated, message: "`channel.canSendReaction` should be used instead.") - var areReactionsEnabled: Bool { - channel?.canSendReaction == true - } - - /// Indicates whether the channel has replies enabled. - @available(*, deprecated, message: "`channel.canSendReply` should be used instead.") - var areRepliesEnabled: Bool { - channel?.canSendReply == true - } - - /// Indicates whether the channel has quotes enabled. - @available(*, deprecated, message: "`channel.canQuoteMessage` should be used instead.") - var areQuotesEnabled: Bool { - channel?.canQuoteMessage == true - } - - /// Indicates whether the channel has read events enabled. - @available(*, deprecated, message: "`channel.canReceiveReadEvents` should be used instead.") - var areReadEventsEnabled: Bool { - channel?.canReceiveReadEvents == true - } - - /// Indicates whether the channel supports uploading files/images. - @available(*, deprecated, message: "`channel.canUploadFile should be used instead.") - var areUploadsEnabled: Bool { - channel?.canUploadFile == true - } -} - -public extension ChatChannelController { - /// Uploads the given file to CDN and returns the file URL. - /// - Parameters: - /// - localFileURL: Local URL of the file. - /// - progress: Upload progress callback - /// - completion: Completion to be called when upload finishes, or errors. - @available(*, deprecated, message: "use uploadAttachment() instead.") - func uploadFile( - localFileURL: URL, - progress: (@Sendable(Double) -> Void)? = nil, - completion: @escaping @MainActor(Result) -> Void - ) { - uploadAttachment(localFileURL: localFileURL, type: .file, progress: progress) { result in - completion(result.map(\.remoteURL)) - } - } - - /// Uploads the given image to CDN and returns the file URL. - /// - Parameters: - /// - localFileURL: Local URL of the image. - /// - progress: Upload progress callback - /// - completion: Completion to be called when upload finishes, or errors. - @available(*, deprecated, message: "use uploadAttachment() instead.") - func uploadImage( - localFileURL: URL, - progress: (@Sendable(Double) -> Void)? = nil, - completion: @escaping @MainActor(Result) -> Void - ) { - uploadAttachment(localFileURL: localFileURL, type: .image, progress: progress) { result in - completion(result.map(\.remoteURL)) - } - } -} - public extension ChatChannel { func lastReadMessageId(userId: UserId) -> MessageId? { guard let currentUserRead = reads.first(where: { diff --git a/Sources/StreamChat/Controllers/ChannelListController/ChannelListController.swift b/Sources/StreamChat/Controllers/ChannelListController/ChannelListController.swift index e59a52db62d..f40f60b24c6 100644 --- a/Sources/StreamChat/Controllers/ChannelListController/ChannelListController.swift +++ b/Sources/StreamChat/Controllers/ChannelListController/ChannelListController.swift @@ -189,15 +189,6 @@ public class ChatChannelListController: DataController, DelegateCallable, DataSt } } - @available(*, deprecated, message: "Please use `markAllRead` available in `CurrentChatUserController`") - public func markAllRead(completion: (@MainActor(Error?) -> Void)? = nil) { - worker.markAllRead { error in - self.callback { - completion?(error) - } - } - } - // MARK: - Internal func refreshLoadedChannels(completion: @escaping @Sendable(Result, Error>) -> Void) { diff --git a/Sources/StreamChat/Controllers/CurrentUserController/CurrentUserController.swift b/Sources/StreamChat/Controllers/CurrentUserController/CurrentUserController.swift index c13037d873f..bfe430acc84 100644 --- a/Sources/StreamChat/Controllers/CurrentUserController/CurrentUserController.swift +++ b/Sources/StreamChat/Controllers/CurrentUserController/CurrentUserController.swift @@ -754,16 +754,3 @@ public extension CurrentChatUserController { set { multicastDelegate.set(mainDelegate: newValue) } } } - -// MARK: - Deprecations - -public extension CurrentChatUserController { - @available( - *, - deprecated, - message: "use addDevice(_pushDevice:) instead. This deprecated function doesn't correctly support multiple push providers." - ) - func addDevice(token: Data, pushProvider: PushProvider = .apn, completion: (@Sendable(Error?) -> Void)? = nil) { - addDevice(.apn(token: token), completion: completion) - } -} diff --git a/Sources/StreamChat/Controllers/SearchControllers/UserSearchController/UserSearchController.swift b/Sources/StreamChat/Controllers/SearchControllers/UserSearchController/UserSearchController.swift index dfdaf77d23a..b9d9b74e994 100644 --- a/Sources/StreamChat/Controllers/SearchControllers/UserSearchController/UserSearchController.swift +++ b/Sources/StreamChat/Controllers/SearchControllers/UserSearchController/UserSearchController.swift @@ -34,11 +34,6 @@ public class ChatUserSearchController: DataController, DelegateCallable, DataSto return _users } - @available(*, deprecated, message: "Please, switch to `userArray: [ChatUser]`") - public var users: LazyCachedMapCollection { - .init(source: userArray, map: { $0 }, context: nil) - } - lazy var userQueryUpdater = self.environment .userQueryUpdaterBuilder( client.databaseContainer, diff --git a/Sources/StreamChat/Deprecations.swift b/Sources/StreamChat/Deprecations.swift deleted file mode 100644 index 03d908b9a6a..00000000000 --- a/Sources/StreamChat/Deprecations.swift +++ /dev/null @@ -1,215 +0,0 @@ -// -// Copyright © 2025 Stream.io Inc. All rights reserved. -// - -import Foundation - -/// - NOTE: Deprecations of the next major release. - -public extension UserPresenceChangedEvent { - @available(*, deprecated, message: "`user: ChatUser` is now accessible. Please, switch to `user.id`") - var userId: UserId { user.id } -} - -public extension UserUpdatedEvent { - @available(*, deprecated, message: "`user: ChatUser` is now accessible. Please, switch to `user.id`") - var userId: UserId { user.id } -} - -public extension UserWatchingEvent { - @available(*, deprecated, message: "`user: ChatUser` is now accessible. Please, switch to `user.id`") - var userId: UserId { user.id } -} - -public extension UserBannedEvent { - @available(*, deprecated, message: "`user: ChatUser` is now accessible. Please, switch to `user.id`") - var userId: UserId { user.id } -} - -public extension UserUnbannedEvent { - @available(*, deprecated, message: "`user: ChatUser` is now accessible. Please, switch to `user.id`") - var userId: UserId { user.id } -} - -public extension ChannelHiddenEvent { - @available(*, deprecated, message: "Please, switch to `createdAt`") - var hiddenAt: Date { createdAt } -} - -public extension ChannelDeletedEvent { - @available(*, deprecated, message: "Please, switch to `createdAt`") - var deletedAt: Date { channel.deletedAt ?? createdAt } -} - -public extension MemberAddedEvent { - @available(*, deprecated, message: "`member: ChatChannelMember` is now accessible. Please, switch to `member.id`") - var memberUserId: UserId { member.id } -} - -public extension MemberUpdatedEvent { - @available(*, deprecated, message: "`member: ChatChannelMember` is now accessible. Please, switch to `member.id`") - var memberUserId: UserId { member.id } -} - -public extension MemberRemovedEvent { - @available(*, deprecated, message: "`user: ChatUser` is now accessible. Please, switch to `user.id`") - var memberUserId: UserId { user.id } -} - -public extension MessageNewEvent { - @available(*, deprecated, message: "`user: ChatUser` is now accessible. Please, switch to `user.id`") - var userId: UserId { user.id } - - @available(*, deprecated, message: "`message: ChatMessage` is now accessible. Please, switch to `message.id`") - var messageId: UserId { message.id } -} - -public extension MessageUpdatedEvent { - @available(*, deprecated, message: "`user: ChatUser` is now accessible. Please, switch to `user.id`") - var userId: UserId { user.id } - - @available(*, deprecated, message: "`message: ChatMessage` is now accessible. Please, switch to `message.id`") - var messageId: UserId { message.id } - - @available(*, deprecated, message: "Use message.updatedAt") - var updatedAt: Date { message.updatedAt } -} - -public extension MessageDeletedEvent { - @available(*, deprecated, message: "`user: ChatUser` is now accessible. Please, switch to `user?.id`") - var userId: UserId { - guard let user = user else { - log.warning("The `message.deleted` event is triggered server-side and has no `user`. Empty `userId` will be returned.") - return "" - } - - return user.id - } - - @available(*, deprecated, message: "`message: ChatMessage` is now accessible. Please, switch to `message.id`") - var messageId: UserId { message.id } - - @available(*, deprecated, message: "Use message.deletedAt") - var deletedAt: Date { message.deletedAt ?? createdAt } -} - -public extension MessageReadEvent { - @available(*, deprecated, message: "`user: ChatUser` is now accessible. Please, switch to `user.id`") - var userId: UserId { user.id } - - @available(*, deprecated, message: "Please, switch to `createdAt`") - var readAt: Date { createdAt } -} - -public extension NotificationMessageNewEvent { - @available(*, deprecated, message: "`message: ChatMessage` is now accessible. Please, switch to `message.author.id`") - var userId: UserId { message.author.id } - - @available(*, deprecated, message: "`message: ChatMessage` is now accessible. Please, switch to `message.id`") - var messageId: MessageId { message.id } -} - -public extension NotificationMarkAllReadEvent { - @available(*, deprecated, message: "`user: ChatUser` is now accessible. Please, switch to `user.id`") - var userId: UserId { user.id } - - @available(*, deprecated, message: "Please, switch to `createdAt`") - var readAt: Date { createdAt } -} - -public extension NotificationMarkReadEvent { - @available(*, deprecated, message: "`user: ChatUser` is now accessible. Please, switch to `user.id`") - var userId: UserId { user.id } - - @available(*, deprecated, message: "Please, switch to `createdAt`") - var readAt: Date { createdAt } -} - -public extension NotificationMutesUpdatedEvent { - @available(*, deprecated, message: "`user: CurrentChatUser` is now accessible. Please, switch to `currentUser.id`") - var currentUserId: UserId { currentUser.id } -} - -public extension NotificationRemovedFromChannelEvent { - @available(*, deprecated, message: "`user: ChatUser` is now accessible. Please, switch to `user.id`") - var currentUserId: UserId { user.id } -} - -public extension NotificationChannelMutesUpdatedEvent { - @available(*, deprecated, message: "`user: CurrentChatUser` is now accessible. Please, switch to `currentUser.id`") - var userId: UserId { currentUser.id } -} - -public extension NotificationInvitedEvent { - @available(*, deprecated, message: "`member: ChatChannelMember` is now accessible. Please, switch to `member.id`") - var memberUserId: UserId { member.id } -} - -public extension NotificationInviteAcceptedEvent { - @available(*, deprecated, message: "`member: ChatChannelMember` is now accessible. Please, switch to `member.id`") - var memberUserId: UserId { member.id } -} - -public extension NotificationInviteRejectedEvent { - @available(*, deprecated, message: "`member: ChatChannelMember` is now accessible. Please, switch to `member.id`") - var memberUserId: UserId { member.id } -} - -public extension ReactionNewEvent { - @available(*, deprecated, message: "`user: ChatUser` is now accessible. Please, switch to `user.id`") - var userId: UserId { user.id } - - @available(*, deprecated, message: "`message: ChatMessage` is now accessible. Please, switch to `message.id`") - var messageId: UserId { message.id } - - @available(*, deprecated, message: "`reaction: ChatMessageReaction` is now accessible. Please, switch to `reaction.type`") - var reactionType: MessageReactionType { reaction.type } - - @available(*, deprecated, message: "`reaction: ChatMessageReaction` is now accessible. Please, switch to `reaction.score`") - var reactionScore: Int { reaction.score } -} - -public extension ReactionUpdatedEvent { - @available(*, deprecated, message: "`user: ChatUser` is now accessible. Please, switch to `user.id`") - var userId: UserId { user.id } - - @available(*, deprecated, message: "`message: ChatMessage` is now accessible. Please, switch to `message.id`") - var messageId: UserId { message.id } - - @available(*, deprecated, message: "`reaction: ChatMessageReaction` is now accessible. Please, switch to `reaction.type`") - var reactionType: MessageReactionType { reaction.type } - - @available(*, deprecated, message: "`reaction: ChatMessageReaction` is now accessible. Please, switch to `reaction.score`") - var reactionScore: Int { reaction.score } - - @available(*, deprecated, message: "`reaction: ChatMessageReaction` is now accessible. Please, switch to `reaction.updatedAt`") - var updatedAt: Date { reaction.updatedAt } -} - -public extension ReactionDeletedEvent { - @available(*, deprecated, message: "`user: ChatUser` is now accessible. Please, switch to `user.id`") - var userId: UserId { user.id } - - @available(*, deprecated, message: "`message: ChatMessage` is now accessible. Please, switch to `message.id`") - var messageId: UserId { message.id } - - @available(*, deprecated, message: "`reaction: ChatMessageReaction` is now accessible. Please, switch to `reaction.type`") - var reactionType: MessageReactionType { reaction.type } - - @available(*, deprecated, message: "`reaction: ChatMessageReaction` is now accessible. Please, switch to `reaction.score`") - var reactionScore: Int { reaction.score } -} - -public extension TypingEvent { - @available(*, deprecated, message: "`user: ChatUser` is now accessible. Please, switch to `user.id`") - var userId: UserId { user.id } -} - -@available(*, deprecated, renamed: "NotificationInviteRejectedEvent") -public typealias NotificationInviteRejected = NotificationInviteRejectedEvent - -@available(*, deprecated, renamed: "NotificationInviteAcceptedEvent") -public typealias NotificationInviteAccepted = NotificationInviteAcceptedEvent - -@available(*, deprecated, renamed: "UnknownChannelEvent") -public typealias UnknownEvent = UnknownChannelEvent diff --git a/Sources/StreamChat/Models/Attachments/ChatMessageImageAttachment.swift b/Sources/StreamChat/Models/Attachments/ChatMessageImageAttachment.swift index d0e5195216b..cc060906c63 100644 --- a/Sources/StreamChat/Models/Attachments/ChatMessageImageAttachment.swift +++ b/Sources/StreamChat/Models/Attachments/ChatMessageImageAttachment.swift @@ -64,56 +64,6 @@ public struct ImageAttachmentPayload: AttachmentPayload { self.originalHeight = originalHeight self.extraData = extraData } - - /// Creates `ImageAttachmentPayload` instance. - /// - /// Use this initializer if the attachment is already uploaded and you have the remote URLs. - @available(*, deprecated, renamed: "init(title:imageRemoteURL:file:originalWidth:originalHeight:extraData:)") - public init( - title: String?, - imageRemoteURL: URL, - originalWidth: Double? = nil, - originalHeight: Double? = nil, - extraData: [String: RawJSON]? = nil - ) { - self.title = title - imageURL = imageRemoteURL - let fileType = AttachmentFileType(ext: imageRemoteURL.pathExtension) - file = AttachmentFile(type: fileType, size: 0, mimeType: nil) - self.originalWidth = originalWidth - self.originalHeight = originalHeight - self.extraData = extraData - } - - @available(*, deprecated, renamed: "imageURL") - /// By default, Stream does not provide a thumbnail url. - /// Since it uses the original image with query parameters to resize it. - /// This property was actually misleading, since it was just using the `imageURL` internally. - public var imagePreviewURL: URL { - get { imageURL } - set { imageURL = newValue } - } - - /// Creates `ImageAttachmentPayload` instance. - /// - /// Use this initializer if the attachment is already uploaded and you have the remote URLs. - @available(*, deprecated, renamed: "init(title:imageRemoteURL:originalWidth:originalHeight:extraData:)") - public init( - title: String?, - imageRemoteURL: URL, - imagePreviewRemoteURL: URL? = nil, - originalWidth: Double? = nil, - originalHeight: Double? = nil, - extraData: [String: RawJSON]? = nil - ) { - self.title = title - imageURL = imageRemoteURL - self.originalWidth = originalWidth - self.originalHeight = originalHeight - let fileType = AttachmentFileType(ext: imageRemoteURL.pathExtension) - file = AttachmentFile(type: fileType, size: 0, mimeType: nil) - self.extraData = extraData - } } extension ImageAttachmentPayload: Hashable {} diff --git a/Sources/StreamChat/Models/Channel.swift b/Sources/StreamChat/Models/Channel.swift index 3d93175fc5b..1738babc8aa 100644 --- a/Sources/StreamChat/Models/Channel.swift +++ b/Sources/StreamChat/Models/Channel.swift @@ -432,11 +432,6 @@ public struct ChannelUnreadCount: Decodable, Equatable, Sendable { } } -public extension ChannelUnreadCount { - @available(*, deprecated, renamed: "mentions") - var mentionedMessages: Int { mentions } -} - /// An action that can be performed in a channel. public struct ChannelCapability: RawRepresentable, ExpressibleByStringLiteral, Hashable, Sendable { public var rawValue: String diff --git a/Sources/StreamChat/Query/Filter.swift b/Sources/StreamChat/Query/Filter.swift index ef28ab530e7..e0e6c318795 100644 --- a/Sources/StreamChat/Query/Filter.swift +++ b/Sources/StreamChat/Query/Filter.swift @@ -311,18 +311,6 @@ public extension Filter { ) } - /// Matches all values that are not equal to a specified value. - @available(*, deprecated, message: "The notEqual filter will be removed in the future") - static func notEqual(_ key: FilterKey, to value: Value) -> Filter { - .init( - operator: .notEqual, - key: key, - value: value, - valueMapper: key.valueMapper, - keyPathString: key.keyPathString - ) - } - /// Matches values that are greater than a specified value. static func greater(_ key: FilterKey, than value: Value) -> Filter { .init( @@ -378,18 +366,6 @@ public extension Filter { ) } - /// Matches none of the values specified in an array. - @available(*, deprecated, message: "The notIn filter will be removed in the future") - static func notIn(_ key: FilterKey, values: [Value]) -> Filter { - .init( - operator: .notIn, - key: key, - value: values, - valueMapper: key.valueMapper, - keyPathString: key.keyPathString - ) - } - /// Matches values by performing text search with the specified value. static func query(_ key: FilterKey, text: String) -> Filter { .init( diff --git a/Sources/StreamChat/Query/PollVoteListQuery.swift b/Sources/StreamChat/Query/PollVoteListQuery.swift index 9c83f1957f2..7b37ea5674e 100644 --- a/Sources/StreamChat/Query/PollVoteListQuery.swift +++ b/Sources/StreamChat/Query/PollVoteListQuery.swift @@ -17,28 +17,6 @@ public struct PollVoteListQuery: Encodable, Sendable { /// The filter details to query the votes. public var filter: Filter? - @available( - *, - deprecated, - message: """ - There are now two new initializers. - This one was not using the optionId argument correctly. - """ - ) - public init( - pollId: String, - optionId: String?, - pagination: Pagination = .init(pageSize: 10, offset: 0), - sorting: [Sorting] = [.init(key: .createdAt, isAscending: false)], - filter: Filter? = nil - ) { - self.pollId = pollId - self.optionId = optionId - self.pagination = pagination - self.sorting = sorting - self.filter = filter - } - /// Creates a vote list query for the given pollId and the provided filter. public init( pollId: String, diff --git a/Sources/StreamChat/Utils/Logger/Destination/BaseLogDestination.swift b/Sources/StreamChat/Utils/Logger/Destination/BaseLogDestination.swift index 6575840d695..b474982033d 100644 --- a/Sources/StreamChat/Utils/Logger/Destination/BaseLogDestination.swift +++ b/Sources/StreamChat/Utils/Logger/Destination/BaseLogDestination.swift @@ -65,11 +65,6 @@ open class BaseLogDestination: LogDestination, @unchecked Sendable { self.showFunctionName = showFunctionName } - open func isEnabled(level: LogLevel) -> Bool { - assertionFailure("`isEnabled(level:)` is deprecated, please use `isEnabled(level:subsystem:)`") - return true - } - /// Checks if this destination is enabled for the given level and subsystems. /// - Parameter level: Log level to be checked /// - Parameter subsystems: Log subsystems to be checked diff --git a/Sources/StreamChat/Utils/Logger/Destination/LogDestination.swift b/Sources/StreamChat/Utils/Logger/Destination/LogDestination.swift index fcd723f9252..a4561ac7193 100644 --- a/Sources/StreamChat/Utils/Logger/Destination/LogDestination.swift +++ b/Sources/StreamChat/Utils/Logger/Destination/LogDestination.swift @@ -61,7 +61,6 @@ public protocol LogDestination: Sendable { showLineNumber: Bool, showFunctionName: Bool ) - func isEnabled(level: LogLevel) -> Bool func isEnabled(level: LogLevel, subsystems: LogSubsystem) -> Bool func process(logDetails: LogDetails) func applyFormatters(logDetails: LogDetails, message: String) -> String @@ -72,6 +71,6 @@ public extension LogDestination { var subsystems: LogSubsystem { .all } func isEnabled(level: LogLevel, subsystems: LogSubsystem) -> Bool { - isEnabled(level: level) && self.subsystems.contains(subsystems) + isEnabled(level: level, subsystems: subsystems) && self.subsystems.contains(subsystems) } } diff --git a/Sources/StreamChat/WebSocketClient/Events/MemberEvents.swift b/Sources/StreamChat/WebSocketClient/Events/MemberEvents.swift index a4340b67d56..2db21d8b1f0 100644 --- a/Sources/StreamChat/WebSocketClient/Events/MemberEvents.swift +++ b/Sources/StreamChat/WebSocketClient/Events/MemberEvents.swift @@ -17,6 +17,11 @@ public struct MemberAddedEvent: MemberEvent, ChannelSpecificEvent { /// The event timestamp. public let createdAt: Date + + /// The member's user id. + public var memberUserId: UserId { + member.id + } } final class MemberAddedEventDTO: EventDTO { @@ -62,6 +67,11 @@ public struct MemberUpdatedEvent: MemberEvent, ChannelSpecificEvent { /// The event timestamp. public let createdAt: Date + + /// The member's user id. + public var memberUserId: UserId { + member.id + } } final class MemberUpdatedEventDTO: EventDTO { @@ -104,6 +114,11 @@ public struct MemberRemovedEvent: MemberEvent, ChannelSpecificEvent { /// The event timestamp. public let createdAt: Date + + /// The member's user id. + public var memberUserId: UserId { + user.id + } } final class MemberRemovedEventDTO: EventDTO { diff --git a/Sources/StreamChat/WebSocketClient/Events/NotificationEvents.swift b/Sources/StreamChat/WebSocketClient/Events/NotificationEvents.swift index b09661cb73a..42e05abc260 100644 --- a/Sources/StreamChat/WebSocketClient/Events/NotificationEvents.swift +++ b/Sources/StreamChat/WebSocketClient/Events/NotificationEvents.swift @@ -375,6 +375,11 @@ public struct NotificationInvitedEvent: MemberEvent, ChannelSpecificEvent { /// The event timestamp. public let createdAt: Date + + /// The member's user id. + public var memberUserId: UserId { + member.id + } } final class NotificationInvitedEventDTO: EventDTO { @@ -424,6 +429,11 @@ public struct NotificationInviteAcceptedEvent: MemberEvent, ChannelSpecificEvent /// The event timestamp. public let createdAt: Date + + /// The member's user id. + public var memberUserId: UserId { + member.id + } } final class NotificationInviteAcceptedEventDTO: EventDTO { @@ -474,6 +484,11 @@ public struct NotificationInviteRejectedEvent: MemberEvent, ChannelSpecificEvent /// The event timestamp. public let createdAt: Date + + /// The member's user id. + public var memberUserId: UserId { + member.id + } } final class NotificationInviteRejectedEventDTO: EventDTO { diff --git a/Sources/StreamChatUI/ChatMessageList/Attachments/UploadingOverlayView.swift b/Sources/StreamChatUI/ChatMessageList/Attachments/UploadingOverlayView.swift index e051a9ed30f..dcc7a38121d 100644 --- a/Sources/StreamChatUI/ChatMessageList/Attachments/UploadingOverlayView.swift +++ b/Sources/StreamChatUI/ChatMessageList/Attachments/UploadingOverlayView.swift @@ -5,11 +5,6 @@ import StreamChat import UIKit -extension ChatMessageGalleryView { - @available(*, deprecated, message: "use UploadingOverlayView instead.") - public typealias UploadingOverlay = UploadingOverlayView -} - open class UploadingOverlayView: _View, ThemeProvider { public var content: AttachmentUploadingState? { didSet { updateContentIfNeeded() } diff --git a/Sources/StreamChatUI/ChatMessageList/ChatMessage/ChatMessageContentView.swift b/Sources/StreamChatUI/ChatMessageList/ChatMessage/ChatMessageContentView.swift index bf63515f0fb..4c3c454401d 100644 --- a/Sources/StreamChatUI/ChatMessageList/ChatMessage/ChatMessageContentView.swift +++ b/Sources/StreamChatUI/ChatMessageList/ChatMessage/ChatMessageContentView.swift @@ -1103,40 +1103,3 @@ extension ChatMessageLayoutOptions { } } } - -extension ChatMessageContentView { - @available(*, deprecated, renamed: "onlyVisibleToYouImageView") - public var onlyVisibleForYouIconImageView: UIImageView? { - onlyVisibleToYouImageView - } - - @available(*, deprecated, renamed: "onlyVisibleToYouLabel") - public var onlyVisibleForYouLabel: UILabel? { - onlyVisibleToYouLabel - } - - @available(*, deprecated, renamed: "onlyVisibleToYouContainer") - public var onlyVisibleForYouContainer: ContainerStackView? { - onlyVisibleToYouContainer - } - - @available(*, deprecated, renamed: "footnoteContainer") - public var metadataContainer: ContainerStackView? { - footnoteContainer - } - - @available(*, deprecated, renamed: "bubbleThreadFootnoteContainer") - public var bubbleThreadMetaContainer: ContainerStackView? { - bubbleThreadFootnoteContainer - } - - @available(*, deprecated, renamed: "createOnlyVisibleToYouImageView") - public func createOnlyVisibleForYouIconImageView() -> UIImageView { - createOnlyVisibleToYouImageView() - } - - @available(*, deprecated, renamed: "createOnlyVisibleToYouLabel") - public func createOnlyVisibleForYouLabel() -> UILabel { - createOnlyVisibleToYouLabel() - } -} diff --git a/Sources/StreamChatUI/ChatMessageList/ChatMessage/ChatMessageLayoutOptions.swift b/Sources/StreamChatUI/ChatMessageList/ChatMessage/ChatMessageLayoutOptions.swift index df4d2bdc749..c8516067eb9 100644 --- a/Sources/StreamChatUI/ChatMessageList/ChatMessage/ChatMessageLayoutOptions.swift +++ b/Sources/StreamChatUI/ChatMessageList/ChatMessage/ChatMessageLayoutOptions.swift @@ -95,8 +95,3 @@ public extension ChatMessageLayoutOption { /// If both are specified in the options, `centered` is prioritized static let centered: Self = "centered" } - -public extension ChatMessageLayoutOption { - @available(*, deprecated, renamed: "onlyVisibleToYouIndicator") - static let onlyVisibleForYouIndicator: Self = onlyVisibleToYouIndicator -} diff --git a/Sources/StreamChatUI/ChatMessageList/ChatMessageListVC.swift b/Sources/StreamChatUI/ChatMessageList/ChatMessageListVC.swift index 02fdd41290a..08b5221d8e9 100644 --- a/Sources/StreamChatUI/ChatMessageList/ChatMessageListVC.swift +++ b/Sources/StreamChatUI/ChatMessageList/ChatMessageListVC.swift @@ -325,12 +325,6 @@ open class ChatMessageListVC: _ViewController, ) } - /// Set the visibility of `scrollToLatestMessageButton`. - @available(*, deprecated, message: "use updateScrollToBottomButtonVisibility(animated:) instead.") - open func setScrollToLatestMessageButton(visible: Bool, animated: Bool = true) { - updateScrollToBottomButtonVisibility() - } - func updateScrollDependentButtonsVisibility(animated: Bool = true) { updateScrollToBottomButtonVisibility(animated: animated) updateJumpToUnreadButtonVisibility(animated: animated) @@ -1271,34 +1265,6 @@ open class ChatMessageListVC: _ViewController, self.pollController = pollController return pollController } - - // MARK: - Deprecations - - /// Jump to a given message. - /// In case the message is already loaded, it directly goes to it. - /// If not, it will load the messages around it and go to that page. - /// - /// - Parameter message: The message which the message list should go to. - /// - Parameter onHighlight: An optional closure to provide highlighting style when the message appears on screen. - @available(*, deprecated, renamed: "jumpToMessage(id:onHighlight:)") - public func jumpToMessage(_ message: ChatMessage, onHighlight: ((IndexPath) -> Void)? = nil) { - jumpToMessage(id: message.id, onHighlight: onHighlight) - } - - @available(*, deprecated, renamed: "scrollToBottom(animated:)") - open func scrollToMostRecentMessage(animated: Bool = true) { - listView.scrollToBottom(animated: animated) - } - - @available(*, deprecated, renamed: "scrollToBottomButton") - open var scrollToLatestMessageButton: ScrollToBottomButton { - scrollToBottomButton - } - - @available(*, deprecated, renamed: "didTapScrollToBottomButton") - @objc open func scrollToLatestMessage() { - didTapScrollToBottomButton() - } } // MARK: - Handle Message Updates diff --git a/Sources/StreamChatUI/ChatMessageList/ChatMessageListVCDelegate.swift b/Sources/StreamChatUI/ChatMessageList/ChatMessageListVCDelegate.swift index 467e11c2665..e2e7694efcb 100644 --- a/Sources/StreamChatUI/ChatMessageList/ChatMessageListVCDelegate.swift +++ b/Sources/StreamChatUI/ChatMessageList/ChatMessageListVCDelegate.swift @@ -70,20 +70,6 @@ import UIKit _ completion: @escaping @MainActor(Error?) -> Void ) - /// Tells the delegate that it should load the page around the given message id. - /// - /// Ex: The user tapped on a quoted message which is not locally available. - /// - Parameters: - /// - vc: The message list informing the delegate of this event. - /// - message: The the message to load the page around it. - /// - onSuccess: Call this closure when the page is successfully loaded. - @available(*, deprecated, renamed: "chatMessageListVC(vc:shouldLoadPageAroundMessageId:completion:)") - func chatMessageListVC( - _ vc: ChatMessageListVC, - shouldLoadPageAroundMessage message: ChatMessage, - _ completion: @escaping @MainActor(Error?) -> Void - ) - /// Tells the delegate that it should load the first page. /// /// Ex: The user tapped on scroll to the bottom or sent a new message when the first page is not currently in the UI. @@ -150,15 +136,6 @@ public extension ChatMessageListVCDelegate { completion(nil) } - @available(*, deprecated, renamed: "chatMessageListVC(vc:shouldLoadPageAroundMessageId:completion:)") - func chatMessageListVC( - _ vc: ChatMessageListVC, - shouldLoadPageAroundMessage message: ChatMessage, - _ completion: @escaping @MainActor(Error?) -> Void - ) { - chatMessageListVC(vc, shouldLoadPageAroundMessageId: message.id, completion) - } - func chatMessageListVCShouldLoadFirstPage(_ vc: ChatMessageListVC) { // no-op } diff --git a/Sources/StreamChatUI/ChatMessageList/ChatMessageListView.swift b/Sources/StreamChatUI/ChatMessageList/ChatMessageListView.swift index 6fc65f2b5dd..41404c5039b 100644 --- a/Sources/StreamChatUI/ChatMessageList/ChatMessageListView.swift +++ b/Sources/StreamChatUI/ChatMessageList/ChatMessageListView.swift @@ -295,14 +295,6 @@ open class ChatMessageListView: UITableView, Customizable, ComponentsProvider { // no-op } } - - // MARK: - Deprecations - - /// Scrolls to most recent message. (Scrolls to the bottom of the message list). - @available(*, deprecated, renamed: "scrollToBottom(animated:)") - open func scrollToMostRecentMessage(animated: Bool = true) { - scrollToBottom(animated: animated) - } } // MARK: Helpers diff --git a/Sources/StreamChatUI/ChatMessageList/Reactions/ChatMessageReactionsPickerVC.swift b/Sources/StreamChatUI/ChatMessageList/Reactions/ChatMessageReactionsPickerVC.swift index f85f6d284e6..d923e758458 100644 --- a/Sources/StreamChatUI/ChatMessageList/Reactions/ChatMessageReactionsPickerVC.swift +++ b/Sources/StreamChatUI/ChatMessageList/Reactions/ChatMessageReactionsPickerVC.swift @@ -5,9 +5,6 @@ import StreamChat import UIKit -@available(*, deprecated, renamed: "ChatMessageReactionsPickerVC") -public typealias ChatMessageReactionsVC = ChatMessageReactionsPickerVC - /// Controller for the message reactions picker as a list of toggles. open class ChatMessageReactionsPickerVC: _ViewController, ThemeProvider, ChatMessageControllerDelegate { public var messageController: ChatMessageController! diff --git a/Sources/StreamChatUI/ChatMessageList/ScrollToBottomButton.swift b/Sources/StreamChatUI/ChatMessageList/ScrollToBottomButton.swift index c981d4a09f2..2816e5a7851 100644 --- a/Sources/StreamChatUI/ChatMessageList/ScrollToBottomButton.swift +++ b/Sources/StreamChatUI/ChatMessageList/ScrollToBottomButton.swift @@ -5,9 +5,6 @@ import StreamChat import UIKit -@available(*, deprecated, renamed: "ScrollToBottomButton") -public typealias ScrollToLatestMessageButton = ScrollToBottomButton - /// A Button that is used to indicate unread messages in the Message list. open class ScrollToBottomButton: _Button, ThemeProvider { /// The unread count that will be shown on the button as a badge icon. diff --git a/Sources/StreamChatUI/ChatThread/ChatThreadVC.swift b/Sources/StreamChatUI/ChatThread/ChatThreadVC.swift index 04e6e1d68cd..0f52cea8723 100644 --- a/Sources/StreamChatUI/ChatThread/ChatThreadVC.swift +++ b/Sources/StreamChatUI/ChatThread/ChatThreadVC.swift @@ -23,10 +23,6 @@ open class ChatThreadVC: _ViewController, /// An optional message id to where the thread should jump to when opening the thread. public var initialReplyId: MessageId? - /// Controller for observing typing events for this thread. - @available(*, deprecated, message: "Events are now handled by the `eventsController`.") - open lazy var channelEventsController: ChannelEventsController = client.channelEventsController(for: messageController.cid) - /// A controller for observing web socket events. open lazy var eventsController: EventsController = client.eventsController() @@ -536,14 +532,4 @@ open class ChatThreadVC: _ViewController, lookUpScope: .subsequentMessagesFromUser ) } - - // MARK: - Deprecations - - @available(*, deprecated, message: "use messageController.isLoadingPreviousReplies instead.") - public var isLoadingPreviousMessages: Bool = false - - @available(*, deprecated, message: "use messageController.loadPreviousReplies() instead.") - open func loadPreviousMessages() { - messageController.loadPreviousReplies() - } } diff --git a/Sources/StreamChatUI/CommonViews/InputTextView/InputTextView.swift b/Sources/StreamChatUI/CommonViews/InputTextView/InputTextView.swift index ab6fdd2f09d..96d04946b50 100644 --- a/Sources/StreamChatUI/CommonViews/InputTextView/InputTextView.swift +++ b/Sources/StreamChatUI/CommonViews/InputTextView/InputTextView.swift @@ -220,28 +220,6 @@ open class InputTextView: UITextView, ThemeProvider { } } - @available(*, deprecated, message: "The calculations made by this method are now happening in a more consistent way inside layoutSubviews. This method is not being used now.") - open func setTextViewHeight() { - var heightToSet = minimumHeight - - if contentSize.height <= minimumHeight { - heightToSet = minimumHeight - } else if contentSize.height >= maximumHeight { - heightToSet = maximumHeight - } else { - heightToSet = contentSize.height - } - - // This is due to bug in UITextView where the scroll sometimes disables - // when a very long text is pasted in it. - // Doing this ensures that it doesn't happen - // Reference: https://stackoverflow.com/a/62386088/5493299 - isScrollEnabled = false - heightConstraint?.constant = heightToSet - layoutIfNeeded() - isScrollEnabled = true - } - // MARK: - Link Detection /// Highlights the links in the input text view. diff --git a/Sources/StreamChatUI/Components.swift b/Sources/StreamChatUI/Components.swift index e219fef3a76..01e38705b0b 100644 --- a/Sources/StreamChatUI/Components.swift +++ b/Sources/StreamChatUI/Components.swift @@ -682,60 +682,4 @@ public struct Components: @unchecked Sendable { public init() {} public nonisolated(unsafe) static var `default` = Self() - - // MARK: Deprecations - - /// The view that shows an overlay with uploading progress for image attachment that is being uploaded. - @available(*, deprecated, renamed: "uploadingOverlayView") - public var imageUploadingOverlay: UploadingOverlayView.Type = UploadingOverlayView.self -} - -// MARK: Deprecations - -public extension Components { - /// The logic to generate a name for the given channel. - @available( - *, - deprecated, - message: "Please use `Appearance.default.formatters.channelName` instead" - ) - @MainActor var channelNamer: ChatChannelNamer { - get { - DefaultChannelNameFormatter.channelNamer - } - set { - DefaultChannelNameFormatter.channelNamer = newValue - } - } - - /// The button that indicates unread messages at the bottom of the message list and scroll to the latest message on tap. - @available(*, deprecated, renamed: "scrollToBottomButton") - var scrollToLatestMessageButton: ScrollToBottomButton.Type { - get { - scrollToBottomButton - } - set { - scrollToBottomButton = newValue - } - } - - @available(*, deprecated, renamed: "userAvatarView") - var mentionAvatarView: ChatUserAvatarView.Type { - get { - userAvatarView - } - set { - userAvatarView = newValue - } - } - - @available(*, deprecated, renamed: "channelListLoadingView") - var chatChannelListLoadingView: ChatChannelListLoadingView.Type { - get { - channelListLoadingView - } - set { - channelListLoadingView = newValue - } - } } diff --git a/Sources/StreamChatUI/Deprecations.swift b/Sources/StreamChatUI/Deprecations.swift deleted file mode 100644 index 498d7840e4f..00000000000 --- a/Sources/StreamChatUI/Deprecations.swift +++ /dev/null @@ -1,317 +0,0 @@ -// -// Copyright © 2025 Stream.io Inc. All rights reserved. -// - -import Foundation -import StreamChat -import UIKit - -// swiftlint:disable all - -/// - NOTE: Deprecations of the next major release. - -public extension ChatMessageLayoutOptionsResolver { - @available( - *, - deprecated, - message: "this propery should have been called `maxTimeIntervalBetweenMessagesInGroup` as it describes the maximum time interval between 2 consecutive messages when they can still be groped. Please use `maxTimeIntervalBetweenMessagesInGroup` instead." - ) - var minTimeIntervalBetweenMessagesInGroup: TimeInterval { - maxTimeIntervalBetweenMessagesInGroup - } - - @available( - *, - deprecated, - message: "this init should have been called `init(maxTimeIntervalBetweenMessagesInGroup:)` as it requires the maximum time interval between 2 consecutive messages can still can be groped. Please use `init(maxTimeIntervalBetweenMessagesInGroup:)` instead." - ) - convenience init(minTimeIntervalBetweenMessagesInGroup: TimeInterval) { - self.init(maxTimeIntervalBetweenMessagesInGroup: minTimeIntervalBetweenMessagesInGroup) - } -} - -@available(*, deprecated, renamed: "ChatMessageActionsTransitionController") -public typealias MessageActionsTransitionController = ChatMessageActionsTransitionController - -@available(*, deprecated, renamed: "VideoLoading") -public typealias VideoPreviewLoader = VideoLoading - -public extension Components { - @available(*, deprecated, renamed: "videoLoader") - var videoPreviewLoader: VideoLoading { - get { videoLoader } - set { videoLoader = newValue } - } -} - -// MARK: - `setDelegate()` deprecations. - -public extension ChatUserSearchController { - @available(*, deprecated, message: "the `delegate` property should be used directly instead.") - func setDelegate(_ delegate: Delegate) { - self.delegate = delegate - } -} - -public extension ChatMessageSearchController { - @available(*, deprecated, message: "the `delegate` property should be used directly instead.") - func setDelegate(_ delegate: Delegate) { - self.delegate = delegate - } -} - -public extension ChatUserController { - @available(*, deprecated, message: "the `delegate` property should be used directly instead.") - func setDelegate(_ delegate: Delegate) { - self.delegate = delegate - } -} - -public extension ChatChannelMemberController { - @available(*, deprecated, message: "the `delegate` property should be used directly instead.") - func setDelegate(_ delegate: Delegate) { - self.delegate = delegate - } -} - -public extension ChatChannelMemberListController { - @available(*, deprecated, message: "the `delegate` property should be used directly instead.") - func setDelegate(_ delegate: Delegate) { - self.delegate = delegate - } -} - -public extension ChatChannelWatcherListController { - @available(*, deprecated, message: "the `delegate` property should be used directly instead.") - func setDelegate(_ delegate: Delegate) { - self.delegate = delegate - } -} - -public extension ChatChannelController { - @available(*, deprecated, message: "the `delegate` property should be used directly instead.") - func setDelegate(_ delegate: Delegate) { - self.delegate = delegate - } -} - -public extension ChatChannelListController { - @available(*, deprecated, message: "the `delegate` property should be used directly instead.") - func setDelegate(_ delegate: Delegate) { - self.delegate = delegate - } -} - -public extension CurrentChatUserController { - @available(*, deprecated, message: "the `delegate` property should be used directly instead.") - func setDelegate(_ delegate: Delegate?) { - self.delegate = delegate - } -} - -public extension ChatConnectionController { - @available(*, deprecated, message: "the `delegate` property should be used directly instead.") - func setDelegate(_ delegate: Delegate?) { - self.delegate = delegate - } -} - -public extension ChatUserListController { - @available(*, deprecated, message: "the `delegate` property should be used directly instead.") - func setDelegate(_ delegate: Delegate) { - self.delegate = delegate - } -} - -extension ChatMessageReactionsView { - @available(*, deprecated, message: "Use ChatMessageReactionItemView instead") - public typealias ItemView = ChatMessageReactionItemView -} - -@available(*, deprecated, message: "Use ChatReactionPickerBubbleView instead") -public typealias ChatMessageReactionsBubbleView = ChatReactionPickerBubbleView - -@available(*, deprecated, message: "Use DefaultChatReactionPickerBubbleView instead") -public typealias ChatMessageDefaultReactionsBubbleView = DefaultChatReactionPickerBubbleView - -// MARK: - Reaction components, deprecated - -extension Components { - @available(*, deprecated, message: "Use reactionPickerVC instead") - public var messageReactionsVC: ChatMessageReactionsVC.Type { - get { - reactionPickerVC - } - set { - reactionPickerVC = newValue - } - } - - @available(*, deprecated, message: "Use messageReactionsBubbleView instead") - public var chatReactionsBubbleView: ChatReactionBubbleBaseView.Type { - get { - messageReactionsBubbleView - } - set { - messageReactionsBubbleView = newValue - } - } - - @available(*, deprecated, message: "Use reactionPickerBubbleView instead") - public var reactionsBubbleView: ChatReactionPickerBubbleView.Type { - get { - reactionPickerBubbleView - } - set { - reactionPickerBubbleView = newValue - } - } - - @available(*, deprecated, message: "Use reactionPickerReactionsView and/or messageReactionsView") - public var reactionsView: ChatMessageReactionsView.Type { - get { - reactionPickerReactionsView - } - set { - reactionPickerReactionsView = newValue - messageReactionsView = newValue - } - } - - @available(*, deprecated, message: "Use reactionPickerReactionItemView and/or messageReactionItemView") - public var reactionItemView: ChatMessageReactionItemView.Type { - get { - reactionPickerReactionItemView - } - set { - reactionPickerReactionItemView = newValue - messageReactionItemView = newValue - } - } -} - -// MARK: - Deprecation of ChatMessageLayoutOptions as an OptionSet - -/// Previously `ChatMessageLayoutOptions` was an `OptionSet`, this limited the customization on -/// the customer side because the raw value needs to be an `Int`. A more flexible approach is to just -/// have a `Set` of `ChatMessageLayoutOption`. So for backwards compatibility we created the following -/// typealias `typealias = Set` and provided an API like the `OptionSet` so we -/// don't break the public API. - -public extension ChatMessageLayoutOptions { - @available(*, deprecated, message: "use `id` instead.") - var rawValue: String { - id - } - - @available(*, deprecated, message: "use `subtracting(_ other: Sequence)` instead.") - mutating func subtracting(_ option: ChatMessageLayoutOption) { - self = subtracting([option]) - } - - @available(*, deprecated, message: "use `intersection(_ other: Sequence)` instead.") - mutating func intersection(_ option: ChatMessageLayoutOption) { - self = intersection([option]) - } - - @available(*, deprecated, message: """ - use `contains(_ member: ChatMessageLayoutOption` instead. And make sure the custom option is being extended in - `ChatMessageLayoutOption` and not in `ChatMessageLayoutOptions`. - """) - func contains(_ options: ChatMessageLayoutOptions) -> Bool { - options.isSubset(of: self) - } - - @available(*, deprecated, message: """ - ChatMessageLayoutOptions is not an OptionSet anymore. Extend ChatMessageLayoutOption to create new options. - Use the string raw value initialiser from `ChatMessageLayoutOption` instead of `ChatMessageLayoutOptions`. - """) - init(rawValue: Int) { - let option = ChatMessageLayoutOption(rawValue: "\(rawValue)") - self = Set(arrayLiteral: option) - } -} - -// MARK: - Refactoring of message list date separator - -extension ChatMessageListScrollOverlayView { - @available(*, deprecated, message: "use `dateSeparatorView.textLabel` instead.") - public var textLabel: UILabel { - dateSeparatorView.textLabel - } -} - -// MARK: - Formatters - -extension DateFormatter { - @available( - *, - deprecated, - message: "Please use `Appearance.default.formatters.messageDateSeparator` instead" - ) - public static var messageListDateOverlay: DateFormatter { - DefaultMessageDateSeparatorFormatter().dateFormatter - } -} - -// MARK: AttachmentsPreviewVC - Mixed Attachments Support - -extension AttachmentsPreviewVC { - @available( - *, - deprecated, - message: "this view has been split into 2 views, horizontalScrollView and verticalScrollView. This change was required to support mixed attachments. We highly recommend stopping using this view since with mixed attachments the customization done to this view won't affect both scroll views." - ) - public var scrollView: UIScrollView { - let axises = Set(content.map { type(of: $0).preferredAxis }) - if axises.contains(.horizontal) { - return horizontalScrollView - } - return verticalScrollView - } - - @available(*, deprecated, renamed: "verticalScrollViewHeightConstraint") - public var scrollViewHeightConstraint: NSLayoutConstraint? { - get { verticalScrollViewHeightConstraint } - set { verticalScrollViewHeightConstraint = newValue } - } - - @available( - *, - deprecated, - message: "this property is not being used anymore by default. There's now two scroll views for each axis." - ) - public var stackViewAxis: NSLayoutConstraint.Axis { - content.first.flatMap { type(of: $0).preferredAxis } ?? .horizontal - } - - @available( - *, - deprecated, - message: "it has been replaced by attachmentPreviews(for:). The name reflects better the intent and when asking for the attachment views, it is safer to specify which axis or axises we want." - ) - public var attachmentViews: [UIView] { - attachmentPreviews(for: [.horizontal, .vertical]) - } -} - -public extension Appearance.Images { - @available(*, deprecated, renamed: "messageDeliveryStatusSent") - var messageSent: UIImage { - get { messageDeliveryStatusSent } - set { messageDeliveryStatusSent = newValue } - } - - @available(*, deprecated, renamed: "messageDeliveryStatusRead") - var readByAll: UIImage { - get { messageDeliveryStatusRead } - set { messageDeliveryStatusRead = newValue } - } -} - -public extension CGSize { - @available(*, deprecated, message: "use Components.avatarThumbnailSize instead.") - static var avatarThumbnailSize: CGSize { CGSize(width: 40, height: 40) } -} - -// swiftlint:enable all diff --git a/Sources/StreamChatUI/Utils/ChatMessage+Extensions.swift b/Sources/StreamChatUI/Utils/ChatMessage+Extensions.swift index 29467d53c48..5ac80ec4d08 100644 --- a/Sources/StreamChatUI/Utils/ChatMessage+Extensions.swift +++ b/Sources/StreamChatUI/Utils/ChatMessage+Extensions.swift @@ -92,19 +92,3 @@ public extension ChatMessage { localState == .sendingFailed && isBounced == true } } - -public extension ChatMessage { - /// A boolean value that checks if the message is visible for current user only. - @available( - *, - deprecated, - message: "This property is deprecated because it does not take `deletedMessagesVisability` setting into account." - ) - var isOnlyVisibleForCurrentUser: Bool { - guard isSentByCurrentUser else { - return false - } - - return isDeleted || type == .ephemeral - } -} diff --git a/Sources/StreamChatUI/Utils/Extensions/ChatChannelNamer.swift b/Sources/StreamChatUI/Utils/Extensions/ChatChannelNamer.swift index dedfe73469c..c1bf6dc4176 100644 --- a/Sources/StreamChatUI/Utils/Extensions/ChatChannelNamer.swift +++ b/Sources/StreamChatUI/Utils/Extensions/ChatChannelNamer.swift @@ -5,17 +5,6 @@ import Foundation import StreamChat -/// Typealias for closure taking `ChatChannel` and `UserId` which returns -/// the current name of the channel. Use this type when you create closure for naming a channel. -/// For example usage, see `DefaultChatChannelNamer` -@available( - *, - deprecated, - message: "Please use a `ChannelNameFormatter` instead" -) -public typealias ChatChannelNamer = - (_ channel: ChatChannel, _ currentUserId: UserId?) -> String? - /// Generates a name for the given channel, given the current user's id. /// /// The priority order is: diff --git a/Sources/StreamChatUI/Utils/ImageLoading/ImageLoading.swift b/Sources/StreamChatUI/Utils/ImageLoading/ImageLoading.swift index d7aaabb9383..ac5060a8e11 100644 --- a/Sources/StreamChatUI/Utils/ImageLoading/ImageLoading.swift +++ b/Sources/StreamChatUI/Utils/ImageLoading/ImageLoading.swift @@ -57,38 +57,6 @@ public protocol ImageLoading: AnyObject { with requests: [ImageDownloadRequest], completion: @escaping (@MainActor([Result]) -> Void) ) - - // MARK: - Deprecations - - @available(*, deprecated, message: "use downloadImage() instead.") - @discardableResult - func loadImage( - using urlRequest: URLRequest, - cachingKey: String?, - completion: @escaping (@MainActor(_ result: Result) -> Void) - ) -> Cancellable? - - @available(*, deprecated, message: "use loadImage(into:from:with:) instead.") - @discardableResult - @MainActor func loadImage( - into imageView: UIImageView, - url: URL?, - imageCDN: ImageCDN, - placeholder: UIImage?, - resize: Bool, - preferredSize: CGSize?, - completion: (@MainActor(_ result: Result) -> Void)? - ) -> Cancellable? - - @available(*, deprecated, message: "use loadMultipleImages() instead.") - func loadImages( - from urls: [URL], - placeholders: [UIImage], - loadThumbnails: Bool, - thumbnailSize: CGSize, - imageCDN: ImageCDN, - completion: @escaping (@MainActor([UIImage]) -> Void) - ) } // MARK: - Image Attachment Helper API @@ -161,67 +129,3 @@ public extension ImageLoading { loadImage(into: imageView, from: url, with: options, completion: nil) } } - -// MARK: Deprecation fallbacks - -public extension ImageLoading { - @available(*, deprecated, message: "use downloadImage() instead.") - func loadImage( - using urlRequest: URLRequest, - cachingKey: String?, completion: @escaping @MainActor(Result) -> Void - ) -> Cancellable? { - guard let url = urlRequest.url else { - StreamConcurrency.onMain { - completion(.failure(NSError(domain: "io.getstream.imageDeprecation.invalidUrl", code: 1))) - } - return nil - } - - return downloadImage( - with: ImageDownloadRequest(url: url, options: ImageDownloadOptions()), - completion: completion - ) - } - - @available(*, deprecated, message: "use loadImage(into:from:with:) instead.") - @discardableResult - @MainActor func loadImage( - into imageView: UIImageView, - url: URL?, - imageCDN: ImageCDN, - placeholder: UIImage? = nil, - resize: Bool = true, - preferredSize: CGSize? = nil, - completion: (@MainActor(_ result: Result) -> Void)? = nil - ) -> Cancellable? { - loadImage( - into: imageView, - from: url, - with: ImageLoaderOptions( - resize: preferredSize.map { ImageResize($0) }, - placeholder: placeholder - ), - completion: completion - ) - } - - @available(*, deprecated, message: "use loadMultipleImages() instead.") - func loadImages( - from urls: [URL], - placeholders: [UIImage], - loadThumbnails: Bool = true, - thumbnailSize: CGSize = Components.default.avatarThumbnailSize, - imageCDN: ImageCDN, - completion: @escaping @MainActor([UIImage]) -> Void - ) { - let requests = urls.map { url in - ImageDownloadRequest(url: url, options: .init(resize: .init(thumbnailSize))) - } - - downloadMultipleImages(with: requests) { results in - let imagesMapper = ImageResultsMapper(results: results) - let images = imagesMapper.mapErrors(with: placeholders) - completion(images) - } - } -} diff --git a/Sources/StreamChatUI/Utils/ImageProcessor/NukeImageProcessor.swift b/Sources/StreamChatUI/Utils/ImageProcessor/NukeImageProcessor.swift index d7407531940..a183fcaabc6 100644 --- a/Sources/StreamChatUI/Utils/ImageProcessor/NukeImageProcessor.swift +++ b/Sources/StreamChatUI/Utils/ImageProcessor/NukeImageProcessor.swift @@ -66,14 +66,6 @@ extension ImageProcessors { private let id: String private let sizeProvider: @Sendable() -> CGSize - /// Initializes the processor with size providing closure. - /// - Parameter sizeProvider: Closure to obtain size after the image is loaded. - @available(*, deprecated, message: "Use init(id:sizeProvider:) instead") - public init(sizeProvider: @escaping @Sendable() -> CGSize) { - // Backwards compatible init - self.init(id: "", sizeProvider: sizeProvider) - } - /// Initializes the processor with size providing closure. /// - Parameters: /// - id: Image identifier. diff --git a/StreamChat.xcodeproj/project.pbxproj b/StreamChat.xcodeproj/project.pbxproj index 57579d767ab..83a39910801 100644 --- a/StreamChat.xcodeproj/project.pbxproj +++ b/StreamChat.xcodeproj/project.pbxproj @@ -479,7 +479,6 @@ 64ECF6D826722733008B9D47 /* ChatThreadVC_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64ECF6A52672271C008B9D47 /* ChatThreadVC_Tests.swift */; }; 64F70D4B26257FD400C9F979 /* Error+InternetNotAvailable_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64F70D4A26257FD400C9F979 /* Error+InternetNotAvailable_Tests.swift */; }; 69736BF226413E5D00090B67 /* ChatMessageListScrollOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69736BF126413E5D00090B67 /* ChatMessageListScrollOverlayView.swift */; }; - 697C6F90260CFA37000E9023 /* Deprecations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69712522260BC9B4003C7B47 /* Deprecations.swift */; }; 780DFCFC25EF7DA500A39A6E /* ChatChannelListVC+SwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 780DFCFB25EF7DA500A39A6E /* ChatChannelListVC+SwiftUI.swift */; }; 7844B10C25EF92B600B87E89 /* ChatChannelListItemView+SwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7844B10B25EF92B600B87E89 /* ChatChannelListItemView+SwiftUI.swift */; }; 7844B14E25EF9F5700B87E89 /* ChatChannelAvatarView+SwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7844B14D25EF9F5700B87E89 /* ChatChannelAvatarView+SwiftUI.swift */; }; @@ -2038,7 +2037,6 @@ BCE484BA1EE03FF336034250 /* FilterEncoding_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCE483AC99F58A9034EA2ECE /* FilterEncoding_Tests.swift */; }; BCE48639FD7B6B05CD63A6AF /* FilterDecoding_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCE4862E2C4943998F0DCBD9 /* FilterDecoding_Tests.swift */; }; BCE486580F913CFFDB3B5ECD /* JSONEncoder_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCE489A4B136D48249DD6969 /* JSONEncoder_Tests.swift */; }; - BD4016362638411D00F09774 /* Deprecations.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD4016352638411D00F09774 /* Deprecations.swift */; }; BD40C1F5265FA80D004392CE /* StreamImageCDN_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD40C1F4265FA80D004392CE /* StreamImageCDN_Tests.swift */; }; BD69F5D52669392E00E9E3FA /* ScrollToBottomButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD69F5D42669392E00E9E3FA /* ScrollToBottomButton.swift */; }; BD837AF02652D23600A99AB5 /* AttachmentPreviewContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD837AEF2652D23600A99AB5 /* AttachmentPreviewContainer.swift */; }; @@ -2076,7 +2074,6 @@ C11B578829DC7B3500D5A248 /* EdgeCasesChannelList.swift in Sources */ = {isa = PBXBuildFile; fileRef = C11B578629DC7B2A00D5A248 /* EdgeCasesChannelList.swift */; }; C11BAA4D2907EC7B004C5EA4 /* AuthenticationRepository_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C11BAA4C2907EC7B004C5EA4 /* AuthenticationRepository_Tests.swift */; }; C121E804274544AC00023E4C /* ChatClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79A0E9AC2498BD0C00E9BD50 /* ChatClient.swift */; }; - C121E805274544AC00023E4C /* Deprecations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 69712522260BC9B4003C7B47 /* Deprecations.swift */; }; C121E806274544AC00023E4C /* Token.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79FC85E624ACCBC500A665ED /* Token.swift */; }; C121E808274544AC00023E4C /* BaseURL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7962958B248147430078EB53 /* BaseURL.swift */; }; C121E809274544AC00023E4C /* ChatClientConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 799C9428247D2FB9001F1104 /* ChatClientConfig.swift */; }; @@ -2310,7 +2307,6 @@ C121EB632746A1E600023E4C /* Appearance+Fonts.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7166CB925BED29200B03B07 /* Appearance+Fonts.swift */; }; C121EB642746A1E600023E4C /* Appearance+SwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDDD1EA92632CE3C00BA007B /* Appearance+SwiftUI.swift */; }; C121EB652746A1E600023E4C /* Components+SwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDDD1E982632C4C900BA007B /* Components+SwiftUI.swift */; }; - C121EB662746A1E600023E4C /* Deprecations.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD4016352638411D00F09774 /* Deprecations.swift */; }; C121EB672746A1E600023E4C /* DateUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA3C98526CA23F300EB8B07 /* DateUtils.swift */; }; C121EB682746A1E600023E4C /* Cancellable.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACF73D7726CFE07900372DC0 /* Cancellable.swift */; }; C121EB692746A1E600023E4C /* ImageLoading.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACCA772926C40C96007AE2ED /* ImageLoading.swift */; }; @@ -3467,7 +3463,6 @@ 64ECF6A52672271C008B9D47 /* ChatThreadVC_Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChatThreadVC_Tests.swift; sourceTree = ""; }; 64ECF6BB2672272D008B9D47 /* ChatThreadVC+SwiftUI_Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ChatThreadVC+SwiftUI_Tests.swift"; sourceTree = ""; }; 64F70D4A26257FD400C9F979 /* Error+InternetNotAvailable_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Error+InternetNotAvailable_Tests.swift"; sourceTree = ""; }; - 69712522260BC9B4003C7B47 /* Deprecations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Deprecations.swift; sourceTree = ""; }; 69736BF126413E5D00090B67 /* ChatMessageListScrollOverlayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessageListScrollOverlayView.swift; sourceTree = ""; }; 780DFCFB25EF7DA500A39A6E /* ChatChannelListVC+SwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ChatChannelListVC+SwiftUI.swift"; sourceTree = ""; }; 780DFD0B25EF80AB00A39A6E /* ChatChannelListVC+SwiftUI_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ChatChannelListVC+SwiftUI_Tests.swift"; sourceTree = ""; }; @@ -4750,7 +4745,6 @@ BCE4862E2C4943998F0DCBD9 /* FilterDecoding_Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FilterDecoding_Tests.swift; sourceTree = ""; }; BCE489A4B136D48249DD6969 /* JSONEncoder_Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONEncoder_Tests.swift; sourceTree = ""; }; BCE48E6828D1A30622C243F0 /* FilterTestScope.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FilterTestScope.swift; sourceTree = ""; }; - BD4016352638411D00F09774 /* Deprecations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Deprecations.swift; sourceTree = ""; }; BD40C1F4265FA80D004392CE /* StreamImageCDN_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StreamImageCDN_Tests.swift; sourceTree = ""; }; BD69F5D42669392E00E9E3FA /* ScrollToBottomButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollToBottomButton.swift; sourceTree = ""; }; BD837AEF2652D23600A99AB5 /* AttachmentPreviewContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentPreviewContainer.swift; sourceTree = ""; }; @@ -5725,7 +5719,6 @@ 79A0E9AC2498BD0C00E9BD50 /* ChatClient.swift */, AD8FEE572AA8E1A100273F88 /* ChatClient+Environment.swift */, AD8FEE5A2AA8E1E400273F88 /* ChatClientFactory.swift */, - 69712522260BC9B4003C7B47 /* Deprecations.swift */, 799C9435247D2FB9001F1104 /* APIClient */, 40789CFB29F6AC4F0018C2BB /* Audio */, 7962958A2481473A0078EB53 /* Config */, @@ -5751,7 +5744,6 @@ 7908823125432C6400896F03 /* StreamChatUI.h */, 7908823225432C6400896F03 /* Info.plist */, C14A46572846636900EF498E /* SDKIdentifier.swift */, - BD4016352638411D00F09774 /* Deprecations.swift */, 8850B929255C286B003AED69 /* Components.swift */, BDDD1E982632C4C900BA007B /* Components+SwiftUI.swift */, 792DD9FA256E67C6001DB91B /* ComponentsProvider.swift */, @@ -11167,7 +11159,6 @@ BD837AF02652D23600A99AB5 /* AttachmentPreviewContainer.swift in Sources */, 40FA4DD72A12A0C300DA21D2 /* RecordingIndicatorView.swift in Sources */, ADDC08082C828FDB00EA0E5F /* PollCreationFeatureCell.swift in Sources */, - BD4016362638411D00F09774 /* Deprecations.swift in Sources */, 7844B14E25EF9F5700B87E89 /* ChatChannelAvatarView+SwiftUI.swift in Sources */, ADA5A0F8276790C100E1C465 /* ChatMessageListDateSeparatorView.swift in Sources */, BDC80CB5265CF4B800F62CE2 /* ImageCDN.swift in Sources */, @@ -12062,7 +12053,6 @@ ADB8B8EE2D8890E000549C95 /* MessageReminder.swift in Sources */, 4F83FA462BA43DC3008BD8CD /* MemberList.swift in Sources */, 7963BD6926B0208900281F8C /* ChatMessageAudioAttachment.swift in Sources */, - 697C6F90260CFA37000E9023 /* Deprecations.swift in Sources */, 7964F3A4249A0ACF002A09EC /* ChannelListQueryDTO.swift in Sources */, 79280F3F2484E3BA00CDEB89 /* ClientError.swift in Sources */, C174E0F6284DFA5A0040B936 /* IdentifiablePayload.swift in Sources */, @@ -12687,7 +12677,6 @@ 40789D1C29F6AC500018C2BB /* AudioPlaybackState.swift in Sources */, AD8C7C612BA3DF2800260715 /* AppSettings.json in Sources */, C121E804274544AC00023E4C /* ChatClient.swift in Sources */, - C121E805274544AC00023E4C /* Deprecations.swift in Sources */, AD37D7D42BC9938E00800D8C /* ThreadRead.swift in Sources */, C121E806274544AC00023E4C /* Token.swift in Sources */, AD37D7D12BC9937F00800D8C /* ThreadParticipant.swift in Sources */, @@ -13150,7 +13139,6 @@ ADBBDA23279F0CFA00E47B1C /* UploadingProgressFormatter.swift in Sources */, AD78F9F428EC72D700BC0FCE /* UIScrollView+Extensions.swift in Sources */, C121EB652746A1E600023E4C /* Components+SwiftUI.swift in Sources */, - C121EB662746A1E600023E4C /* Deprecations.swift in Sources */, C121EB672746A1E600023E4C /* DateUtils.swift in Sources */, C121EB682746A1E600023E4C /* Cancellable.swift in Sources */, ADE57B7D2C36E71200DD6B88 /* ChatThreadListHeaderBannerView.swift in Sources */, diff --git a/TestTools/StreamChatTestMockServer/Swifter/WebSockets.swift b/TestTools/StreamChatTestMockServer/Swifter/WebSockets.swift index 177813adee1..b4e0554f5be 100644 --- a/TestTools/StreamChatTestMockServer/Swifter/WebSockets.swift +++ b/TestTools/StreamChatTestMockServer/Swifter/WebSockets.swift @@ -7,13 +7,6 @@ import Foundation -@available(*, deprecated, message: "Use websocket(text:binary:pong:connected:disconnected:) instead.") -public func websocket(_ text: @escaping (WebSocketSession, String) -> Void, - _ binary: @escaping (WebSocketSession, [UInt8]) -> Void, - _ pong: @escaping (WebSocketSession, [UInt8]) -> Void) -> ((HttpRequest) -> HttpResponse) { - return websocket(text: text, binary: binary, pong: pong) -} - // swiftlint:disable function_body_length public func websocket( text: ((WebSocketSession, String) -> Void)? = nil, diff --git a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChannelListController_Mock.swift b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChannelListController_Mock.swift index 30dc5b28aef..94b30339690 100644 --- a/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChannelListController_Mock.swift +++ b/TestTools/StreamChatTestTools/Mocks/StreamChat/Controllers/ChannelListController_Mock.swift @@ -23,7 +23,7 @@ final class ChannelListController_Mock: ChatChannelListController, @unchecked Se } init() { - super.init(query: .init(filter: .notEqual("cid", to: "")), client: .mock) + super.init(query: .init(filter: .nonEmpty), client: .mock) } override func synchronize(_ completion: (@MainActor(Error?) -> Void)? = nil) { diff --git a/TestTools/StreamChatTestTools/TestData/FilterTestScope.swift b/TestTools/StreamChatTestTools/TestData/FilterTestScope.swift index 80394c318eb..f0b78078045 100644 --- a/TestTools/StreamChatTestTools/TestData/FilterTestScope.swift +++ b/TestTools/StreamChatTestTools/TestData/FilterTestScope.swift @@ -52,21 +52,18 @@ struct FilterCodingTestPair { static let allCases: [FilterCodingTestPair] = [ .equalInt(), - .notEqualDate(), .greaterDouble(), .greaterOrEqualBool(), .lessInt(), .lessOrEqualDouble(), .inArrayInt(), .inArrayDouble(), - .notInArrayString(), .query(), .autocomplete(), .existsTrue(), .notExists(), .containsAndEqual(), - .greaterOrLess(), - .nonEqualNorEqual() + .greaterOrLess() ] } @@ -81,23 +78,6 @@ extension FilterCodingTestPair { return FilterCodingTestPair(json: json, filter: filter) } - static func notEqualDate() -> FilterCodingTestPair { - let dateComponents = DateComponents( - timeZone: TimeZone(secondsFromGMT: 0), - year: 2020, - month: 8, - day: 12, - hour: 13, - minute: 14, - second: 59 - ) - let date: Date = Calendar.gmtCalendar.date(from: dateComponents)! - let dateString = "2020-08-12T13:14:59Z" - let json = "{\"test_key_Date\":{\"$ne\":\"\(dateString)\"}}" - let filter: Filter = .notEqual(.testKeyDate, to: date) - return FilterCodingTestPair(json: json, filter: filter) - } - // Note: Double encoding strange format: // Built-in encoder for Double will output enough decimal // digits in the JSON representation to guarantee that it will come out @@ -145,15 +125,7 @@ extension FilterCodingTestPair { let filter: Filter = .in(.testKeyArrayDouble, values: array) return FilterCodingTestPair(json: json, filter: filter) } - - static func notInArrayString() -> FilterCodingTestPair { - let array = ["1", "2", "3", "4"] - let arrayJSON = #"["1","2","3","4"]"# - let json = "{\"test_key_ArrayString\":{\"$nin\":\(arrayJSON)}}" - let filter: Filter = .notIn(.testKeyArrayString, values: array) - return FilterCodingTestPair(json: json, filter: filter) - } - + static func query() -> FilterCodingTestPair { let json = #"{"test_key":{"$q":"Quick brown fox jump over lazy dog"}}"# let filter: Filter = .query(.testKey, text: "Quick brown fox jump over lazy dog") @@ -192,15 +164,6 @@ extension FilterCodingTestPair { return FilterCodingTestPair(json: json, filter: filter) } - static func nonEqualNorEqual() -> FilterCodingTestPair { - let json = #"{"$nor":[{"test_key_Bool":{"$ne":true}},{"test_key_Double":{"$eq":678.89999999999998}}]}"# - let filter: Filter = .nor([ - .notEqual(.testKeyBool, to: true), - .equal(.testKeyDouble, to: 678.9) - ]) - return FilterCodingTestPair(json: json, filter: filter) - } - private static func existsFilter(exists: Bool) -> FilterCodingTestPair { let json = "{\"test_key_Int\":{\"$exists\":\(exists)}}" let filter: Filter = .exists(.testKeyInt, exists: exists) diff --git a/Tests/StreamChatTests/APIClient/Endpoints/Payloads/MessageAttachmentPayload_Tests.swift b/Tests/StreamChatTests/APIClient/Endpoints/Payloads/MessageAttachmentPayload_Tests.swift index 7a1eda2f860..dff76369ed2 100644 --- a/Tests/StreamChatTests/APIClient/Endpoints/Payloads/MessageAttachmentPayload_Tests.swift +++ b/Tests/StreamChatTests/APIClient/Endpoints/Payloads/MessageAttachmentPayload_Tests.swift @@ -63,3 +63,11 @@ final class MessageAttachmentPayload_Tests: XCTestCase { XCTAssertEqual(payload.type, .unknown) } } + +extension RawJSON { + func dictionary(with value: RawJSON?, forKey key: String) -> RawJSON? { + guard case var .dictionary(content) = self else { return nil } + content[key] = value + return .dictionary(content) + } +} diff --git a/Tests/StreamChatTests/Config/Token_Tests.swift b/Tests/StreamChatTests/Config/Token_Tests.swift index ee897e8a7d8..64a39cccb60 100644 --- a/Tests/StreamChatTests/Config/Token_Tests.swift +++ b/Tests/StreamChatTests/Config/Token_Tests.swift @@ -22,27 +22,23 @@ final class Token_Tests: XCTestCase { let jwtToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoibHVrZV9za3l3YWxrZXIifQ.kFSLHRB5X62t0Zlc7nwczWUfsQMwfkpylC6jCUZ6Mc0" let token = try Token(rawValue: jwtToken) XCTAssertEqual(token.expiration, nil) - XCTAssertEqual(token.isExpired, false) } func test_expiration_whenExpired() throws { let jwtToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoibHVrZV9za3l3YWxrZXIiLCJleHAiOjI1NTMzODE1Mjl9.i1vpWu_9uV6DO7eIYuUokQxfMaTgh-Xq089wKLGw_sY" let token = try Token(rawValue: jwtToken) XCTAssertEqual(token.expiration?.timeIntervalSince1970, 2_553_381_529) - XCTAssertEqual(token.isExpired, false) } func test_expiration_whenNotExpired() throws { let jwtToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoibHVrZV9za3l3YWxrZXIiLCJleHAiOjE2MDY2OTY3Mjl9.AkmNHUTKEFR8UP0W2HLFsS006Bi2IT7-fzMtJuI_J9Q" let token = try Token(rawValue: jwtToken) XCTAssertEqual(token.expiration?.timeIntervalSince1970, 1_606_696_729) - XCTAssertEqual(token.isExpired, true) } func test_anonymousToken() { let token = Token.anonymous XCTAssertEqual(token.expiration, nil) - XCTAssertEqual(token.isExpired, false) XCTAssertEqual(token.rawValue, "") XCTAssertTrue(!token.userId.isEmpty) } @@ -51,7 +47,6 @@ final class Token_Tests: XCTestCase { let expectedUserId = "luke_skywalker" let token = Token.development(userId: expectedUserId) XCTAssertEqual(token.expiration, nil) - XCTAssertEqual(token.isExpired, false) XCTAssertEqual(token.rawValue, "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoibHVrZV9za3l3YWxrZXIifQ==.devtoken") XCTAssertEqual(token.userId, expectedUserId) } diff --git a/Tests/StreamChatTests/Controllers/ChannelListController/ChannelListController_Tests.swift b/Tests/StreamChatTests/Controllers/ChannelListController/ChannelListController_Tests.swift index db985a30459..0ecf40d6779 100644 --- a/Tests/StreamChatTests/Controllers/ChannelListController/ChannelListController_Tests.swift +++ b/Tests/StreamChatTests/Controllers/ChannelListController/ChannelListController_Tests.swift @@ -839,51 +839,6 @@ final class ChannelListController_Tests: XCTestCase { XCTAssertEqual(receivedError, error) } - // MARK: - Mark all read - - func test_markAllRead_callsChannelListUpdater() { - // Simulate `markRead` call and catch the completion - nonisolated(unsafe) var completionCalled = false - controller.markAllRead { error in - XCTAssertNil(error) - completionCalled = true - } - - // Keep a weak ref so we can check if it's actually deallocated - weak var weakController = controller - - // (Try to) deallocate the controller - // by not keeping any references to it - controller = nil - - XCTAssertFalse(completionCalled) - - // Simulate successfull udpate - env.channelListUpdater!.markAllRead_completion?(nil) - // Release reference of completion so we can deallocate stuff - env.channelListUpdater!.markAllRead_completion = nil - - // Assert completion is called - AssertAsync.willBeTrue(completionCalled) - // `weakController` should be deallocated too - AssertAsync.canBeReleased(&weakController) - } - - func test_markAllRead_propagatesErrorFromUpdater() { - // Simulate `markRead` call and catch the completion - nonisolated(unsafe) var completionCalledError: Error? - controller.markAllRead { - completionCalledError = $0 - } - - // Simulate failed udpate - let testError = TestError() - env.channelListUpdater!.markAllRead_completion?(testError) - - // Completion should be called with the error - AssertAsync.willBeEqual(completionCalledError as? TestError, testError) - } - // MARK: - List Ordering initial value func test_inits_propagate_desiredMessageOrdering() { @@ -974,19 +929,6 @@ final class ChannelListController_Tests: XCTestCase { ) } - func test_filterPredicate_notEqual_containsExpectedItems() throws { - let cid = ChannelId.unique - - try assertFilterPredicate( - .notEqual(.name, to: "test"), - channelsInDB: [ - .dummy(channel: .dummy(name: "test")), - .dummy(channel: .dummy(cid: cid, name: "test2")) - ], - expectedResult: [cid] - ) - } - func test_filterPredicate_greater_containsExpectedItems() throws { let cid = ChannelId.unique @@ -1111,25 +1053,6 @@ final class ChannelListController_Tests: XCTestCase { ) } - func test_filterPredicate_notIn_containsExpectedItems() throws { - let memberId1 = UserId.unique - let memberId2 = UserId.unique - let cid1 = ChannelId.unique - let cid2 = ChannelId.unique - let cid3 = ChannelId.unique - - try assertFilterPredicate( - .notIn(.members, values: [memberId1, memberId2]), - channelsInDB: [ - .dummy(channel: .dummy(cid: cid1, members: [.dummy(user: .dummy(userId: memberId1))])), - .dummy(channel: .dummy(cid: cid2, members: [.dummy(user: .dummy(userId: memberId2))])), - .dummy(channel: .dummy(cid: cid3)), - .dummy(channel: .dummy(members: [.dummy(user: .dummy(userId: memberId1)), .dummy(user: .dummy(userId: memberId2))])) - ], - expectedResult: [cid1, cid2, cid3] - ) - } - func test_filterPredicate_autocomplete_containsExpectedItems() throws { let cid1 = ChannelId.unique let cid2 = ChannelId.unique diff --git a/Tests/StreamChatTests/Database/DatabaseContainer_Tests.swift b/Tests/StreamChatTests/Database/DatabaseContainer_Tests.swift index af05b64034e..9c208ae6c7d 100644 --- a/Tests/StreamChatTests/Database/DatabaseContainer_Tests.swift +++ b/Tests/StreamChatTests/Database/DatabaseContainer_Tests.swift @@ -454,7 +454,7 @@ final class DatabaseContainer_Tests: XCTestCase { ) try session.savePollVote( payload: self.dummyPollVotePayload(pollId: "pollId"), - query: .init(pollId: "pollId", optionId: "test", filter: .contains(.pollId, value: "pollId")), + query: .init(pollId: "pollId", filter: .contains(.pollId, value: "pollId")), cache: nil ) diff --git a/Tests/StreamChatTests/Models/Attachments/AnyAttachmentPayload_Tests.swift b/Tests/StreamChatTests/Models/Attachments/AnyAttachmentPayload_Tests.swift index 334cf69b9b7..1c925efd92f 100644 --- a/Tests/StreamChatTests/Models/Attachments/AnyAttachmentPayload_Tests.swift +++ b/Tests/StreamChatTests/Models/Attachments/AnyAttachmentPayload_Tests.swift @@ -137,7 +137,11 @@ final class AnyAttachmentPayload_Tests: XCTestCase { let remoteAttachment = ChatMessageImageAttachment( id: .unique, type: .image, - payload: .init(title: nil, imageRemoteURL: .localYodaImage), + payload: .init( + title: nil, + imageRemoteURL: .localYodaImage, + file: try .init(url: .localYodaImage) + ), downloadingState: nil, uploadingState: nil ).asAnyAttachment @@ -150,7 +154,11 @@ final class AnyAttachmentPayload_Tests: XCTestCase { let localAttachment = ChatMessageImageAttachment( id: .unique, type: .image, - payload: .init(title: nil, imageRemoteURL: .localYodaImage), + payload: .init( + title: nil, + imageRemoteURL: .localYodaImage, + file: try .init(url: .localYodaImage) + ), downloadingState: nil, uploadingState: try .mock(localFileURL: .localYodaImage, state: .uploaded) ).asAnyAttachment @@ -163,7 +171,11 @@ final class AnyAttachmentPayload_Tests: XCTestCase { let localAttachment = ChatMessageImageAttachment( id: .unique, type: .image, - payload: .init(title: nil, imageRemoteURL: .localYodaImage), + payload: .init( + title: nil, + imageRemoteURL: .localYodaImage, + file: try .init(url: .localYodaImage) + ), downloadingState: nil, uploadingState: try .mock(localFileURL: .localYodaImage, state: .uploadingFailed) ).asAnyAttachment diff --git a/Tests/StreamChatTests/Models/Attachments/AnyAttachmentUpdater_Tests.swift b/Tests/StreamChatTests/Models/Attachments/AnyAttachmentUpdater_Tests.swift index 0f47c56cb29..527803de05b 100644 --- a/Tests/StreamChatTests/Models/Attachments/AnyAttachmentUpdater_Tests.swift +++ b/Tests/StreamChatTests/Models/Attachments/AnyAttachmentUpdater_Tests.swift @@ -13,7 +13,12 @@ final class AnyAttachmentUpdater_Tests: XCTestCase { var attachment = ChatMessageImageAttachment( id: .init(cid: .unique, messageId: .unique, index: .unique), type: .image, - payload: .init(title: "old", imageRemoteURL: .localYodaImage, extraData: [:]), + payload: .init( + title: "old", + imageRemoteURL: .localYodaImage, + file: try .init(url: .localYodaImage), + extraData: [:] + ), downloadingState: nil, uploadingState: nil ).asAnyAttachment diff --git a/Tests/StreamChatTests/Query/Filter_Tests.swift b/Tests/StreamChatTests/Query/Filter_Tests.swift index 924f2dbd898..afcfeb80e23 100644 --- a/Tests/StreamChatTests/Query/Filter_Tests.swift +++ b/Tests/StreamChatTests/Query/Filter_Tests.swift @@ -18,11 +18,6 @@ final class Filter_Tests: XCTestCase { XCTAssertEqual(filter.value as? [String], ["eq value 1", "eq value 2"]) XCTAssertEqual(filter.operator, FilterOperator.equal.rawValue) - filter = .notEqual(.testKey, to: "not equal value") - XCTAssertEqual(filter.key, FilterKey.testKey.rawValue) - XCTAssertEqual(filter.value as? String, "not equal value") - XCTAssertEqual(filter.operator, FilterOperator.notEqual.rawValue) - filter = .greater(.testKey, than: "greater value") XCTAssertEqual(filter.key, FilterKey.testKey.rawValue) XCTAssertEqual(filter.value as? String, "greater value") @@ -48,11 +43,6 @@ final class Filter_Tests: XCTestCase { XCTAssertEqual(filter.value as? [String], ["in value 1", "in value 2"]) XCTAssertEqual(filter.operator, FilterOperator.in.rawValue) - filter = .notIn(.testKey, values: ["nin value 1", "nin value 2"]) - XCTAssertEqual(filter.key, FilterKey.testKey.rawValue) - XCTAssertEqual(filter.value as? [String], ["nin value 1", "nin value 2"]) - XCTAssertEqual(filter.operator, FilterOperator.notIn.rawValue) - filter = .query(.testKey, text: "searched text") XCTAssertEqual(filter.key, FilterKey.testKey.rawValue) XCTAssertEqual(filter.value as? String, "searched text") @@ -106,9 +96,9 @@ final class Filter_Tests: XCTestCase { // Test group filter let filter1: Filter = .equal(.testKey, to: "test_value_1") - let filter2: Filter = .notEqual(.testKey, to: "test_value_2") + let filter2: Filter = .equal(.testKey, to: "test_value_2") filter = .or([filter1, filter2]) - XCTAssertEqual(filter.serialized, #"{"$or":[{"test_key":{"$eq":"test_value_1"}},{"test_key":{"$ne":"test_value_2"}}]}"#) + XCTAssertEqual(filter.serialized, #"{"$or":[{"test_key":{"$eq":"test_value_1"}},{"test_key":{"$eq":"test_value_2"}}]}"#) XCTAssertEqual(jsonString.deserializeFilter(), filter) } diff --git a/Tests/StreamChatUITests/SnapshotTests/ChatChannelList/ChatChannelListItemView_Tests.swift b/Tests/StreamChatUITests/SnapshotTests/ChatChannelList/ChatChannelListItemView_Tests.swift index e22f0d22927..bafce29fa0d 100644 --- a/Tests/StreamChatUITests/SnapshotTests/ChatChannelList/ChatChannelListItemView_Tests.swift +++ b/Tests/StreamChatUITests/SnapshotTests/ChatChannelList/ChatChannelListItemView_Tests.swift @@ -732,7 +732,8 @@ import XCTest type: .image, payload: try JSONEncoder().encode(ImageAttachmentPayload( title: nil, - imageRemoteURL: .localYodaImage + imageRemoteURL: .localYodaImage, + file: try .init(url: .localYodaImage) ) ) ) @@ -1777,7 +1778,8 @@ import XCTest type: .image, payload: try JSONEncoder().encode(ImageAttachmentPayload( title: "Test", - imageRemoteURL: URL(string: "Url")! + imageRemoteURL: URL(string: "Url")!, + file: try .init(url: .localYodaImage) )) ) ], diff --git a/Tests/StreamChatUITests/SnapshotTests/ChatMessageList/ChatMessage/ChatMessageContentView_Tests.swift b/Tests/StreamChatUITests/SnapshotTests/ChatMessageList/ChatMessage/ChatMessageContentView_Tests.swift index a32d7b4eb5b..20d613a9e73 100644 --- a/Tests/StreamChatUITests/SnapshotTests/ChatMessageList/ChatMessage/ChatMessageContentView_Tests.swift +++ b/Tests/StreamChatUITests/SnapshotTests/ChatMessageList/ChatMessage/ChatMessageContentView_Tests.swift @@ -628,7 +628,9 @@ import XCTest id: .unique, type: .image, payload: try JSONEncoder.stream.encode(ImageAttachmentPayload( - title: nil, imageRemoteURL: TestImages.r2.url + title: nil, + imageRemoteURL: TestImages.r2.url, + file: try .init(url: TestImages.r2.url) )), uploadingState: nil )], @@ -701,7 +703,8 @@ import XCTest type: .image, payload: try JSONEncoder.stream.encode(ImageAttachmentPayload( title: nil, - imageRemoteURL: TestImages.r2.url + imageRemoteURL: TestImages.r2.url, + file: try .init(url: TestImages.r2.url) )), uploadingState: nil )], diff --git a/Tests/StreamChatUITests/SnapshotTests/CommonViews/Suggestions/ChatMentionSuggestionView/ChatMentionSuggestionView_Tests.swift b/Tests/StreamChatUITests/SnapshotTests/CommonViews/Suggestions/ChatMentionSuggestionView/ChatMentionSuggestionView_Tests.swift index 04e92dc96dc..2c1dfed0683 100644 --- a/Tests/StreamChatUITests/SnapshotTests/CommonViews/Suggestions/ChatMentionSuggestionView/ChatMentionSuggestionView_Tests.swift +++ b/Tests/StreamChatUITests/SnapshotTests/CommonViews/Suggestions/ChatMentionSuggestionView/ChatMentionSuggestionView_Tests.swift @@ -85,7 +85,7 @@ import XCTest var components = Components.mock components.onlineIndicatorView = RectIndicator.self - components.mentionAvatarView = CustomAvatarView.self + components.userAvatarView = CustomAvatarView.self let view = ChatMentionSuggestionView().withoutAutoresizingMaskConstraints view.widthAnchor.constraint(equalToConstant: Self.defaultCellWidth).isActive = true