diff --git a/Package.swift b/Package.swift index 414586f3d..b81c7db0d 100644 --- a/Package.swift +++ b/Package.swift @@ -16,7 +16,7 @@ let package = Package( ) ], dependencies: [ - .package(url: "https://github.com/GetStream/stream-chat-swift.git", from: "4.91.0") + .package(url: "https://github.com/GetStream/stream-chat-swift.git", branch: "v5") ], targets: [ .target( diff --git a/Sources/StreamChatSwiftUI/ChatChannel/ChannelInfo/FileAttachmentsView.swift b/Sources/StreamChatSwiftUI/ChatChannel/ChannelInfo/FileAttachmentsView.swift index 5d61bb841..c9f67de08 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/ChannelInfo/FileAttachmentsView.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/ChannelInfo/FileAttachmentsView.swift @@ -108,5 +108,3 @@ struct MonthlyAttachmentsHeader: View { .background(Color(colors.background6)) } } - -extension ChatMessageFileAttachment: Identifiable {} diff --git a/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelView.swift b/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelView.swift index 6f11ada30..6726b9201 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelView.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelView.swift @@ -83,7 +83,7 @@ public struct ChatChannelView: View, KeyboardReadable { ) } else { ZStack { - factory.makeEmptyMessagesView(for: channel, colors: colors) + factory.makeEmptyMessagesView(options: EmptyMessagesViewOptions(channel: channel, colors: colors)) .dismissKeyboardOnTap(enabled: keyboardShown) { hideComposerCommandsAndAttachmentsPicker() } diff --git a/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift b/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift index 8bbaef0a6..1ea8d2bfc 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/ChatChannelViewModel.swift @@ -813,7 +813,7 @@ import SwiftUI } } -extension ChatMessage: Identifiable { +extension ChatMessage { @MainActor public var scrollMessageId: String { messageId } diff --git a/Sources/StreamChatSwiftUI/ChatChannel/Composer/MessageComposerView.swift b/Sources/StreamChatSwiftUI/ChatChannel/Composer/MessageComposerView.swift index d78410ce7..72a5336d2 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/Composer/MessageComposerView.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/Composer/MessageComposerView.swift @@ -410,13 +410,15 @@ public struct ComposerInputView: View, KeyboardReadable { } factory.makeComposerTextInputView( - text: $text, - height: $textHeight, - selectedRangeLocation: $selectedRangeLocation, - placeholder: isInCooldown ? L10n.Composer.Placeholder.slowMode : (isChannelFrozen ? L10n.Composer.Placeholder.messageDisabled : L10n.Composer.Placeholder.message), - editable: !isInputDisabled, - maxMessageLength: maxMessageLength, - currentHeight: textFieldHeight + options: ComposerTextInputViewOptions( + text: $text, + height: $textHeight, + selectedRangeLocation: $selectedRangeLocation, + placeholder: isInCooldown ? L10n.Composer.Placeholder.slowMode : (isChannelFrozen ? L10n.Composer.Placeholder.messageDisabled : L10n.Composer.Placeholder.message), + editable: !isInputDisabled, + maxMessageLength: maxMessageLength, + currentHeight: textFieldHeight + ) ) .environmentObject(viewModel) .accessibilityIdentifier("ComposerTextInputView") diff --git a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageListView.swift b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageListView.swift index e2989e7fd..7bce190ed 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageListView.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageListView.swift @@ -321,7 +321,7 @@ public struct MessageListView: View, KeyboardReadable { ) ) : nil ) - .modifier(factory.makeMessageListContainerModifier()) + .modifier(factory.makeMessageListContainerModifier(options: MessageListContainerModifierOptions())) .onDisappear { messageRenderingUtil.update(previousTopMessage: nil) } diff --git a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/Polls/PollAttachmentView.swift b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/Polls/PollAttachmentView.swift index 1847f3a86..493219086 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/Polls/PollAttachmentView.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/Polls/PollAttachmentView.swift @@ -180,8 +180,6 @@ public struct PollAttachmentView: View { } } -extension PollOption: Identifiable {} - struct PollOptionView: View { @ObservedObject var viewModel: PollAttachmentViewModel diff --git a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/Polls/PollCommentsViewModel.swift b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/Polls/PollCommentsViewModel.swift index dc64d38b8..03d8e28ee 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/Polls/PollCommentsViewModel.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/Polls/PollCommentsViewModel.swift @@ -45,7 +45,7 @@ import SwiftUI $comments .dropFirst() .map { _ in true } - .assignWeakly(to: \.animateChanges, on: self) + .assign(to: \.animateChanges, onWeak: self) .store(in: &cancellables) } diff --git a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/Polls/PollOptionAllVotesViewModel.swift b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/Polls/PollOptionAllVotesViewModel.swift index f2cc80da9..7ee15f616 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/Polls/PollOptionAllVotesViewModel.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/Polls/PollOptionAllVotesViewModel.swift @@ -33,7 +33,7 @@ import SwiftUI $pollVotes .dropFirst() .map { _ in true } - .assignWeakly(to: \.animateChanges, on: self) + .assign(to: \.animateChanges, onWeak: self) .store(in: &cancellables) } diff --git a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/Polls/PollResultsView.swift b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/Polls/PollResultsView.swift index c95cf926d..258d4338d 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/MessageList/Polls/PollResultsView.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/MessageList/Polls/PollResultsView.swift @@ -135,7 +135,7 @@ struct PollOptionResultsView: View { } } -extension PollVote: Identifiable { +extension PollVote { var displayId: String { "\(id)-\(optionId ?? user?.id ?? "")-\(pollId)" } diff --git a/Sources/StreamChatSwiftUI/ChatChannel/Polls/CreatePollViewModel.swift b/Sources/StreamChatSwiftUI/ChatChannel/Polls/CreatePollViewModel.swift index 97f6130e7..e1b92cb04 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/Polls/CreatePollViewModel.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/Polls/CreatePollViewModel.swift @@ -81,7 +81,7 @@ import SwiftUI .combineLatest($maxVotesEnabled) .map { $0 && $1 } .removeDuplicates() - .assignWeakly(to: \.showsMaxVotesError, on: self) + .assign(to: \.showsMaxVotesError, onWeak: self) .store(in: &cancellables) $options .map { options in @@ -97,7 +97,7 @@ import SwiftUI return errorIndices } .removeDuplicates() - .assignWeakly(to: \.optionsErrorIndices, on: self) + .assign(to: \.optionsErrorIndices, onWeak: self) .store(in: &cancellables) } diff --git a/Sources/StreamChatSwiftUI/ChatChannel/Reactions/ReactionsUsersView.swift b/Sources/StreamChatSwiftUI/ChatChannel/Reactions/ReactionsUsersView.swift index e4b963505..1203fe2b2 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/Reactions/ReactionsUsersView.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/Reactions/ReactionsUsersView.swift @@ -79,9 +79,3 @@ struct ReactionsUsersView: View { .accessibilityIdentifier("ReactionsUsersView") } } - -extension ChatMessageReaction: Identifiable { - public var id: String { - "\(author.id)-\(type.rawValue)" - } -} diff --git a/Sources/StreamChatSwiftUI/ChatChannel/Reactions/ReactionsView.swift b/Sources/StreamChatSwiftUI/ChatChannel/Reactions/ReactionsView.swift index 9a1077bd5..644dd20b0 100644 --- a/Sources/StreamChatSwiftUI/ChatChannel/Reactions/ReactionsView.swift +++ b/Sources/StreamChatSwiftUI/ChatChannel/Reactions/ReactionsView.swift @@ -120,9 +120,3 @@ public struct ReactionIcon: View { .foregroundColor(color) } } - -extension MessageReactionType: Identifiable { - public var id: String { - rawValue - } -} diff --git a/Sources/StreamChatSwiftUI/ChatChannelList/ChatChannelList.swift b/Sources/StreamChatSwiftUI/ChatChannelList/ChatChannelList.swift index c9e2a738f..8731b9386 100644 --- a/Sources/StreamChatSwiftUI/ChatChannelList/ChatChannelList.swift +++ b/Sources/StreamChatSwiftUI/ChatChannelList/ChatChannelList.swift @@ -211,10 +211,3 @@ public struct ChannelsLazyVStack: View { .modifier(factory.makeChannelListModifier(options: ChannelListModifierOptions())) } } - -/// Determines the uniqueness of the channel list item. -extension ChatChannel: Identifiable { - public var id: String { - cid.rawValue - } -} diff --git a/Sources/StreamChatSwiftUI/ChatThreadList/ChatThreadList.swift b/Sources/StreamChatSwiftUI/ChatThreadList/ChatThreadList.swift index a087a8a66..8771a0073 100644 --- a/Sources/StreamChatSwiftUI/ChatThreadList/ChatThreadList.swift +++ b/Sources/StreamChatSwiftUI/ChatThreadList/ChatThreadList.swift @@ -119,10 +119,3 @@ public struct ThreadsLazyVStack: View { } } } - -/// Determines the uniqueness of the channel list item. -extension ChatThread: Identifiable { - public var id: String { - parentMessageId - } -} diff --git a/Sources/StreamChatSwiftUI/DependencyInjection.swift b/Sources/StreamChatSwiftUI/DependencyInjection.swift deleted file mode 100644 index 89ef3ed12..000000000 --- a/Sources/StreamChatSwiftUI/DependencyInjection.swift +++ /dev/null @@ -1,45 +0,0 @@ -// -// Copyright © 2025 Stream.io Inc. All rights reserved. -// - -import Foundation -import StreamChat - -@MainActor public protocol InjectionKey { - /// The associated type representing the type of the dependency injection key's value. - associatedtype Value - - /// The default value for the dependency injection key. - static var currentValue: Self.Value { get set } -} - -/// Provides access to injected dependencies. -@MainActor public struct InjectedValues { - /// This is only used as an accessor to the computed properties within extensions of `InjectedValues`. - private static var current = InjectedValues() - - /// A static subscript for updating the `currentValue` of `InjectionKey` instances. - public static subscript(key: K.Type) -> K.Value where K: InjectionKey { - get { key.currentValue } - set { key.currentValue = newValue } - } - - /// A static subscript accessor for updating and references dependencies directly. - public static subscript(_ keyPath: WritableKeyPath) -> T { - get { current[keyPath: keyPath] } - set { current[keyPath: keyPath] = newValue } - } -} - -@MainActor @propertyWrapper -public struct Injected { - private let keyPath: WritableKeyPath - public var wrappedValue: T { - get { InjectedValues[keyPath] } - set { InjectedValues[keyPath] = newValue } - } - - public init(_ keyPath: WritableKeyPath) { - self.keyPath = keyPath - } -} diff --git a/Sources/StreamChatSwiftUI/InjectedValuesExtensions.swift b/Sources/StreamChatSwiftUI/InjectedValuesExtensions.swift index 0dc07b6c3..4c9fdff2f 100644 --- a/Sources/StreamChatSwiftUI/InjectedValuesExtensions.swift +++ b/Sources/StreamChatSwiftUI/InjectedValuesExtensions.swift @@ -7,7 +7,7 @@ import StreamChat extension InjectedValues { /// Provides access to the `ChatClient` instance. - public var chatClient: ChatClient { + @MainActor public var chatClient: ChatClient { get { streamChat.chatClient } @@ -17,7 +17,7 @@ extension InjectedValues { } /// Provides access to the `ColorPalette` instance. - public var colors: ColorPalette { + @MainActor public var colors: ColorPalette { get { streamChat.appearance.colors } @@ -27,7 +27,7 @@ extension InjectedValues { } /// Provides access to the `Utils` instance. - public var utils: Utils { + @MainActor public var utils: Utils { get { streamChat.utils } @@ -37,7 +37,7 @@ extension InjectedValues { } /// Provides access to the `Images` instance. - public var images: Images { + @MainActor public var images: Images { get { streamChat.appearance.images } @@ -47,7 +47,7 @@ extension InjectedValues { } /// Provides access to the `Fonts` instance. - public var fonts: Fonts { + @MainActor public var fonts: Fonts { get { streamChat.appearance.fonts } diff --git a/Sources/StreamChatSwiftUI/StreamChat.swift b/Sources/StreamChatSwiftUI/StreamChat.swift index bbfaa8343..ce3e5282a 100644 --- a/Sources/StreamChatSwiftUI/StreamChat.swift +++ b/Sources/StreamChatSwiftUI/StreamChat.swift @@ -26,7 +26,7 @@ import StreamChat /// Returns the current value for the `StreamChat` instance. private struct StreamChatProviderKey: InjectionKey { - static var currentValue: StreamChat? + nonisolated(unsafe) static var currentValue: StreamChat? } extension InjectedValues { diff --git a/Sources/StreamChatSwiftUI/Utils/Common/Publisher+Extensions.swift b/Sources/StreamChatSwiftUI/Utils/Common/Publisher+Extensions.swift deleted file mode 100644 index efb608179..000000000 --- a/Sources/StreamChatSwiftUI/Utils/Common/Publisher+Extensions.swift +++ /dev/null @@ -1,17 +0,0 @@ -// -// Copyright © 2025 Stream.io Inc. All rights reserved. -// - -import Combine - -extension Publisher where Failure == Never { - /// Assigns each element from a publisher to a property on an object without retaining the object. - func assignWeakly( - to keyPath: ReferenceWritableKeyPath, - on root: Root - ) -> AnyCancellable { - sink { [weak root] in - root?[keyPath: keyPath] = $0 - } - } -} diff --git a/Sources/StreamChatSwiftUI/Utils/StreamConcurrency.swift b/Sources/StreamChatSwiftUI/Utils/StreamConcurrency.swift deleted file mode 100644 index 46f2cbace..000000000 --- a/Sources/StreamChatSwiftUI/Utils/StreamConcurrency.swift +++ /dev/null @@ -1,28 +0,0 @@ -// -// Copyright © 2025 Stream.io Inc. All rights reserved. -// - -import Foundation - -enum StreamConcurrency { - /// Synchronously performs the provided action on the main thread. - /// - /// Used for ensuring that we are on the main thread when compiler can't know it. For example, - /// controller completion handlers by default are called from main thread, but one can - /// configure controller to use background thread for completions instead. - /// - /// - Important: It is safe to call from any thread. It does not deadlock if we are already on the main thread. - /// - Important: Prefer Task { @MainActor if possible. - static func onMain(_ action: @MainActor () throws -> T) rethrows -> T where T: Sendable { - if Thread.current.isMainThread { - try MainActor.assumeIsolated { - try action() - } - } else { - // We use sync here, because this function supports returning a value. - try DispatchQueue.main.sync { - try action() - } - } - } -} diff --git a/Sources/StreamChatSwiftUI/Utils/StreamCore+Extensions.swift b/Sources/StreamChatSwiftUI/Utils/StreamCore+Extensions.swift new file mode 100644 index 000000000..71fa71a0f --- /dev/null +++ b/Sources/StreamChatSwiftUI/Utils/StreamCore+Extensions.swift @@ -0,0 +1,6 @@ +// +// Copyright © 2025 Stream.io Inc. All rights reserved. +// + +import Foundation +@_exported import StreamCore diff --git a/Sources/StreamChatSwiftUI/Utils/StringExtensions.swift b/Sources/StreamChatSwiftUI/Utils/StringExtensions.swift index beaeba4c0..14d486fdd 100644 --- a/Sources/StreamChatSwiftUI/Utils/StringExtensions.swift +++ b/Sources/StreamChatSwiftUI/Utils/StringExtensions.swift @@ -32,7 +32,7 @@ extension Character { extension String { /// Checks whether a string is a single emoji var isSingleEmoji: Bool { count == 1 && containsEmoji } - + /// Checks whether the string contains an emoji var containsEmoji: Bool { contains { $0.isEmoji } } @@ -42,54 +42,6 @@ extension String { // MARK: - -extension String { - /// computes levenshtein distance with another string (0 - public func levenshtein(_ other: String) -> Int { - let sCount = count - let oCount = other.count - - guard sCount != 0 else { - return oCount - } - - guard oCount != 0 else { - return sCount - } - - let line: [Int] = Array(repeating: 0, count: oCount + 1) - var mat: [[Int]] = Array(repeating: line, count: sCount + 1) - - for i in 0...sCount { - mat[i][0] = i - } - - for j in 0...oCount { - mat[0][j] = j - } - - for j in 1...oCount { - for i in 1...sCount { - if self[i - 1] == other[j - 1] { - mat[i][j] = mat[i - 1][j - 1] // no operation - } else { - let del = mat[i - 1][j] + 1 // deletion - let ins = mat[i][j - 1] + 1 // insertion - let sub = mat[i - 1][j - 1] + 1 // substitution - mat[i][j] = min(min(del, ins), sub) - } - } - } - - return mat[sCount][oCount] - } -} - -extension String { - subscript(index: Int) -> Character { - self[self.index(startIndex, offsetBy: index)] - } -} - extension String { /// Checks whether the string is a URL. var isURL: Bool { @@ -114,20 +66,6 @@ extension String { static let unknownMessageId = "unknown" } -extension String { - func ranges(of string: some StringProtocol, options: String.CompareOptions = []) -> [Range] { - var result: [Range] = [] - var startIndex = startIndex - while startIndex < endIndex, let range = self[startIndex...].range(of: string, options: options) { - result.append(range) - startIndex = range.lowerBound < range.upperBound - ? range.upperBound - : index(range.lowerBound, offsetBy: 1, limitedBy: endIndex) ?? endIndex - } - return result - } -} - extension String { var trimmed: Self { trimmingCharacters(in: .whitespacesAndNewlines) diff --git a/Sources/StreamChatSwiftUI/ViewFactory/DefaultViewFactory.swift b/Sources/StreamChatSwiftUI/ViewFactory/DefaultViewFactory.swift index dd836a78c..574e3e10d 100644 --- a/Sources/StreamChatSwiftUI/ViewFactory/DefaultViewFactory.swift +++ b/Sources/StreamChatSwiftUI/ViewFactory/DefaultViewFactory.swift @@ -978,6 +978,12 @@ extension ViewFactory { ) -> some View { AddUsersView(loadedUserIds: options.options.loadedUsers.map(\.id), onUserTap: options.onUserTap) } + + public func makeAttachmentTextView( + options: AttachmentTextViewOptions + ) -> some View { + StreamTextView(message: options.message) + } } /// Default class conforming to `ViewFactory`, used throughout the SDK. diff --git a/Sources/StreamChatSwiftUI/ViewFactory/ViewFactory.swift b/Sources/StreamChatSwiftUI/ViewFactory/ViewFactory.swift index 38465faa9..8b5d40d51 100644 --- a/Sources/StreamChatSwiftUI/ViewFactory/ViewFactory.swift +++ b/Sources/StreamChatSwiftUI/ViewFactory/ViewFactory.swift @@ -632,4 +632,12 @@ import SwiftUI /// - Parameter options: the options for creating the add users view. /// - Returns: The view shown in the add users slot. func makeAddUsersView(options: AddUsersViewOptions) -> AddUsersViewType + + associatedtype AttachmentTextViewType: View + /// Creates a view for displaying the text of an attachment. + /// - Parameter options: Configuration options for the attachment text view, such as message. + /// - Returns: The view shown in the attachment text slot. + func makeAttachmentTextView( + options: AttachmentTextViewOptions + ) -> AttachmentTextViewType } diff --git a/StreamChatSwiftUI.xcodeproj/project.pbxproj b/StreamChatSwiftUI.xcodeproj/project.pbxproj index 0afb70403..069a528f7 100644 --- a/StreamChatSwiftUI.xcodeproj/project.pbxproj +++ b/StreamChatSwiftUI.xcodeproj/project.pbxproj @@ -10,7 +10,6 @@ 402C54482B6AAC0100672BFB /* StreamChatSwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8465FBB52746873A00AF091E /* StreamChatSwiftUI.framework */; }; 402C54492B6AAC0100672BFB /* StreamChatSwiftUI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8465FBB52746873A00AF091E /* StreamChatSwiftUI.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 4F03F18F2E0140C6001C71A2 /* ChannelAvatarsMerger_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F03F18E2E0140C6001C71A2 /* ChannelAvatarsMerger_Tests.swift */; }; - 4F0695102D96A58300DB7E3B /* StreamConcurrency.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F06950F2D96A57C00DB7E3B /* StreamConcurrency.swift */; }; 4F077EF82C85E05700F06D83 /* DelayedRenderingViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F077EF72C85E05700F06D83 /* DelayedRenderingViewModifier.swift */; }; 4F0AC7F82DCA2CCE00ACB1AC /* ImageProcessors+Anonymous.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F0AC7D62DCA2CCE00ACB1AC /* ImageProcessors+Anonymous.swift */; }; 4F0AC7F92DCA2CCE00ACB1AC /* ImageViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F0AC7EC2DCA2CCE00ACB1AC /* ImageViewExtensions.swift */; }; @@ -78,7 +77,6 @@ 4F0AC8372DCA2CCE00ACB1AC /* ImageLoadingOptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F0AC7EB2DCA2CCE00ACB1AC /* ImageLoadingOptions.swift */; }; 4F0AC8382DCA2CCE00ACB1AC /* DataCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F0AC7AA2DCA2CCE00ACB1AC /* DataCache.swift */; }; 4F0B67C92E7025B6003DA844 /* GalleryHeaderView_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F0B67C82E7025B6003DA844 /* GalleryHeaderView_Tests.swift */; }; - 4F198FDD2C0480EC00148F49 /* Publisher+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F198FDC2C0480EC00148F49 /* Publisher+Extensions.swift */; }; 4F3536942E6EFB510046678E /* NavigationBarThemeViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F3536932E6EFB4B0046678E /* NavigationBarThemeViewModifier.swift */; }; 4F65F1862D06EEA7009F69A8 /* ChooseChannelQueryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F65F1852D06EEA5009F69A8 /* ChooseChannelQueryView.swift */; }; 4F65F18A2D071798009F69A8 /* ChannelListQueryIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F65F1892D071798009F69A8 /* ChannelListQueryIdentifier.swift */; }; @@ -96,6 +94,9 @@ 4FA3741A2D799CA400294721 /* AppConfigurationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FA374192D799CA400294721 /* AppConfigurationView.swift */; }; 4FA3741D2D799FC300294721 /* AppConfigurationTranslationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FA3741C2D799FC300294721 /* AppConfigurationTranslationView.swift */; }; 4FA3741F2D79A64F00294721 /* AppConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FA3741E2D79A64900294721 /* AppConfiguration.swift */; }; + 4FAF7A552EAA1940006F74A1 /* StreamCore+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FAF7A542EAA193B006F74A1 /* StreamCore+Extensions.swift */; }; + 4FB52B472EBB63F700491977 /* StreamCore in Frameworks */ = {isa = PBXBuildFile; productRef = 4FB52B462EBB63F700491977 /* StreamCore */; }; + 4FB52B492EBB643700491977 /* StreamCore in Frameworks */ = {isa = PBXBuildFile; productRef = 4FB52B482EBB643700491977 /* StreamCore */; }; 4FCD7DA72D632121000EEB0F /* MarkdownFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FCD7DA62D63211B000EEB0F /* MarkdownFormatter.swift */; }; 4FCD7DBD2D633F72000EEB0F /* AttributedString+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FCD7DBC2D633F6C000EEB0F /* AttributedString+Extensions.swift */; }; 4FD3592A2C05EA8F00B1D63B /* CreatePollViewModel_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FD359292C05EA8F00B1D63B /* CreatePollViewModel_Tests.swift */; }; @@ -212,7 +213,6 @@ 8465FCE7274695B400AF091E /* StreamChatSwiftUI.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 8465FBB52746873A00AF091E /* StreamChatSwiftUI.framework */; platformFilter = ios; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 8465FD6A2746A95700AF091E /* L10n.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8465FCED2746A95600AF091E /* L10n.swift */; }; 8465FD6B2746A95700AF091E /* L10n_template.stencil in Resources */ = {isa = PBXBuildFile; fileRef = 8465FCEE2746A95600AF091E /* L10n_template.stencil */; }; - 8465FD6E2746A95700AF091E /* DependencyInjection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8465FCF12746A95600AF091E /* DependencyInjection.swift */; }; 8465FD6F2746A95700AF091E /* StreamChat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8465FCF22746A95600AF091E /* StreamChat.swift */; }; 8465FD702746A95700AF091E /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8465FCF42746A95600AF091E /* Localizable.strings */; }; 8465FD712746A95700AF091E /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 8465FCF62746A95600AF091E /* Localizable.stringsdict */; }; @@ -375,7 +375,6 @@ 84B738332BE2575E00EC66EC /* PollOptionAllVotesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B738322BE2575E00EC66EC /* PollOptionAllVotesView.swift */; }; 84B738352BE2661B00EC66EC /* PollOptionAllVotesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B738342BE2661B00EC66EC /* PollOptionAllVotesViewModel.swift */; }; 84B738402BE8EE1800EC66EC /* PollCommentsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B7383F2BE8EE1800EC66EC /* PollCommentsView.swift */; }; - 84B87F232861C0C900959CBE /* StreamChat in Frameworks */ = {isa = PBXBuildFile; productRef = 84B87F222861C0C900959CBE /* StreamChat */; }; 84B9B20E27998E9200BFAEAE /* ColorExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B9B20D27998E9200BFAEAE /* ColorExtensions.swift */; }; 84BB4C4C2841104700CBE004 /* MessageListDateUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84BB4C4B2841104700CBE004 /* MessageListDateUtils.swift */; }; 84BB4C4E284115C200CBE004 /* MessageListDateUtils_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84BB4C4D284115C200CBE004 /* MessageListDateUtils_Tests.swift */; }; @@ -532,6 +531,7 @@ C14A465B284665B100EF498E /* SDKIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = C14A465A284665B100EF498E /* SDKIdentifier.swift */; }; C52A0B5F2E1557F900176379 /* VideoPlayerFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C52A0B5E2E1557F300176379 /* VideoPlayerFooterView.swift */; }; E3A1C01C282BAC66002D1E26 /* Sentry in Frameworks */ = {isa = PBXBuildFile; productRef = E3A1C01B282BAC66002D1E26 /* Sentry */; }; + E3A1C01D282BAC66002D1E27 /* StreamChat in Frameworks */ = {isa = PBXBuildFile; productRef = 82FF61EB2B6AB789007185B6 /* StreamChat */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -604,7 +604,6 @@ /* Begin PBXFileReference section */ 4A65451E274BA170003C5FA8 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 4F03F18E2E0140C6001C71A2 /* ChannelAvatarsMerger_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelAvatarsMerger_Tests.swift; sourceTree = ""; }; - 4F06950F2D96A57C00DB7E3B /* StreamConcurrency.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StreamConcurrency.swift; sourceTree = ""; }; 4F077EF72C85E05700F06D83 /* DelayedRenderingViewModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DelayedRenderingViewModifier.swift; sourceTree = ""; }; 4F0AC7AA2DCA2CCE00ACB1AC /* DataCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataCache.swift; sourceTree = ""; }; 4F0AC7AB2DCA2CCE00ACB1AC /* DataCaching.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataCaching.swift; sourceTree = ""; }; @@ -672,7 +671,6 @@ 4F0AC7F52DCA2CCE00ACB1AC /* ImageDecoders+Video.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ImageDecoders+Video.swift"; sourceTree = ""; }; 4F0AC7F62DCA2CCE00ACB1AC /* NukeVideoPlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NukeVideoPlayerView.swift; sourceTree = ""; }; 4F0B67C82E7025B6003DA844 /* GalleryHeaderView_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GalleryHeaderView_Tests.swift; sourceTree = ""; }; - 4F198FDC2C0480EC00148F49 /* Publisher+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Publisher+Extensions.swift"; sourceTree = ""; }; 4F3536932E6EFB4B0046678E /* NavigationBarThemeViewModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationBarThemeViewModifier.swift; sourceTree = ""; }; 4F65F1852D06EEA5009F69A8 /* ChooseChannelQueryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChooseChannelQueryView.swift; sourceTree = ""; }; 4F65F1892D071798009F69A8 /* ChannelListQueryIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChannelListQueryIdentifier.swift; sourceTree = ""; }; @@ -689,6 +687,7 @@ 4FA374192D799CA400294721 /* AppConfigurationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppConfigurationView.swift; sourceTree = ""; }; 4FA3741C2D799FC300294721 /* AppConfigurationTranslationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppConfigurationTranslationView.swift; sourceTree = ""; }; 4FA3741E2D79A64900294721 /* AppConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppConfiguration.swift; sourceTree = ""; }; + 4FAF7A542EAA193B006F74A1 /* StreamCore+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "StreamCore+Extensions.swift"; sourceTree = ""; }; 4FCD7DA62D63211B000EEB0F /* MarkdownFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkdownFormatter.swift; sourceTree = ""; }; 4FCD7DBC2D633F6C000EEB0F /* AttributedString+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AttributedString+Extensions.swift"; sourceTree = ""; }; 4FD359292C05EA8F00B1D63B /* CreatePollViewModel_Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatePollViewModel_Tests.swift; sourceTree = ""; }; @@ -807,7 +806,6 @@ 8465FCD7274694D200AF091E /* CustomChannelHeader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomChannelHeader.swift; sourceTree = ""; }; 8465FCED2746A95600AF091E /* L10n.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = L10n.swift; sourceTree = ""; }; 8465FCEE2746A95600AF091E /* L10n_template.stencil */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = L10n_template.stencil; sourceTree = ""; }; - 8465FCF12746A95600AF091E /* DependencyInjection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DependencyInjection.swift; sourceTree = ""; }; 8465FCF22746A95600AF091E /* StreamChat.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StreamChat.swift; sourceTree = ""; }; 8465FCF52746A95600AF091E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; 8465FCF72746A95600AF091E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = ""; }; @@ -1163,6 +1161,7 @@ buildActionMask = 2147483647; files = ( 84E95A77284A486600699FD3 /* StreamChat in Frameworks */, + 4FB52B492EBB643700491977 /* StreamCore in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1180,9 +1179,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 84B87F232861C0C900959CBE /* StreamChat in Frameworks */, 8465FCE6274695B400AF091E /* StreamChatSwiftUI.framework in Frameworks */, E3A1C01C282BAC66002D1E26 /* Sentry in Frameworks */, + E3A1C01D282BAC66002D1E27 /* StreamChat in Frameworks */, + 4FB52B472EBB63F700491977 /* StreamCore in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1658,7 +1658,6 @@ 8465FD622746A95700AF091E /* Images.swift */, 8465FD642746A95700AF091E /* ColorPalette.swift */, 8465FD632746A95700AF091E /* Utils.swift */, - 8465FCF12746A95600AF091E /* DependencyInjection.swift */, 8465FD5F2746A95700AF091E /* InjectedValuesExtensions.swift */, 84EB88092E8A747D0076DC17 /* ViewFactory */, 8465FD4C2746A95600AF091E /* ChatChannelList */, @@ -1875,7 +1874,7 @@ AD3AB64F2CB41B0D0014D4D7 /* NavigationContainerView.swift */, 8465FD332746A95600AF091E /* NukeImageLoader.swift */, 84C0C9A228CF18F700CD0136 /* SnapshotCreator.swift */, - 4F06950F2D96A57C00DB7E3B /* StreamConcurrency.swift */, + 4FAF7A542EAA193B006F74A1 /* StreamCore+Extensions.swift */, 84F130C02AEAA957006E7B52 /* StreamLazyImage.swift */, 8465FD3B2746A95600AF091E /* StringExtensions.swift */, 4FEAB3172BFF71F70057E511 /* SwiftUI+UIAlertController.swift */, @@ -1906,7 +1905,6 @@ 8465FD432746A95600AF091E /* NSLayoutConstraint+Extensions.swift */, 8465FD492746A95600AF091E /* NukeImageProcessor.swift */, 4F7720AD2C58C45000BAEC02 /* OnLoadViewModifier.swift */, - 4F198FDC2C0480EC00148F49 /* Publisher+Extensions.swift */, 8465FD3E2746A95600AF091E /* UIColor+Extensions.swift */, 8465FD3C2746A95600AF091E /* UIFont+Extensions.swift */, 8465FD3F2746A95600AF091E /* UIImage+Extensions.swift */, @@ -2377,6 +2375,7 @@ name = StreamChatSwiftUI; packageProductDependencies = ( 84E95A76284A486600699FD3 /* StreamChat */, + 4FB52B482EBB643700491977 /* StreamCore */, ); productName = StreamChatSwiftUI; productReference = 8465FBB52746873A00AF091E /* StreamChatSwiftUI.framework */; @@ -2421,7 +2420,8 @@ name = DemoAppSwiftUI; packageProductDependencies = ( E3A1C01B282BAC66002D1E26 /* Sentry */, - 84B87F222861C0C900959CBE /* StreamChat */, + 82FF61EB2B6AB789007185B6 /* StreamChat */, + 4FB52B462EBB63F700491977 /* StreamCore */, ); productName = DemoAppSwiftUI; productReference = 8465FCBC27468B6900AF091E /* DemoAppSwiftUI.app */; @@ -2471,6 +2471,7 @@ 8400A346282C06F90067D3A0 /* XCRemoteSwiftPackageReference "OHHTTPStubs" */, 84E95A75284A486600699FD3 /* XCRemoteSwiftPackageReference "stream-chat-swift" */, 82543C7B2AD41B0400D5F6CD /* XCRemoteSwiftPackageReference "stream-chat-swift-test-helpers" */, + 4FB52B452EBB63F700491977 /* XCRemoteSwiftPackageReference "stream-core-swift" */, ); productRefGroup = 8465FBB62746873A00AF091E /* Products */; projectDirPath = ""; @@ -2674,6 +2675,7 @@ 4FEAB3182BFF71F70057E511 /* SwiftUI+UIAlertController.swift in Sources */, 84DEC8EC27611CAE00172876 /* SendInChannelView.swift in Sources */, 84F130C12AEAA957006E7B52 /* StreamLazyImage.swift in Sources */, + 4FAF7A552EAA1940006F74A1 /* StreamCore+Extensions.swift in Sources */, ADE0F5602CB846EC0053B8B9 /* FloatingBannerViewModifier.swift in Sources */, 8465FD9F2746A95700AF091E /* ChatChannelExtensions.swift in Sources */, 844D1D6628510304000CCCB9 /* ChannelControllerFactory.swift in Sources */, @@ -2687,7 +2689,6 @@ 8465FDB52746A95700AF091E /* Cache.swift in Sources */, 84A1CAD12816C6900046595A /* AddUsersViewModel.swift in Sources */, AD3DB82F2E7C2E190023D377 /* GalleryHeaderViewDateFormatter.swift in Sources */, - 4F198FDD2C0480EC00148F49 /* Publisher+Extensions.swift in Sources */, 84289BEF2807246E00282ABE /* FileAttachmentsViewModel.swift in Sources */, 84AB7B2A2773D97E00631A10 /* MentionsCommandHandler.swift in Sources */, 84DEC8EA2761089A00172876 /* MessageThreadHeaderViewModifier.swift in Sources */, @@ -2747,7 +2748,6 @@ 84A1CACF2816BCF00046595A /* AddUsersView.swift in Sources */, 8465FD9C2746A95700AF091E /* MessageActionsView.swift in Sources */, 849F6BF02B1A06D10032303E /* JumpToUnreadButton.swift in Sources */, - 8465FD6E2746A95700AF091E /* DependencyInjection.swift in Sources */, 841B64D62775FDA00016FF3B /* InstantCommandsHandler.swift in Sources */, 8465FDC92746A95700AF091E /* ChatChannelSwipeableListItem.swift in Sources */, 82D64B6A2AD7E5AC00C5C79E /* SwiftyGifManager.swift in Sources */, @@ -2903,7 +2903,6 @@ 84B738352BE2661B00EC66EC /* PollOptionAllVotesViewModel.swift in Sources */, 8465FDAC2746A95700AF091E /* UIFont+Extensions.swift in Sources */, 846D6564279FF0800094B36E /* ReactionUserView.swift in Sources */, - 4F0695102D96A58300DB7E3B /* StreamConcurrency.swift in Sources */, 8465FDB12746A95700AF091E /* ChatChannelNamer.swift in Sources */, 8465FD9E2746A95700AF091E /* ChatChannelHelpers.swift in Sources */, 84E4F7CF294C69F300DD4CE3 /* MessageIdBuilder.swift in Sources */, @@ -3833,6 +3832,14 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ + 4FB52B452EBB63F700491977 /* XCRemoteSwiftPackageReference "stream-core-swift" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/GetStream/stream-core-swift"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.5.0; + }; + }; 82543C7B2AD41B0400D5F6CD /* XCRemoteSwiftPackageReference "stream-chat-swift-test-helpers" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/GetStream/stream-chat-swift-test-helpers.git"; @@ -3876,6 +3883,16 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ + 4FB52B462EBB63F700491977 /* StreamCore */ = { + isa = XCSwiftPackageProductDependency; + package = 4FB52B452EBB63F700491977 /* XCRemoteSwiftPackageReference "stream-core-swift" */; + productName = StreamCore; + }; + 4FB52B482EBB643700491977 /* StreamCore */ = { + isa = XCSwiftPackageProductDependency; + package = 4FB52B452EBB63F700491977 /* XCRemoteSwiftPackageReference "stream-core-swift" */; + productName = StreamCore; + }; 8205B4132AD41CC700265B84 /* StreamSwiftTestHelpers */ = { isa = XCSwiftPackageProductDependency; package = 82543C7B2AD41B0400D5F6CD /* XCRemoteSwiftPackageReference "stream-chat-swift-test-helpers" */; @@ -3911,11 +3928,6 @@ package = 84E95A75284A486600699FD3 /* XCRemoteSwiftPackageReference "stream-chat-swift" */; productName = StreamChatTestTools; }; - 84B87F222861C0C900959CBE /* StreamChat */ = { - isa = XCSwiftPackageProductDependency; - package = 84E95A75284A486600699FD3 /* XCRemoteSwiftPackageReference "stream-chat-swift" */; - productName = StreamChat; - }; 84E95A76284A486600699FD3 /* StreamChat */ = { isa = XCSwiftPackageProductDependency; package = 84E95A75284A486600699FD3 /* XCRemoteSwiftPackageReference "stream-chat-swift" */; diff --git a/StreamChatSwiftUITests/Infrastructure/Mocks/EventBatcherMock.swift b/StreamChatSwiftUITests/Infrastructure/Mocks/EventBatcherMock.swift index 282fa7716..3b00587a7 100644 --- a/StreamChatSwiftUITests/Infrastructure/Mocks/EventBatcherMock.swift +++ b/StreamChatSwiftUITests/Infrastructure/Mocks/EventBatcherMock.swift @@ -12,7 +12,7 @@ final class EventBatcherMock: EventBatcher, @unchecked Sendable { init( period: TimeInterval = 0, - timerType: StreamChat.Timer.Type = DefaultTimer.self, + timerType: TimerScheduling.Type = DefaultTimer.self, handler: @escaping (_ batch: [Event], _ completion: @escaping @Sendable () -> Void) -> Void ) { self.handler = handler diff --git a/StreamChatSwiftUITests/Infrastructure/Mocks/EventNotificationCenterMock.swift b/StreamChatSwiftUITests/Infrastructure/Mocks/EventNotificationCenterMock.swift index 1102f7d6e..7ac8a5240 100644 --- a/StreamChatSwiftUITests/Infrastructure/Mocks/EventNotificationCenterMock.swift +++ b/StreamChatSwiftUITests/Infrastructure/Mocks/EventNotificationCenterMock.swift @@ -6,7 +6,7 @@ import Foundation @testable import StreamChat /// Mock implementation of `EventNotificationCenter` -final class EventNotificationCenterMock: EventNotificationCenter, @unchecked Sendable { +final class EventNotificationCenterMock: PersistentEventNotificationCenter, @unchecked Sendable { lazy var mock_process = MockFunc<([Event], Bool, (@Sendable () -> Void)?), Void>.mock(for: process) override func process( diff --git a/StreamChatSwiftUITests/Infrastructure/Mocks/InternetConnectionMock.swift b/StreamChatSwiftUITests/Infrastructure/Mocks/InternetConnectionMock.swift index ad394bdb2..ad5deaac9 100644 --- a/StreamChatSwiftUITests/Infrastructure/Mocks/InternetConnectionMock.swift +++ b/StreamChatSwiftUITests/Infrastructure/Mocks/InternetConnectionMock.swift @@ -22,7 +22,7 @@ class InternetConnectionMock: InternetConnection, @unchecked Sendable { class InternetConnectionMonitorMock: InternetConnectionMonitor, @unchecked Sendable { weak var delegate: InternetConnectionDelegate? - var status: InternetConnection.Status = .unknown { + var status: InternetConnectionStatus = .unknown { didSet { delegate?.internetConnectionStatusDidChange(status: status) } diff --git a/StreamChatSwiftUITests/Infrastructure/Mocks/VirtualTimer.swift b/StreamChatSwiftUITests/Infrastructure/Mocks/VirtualTimer.swift index 04fcdf6ee..179e4057a 100644 --- a/StreamChatSwiftUITests/Infrastructure/Mocks/VirtualTimer.swift +++ b/StreamChatSwiftUITests/Infrastructure/Mocks/VirtualTimer.swift @@ -6,7 +6,7 @@ import Foundation @testable import StreamChat import XCTest -struct VirtualTimeTimer: StreamChat.Timer { +struct VirtualTimeTimer: TimerScheduling { static var time: VirtualTime! static func schedule(timeInterval: TimeInterval, queue: DispatchQueue, onFire: @escaping () -> Void) -> TimerControl { diff --git a/StreamChatSwiftUITests/Infrastructure/Mocks/WebSocketEngineMock.swift b/StreamChatSwiftUITests/Infrastructure/Mocks/WebSocketEngineMock.swift index 1adbeb447..64361a075 100644 --- a/StreamChatSwiftUITests/Infrastructure/Mocks/WebSocketEngineMock.swift +++ b/StreamChatSwiftUITests/Infrastructure/Mocks/WebSocketEngineMock.swift @@ -4,6 +4,7 @@ import Foundation @testable import StreamChat +@testable import StreamCore class WebSocketEngineMock: WebSocketEngine, @unchecked Sendable { var request: URLRequest @@ -38,7 +39,15 @@ class WebSocketEngineMock: WebSocketEngine, @unchecked Sendable { func disconnect() { disconnect_calledCount += 1 } + + func disconnect(with code: URLSessionWebSocketTask.CloseCode) { + disconnect_calledCount += 1 + } + func send(message: any SendableEvent) {} + + func send(jsonMessage: any Codable) {} + func sendPing() { sendPing_calledCount += 1 } @@ -56,7 +65,7 @@ class WebSocketEngineMock: WebSocketEngine, @unchecked Sendable { } func simulateMessageReceived(_ data: Data) { - delegate?.webSocketDidReceiveMessage(String(data: data, encoding: .utf8)!) + delegate?.webSocketDidReceiveMessage(data) } func simulatePong() { diff --git a/StreamChatSwiftUITests/Infrastructure/Mocks/WebSocketPingControllerMock.swift b/StreamChatSwiftUITests/Infrastructure/Mocks/WebSocketPingControllerMock.swift index 58b9807fc..e255fb996 100644 --- a/StreamChatSwiftUITests/Infrastructure/Mocks/WebSocketPingControllerMock.swift +++ b/StreamChatSwiftUITests/Infrastructure/Mocks/WebSocketPingControllerMock.swift @@ -4,6 +4,7 @@ import Foundation @testable import StreamChat +@testable import StreamCore class WebSocketPingControllerMock: WebSocketPingController, @unchecked Sendable { var connectionStateDidChange_connectionStates: [WebSocketConnectionState] = [] diff --git a/StreamChatSwiftUITests/Infrastructure/TestTools/ChatClient_Mock.swift b/StreamChatSwiftUITests/Infrastructure/TestTools/ChatClient_Mock.swift index 2a95a9a43..7603bb479 100644 --- a/StreamChatSwiftUITests/Infrastructure/TestTools/ChatClient_Mock.swift +++ b/StreamChatSwiftUITests/Infrastructure/TestTools/ChatClient_Mock.swift @@ -34,9 +34,8 @@ public extension ChatClient { webSocketClientBuilder: { WebSocketClient_Mock( sessionConfiguration: $0, - requestEncoder: $1, - eventDecoder: $2, - eventNotificationCenter: $3 + eventDecoder: $1, + eventNotificationCenter: $2 ) }, databaseContainerBuilder: { diff --git a/StreamChatSwiftUITests/Tests/ChatChannel/MessageComposerView_Tests.swift b/StreamChatSwiftUITests/Tests/ChatChannel/MessageComposerView_Tests.swift index 0bd975668..3c2aff650 100644 --- a/StreamChatSwiftUITests/Tests/ChatChannel/MessageComposerView_Tests.swift +++ b/StreamChatSwiftUITests/Tests/ChatChannel/MessageComposerView_Tests.swift @@ -301,7 +301,7 @@ import XCTest // When let pickerTypeState: Binding = .constant(.expanded(.none)) - let view = factory.makeLeadingComposerView(state: pickerTypeState, channelConfig: nil) + let view = factory.makeLeadingComposerView(options: LeadingComposerViewOptions(state: pickerTypeState, channelConfig: nil)) .environmentObject(viewModel) .frame(width: 36, height: 36) @@ -317,11 +317,11 @@ import XCTest let viewModel = MessageComposerViewModel(channelController: mockChannelController, messageController: nil) // When - let view = factory.makeTrailingComposerView( + let view = factory.makeTrailingComposerView(options: TrailingComposerViewOptions( enabled: true, cooldownDuration: 0, onTap: {} - ) + )) .environmentObject(viewModel) .frame(width: 100, height: 40) diff --git a/StreamChatSwiftUITests/Tests/Utils/StringExtensions_Tests.swift b/StreamChatSwiftUITests/Tests/Utils/StringExtensions_Tests.swift index 38a6d8e14..3ea0a567f 100644 --- a/StreamChatSwiftUITests/Tests/Utils/StringExtensions_Tests.swift +++ b/StreamChatSwiftUITests/Tests/Utils/StringExtensions_Tests.swift @@ -44,14 +44,6 @@ class String_Extensions_Tests: XCTestCase { XCTAssertFalse("#".containsEmoji) } - func testLevenshtein() throws { - XCTAssertEqual("".levenshtein(""), "".levenshtein("")) - XCTAssertEqual("".levenshtein(""), 0) - XCTAssertEqual("a".levenshtein(""), 1) - XCTAssertEqual("".levenshtein("a"), 1) - XCTAssertEqual("tommaso".levenshtein("ToMmAsO"), 4) - } - func testValidURL() { XCTAssert("https://example.com".isURL == true) } @@ -61,24 +53,4 @@ class String_Extensions_Tests: XCTestCase { XCTAssert("example".isURL == false) XCTAssert("invalid_url".isURL == false) } - - func testRangesOfString() { - let mention = "@Martin" - let string = "Hey \(mention), how are you?" - let result = string - .ranges(of: mention, options: [.caseInsensitive]) - .map { NSRange($0, in: string) } - .first - XCTAssertEqual(result, NSRange(location: 4, length: 7)) - } - - func testRangesOfStringNotFound() { - let string = "Hey @Martin, how are you?" - let mention = "@Alexey" - let result = string - .ranges(of: mention, options: [.caseInsensitive]) - .map { NSRange($0, in: string) } - .first - XCTAssertEqual(result, nil) - } } diff --git a/StreamChatSwiftUITestsApp/InternetConnectionMonitor_Mock.swift b/StreamChatSwiftUITestsApp/InternetConnectionMonitor_Mock.swift index cb5a87b6d..7b888a620 100644 --- a/StreamChatSwiftUITestsApp/InternetConnectionMonitor_Mock.swift +++ b/StreamChatSwiftUITestsApp/InternetConnectionMonitor_Mock.swift @@ -7,15 +7,15 @@ import Foundation // #if TESTS @testable import StreamChat -final class InternetConnectionMonitor_Mock: InternetConnectionMonitor { +final class InternetConnectionMonitor_Mock: InternetConnectionMonitor, @unchecked Sendable { var delegate: InternetConnectionDelegate? - var status: InternetConnection.Status = .available(.great) + var status: InternetConnectionStatus = .available(.great) func start() {} func stop() {} - func update(with status: InternetConnection.Status) { + func update(with status: InternetConnectionStatus) { self.status = status delegate?.internetConnectionStatusDidChange(status: status) }