diff --git a/ElementX/Sources/Mocks/ClientProxyMock.swift b/ElementX/Sources/Mocks/ClientProxyMock.swift index e2c9ae69f..c180dea37 100644 --- a/ElementX/Sources/Mocks/ClientProxyMock.swift +++ b/ElementX/Sources/Mocks/ClientProxyMock.swift @@ -81,9 +81,11 @@ extension ClientProxyMock { recentlyVisitedRoomsReturnValue = .success([]) recentConversationCounterpartsReturnValue = [] - loadMediaContentForSourceThrowableError = ClientProxyError.sdkError(ClientProxyMockError.generic) - loadMediaThumbnailForSourceWidthHeightThrowableError = ClientProxyError.sdkError(ClientProxyMockError.generic) - loadMediaFileForSourceFilenameThrowableError = ClientProxyError.sdkError(ClientProxyMockError.generic) + let mediaLoader = MediaLoaderMock() + mediaLoader.loadMediaContentForSourceThrowableError = ClientProxyError.sdkError(ClientProxyMockError.generic) + mediaLoader.loadMediaThumbnailForSourceWidthHeightThrowableError = ClientProxyError.sdkError(ClientProxyMockError.generic) + mediaLoader.loadMediaFileForSourceFilenameThrowableError = ClientProxyError.sdkError(ClientProxyMockError.generic) + self.mediaLoader = mediaLoader secureBackupController = SecureBackupControllerMock(.init(recoveryState: configuration.recoveryState)) resetIdentityReturnValue = .success(IdentityResetHandleSDKMock(.init())) diff --git a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift index 09fdebe4c..fdd917242 100644 --- a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift @@ -2130,6 +2130,11 @@ class ClientProxyMock: ClientProxyProtocol, @unchecked Sendable { } var underlyingHideInviteAvatarsPublisher: CurrentValuePublisher! var pusherNotificationClientIdentifier: String? + var mediaLoader: MediaLoaderProtocol { + get { return underlyingMediaLoader } + set(value) { underlyingMediaLoader = value } + } + var underlyingMediaLoader: MediaLoaderProtocol! var roomSummaryProvider: RoomSummaryProviderProtocol { get { return underlyingRoomSummaryProvider } set(value) { underlyingRoomSummaryProvider = value } @@ -5204,228 +5209,6 @@ class ClientProxyMock: ClientProxyProtocol, @unchecked Sendable { return setHideInviteAvatarsReturnValue } } - //MARK: - loadMediaContentForSource - - var loadMediaContentForSourceThrowableError: Error? - var loadMediaContentForSourceUnderlyingCallsCount = 0 - var loadMediaContentForSourceCallsCount: Int { - get { - if Thread.isMainThread { - return loadMediaContentForSourceUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = loadMediaContentForSourceUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - loadMediaContentForSourceUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - loadMediaContentForSourceUnderlyingCallsCount = newValue - } - } - } - } - var loadMediaContentForSourceCalled: Bool { - return loadMediaContentForSourceCallsCount > 0 - } - var loadMediaContentForSourceReceivedSource: MediaSourceProxy? - var loadMediaContentForSourceReceivedInvocations: [MediaSourceProxy] = [] - - var loadMediaContentForSourceUnderlyingReturnValue: Data! - var loadMediaContentForSourceReturnValue: Data! { - get { - if Thread.isMainThread { - return loadMediaContentForSourceUnderlyingReturnValue - } else { - var returnValue: Data? = nil - DispatchQueue.main.sync { - returnValue = loadMediaContentForSourceUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - loadMediaContentForSourceUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - loadMediaContentForSourceUnderlyingReturnValue = newValue - } - } - } - } - var loadMediaContentForSourceClosure: ((MediaSourceProxy) async throws -> Data)? - - func loadMediaContentForSource(_ source: MediaSourceProxy) async throws -> Data { - if let error = loadMediaContentForSourceThrowableError { - throw error - } - loadMediaContentForSourceCallsCount += 1 - loadMediaContentForSourceReceivedSource = source - DispatchQueue.main.async { - self.loadMediaContentForSourceReceivedInvocations.append(source) - } - if let loadMediaContentForSourceClosure = loadMediaContentForSourceClosure { - return try await loadMediaContentForSourceClosure(source) - } else { - return loadMediaContentForSourceReturnValue - } - } - //MARK: - loadMediaThumbnailForSource - - var loadMediaThumbnailForSourceWidthHeightThrowableError: Error? - var loadMediaThumbnailForSourceWidthHeightUnderlyingCallsCount = 0 - var loadMediaThumbnailForSourceWidthHeightCallsCount: Int { - get { - if Thread.isMainThread { - return loadMediaThumbnailForSourceWidthHeightUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = loadMediaThumbnailForSourceWidthHeightUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - loadMediaThumbnailForSourceWidthHeightUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - loadMediaThumbnailForSourceWidthHeightUnderlyingCallsCount = newValue - } - } - } - } - var loadMediaThumbnailForSourceWidthHeightCalled: Bool { - return loadMediaThumbnailForSourceWidthHeightCallsCount > 0 - } - var loadMediaThumbnailForSourceWidthHeightReceivedArguments: (source: MediaSourceProxy, width: UInt, height: UInt)? - var loadMediaThumbnailForSourceWidthHeightReceivedInvocations: [(source: MediaSourceProxy, width: UInt, height: UInt)] = [] - - var loadMediaThumbnailForSourceWidthHeightUnderlyingReturnValue: Data! - var loadMediaThumbnailForSourceWidthHeightReturnValue: Data! { - get { - if Thread.isMainThread { - return loadMediaThumbnailForSourceWidthHeightUnderlyingReturnValue - } else { - var returnValue: Data? = nil - DispatchQueue.main.sync { - returnValue = loadMediaThumbnailForSourceWidthHeightUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - loadMediaThumbnailForSourceWidthHeightUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - loadMediaThumbnailForSourceWidthHeightUnderlyingReturnValue = newValue - } - } - } - } - var loadMediaThumbnailForSourceWidthHeightClosure: ((MediaSourceProxy, UInt, UInt) async throws -> Data)? - - func loadMediaThumbnailForSource(_ source: MediaSourceProxy, width: UInt, height: UInt) async throws -> Data { - if let error = loadMediaThumbnailForSourceWidthHeightThrowableError { - throw error - } - loadMediaThumbnailForSourceWidthHeightCallsCount += 1 - loadMediaThumbnailForSourceWidthHeightReceivedArguments = (source: source, width: width, height: height) - DispatchQueue.main.async { - self.loadMediaThumbnailForSourceWidthHeightReceivedInvocations.append((source: source, width: width, height: height)) - } - if let loadMediaThumbnailForSourceWidthHeightClosure = loadMediaThumbnailForSourceWidthHeightClosure { - return try await loadMediaThumbnailForSourceWidthHeightClosure(source, width, height) - } else { - return loadMediaThumbnailForSourceWidthHeightReturnValue - } - } - //MARK: - loadMediaFileForSource - - var loadMediaFileForSourceFilenameThrowableError: Error? - var loadMediaFileForSourceFilenameUnderlyingCallsCount = 0 - var loadMediaFileForSourceFilenameCallsCount: Int { - get { - if Thread.isMainThread { - return loadMediaFileForSourceFilenameUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = loadMediaFileForSourceFilenameUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - loadMediaFileForSourceFilenameUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - loadMediaFileForSourceFilenameUnderlyingCallsCount = newValue - } - } - } - } - var loadMediaFileForSourceFilenameCalled: Bool { - return loadMediaFileForSourceFilenameCallsCount > 0 - } - var loadMediaFileForSourceFilenameReceivedArguments: (source: MediaSourceProxy, filename: String?)? - var loadMediaFileForSourceFilenameReceivedInvocations: [(source: MediaSourceProxy, filename: String?)] = [] - - var loadMediaFileForSourceFilenameUnderlyingReturnValue: MediaFileHandleProxy! - var loadMediaFileForSourceFilenameReturnValue: MediaFileHandleProxy! { - get { - if Thread.isMainThread { - return loadMediaFileForSourceFilenameUnderlyingReturnValue - } else { - var returnValue: MediaFileHandleProxy? = nil - DispatchQueue.main.sync { - returnValue = loadMediaFileForSourceFilenameUnderlyingReturnValue - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - loadMediaFileForSourceFilenameUnderlyingReturnValue = newValue - } else { - DispatchQueue.main.sync { - loadMediaFileForSourceFilenameUnderlyingReturnValue = newValue - } - } - } - } - var loadMediaFileForSourceFilenameClosure: ((MediaSourceProxy, String?) async throws -> MediaFileHandleProxy)? - - func loadMediaFileForSource(_ source: MediaSourceProxy, filename: String?) async throws -> MediaFileHandleProxy { - if let error = loadMediaFileForSourceFilenameThrowableError { - throw error - } - loadMediaFileForSourceFilenameCallsCount += 1 - loadMediaFileForSourceFilenameReceivedArguments = (source: source, filename: filename) - DispatchQueue.main.async { - self.loadMediaFileForSourceFilenameReceivedInvocations.append((source: source, filename: filename)) - } - if let loadMediaFileForSourceFilenameClosure = loadMediaFileForSourceFilenameClosure { - return try await loadMediaFileForSourceFilenameClosure(source, filename) - } else { - return loadMediaFileForSourceFilenameReturnValue - } - } } class CompletionSuggestionServiceMock: CompletionSuggestionServiceProtocol, @unchecked Sendable { var suggestionsPublisher: AnyPublisher<[SuggestionItem], Never> { diff --git a/ElementX/Sources/Mocks/MediaProviderMock.swift b/ElementX/Sources/Mocks/MediaProviderMock.swift index b9c8ea601..6137a2445 100644 --- a/ElementX/Sources/Mocks/MediaProviderMock.swift +++ b/ElementX/Sources/Mocks/MediaProviderMock.swift @@ -7,17 +7,11 @@ import SwiftUI -extension MediaProviderProtocol where Self == MediaProviderMock { - static var mock: MediaProviderMock { .shared } -} - extension MediaProviderMock { - static let shared = MediaProviderMock(.init()) - struct Configuration { } // swiftlint:disable:next cyclomatic_complexity - convenience init(_ configuration: Configuration) { + convenience init(configuration: Configuration) { self.init() imageFromSourceSizeClosure = { mediaSource, _ in diff --git a/ElementX/Sources/Mocks/UserSessionMock.swift b/ElementX/Sources/Mocks/UserSessionMock.swift index 7ce0400e0..6f5794518 100644 --- a/ElementX/Sources/Mocks/UserSessionMock.swift +++ b/ElementX/Sources/Mocks/UserSessionMock.swift @@ -17,7 +17,7 @@ extension UserSessionMock { self.init() clientProxy = configuration.clientProxy - mediaProvider = .mock + mediaProvider = MediaProviderMock(configuration: .init()) voiceMessageMediaManager = VoiceMessageMediaManagerMock() sessionSecurityStatePublisher = CurrentValueSubject(.init(verificationState: .verified, recoveryState: .enabled)).asCurrentValuePublisher() diff --git a/ElementX/Sources/Other/Pills/PillView.swift b/ElementX/Sources/Other/Pills/PillView.swift index 94090a0d7..3c0dac2e6 100644 --- a/ElementX/Sources/Other/Pills/PillView.swift +++ b/ElementX/Sources/Other/Pills/PillView.swift @@ -42,6 +42,8 @@ struct PillView: View { } struct PillView_Previews: PreviewProvider, TestablePreview { + static let mockMediaProvider = MediaProviderMock(configuration: .init()) + static var previews: some View { PillView(context: PillContext.mock(viewState: .mention(isOwnMention: false, displayText: PillUtilities.userPillDisplayText(username: "User", diff --git a/ElementX/Sources/Other/SwiftUI/Animation/ShimmerModifier.swift b/ElementX/Sources/Other/SwiftUI/Animation/ShimmerModifier.swift index b4ff484aa..25e49d5c6 100644 --- a/ElementX/Sources/Other/SwiftUI/Animation/ShimmerModifier.swift +++ b/ElementX/Sources/Other/SwiftUI/Animation/ShimmerModifier.swift @@ -70,7 +70,7 @@ struct ShimmerOverlay_Previews: PreviewProvider, TestablePreview { static var previews: some View { VStack(spacing: 0) { ForEach(0...8, id: \.self) { _ in - HomeScreenRoomCell(room: .placeholder(), isSelected: false, mediaProvider: .mock) { _ in } + HomeScreenRoomCell(room: .placeholder(), isSelected: false, mediaProvider: MediaProviderMock(configuration: .init())) { _ in } } } .redacted(reason: .placeholder) diff --git a/ElementX/Sources/Other/SwiftUI/ViewModel/StateStoreViewModel.swift b/ElementX/Sources/Other/SwiftUI/ViewModel/StateStoreViewModel.swift index 8ab2fc3d0..00b0ff198 100644 --- a/ElementX/Sources/Other/SwiftUI/ViewModel/StateStoreViewModel.swift +++ b/ElementX/Sources/Other/SwiftUI/ViewModel/StateStoreViewModel.swift @@ -65,12 +65,7 @@ class StateStoreViewModel { /// An optional image loading service so that views can manage themselves /// Intentionally non-generic so that it doesn't grow uncontrollably - /// - /// We noticed that the keyboard appears to hold onto the Context of the last screen that had text input focus: - /// https://github.com/element-hq/element-x-ios/issues/4465 - /// Therefore this is `weak` so that the underlying `MatrixRustSDK.Client` isn't retained when e.g. clearing - /// the cache, otherwise we have the potential for 2 `Client`s to be alive at the same time causing havoc. - private(set) weak var mediaProvider: MediaProviderProtocol? + let mediaProvider: MediaProviderProtocol? /// Set-able/Bindable access to the bindable state. subscript(dynamicMember keyPath: WritableKeyPath) -> T { diff --git a/ElementX/Sources/Other/SwiftUI/ViewModel/StateStoreViewModelV2.swift b/ElementX/Sources/Other/SwiftUI/ViewModel/StateStoreViewModelV2.swift index e386de1eb..eca817e93 100644 --- a/ElementX/Sources/Other/SwiftUI/ViewModel/StateStoreViewModelV2.swift +++ b/ElementX/Sources/Other/SwiftUI/ViewModel/StateStoreViewModelV2.swift @@ -67,12 +67,7 @@ class StateStoreViewModelV2 { /// An optional image loading service so that views can manage themselves /// Intentionally non-generic so that it doesn't grow uncontrollably - /// - /// We noticed that the keyboard appears to hold onto the Context of the last screen that had text input focus: - /// https://github.com/element-hq/element-x-ios/issues/4465 - /// Therefore this is `weak` so that the underlying `MatrixRustSDK.Client` isn't retained when e.g. clearing - /// the cache, otherwise we have the potential for 2 `Client`s to be alive at the same time causing havoc. - private(set) weak var mediaProvider: MediaProviderProtocol? + let mediaProvider: MediaProviderProtocol? /// Set-able access to the bindable state. subscript(dynamicMember keyPath: WritableKeyPath) -> T { diff --git a/ElementX/Sources/Other/SwiftUI/Views/AvatarHeaderView.swift b/ElementX/Sources/Other/SwiftUI/Views/AvatarHeaderView.swift index 92b655533..b3f9a1970 100644 --- a/ElementX/Sources/Other/SwiftUI/Views/AvatarHeaderView.swift +++ b/ElementX/Sources/Other/SwiftUI/Views/AvatarHeaderView.swift @@ -234,7 +234,7 @@ struct AvatarHeaderView_Previews: PreviewProvider, TestablePreview { isPublic: true, isDirect: false), avatarSize: .room(on: .details), - mediaProvider: .mock) { + mediaProvider: MediaProviderMock(configuration: .init())) { HStack(spacing: 32) { ShareLink(item: "test") { CompoundIcon(\.shareIos) @@ -248,7 +248,7 @@ struct AvatarHeaderView_Previews: PreviewProvider, TestablePreview { Form { AvatarHeaderView(accountOwner: RoomMemberDetails(withProxy: RoomMemberProxyMock.mockMe), dmRecipient: RoomMemberDetails(withProxy: RoomMemberProxyMock.mockAlice), - mediaProvider: .mock) { + mediaProvider: MediaProviderMock(configuration: .init())) { HStack(spacing: 32) { ShareLink(item: "test") { CompoundIcon(\.shareIos) @@ -263,16 +263,16 @@ struct AvatarHeaderView_Previews: PreviewProvider, TestablePreview { VStack(spacing: 16) { AvatarHeaderView(member: RoomMemberDetails(withProxy: RoomMemberProxyMock.mockAlice), avatarSize: .room(on: .details), - mediaProvider: .mock) { Text("") } + mediaProvider: MediaProviderMock(configuration: .init())) { Text("") } AvatarHeaderView(member: RoomMemberDetails(withProxy: RoomMemberProxyMock.mockBob), isVerified: true, avatarSize: .room(on: .details), - mediaProvider: .mock) { Text("") } + mediaProvider: MediaProviderMock(configuration: .init())) { Text("") } AvatarHeaderView(member: RoomMemberDetails(withProxy: RoomMemberProxyMock.mockBanned[3]), avatarSize: .room(on: .details), - mediaProvider: .mock) { Text("") } + mediaProvider: MediaProviderMock(configuration: .init())) { Text("") } } .padding() .background(Color.compound.bgSubtleSecondaryLevel0) diff --git a/ElementX/Sources/Other/SwiftUI/Views/LoadableImage.swift b/ElementX/Sources/Other/SwiftUI/Views/LoadableImage.swift index cda63312f..0d46166f5 100644 --- a/ElementX/Sources/Other/SwiftUI/Views/LoadableImage.swift +++ b/ElementX/Sources/Other/SwiftUI/Views/LoadableImage.swift @@ -396,7 +396,7 @@ struct LoadableImage_Previews: PreviewProvider, TestablePreview { } static func makeMediaProvider(isLoading: Bool = false) -> MediaProviderProtocol { - let mediaProvider = MediaProviderMock(.init()) + let mediaProvider = MediaProviderMock(configuration: .init()) if isLoading { mediaProvider.imageFromSourceSizeClosure = { _, _ in nil } diff --git a/ElementX/Sources/Other/SwiftUI/Views/RoomAvatarImage.swift b/ElementX/Sources/Other/SwiftUI/Views/RoomAvatarImage.swift index df1933517..0e865eb66 100644 --- a/ElementX/Sources/Other/SwiftUI/Views/RoomAvatarImage.swift +++ b/ElementX/Sources/Other/SwiftUI/Views/RoomAvatarImage.swift @@ -133,27 +133,27 @@ struct RoomAvatarImage_Previews: PreviewProvider, TestablePreview { name: "Room", avatarURL: nil), avatarSize: .room(on: .chats), - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) RoomAvatarImage(avatar: .room(id: "!2:server.com", name: "Room", avatarURL: .mockMXCAvatar), avatarSize: .room(on: .chats), - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) RoomAvatarImage(avatar: .space(id: "!space:server.com", name: "Room", avatarURL: nil), avatarSize: .room(on: .chats), - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) RoomAvatarImage(avatar: .space(id: "!otherspace:server.com", name: "Room", avatarURL: .mockMXCAvatar), avatarSize: .room(on: .chats), - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) - RoomAvatarImage(avatar: .tombstoned, avatarSize: .room(on: .chats), mediaProvider: .mock) + RoomAvatarImage(avatar: .tombstoned, avatarSize: .room(on: .chats), mediaProvider: MediaProviderMock(configuration: .init())) } HStack(spacing: 12) { @@ -161,18 +161,18 @@ struct RoomAvatarImage_Previews: PreviewProvider, TestablePreview { displayName: "User", avatarURL: nil)]), avatarSize: .room(on: .chats), - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) RoomAvatarImage(avatar: .heroes([.init(userID: "@user:server.com", displayName: "User", avatarURL: .mockMXCAvatar)]), avatarSize: .room(on: .chats), - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) RoomAvatarImage(avatar: .heroes([.init(userID: "@alice:server.com", displayName: "Alice", avatarURL: nil), .init(userID: "@bob:server.net", displayName: "Bob", avatarURL: nil)]), avatarSize: .room(on: .chats), - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) } } } diff --git a/ElementX/Sources/Other/SwiftUI/Views/RoomHeaderView.swift b/ElementX/Sources/Other/SwiftUI/Views/RoomHeaderView.swift index e3567d87d..68b27e4a9 100644 --- a/ElementX/Sources/Other/SwiftUI/Views/RoomHeaderView.swift +++ b/ElementX/Sources/Other/SwiftUI/Views/RoomHeaderView.swift @@ -75,7 +75,7 @@ struct RoomHeaderView_Previews: PreviewProvider, TestablePreview { name: "Some Room Name", avatarURL: avatarURL), dmRecipientVerificationState: verificationState, - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) .padding() } } diff --git a/ElementX/Sources/Other/SwiftUI/Views/RoomInviterLabel.swift b/ElementX/Sources/Other/SwiftUI/Views/RoomInviterLabel.swift index cbd65c54c..d735c8feb 100644 --- a/ElementX/Sources/Other/SwiftUI/Views/RoomInviterLabel.swift +++ b/ElementX/Sources/Other/SwiftUI/Views/RoomInviterLabel.swift @@ -63,13 +63,13 @@ struct RoomInviterLabel_Previews: PreviewProvider, TestablePreview { static var previews: some View { VStack(spacing: 10) { RoomInviterLabel(inviter: .init(member: RoomMemberProxyMock.mockAlice), - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) RoomInviterLabel(inviter: .init(member: RoomMemberProxyMock.mockDan), - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) RoomInviterLabel(inviter: .init(member: RoomMemberProxyMock.mockNoName), - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) RoomInviterLabel(inviter: .init(member: RoomMemberProxyMock.mockCharlie), - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) .foregroundStyle(.compound.textPrimary) } .font(.compound.bodyMD) diff --git a/ElementX/Sources/Other/SwiftUI/Views/StackedAvatarsView.swift b/ElementX/Sources/Other/SwiftUI/Views/StackedAvatarsView.swift index b8e1617c5..95fea362f 100644 --- a/ElementX/Sources/Other/SwiftUI/Views/StackedAvatarsView.swift +++ b/ElementX/Sources/Other/SwiftUI/Views/StackedAvatarsView.swift @@ -54,13 +54,13 @@ struct StackedAvatarsView_Previews: PreviewProvider, TestablePreview { lineWidth: 2, avatars: avatars, avatarSize: .user(on: .knockingUsersBannerStack), - mediaProvider: .mock) + mediaProvider: MediaProviderMock()) StackedAvatarsView(overlap: 16, lineWidth: 2, shouldStackFromLast: true, avatars: avatars, avatarSize: .user(on: .knockingUsersBannerStack), - mediaProvider: .mock) + mediaProvider: MediaProviderMock()) } } } diff --git a/ElementX/Sources/Other/SwiftUI/Views/UserProfileListRow.swift b/ElementX/Sources/Other/SwiftUI/Views/UserProfileListRow.swift index 406de9632..02dc0ba0b 100644 --- a/ElementX/Sources/Other/SwiftUI/Views/UserProfileListRow.swift +++ b/ElementX/Sources/Other/SwiftUI/Views/UserProfileListRow.swift @@ -65,21 +65,21 @@ struct UserProfileCell_Previews: PreviewProvider, TestablePreview { static var previews: some View { Form { - UserProfileListRow(user: .mockAlice, membership: nil, mediaProvider: .mock, + UserProfileListRow(user: .mockAlice, membership: nil, mediaProvider: MediaProviderMock(configuration: .init()), kind: .multiSelection(isSelected: true, action: action)) - UserProfileListRow(user: .mockBob, membership: nil, mediaProvider: .mock, + UserProfileListRow(user: .mockBob, membership: nil, mediaProvider: MediaProviderMock(configuration: .init()), kind: .multiSelection(isSelected: false, action: action)) - UserProfileListRow(user: .mockCharlie, membership: .join, mediaProvider: .mock, + UserProfileListRow(user: .mockCharlie, membership: .join, mediaProvider: MediaProviderMock(configuration: .init()), kind: .multiSelection(isSelected: true, action: action)) .disabled(true) - UserProfileListRow(user: .init(userID: "@someone:matrix.org"), membership: .join, mediaProvider: .mock, + UserProfileListRow(user: .init(userID: "@someone:matrix.org"), membership: .join, mediaProvider: MediaProviderMock(configuration: .init()), kind: .multiSelection(isSelected: false, action: action)) .disabled(true) - UserProfileListRow(user: .init(userID: "@someone:matrix.org"), membership: nil, mediaProvider: .mock, + UserProfileListRow(user: .init(userID: "@someone:matrix.org"), membership: nil, mediaProvider: MediaProviderMock(configuration: .init()), kind: .multiSelection(isSelected: false, action: action)) } .compoundList() diff --git a/ElementX/Sources/Screens/FilePreviewScreen/TimelineMediaPreviewModifier.swift b/ElementX/Sources/Screens/FilePreviewScreen/TimelineMediaPreviewModifier.swift index 02ba7f6c4..fb784ea24 100644 --- a/ElementX/Sources/Screens/FilePreviewScreen/TimelineMediaPreviewModifier.swift +++ b/ElementX/Sources/Screens/FilePreviewScreen/TimelineMediaPreviewModifier.swift @@ -135,12 +135,9 @@ private struct MediaPreviewViewController: UIViewControllerRepresentable { // MARK: - Previews struct TimelineMediaPreviewModifier_Previews: PreviewProvider { - static let viewModel = makeViewModel(mediaProvider: mediaProvider) - static let mediaProvider = MediaProviderMock(.init()) - static let downloadingViewModel = makeViewModel(isDownloading: true, mediaProvider: downloadingMediaProvider) - static let downloadingMediaProvider = MediaProviderMock(.init()) - static let downloadErrorViewModel = makeViewModel(isDownloadError: true, mediaProvider: downloadErrorMediaProvider) - static let downloadErrorMediaProvider = MediaProviderMock(.init()) + static let viewModel = makeViewModel() + static let downloadingViewModel = makeViewModel(isDownloading: true) + static let downloadErrorViewModel = makeViewModel(isDownloadError: true) static var previews: some View { MediaPreviewViewController(viewModel: viewModel, dismissalPublisher: .init()) { } @@ -151,7 +148,7 @@ struct TimelineMediaPreviewModifier_Previews: PreviewProvider { .previewDisplayName("Download Error") } - static func makeViewModel(isDownloading: Bool = false, isDownloadError: Bool = false, mediaProvider: MediaProviderMock) -> TimelineMediaPreviewViewModel { + static func makeViewModel(isDownloading: Bool = false, isDownloadError: Bool = false) -> TimelineMediaPreviewViewModel { let item = FileRoomTimelineItem(id: .randomEvent, timestamp: .mock, isOutgoing: false, @@ -168,6 +165,8 @@ struct TimelineMediaPreviewModifier_Previews: PreviewProvider { let timelineController = MockTimelineController(timelineKind: .media(.mediaFilesScreen)) timelineController.timelineItems = [item] + let mediaProvider = MediaProviderMock(configuration: .init()) + if isDownloading { mediaProvider.loadFileFromSourceFilenameClosure = { _, _ in try? await Task.sleep(for: .seconds(3600)) diff --git a/ElementX/Sources/Screens/FilePreviewScreen/View/TimelineMediaPreviewDetailsView.swift b/ElementX/Sources/Screens/FilePreviewScreen/View/TimelineMediaPreviewDetailsView.swift index 7020d292f..48da4fa89 100644 --- a/ElementX/Sources/Screens/FilePreviewScreen/View/TimelineMediaPreviewDetailsView.swift +++ b/ElementX/Sources/Screens/FilePreviewScreen/View/TimelineMediaPreviewDetailsView.swift @@ -229,7 +229,7 @@ struct TimelineMediaPreviewDetailsView_Previews: PreviewProvider, TestablePrevie let viewModel = TimelineMediaPreviewViewModel(initialItem: item, timelineViewModel: TimelineViewModel.mock(timelineKind: timelineKind, timelineController: timelineController), - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), photoLibraryManager: PhotoLibraryManagerMock(.init()), userIndicatorController: UserIndicatorControllerMock(), appMediator: AppMediatorMock()) diff --git a/ElementX/Sources/Screens/FilePreviewScreen/View/TimelineMediaPreviewRedactConfirmationView.swift b/ElementX/Sources/Screens/FilePreviewScreen/View/TimelineMediaPreviewRedactConfirmationView.swift index 24b8416f1..4673d300b 100644 --- a/ElementX/Sources/Screens/FilePreviewScreen/View/TimelineMediaPreviewRedactConfirmationView.swift +++ b/ElementX/Sources/Screens/FilePreviewScreen/View/TimelineMediaPreviewRedactConfirmationView.swift @@ -147,7 +147,7 @@ struct TimelineMediaPreviewRedactConfirmationView_Previews: PreviewProvider, Tes return TimelineMediaPreviewViewModel(initialItem: item, timelineViewModel: TimelineViewModel.mock(timelineKind: timelineController.timelineKind, timelineController: timelineController), - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), photoLibraryManager: PhotoLibraryManagerMock(.init()), userIndicatorController: UserIndicatorControllerMock(), appMediator: AppMediatorMock()) diff --git a/ElementX/Sources/Screens/GlobalSearchScreen/View/GlobalSearchScreen.swift b/ElementX/Sources/Screens/GlobalSearchScreen/View/GlobalSearchScreen.swift index cab900a51..76f18a86b 100644 --- a/ElementX/Sources/Screens/GlobalSearchScreen/View/GlobalSearchScreen.swift +++ b/ElementX/Sources/Screens/GlobalSearchScreen/View/GlobalSearchScreen.swift @@ -206,7 +206,7 @@ private class GlobalSearchTextField: UITextField { struct GlobalSearchScreen_Previews: PreviewProvider, TestablePreview { static let viewModel = GlobalSearchScreenViewModel(roomSummaryProvider: RoomSummaryProviderMock(.init(state: .loaded(.mockRooms))), - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) static var previews: some View { NavigationStack { diff --git a/ElementX/Sources/Screens/GlobalSearchScreen/View/GlobalSearchScreenCell.swift b/ElementX/Sources/Screens/GlobalSearchScreen/View/GlobalSearchScreenCell.swift index 986a4d15e..1300dff95 100644 --- a/ElementX/Sources/Screens/GlobalSearchScreen/View/GlobalSearchScreenCell.swift +++ b/ElementX/Sources/Screens/GlobalSearchScreen/View/GlobalSearchScreenCell.swift @@ -37,7 +37,7 @@ struct GlobalSearchScreenListRow: View { struct GlobalSearchScreenListRow_Previews: PreviewProvider, TestablePreview { static let viewModel = GlobalSearchScreenViewModel(roomSummaryProvider: RoomSummaryProviderMock(.init(state: .loaded(.mockRooms))), - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) static var previews: some View { List { diff --git a/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomCell.swift b/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomCell.swift index 866d89c78..d9926f368 100644 --- a/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomCell.swift +++ b/ElementX/Sources/Screens/HomeScreen/View/HomeScreenRoomCell.swift @@ -176,17 +176,17 @@ struct HomeScreenRoomCell_Previews: PreviewProvider, TestablePreview { static var previews: some View { VStack(spacing: 0) { ForEach(genericRooms) { room in - HomeScreenRoomCell(room: room, isSelected: false, mediaProvider: .mock) { _ in } + HomeScreenRoomCell(room: room, isSelected: false, mediaProvider: MediaProviderMock(configuration: .init())) { _ in } } - HomeScreenRoomCell(room: .placeholder(), isSelected: false, mediaProvider: .mock) { _ in } + HomeScreenRoomCell(room: .placeholder(), isSelected: false, mediaProvider: MediaProviderMock(configuration: .init())) { _ in } .redacted(reason: .placeholder) } .previewDisplayName("Generic") VStack(spacing: 0) { ForEach(notificationsStateRooms) { room in - HomeScreenRoomCell(room: room, isSelected: false, mediaProvider: .mock) { _ in } + HomeScreenRoomCell(room: room, isSelected: false, mediaProvider: MediaProviderMock(configuration: .init())) { _ in } } } .previewLayout(.sizeThatFits) diff --git a/ElementX/Sources/Screens/InviteUsersScreen/View/InviteUsersScreenSelectedItem.swift b/ElementX/Sources/Screens/InviteUsersScreen/View/InviteUsersScreenSelectedItem.swift index f08b0ea74..02e64fdfd 100644 --- a/ElementX/Sources/Screens/InviteUsersScreen/View/InviteUsersScreenSelectedItem.swift +++ b/ElementX/Sources/Screens/InviteUsersScreen/View/InviteUsersScreenSelectedItem.swift @@ -53,7 +53,7 @@ struct InviteUsersScreenSelectedItem_Previews: PreviewProvider, TestablePreview ScrollView(.horizontal) { HStack(spacing: 28) { ForEach(people, id: \.userID) { user in - InviteUsersScreenSelectedItem(user: user, mediaProvider: .mock) { } + InviteUsersScreenSelectedItem(user: user, mediaProvider: MediaProviderMock(configuration: .init())) { } .frame(width: 72) } } diff --git a/ElementX/Sources/Screens/KnockRequestsListScreen/View/KnockRequestsListScreen.swift b/ElementX/Sources/Screens/KnockRequestsListScreen/View/KnockRequestsListScreen.swift index 59be0c7b4..1ab45e435 100644 --- a/ElementX/Sources/Screens/KnockRequestsListScreen/View/KnockRequestsListScreen.swift +++ b/ElementX/Sources/Screens/KnockRequestsListScreen/View/KnockRequestsListScreen.swift @@ -163,7 +163,7 @@ extension KnockRequestsListScreenViewModel { knockRequestsState: requestsState, ownUserID: RoomMemberProxyMock.mockAdmin.userID, joinRule: .knock)), - mediaProvider: .mock, + mediaProvider: MediaProviderMock(), userIndicatorController: UserIndicatorControllerMock()) } } diff --git a/ElementX/Sources/Screens/ManageRoomMemberSheet/View/ManageRoomMemberSheetView.swift b/ElementX/Sources/Screens/ManageRoomMemberSheet/View/ManageRoomMemberSheetView.swift index f1b1f2217..83bd19e8e 100644 --- a/ElementX/Sources/Screens/ManageRoomMemberSheet/View/ManageRoomMemberSheetView.swift +++ b/ElementX/Sources/Screens/ManageRoomMemberSheet/View/ManageRoomMemberSheetView.swift @@ -113,6 +113,6 @@ private extension ManageRoomMemberSheetViewModel { roomProxy: JoinedRoomProxyMock(.init()), userIndicatorController: UserIndicatorControllerMock(), analyticsService: ServiceLocator.shared.analytics, - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) } } diff --git a/ElementX/Sources/Screens/MediaEventsTimelineScreen/View/MediaEventsTimelineScreen.swift b/ElementX/Sources/Screens/MediaEventsTimelineScreen/View/MediaEventsTimelineScreen.swift index bb66789bc..7bfce42a0 100644 --- a/ElementX/Sources/Screens/MediaEventsTimelineScreen/View/MediaEventsTimelineScreen.swift +++ b/ElementX/Sources/Screens/MediaEventsTimelineScreen/View/MediaEventsTimelineScreen.swift @@ -285,7 +285,7 @@ struct MediaEventsTimelineScreen_Previews: PreviewProvider, TestablePreview { MediaEventsTimelineScreenViewModel(mediaTimelineViewModel: makeTimelineViewModel(empty: empty), filesTimelineViewModel: makeTimelineViewModel(empty: empty), initialScreenMode: screenMode, - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), userIndicatorController: UserIndicatorControllerMock(), appMediator: AppMediatorMock()) } diff --git a/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/View/SessionVerificationRequestDetailsView.swift b/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/View/SessionVerificationRequestDetailsView.swift index 7a7ecd78e..d7011d1fe 100644 --- a/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/View/SessionVerificationRequestDetailsView.swift +++ b/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/View/SessionVerificationRequestDetailsView.swift @@ -120,13 +120,13 @@ struct SessionVerificationRequestDetailsView_Previews: PreviewProvider, Testable static var previews: some View { SessionVerificationRequestDetailsView(details: details, isUserVerification: true, - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) .padding() .previewDisplayName("User") SessionVerificationRequestDetailsView(details: details, isUserVerification: false, - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) .padding() .previewDisplayName("Device") } diff --git a/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/View/SessionVerificationScreen.swift b/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/View/SessionVerificationScreen.swift index f726cc2b3..59f7be832 100644 --- a/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/View/SessionVerificationScreen.swift +++ b/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/View/SessionVerificationScreen.swift @@ -263,7 +263,7 @@ struct SessionVerification_Previews: PreviewProvider, TestablePreview { let viewModel = SessionVerificationScreenViewModel(sessionVerificationControllerProxy: SessionVerificationControllerProxyMock.configureMock(), flow: flow, appSettings: AppSettings(), - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), verificationState: state) return SessionVerificationScreen(context: viewModel.context) diff --git a/ElementX/Sources/Screens/RoomChangeRolesScreen/View/RoomChangeRolesScreen.swift b/ElementX/Sources/Screens/RoomChangeRolesScreen/View/RoomChangeRolesScreen.swift index 60e11e521..5b10e2a93 100644 --- a/ElementX/Sources/Screens/RoomChangeRolesScreen/View/RoomChangeRolesScreen.swift +++ b/ElementX/Sources/Screens/RoomChangeRolesScreen/View/RoomChangeRolesScreen.swift @@ -146,7 +146,7 @@ struct RoomChangeRolesScreen_Previews: PreviewProvider, TestablePreview { return RoomChangeRolesScreenViewModel(mode: mode, roomProxy: JoinedRoomProxyMock(.init(members: members)), - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), userIndicatorController: UserIndicatorControllerMock(), analytics: ServiceLocator.shared.analytics) } diff --git a/ElementX/Sources/Screens/RoomChangeRolesScreen/View/RoomChangeRolesScreenRow.swift b/ElementX/Sources/Screens/RoomChangeRolesScreen/View/RoomChangeRolesScreenRow.swift index f181de025..3a37623e0 100644 --- a/ElementX/Sources/Screens/RoomChangeRolesScreen/View/RoomChangeRolesScreenRow.swift +++ b/ElementX/Sources/Screens/RoomChangeRolesScreen/View/RoomChangeRolesScreenRow.swift @@ -39,34 +39,34 @@ struct RoomChangeRolesScreenRow_Previews: PreviewProvider, TestablePreview { static var previews: some View { Form { RoomChangeRolesScreenRow(member: .init(withProxy: RoomMemberProxyMock.mockAlice), - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), isSelected: true, action: action) RoomChangeRolesScreenRow(member: .init(withProxy: RoomMemberProxyMock.mockBob), - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), isSelected: false, action: action) RoomChangeRolesScreenRow(member: .init(withProxy: RoomMemberProxyMock.mockInvited), - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), isSelected: false, action: action) RoomChangeRolesScreenRow(member: .init(withProxy: RoomMemberProxyMock.mockCharlie), - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), isSelected: true, action: action) .disabled(true) RoomChangeRolesScreenRow(member: .init(withProxy: RoomMemberProxyMock(with: .init(userID: "@someone:matrix.org", membership: .join))), - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), isSelected: false, action: action) .disabled(true) RoomChangeRolesScreenRow(member: .init(withProxy: RoomMemberProxyMock(with: .init(userID: "@someone:matrix.org", membership: .join))), - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), isSelected: false, action: action) } diff --git a/ElementX/Sources/Screens/RoomChangeRolesScreen/View/RoomChangeRolesScreenSelectedItem.swift b/ElementX/Sources/Screens/RoomChangeRolesScreen/View/RoomChangeRolesScreenSelectedItem.swift index 3bfc65bd1..0d8ca8ebf 100644 --- a/ElementX/Sources/Screens/RoomChangeRolesScreen/View/RoomChangeRolesScreenSelectedItem.swift +++ b/ElementX/Sources/Screens/RoomChangeRolesScreen/View/RoomChangeRolesScreenSelectedItem.swift @@ -75,7 +75,7 @@ struct RoomChangeRolesScreenSelectedItem_Previews: PreviewProvider, TestablePrev HStack(spacing: 12) { ForEach(members, id: \.id) { member in RoomChangeRolesScreenSelectedItem(member: member, - mediaProvider: .mock) { } + mediaProvider: MediaProviderMock(configuration: .init())) { } .frame(width: 72) } } diff --git a/ElementX/Sources/Screens/RoomDirectorySearchScreen/View/RoomDirectoryCell.swift b/ElementX/Sources/Screens/RoomDirectorySearchScreen/View/RoomDirectoryCell.swift index ec74ed6eb..6258161ee 100644 --- a/ElementX/Sources/Screens/RoomDirectorySearchScreen/View/RoomDirectoryCell.swift +++ b/ElementX/Sources/Screens/RoomDirectorySearchScreen/View/RoomDirectoryCell.swift @@ -55,7 +55,7 @@ struct RoomDirectorySearchCell_Previews: PreviewProvider, TestablePreview { name: "Test title", avatarURL: nil), canBeJoined: true), - mediaProvider: .mock) { } + mediaProvider: MediaProviderMock(configuration: .init())) { } RoomDirectorySearchCell(result: .init(id: "!test_id_2:matrix.org", alias: "#test:example.com", @@ -65,7 +65,7 @@ struct RoomDirectorySearchCell_Previews: PreviewProvider, TestablePreview { name: nil, avatarURL: nil), canBeJoined: true), - mediaProvider: .mock) { } + mediaProvider: MediaProviderMock(configuration: .init())) { } RoomDirectorySearchCell(result: .init(id: "!test_id_3:example.com", alias: "#test_no_topic:example.com", @@ -75,7 +75,7 @@ struct RoomDirectorySearchCell_Previews: PreviewProvider, TestablePreview { name: "Test title no topic", avatarURL: nil), canBeJoined: true), - mediaProvider: .mock) { } + mediaProvider: MediaProviderMock(configuration: .init())) { } RoomDirectorySearchCell(result: .init(id: "!test_id_4:example.com", alias: "#test_no_topic:example.com", @@ -85,7 +85,7 @@ struct RoomDirectorySearchCell_Previews: PreviewProvider, TestablePreview { name: nil, avatarURL: nil), canBeJoined: true), - mediaProvider: .mock) { } + mediaProvider: MediaProviderMock(configuration: .init())) { } RoomDirectorySearchCell(result: .init(id: "!test_id_5:example.com", alias: nil, @@ -95,7 +95,7 @@ struct RoomDirectorySearchCell_Previews: PreviewProvider, TestablePreview { name: "Test title no alias", avatarURL: nil), canBeJoined: false), - mediaProvider: .mock) { } + mediaProvider: MediaProviderMock(configuration: .init())) { } RoomDirectorySearchCell(result: .init(id: "!test_id_6:example.com", alias: nil, @@ -105,7 +105,7 @@ struct RoomDirectorySearchCell_Previews: PreviewProvider, TestablePreview { name: "Test title no alias", avatarURL: nil), canBeJoined: false), - mediaProvider: .mock) { } + mediaProvider: MediaProviderMock(configuration: .init())) { } RoomDirectorySearchCell(result: .init(id: "!test_id_7:example.com", alias: nil, @@ -115,7 +115,7 @@ struct RoomDirectorySearchCell_Previews: PreviewProvider, TestablePreview { name: nil, avatarURL: nil), canBeJoined: false), - mediaProvider: .mock) { } + mediaProvider: MediaProviderMock(configuration: .init())) { } RoomDirectorySearchCell(result: .init(id: "!test_id_8:example.com", alias: nil, name: nil, @@ -124,7 +124,7 @@ struct RoomDirectorySearchCell_Previews: PreviewProvider, TestablePreview { name: nil, avatarURL: nil), canBeJoined: false), - mediaProvider: .mock) { } + mediaProvider: MediaProviderMock(configuration: .init())) { } } .compoundList() } diff --git a/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/CompletionSuggestionView.swift b/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/CompletionSuggestionView.swift index 1f8256f99..28dce8003 100644 --- a/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/CompletionSuggestionView.swift +++ b/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/CompletionSuggestionView.swift @@ -113,13 +113,13 @@ struct CompletionSuggestion_Previews: PreviewProvider, TestablePreview { static var previews: some View { // Putting them is VStack allows the preview to work properly in tests VStack(spacing: 8) { - CompletionSuggestionView(mediaProvider: .mock, + CompletionSuggestionView(mediaProvider: MediaProviderMock(configuration: .init()), items: [.init(suggestionType: .user(.init(id: "@user_mention_1:matrix.org", displayName: "User 1", avatarURL: nil)), range: .init(), rawSuggestionText: ""), .init(suggestionType: .user(.init(id: "@user_mention_2:matrix.org", displayName: "User 2", avatarURL: .mockMXCUserAvatar)), range: .init(), rawSuggestionText: "")]) { _ in } } VStack(spacing: 8) { - CompletionSuggestionView(mediaProvider: .mock, + CompletionSuggestionView(mediaProvider: MediaProviderMock(configuration: .init()), items: multipleItems) { _ in } } } diff --git a/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/ComposerToolbar.swift b/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/ComposerToolbar.swift index 1beda995b..06ca0e994 100644 --- a/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/ComposerToolbar.swift +++ b/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/ComposerToolbar.swift @@ -333,7 +333,7 @@ struct ComposerToolbar_Previews: PreviewProvider, TestablePreview { static let composerViewModel = ComposerToolbarViewModel(roomProxy: JoinedRoomProxyMock(.init()), wysiwygViewModel: wysiwygViewModel, completionSuggestionService: CompletionSuggestionServiceMock(configuration: .init(suggestions: suggestions)), - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), mentionDisplayHelper: ComposerMentionDisplayHelper.mock, appSettings: ServiceLocator.shared.settings, analyticsService: ServiceLocator.shared.analytics, @@ -383,7 +383,7 @@ extension ComposerToolbar { let model = ComposerToolbarViewModel(roomProxy: JoinedRoomProxyMock(.init()), wysiwygViewModel: wysiwygViewModel, completionSuggestionService: CompletionSuggestionServiceMock(configuration: .init()), - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), mentionDisplayHelper: ComposerMentionDisplayHelper.mock, appSettings: ServiceLocator.shared.settings, analyticsService: ServiceLocator.shared.analytics, @@ -400,7 +400,7 @@ extension ComposerToolbar { let model = ComposerToolbarViewModel(roomProxy: JoinedRoomProxyMock(.init()), wysiwygViewModel: wysiwygViewModel, completionSuggestionService: CompletionSuggestionServiceMock(configuration: .init()), - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), mentionDisplayHelper: ComposerMentionDisplayHelper.mock, appSettings: ServiceLocator.shared.settings, analyticsService: ServiceLocator.shared.analytics, @@ -417,7 +417,7 @@ extension ComposerToolbar { let model = ComposerToolbarViewModel(roomProxy: JoinedRoomProxyMock(.init()), wysiwygViewModel: wysiwygViewModel, completionSuggestionService: CompletionSuggestionServiceMock(configuration: .init()), - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), mentionDisplayHelper: ComposerMentionDisplayHelper.mock, appSettings: ServiceLocator.shared.settings, analyticsService: ServiceLocator.shared.analytics, @@ -435,7 +435,7 @@ extension ComposerToolbar { let model = ComposerToolbarViewModel(roomProxy: JoinedRoomProxyMock(.init()), wysiwygViewModel: wysiwygViewModel, completionSuggestionService: CompletionSuggestionServiceMock(configuration: .init()), - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), mentionDisplayHelper: ComposerMentionDisplayHelper.mock, appSettings: ServiceLocator.shared.settings, analyticsService: ServiceLocator.shared.analytics, @@ -456,7 +456,7 @@ extension ComposerToolbar { let model = ComposerToolbarViewModel(roomProxy: JoinedRoomProxyMock(.init()), wysiwygViewModel: wysiwygViewModel, completionSuggestionService: CompletionSuggestionServiceMock(configuration: .init()), - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), mentionDisplayHelper: ComposerMentionDisplayHelper.mock, appSettings: ServiceLocator.shared.settings, analyticsService: ServiceLocator.shared.analytics, @@ -479,7 +479,7 @@ extension ComposerToolbar { let model = ComposerToolbarViewModel(roomProxy: JoinedRoomProxyMock(.init()), wysiwygViewModel: wysiwygViewModel, completionSuggestionService: CompletionSuggestionServiceMock(configuration: .init()), - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), mentionDisplayHelper: ComposerMentionDisplayHelper.mock, appSettings: ServiceLocator.shared.settings, analyticsService: ServiceLocator.shared.analytics, diff --git a/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/MentionSuggestionItemView.swift b/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/MentionSuggestionItemView.swift index bbc61683a..789b54568 100644 --- a/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/MentionSuggestionItemView.swift +++ b/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/MentionSuggestionItemView.swift @@ -45,14 +45,16 @@ struct MentionSuggestionItemView: View { } struct MentionSuggestionItemView_Previews: PreviewProvider, TestablePreview { + static let mockMediaProvider = MediaProviderMock(configuration: .init()) + static var previews: some View { - MentionSuggestionItemView(mediaProvider: .mock, item: .init(suggestionType: .user(.init(id: "test", displayName: "Test", avatarURL: .mockMXCUserAvatar)), range: .init(), rawSuggestionText: "")) + MentionSuggestionItemView(mediaProvider: mockMediaProvider, item: .init(suggestionType: .user(.init(id: "test", displayName: "Test", avatarURL: .mockMXCUserAvatar)), range: .init(), rawSuggestionText: "")) .previewDisplayName("User") - MentionSuggestionItemView(mediaProvider: .mock, item: .init(suggestionType: .user(.init(id: "test2", displayName: nil, avatarURL: nil)), range: .init(), rawSuggestionText: "")) + MentionSuggestionItemView(mediaProvider: mockMediaProvider, item: .init(suggestionType: .user(.init(id: "test2", displayName: nil, avatarURL: nil)), range: .init(), rawSuggestionText: "")) .previewDisplayName("User no display name") - MentionSuggestionItemView(mediaProvider: .mock, item: .init(suggestionType: .allUsers(.room(id: "room", name: "Room", avatarURL: .mockMXCAvatar)), range: .init(), rawSuggestionText: "")) + MentionSuggestionItemView(mediaProvider: mockMediaProvider, item: .init(suggestionType: .allUsers(.room(id: "room", name: "Room", avatarURL: .mockMXCAvatar)), range: .init(), rawSuggestionText: "")) .previewDisplayName("All users") - MentionSuggestionItemView(mediaProvider: .mock, + MentionSuggestionItemView(mediaProvider: mockMediaProvider, item: .init(suggestionType: .room(.init(id: "room", canonicalAlias: "#room:matrix.org", name: "Room", diff --git a/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/RoomAttachmentPicker.swift b/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/RoomAttachmentPicker.swift index 1de0b90db..c22be2d49 100644 --- a/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/RoomAttachmentPicker.swift +++ b/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/RoomAttachmentPicker.swift @@ -91,7 +91,7 @@ struct RoomAttachmentPicker_Previews: PreviewProvider, TestablePreview { static let viewModel = ComposerToolbarViewModel(roomProxy: JoinedRoomProxyMock(.init()), wysiwygViewModel: WysiwygComposerViewModel(), completionSuggestionService: CompletionSuggestionServiceMock(configuration: .init()), - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), mentionDisplayHelper: ComposerMentionDisplayHelper.mock, appSettings: ServiceLocator.shared.settings, analyticsService: ServiceLocator.shared.analytics, diff --git a/ElementX/Sources/Screens/RoomScreen/View/RoomScreenFooterView.swift b/ElementX/Sources/Screens/RoomScreen/View/RoomScreenFooterView.swift index b6440e9a9..0a48b0ca4 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/RoomScreenFooterView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/RoomScreenFooterView.swift @@ -166,11 +166,11 @@ struct RoomScreenFooterView_Previews: PreviewProvider, TestablePreview { learnMoreURL: "https://element.io/") static var previews: some View { - RoomScreenFooterView(details: bobDetails, mediaProvider: .mock) { _ in } + RoomScreenFooterView(details: bobDetails, mediaProvider: MediaProviderMock(configuration: .init())) { _ in } .previewDisplayName("With displayname") - RoomScreenFooterView(details: noNameDetails, mediaProvider: .mock) { _ in } + RoomScreenFooterView(details: noNameDetails, mediaProvider: MediaProviderMock(configuration: .init())) { _ in } .previewDisplayName("Without displayname") - RoomScreenFooterView(details: verificationViolationDetails, mediaProvider: .mock) { _ in } + RoomScreenFooterView(details: verificationViolationDetails, mediaProvider: MediaProviderMock(configuration: .init())) { _ in } .previewDisplayName("Verification Violation") } } diff --git a/ElementX/Sources/Screens/Spaces/Common/SpaceHeaderView.swift b/ElementX/Sources/Screens/Spaces/Common/SpaceHeaderView.swift index 5f6d88be2..0a0110941 100644 --- a/ElementX/Sources/Screens/Spaces/Common/SpaceHeaderView.swift +++ b/ElementX/Sources/Screens/Spaces/Common/SpaceHeaderView.swift @@ -160,12 +160,14 @@ struct SpaceHeaderMembersView: View { } struct SpaceHeaderView_Previews: PreviewProvider, TestablePreview { + static let mediaProvider = MediaProviderMock(configuration: .init()) + static let spaces = makeSpaceRooms() static var previews: some View { VStack(spacing: 0) { ForEach(spaces, id: \.id) { space in - SpaceHeaderView(spaceRoomProxy: space, mediaProvider: .mock) + SpaceHeaderView(spaceRoomProxy: space, mediaProvider: mediaProvider) } } } diff --git a/ElementX/Sources/Screens/Spaces/Common/SpaceRoomCell.swift b/ElementX/Sources/Screens/Spaces/Common/SpaceRoomCell.swift index 59ce045e3..402e1ab78 100644 --- a/ElementX/Sources/Screens/Spaces/Common/SpaceRoomCell.swift +++ b/ElementX/Sources/Screens/Spaces/Common/SpaceRoomCell.swift @@ -134,6 +134,8 @@ struct SpaceRoomCellButtonStyle: ButtonStyle { } struct SpaceRoomCell_Previews: PreviewProvider, TestablePreview { + static let mediaProvider = MediaProviderMock(configuration: .init()) + static let spaces = [SpaceRoomProxyProtocol].mockSpaceList static var previews: some View { @@ -141,7 +143,7 @@ struct SpaceRoomCell_Previews: PreviewProvider, TestablePreview { ForEach(spaces, id: \.id) { space in SpaceRoomCell(spaceRoomProxy: space, isSelected: false, - mediaProvider: .mock) { _ in } + mediaProvider: mediaProvider) { _ in } } } } diff --git a/ElementX/Sources/Screens/Spaces/SpaceScreen/View/SpaceScreen.swift b/ElementX/Sources/Screens/Spaces/SpaceScreen/View/SpaceScreen.swift index 45e93b8d9..e3a87aa2c 100644 --- a/ElementX/Sources/Screens/Spaces/SpaceScreen/View/SpaceScreen.swift +++ b/ElementX/Sources/Screens/Spaces/SpaceScreen/View/SpaceScreen.swift @@ -78,7 +78,7 @@ struct SpaceScreen_Previews: PreviewProvider, TestablePreview { let viewModel = SpaceScreenViewModel(spaceRoomListProxy: spaceRoomListProxy, spaceServiceProxy: SpaceServiceProxyMock(.init()), selectedSpaceRoomPublisher: .init(nil), - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), userIndicatorController: UserIndicatorControllerMock()) return viewModel } diff --git a/ElementX/Sources/Screens/Timeline/View/ReadReceipts/ReadReceiptCell.swift b/ElementX/Sources/Screens/Timeline/View/ReadReceipts/ReadReceiptCell.swift index aeb794bb5..1d5423291 100644 --- a/ElementX/Sources/Screens/Timeline/View/ReadReceipts/ReadReceiptCell.swift +++ b/ElementX/Sources/Screens/Timeline/View/ReadReceipts/ReadReceiptCell.swift @@ -63,18 +63,18 @@ struct ReadReceiptCell_Previews: PreviewProvider, TestablePreview { formattedTimestamp: "10:00"), memberState: .init(displayName: "Test", avatarURL: nil), - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) .previewDisplayName("No Image") ReadReceiptCell(readReceipt: .init(userID: "@test:matrix.org", formattedTimestamp: "10:00"), memberState: .init(displayName: "Test", avatarURL: .mockMXCUserAvatar), - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) .previewDisplayName("With Image") ReadReceiptCell(readReceipt: .init(userID: "@test:matrix.org", formattedTimestamp: "10:00"), memberState: nil, - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) .previewDisplayName("Loading Member") } } diff --git a/ElementX/Sources/Screens/Timeline/View/Supplementary/ReactionsSummaryView.swift b/ElementX/Sources/Screens/Timeline/View/Supplementary/ReactionsSummaryView.swift index f02d9e83e..97ea6c1db 100644 --- a/ElementX/Sources/Screens/Timeline/View/Supplementary/ReactionsSummaryView.swift +++ b/ElementX/Sources/Screens/Timeline/View/Supplementary/ReactionsSummaryView.swift @@ -139,7 +139,7 @@ struct ReactionsSummaryView_Previews: PreviewProvider, TestablePreview { static var previews: some View { ReactionsSummaryView(reactions: AggregatedReaction.mockReactions, members: [:], - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), selectedReactionKey: AggregatedReaction.mockReactions[0].key) } } diff --git a/ElementX/Sources/Services/Client/ClientProxy.swift b/ElementX/Sources/Services/Client/ClientProxy.swift index 0eac9a766..ab65bb02d 100644 --- a/ElementX/Sources/Services/Client/ClientProxy.swift +++ b/ElementX/Sources/Services/Client/ClientProxy.swift @@ -17,7 +17,7 @@ class ClientProxy: ClientProxyProtocol { private let networkMonitor: NetworkMonitorProtocol private let appSettings: AppSettings - private let mediaLoader: MediaLoaderProtocol + let mediaLoader: MediaLoaderProtocol private let clientQueue: DispatchQueue private var roomListService: RoomListService @@ -1117,20 +1117,6 @@ class ClientProxy: ClientProxyProtocol { } } -extension ClientProxy: MediaLoaderProtocol { - func loadMediaContentForSource(_ source: MediaSourceProxy) async throws -> Data { - try await mediaLoader.loadMediaContentForSource(source) - } - - func loadMediaThumbnailForSource(_ source: MediaSourceProxy, width: UInt, height: UInt) async throws -> Data { - try await mediaLoader.loadMediaThumbnailForSource(source, width: width, height: height) - } - - func loadMediaFileForSource(_ source: MediaSourceProxy, filename: String?) async throws -> MediaFileHandleProxy { - try await mediaLoader.loadMediaFileForSource(source, filename: filename) - } -} - private class ClientDelegateWrapper: ClientDelegate { private let authErrorCallback: (Bool) -> Void diff --git a/ElementX/Sources/Services/Client/ClientProxyProtocol.swift b/ElementX/Sources/Services/Client/ClientProxyProtocol.swift index 9f1ddf67f..a6008a417 100644 --- a/ElementX/Sources/Services/Client/ClientProxyProtocol.swift +++ b/ElementX/Sources/Services/Client/ClientProxyProtocol.swift @@ -73,7 +73,7 @@ enum TimelineMediaVisibility: Decodable { } // sourcery: AutoMockable -protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol { +protocol ClientProxyProtocol: AnyObject { var actionsPublisher: AnyPublisher { get } var loadingStatePublisher: CurrentValuePublisher { get } @@ -105,6 +105,8 @@ protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol { var pusherNotificationClientIdentifier: String? { get } + var mediaLoader: MediaLoaderProtocol { get } + var roomSummaryProvider: RoomSummaryProviderProtocol { get } /// Used for listing rooms that shouldn't be affected by the main `roomSummaryProvider` filtering diff --git a/ElementX/Sources/Services/Media/Provider/MediaLoader.swift b/ElementX/Sources/Services/Media/Provider/MediaLoader.swift index 89478fc6c..79214f534 100644 --- a/ElementX/Sources/Services/Media/Provider/MediaLoader.swift +++ b/ElementX/Sources/Services/Media/Provider/MediaLoader.swift @@ -16,7 +16,17 @@ private final class MediaRequest { } actor MediaLoader: MediaLoaderProtocol { - private let client: ClientProtocol + // We noticed that the keyboard appears to hold onto a reference to the `Context` of the last + // screen that had text input focus, resulting in its MediaProvider staying alive which in + // turn keeps this loader alive: https://github.com/element-hq/element-x-ios/issues/4465 + // Therefore the client is `weak` so that the underlying `MatrixRustSDK.Client` is released + // when e.g. clearing the cache, otherwise we have the potential for 2 `Client`s to be alive + // at the same time causing havoc. + // + // Whilst a more correct fix would be to make `Context.mediaProvider` weak, this requires a + // bunch of workarounds in our preview tests to keep the mock provider alive as some ViewModels + // don't have an accompanying ClientMock to own it. + private weak var client: ClientProtocol? private var ongoingRequests = [MediaSourceProxy: MediaRequest]() init(client: ClientProtocol) { @@ -24,18 +34,21 @@ actor MediaLoader: MediaLoaderProtocol { } func loadMediaContentForSource(_ source: MediaSourceProxy) async throws -> Data { - try await enqueueLoadMediaRequest(forSource: source) { - try await self.client.getMediaContent(mediaSource: source.underlyingSource) + try await enqueueLoadMediaRequest(forSource: source) { [weak client] in + guard let client else { throw MediaLoaderError.missingClient } + return try await client.getMediaContent(mediaSource: source.underlyingSource) } } func loadMediaThumbnailForSource(_ source: MediaSourceProxy, width: UInt, height: UInt) async throws -> Data { - try await enqueueLoadMediaRequest(forSource: source) { - try await self.client.getMediaThumbnail(mediaSource: source.underlyingSource, width: UInt64(width), height: UInt64(height)) + try await enqueueLoadMediaRequest(forSource: source) { [weak client] in + guard let client else { throw MediaLoaderError.missingClient } + return try await client.getMediaThumbnail(mediaSource: source.underlyingSource, width: UInt64(width), height: UInt64(height)) } } func loadMediaFileForSource(_ source: MediaSourceProxy, filename: String?) async throws -> MediaFileHandleProxy { + guard let client else { throw MediaLoaderError.missingClient } let result = try await client.getMediaFile(mediaSource: source.underlyingSource, filename: filename, mimeType: source.mimeType ?? "application/octet-stream", diff --git a/ElementX/Sources/Services/Media/Provider/MediaLoaderProtocol.swift b/ElementX/Sources/Services/Media/Provider/MediaLoaderProtocol.swift index 55666713b..b1274ead2 100644 --- a/ElementX/Sources/Services/Media/Provider/MediaLoaderProtocol.swift +++ b/ElementX/Sources/Services/Media/Provider/MediaLoaderProtocol.swift @@ -7,6 +7,10 @@ import Foundation +enum MediaLoaderError: Error { + case missingClient +} + // sourcery: AutoMockable protocol MediaLoaderProtocol { func loadMediaContentForSource(_ source: MediaSourceProxy) async throws -> Data diff --git a/ElementX/Sources/Services/Media/Provider/MediaProvider.swift b/ElementX/Sources/Services/Media/Provider/MediaProvider.swift index 2db1ad263..26e73087f 100644 --- a/ElementX/Sources/Services/Media/Provider/MediaProvider.swift +++ b/ElementX/Sources/Services/Media/Provider/MediaProvider.swift @@ -9,7 +9,7 @@ import Combine import Kingfisher import UIKit -class MediaProvider: MediaProviderProtocol { +struct MediaProvider: MediaProviderProtocol { private let mediaLoader: MediaLoaderProtocol private let imageCache: Kingfisher.ImageCache private let homeserverReachabilityPublisher: CurrentValuePublisher? diff --git a/ElementX/Sources/Services/Media/Provider/MediaProviderProtocol.swift b/ElementX/Sources/Services/Media/Provider/MediaProviderProtocol.swift index 16611d28e..1fe98f16d 100644 --- a/ElementX/Sources/Services/Media/Provider/MediaProviderProtocol.swift +++ b/ElementX/Sources/Services/Media/Provider/MediaProviderProtocol.swift @@ -17,7 +17,7 @@ enum MediaProviderError: Error { } // sourcery: AutoMockable -protocol MediaProviderProtocol: AnyObject { +protocol MediaProviderProtocol { func imageFromSource(_ source: MediaSourceProxy?, size: CGSize?) -> UIImage? func loadImageFromSource(_ source: MediaSourceProxy, size: CGSize?) async -> Result func loadImageDataFromSource(_ source: MediaSourceProxy) async -> Result diff --git a/ElementX/Sources/Services/UserSession/UserSessionStore.swift b/ElementX/Sources/Services/UserSession/UserSessionStore.swift index 8697b9b31..ec7d4dd66 100644 --- a/ElementX/Sources/Services/UserSession/UserSessionStore.swift +++ b/ElementX/Sources/Services/UserSession/UserSessionStore.swift @@ -94,7 +94,7 @@ class UserSessionStore: UserSessionStoreProtocol { // MARK: - Private private func buildUserSessionWithClient(_ clientProxy: ClientProxyProtocol) -> UserSessionProtocol { - let mediaProvider = MediaProvider(mediaLoader: clientProxy, + let mediaProvider = MediaProvider(mediaLoader: clientProxy.mediaLoader, imageCache: .onlyInMemory, homeserverReachabilityPublisher: clientProxy.homeserverReachabilityPublisher) diff --git a/ElementX/Sources/UITests/UITestsAppCoordinator.swift b/ElementX/Sources/UITests/UITestsAppCoordinator.swift index df2602486..12b487ab8 100644 --- a/ElementX/Sources/UITests/UITestsAppCoordinator.swift +++ b/ElementX/Sources/UITests/UITestsAppCoordinator.swift @@ -562,7 +562,7 @@ class MockScreen: Identifiable { let parameters = SessionVerificationScreenCoordinatorParameters(sessionVerificationControllerProxy: sessionVerificationControllerProxy, flow: .deviceInitiator, appSettings: ServiceLocator.shared.settings, - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) return SessionVerificationScreenCoordinator(parameters: parameters) case .userSessionScreen, .userSessionScreenReply, .userSessionSpacesFlow: let appSettings: AppSettings = ServiceLocator.shared.settings @@ -618,7 +618,7 @@ class MockScreen: Identifiable { let navigationStackCoordinator = NavigationStackCoordinator() navigationStackCoordinator.setRootCoordinator(BlankFormCoordinator()) let coordinator = RoomRolesAndPermissionsFlowCoordinator(parameters: .init(roomProxy: JoinedRoomProxyMock(.init(members: .allMembersAsAdmin)), - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), navigationStackCoordinator: navigationStackCoordinator, userIndicatorController: ServiceLocator.shared.userIndicatorController, analytics: ServiceLocator.shared.analytics)) @@ -750,7 +750,7 @@ class MockScreen: Identifiable { timelineItemFactory: RoomTimelineItemFactory(userID: "@alice:matrix.org", attributedStringBuilder: AttributedStringBuilder(mentionBuilder: MentionBuilder()), stateEventStringBuilder: RoomStateEventStringBuilder(userID: "@alice:matrix.org")), - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), appSettings: ServiceLocator.shared.settings) let flowCoordinator = ChatsFlowCoordinator(isNewLogin: false, diff --git a/UnitTests/Sources/ComposerToolbarViewModelTests.swift b/UnitTests/Sources/ComposerToolbarViewModelTests.swift index 4f6c3bb3f..cecc4cafe 100644 --- a/UnitTests/Sources/ComposerToolbarViewModelTests.swift +++ b/UnitTests/Sources/ComposerToolbarViewModelTests.swift @@ -98,7 +98,7 @@ class ComposerToolbarViewModelTests: XCTestCase { viewModel = ComposerToolbarViewModel(roomProxy: JoinedRoomProxyMock(.init()), wysiwygViewModel: wysiwygViewModel, completionSuggestionService: mockCompletionSuggestionService, - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), mentionDisplayHelper: ComposerMentionDisplayHelper.mock, appSettings: ServiceLocator.shared.settings, analyticsService: ServiceLocator.shared.analytics, @@ -683,7 +683,7 @@ class ComposerToolbarViewModelTests: XCTestCase { viewModel = ComposerToolbarViewModel(roomProxy: roomProxyMock, wysiwygViewModel: wysiwygViewModel, completionSuggestionService: mockCompletionSuggestionService, - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), mentionDisplayHelper: ComposerMentionDisplayHelper.mock, appSettings: ServiceLocator.shared.settings, analyticsService: ServiceLocator.shared.analytics, @@ -727,7 +727,7 @@ class ComposerToolbarViewModelTests: XCTestCase { viewModel = ComposerToolbarViewModel(roomProxy: roomProxyMock, wysiwygViewModel: wysiwygViewModel, completionSuggestionService: mockCompletionSuggestionService, - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), mentionDisplayHelper: ComposerMentionDisplayHelper.mock, appSettings: ServiceLocator.shared.settings, analyticsService: ServiceLocator.shared.analytics, @@ -761,7 +761,7 @@ class ComposerToolbarViewModelTests: XCTestCase { viewModel = ComposerToolbarViewModel(roomProxy: roomProxyMock, wysiwygViewModel: wysiwygViewModel, completionSuggestionService: mockCompletionSuggestionService, - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), mentionDisplayHelper: ComposerMentionDisplayHelper.mock, appSettings: ServiceLocator.shared.settings, analyticsService: ServiceLocator.shared.analytics, @@ -796,7 +796,7 @@ class ComposerToolbarViewModelTests: XCTestCase { roomProxy: JoinedRoomProxyMock(.init()), wysiwygViewModel: wysiwygViewModel, completionSuggestionService: completionSuggestionServiceMock, - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), mentionDisplayHelper: ComposerMentionDisplayHelper.mock, appSettings: ServiceLocator.shared.settings, analyticsService: ServiceLocator.shared.analytics, diff --git a/UnitTests/Sources/GlobalSearchScreenViewModelTests.swift b/UnitTests/Sources/GlobalSearchScreenViewModelTests.swift index 479259c5c..148ff2543 100644 --- a/UnitTests/Sources/GlobalSearchScreenViewModelTests.swift +++ b/UnitTests/Sources/GlobalSearchScreenViewModelTests.swift @@ -19,7 +19,7 @@ class GlobalSearchScreenViewModelTests: XCTestCase { override func setUpWithError() throws { cancellables.removeAll() viewModel = GlobalSearchScreenViewModel(roomSummaryProvider: RoomSummaryProviderMock(.init(state: .loaded(.mockRooms))), - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) context = viewModel.context } diff --git a/UnitTests/Sources/KnockRequestsListScreenViewModelTests.swift b/UnitTests/Sources/KnockRequestsListScreenViewModelTests.swift index cc36abf3e..1aedacc49 100644 --- a/UnitTests/Sources/KnockRequestsListScreenViewModelTests.swift +++ b/UnitTests/Sources/KnockRequestsListScreenViewModelTests.swift @@ -24,7 +24,7 @@ class KnockRequestsListScreenViewModelTests: XCTestCase { func testLoadingState() async throws { let roomProxyMock = JoinedRoomProxyMock(.init(knockRequestsState: .loading, joinRule: .knock)) viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock, - mediaProvider: .mock, + mediaProvider: MediaProviderMock(), userIndicatorController: UserIndicatorControllerMock()) let deferred = deferFulfillment(context.$viewState) { state in @@ -42,7 +42,7 @@ class KnockRequestsListScreenViewModelTests: XCTestCase { func testEmptyState() async throws { let roomProxyMock = JoinedRoomProxyMock(.init(knockRequestsState: .loaded([]), joinRule: .knock)) viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock, - mediaProvider: .mock, + mediaProvider: MediaProviderMock(), userIndicatorController: UserIndicatorControllerMock()) let deferred = deferFulfillment(context.$viewState) { state in @@ -66,7 +66,7 @@ class KnockRequestsListScreenViewModelTests: XCTestCase { ownUserID: RoomMemberProxyMock.mockAdmin.userID, joinRule: .knock)) viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock, - mediaProvider: .mock, + mediaProvider: MediaProviderMock(), userIndicatorController: UserIndicatorControllerMock()) var deferred = deferFulfillment(context.$viewState) { state in @@ -141,7 +141,7 @@ class KnockRequestsListScreenViewModelTests: XCTestCase { KnockRequestProxyMock(.init(eventID: "4", userID: "@dan:matrix.org"))]), joinRule: .knock)) viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock, - mediaProvider: .mock, + mediaProvider: MediaProviderMock(), userIndicatorController: UserIndicatorControllerMock()) var deferred = deferFulfillment(context.$viewState) { state in @@ -189,7 +189,7 @@ class KnockRequestsListScreenViewModelTests: XCTestCase { ownUserID: RoomMemberProxyMock.mockAdmin.userID, joinRule: .invite)) viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock, - mediaProvider: .mock, + mediaProvider: MediaProviderMock(), userIndicatorController: UserIndicatorControllerMock()) let deferred = deferFulfillment(context.$viewState) { state in @@ -210,7 +210,7 @@ class KnockRequestsListScreenViewModelTests: XCTestCase { joinRule: .knock, powerLevelsConfiguration: .init(canUserInvite: false))) viewModel = KnockRequestsListScreenViewModel(roomProxy: roomProxyMock, - mediaProvider: .mock, + mediaProvider: MediaProviderMock(), userIndicatorController: UserIndicatorControllerMock()) let deferred = deferFulfillment(context.$viewState) { state in diff --git a/UnitTests/Sources/ManageRoomMemberSheetViewModelTests.swift b/UnitTests/Sources/ManageRoomMemberSheetViewModelTests.swift index dd2b27646..ee14d978e 100644 --- a/UnitTests/Sources/ManageRoomMemberSheetViewModelTests.swift +++ b/UnitTests/Sources/ManageRoomMemberSheetViewModelTests.swift @@ -32,7 +32,7 @@ class ManageRoomMemberSheetViewModelTests: XCTestCase { roomProxy: roomProxy, userIndicatorController: UserIndicatorControllerMock(), analyticsService: ServiceLocator.shared.analytics, - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) let deferred = deferFulfillment(context.observe(\.viewState.bindings.alertInfo)) { $0 != nil } let deferredAction = deferFulfillment(viewModel.actions) { action in @@ -63,7 +63,7 @@ class ManageRoomMemberSheetViewModelTests: XCTestCase { roomProxy: roomProxy, userIndicatorController: UserIndicatorControllerMock(), analyticsService: ServiceLocator.shared.analytics, - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) let deferred = deferFulfillment(context.observe(\.viewState.bindings.alertInfo)) { $0 != nil } context.send(viewAction: .ban) @@ -85,7 +85,7 @@ class ManageRoomMemberSheetViewModelTests: XCTestCase { roomProxy: roomProxy, userIndicatorController: UserIndicatorControllerMock(), analyticsService: ServiceLocator.shared.analytics, - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) let deferredAction = deferFulfillment(viewModel.actions) { action in action == .dismiss(shouldShowDetails: true) diff --git a/UnitTests/Sources/RoomChangeRolesScreenViewModelTests.swift b/UnitTests/Sources/RoomChangeRolesScreenViewModelTests.swift index d3589fe6f..bd09fc429 100644 --- a/UnitTests/Sources/RoomChangeRolesScreenViewModelTests.swift +++ b/UnitTests/Sources/RoomChangeRolesScreenViewModelTests.swift @@ -196,7 +196,7 @@ class RoomChangeRolesScreenViewModelTests: XCTestCase { roomProxy = JoinedRoomProxyMock(.init(members: .allMembersAsAdmin)) viewModel = RoomChangeRolesScreenViewModel(mode: mode, roomProxy: roomProxy, - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), userIndicatorController: UserIndicatorControllerMock(), analytics: ServiceLocator.shared.analytics) } diff --git a/UnitTests/Sources/SessionVerificationViewModelTests.swift b/UnitTests/Sources/SessionVerificationViewModelTests.swift index b69371e18..149c77232 100644 --- a/UnitTests/Sources/SessionVerificationViewModelTests.swift +++ b/UnitTests/Sources/SessionVerificationViewModelTests.swift @@ -21,7 +21,7 @@ class SessionVerificationViewModelTests: XCTestCase { viewModel = SessionVerificationScreenViewModel(sessionVerificationControllerProxy: sessionVerificationController, flow: .deviceInitiator, appSettings: AppSettings(), - mediaProvider: .mock) + mediaProvider: MediaProviderMock(configuration: .init())) context = viewModel.context } diff --git a/UnitTests/Sources/SpaceScreenViewModelTests.swift b/UnitTests/Sources/SpaceScreenViewModelTests.swift index 755b90625..980436fba 100644 --- a/UnitTests/Sources/SpaceScreenViewModelTests.swift +++ b/UnitTests/Sources/SpaceScreenViewModelTests.swift @@ -118,7 +118,7 @@ class SpaceScreenViewModelTests: XCTestCase { viewModel = SpaceScreenViewModel(spaceRoomListProxy: spaceRoomListProxy, spaceServiceProxy: spaceServiceProxy, selectedSpaceRoomPublisher: .init(nil), - mediaProvider: .mock, + mediaProvider: MediaProviderMock(configuration: .init()), userIndicatorController: UserIndicatorControllerMock()) } } diff --git a/UnitTests/Sources/TimelineMediaPreviewViewModelTests.swift b/UnitTests/Sources/TimelineMediaPreviewViewModelTests.swift index 072754dac..0958198a7 100644 --- a/UnitTests/Sources/TimelineMediaPreviewViewModelTests.swift +++ b/UnitTests/Sources/TimelineMediaPreviewViewModelTests.swift @@ -281,7 +281,7 @@ class TimelineMediaPreviewViewModelTests: XCTestCase { timelineController = MockTimelineController(timelineKind: .media(.mediaFilesScreen)) timelineController.timelineItems = initialItems - mediaProvider = MediaProviderMock(.init()) + mediaProvider = MediaProviderMock(configuration: .init()) photoLibraryManager = PhotoLibraryManagerMock(.init(authorizationDenied: photoLibraryAuthorizationDenied)) viewModel = TimelineMediaPreviewViewModel(initialItem: initialItems[initialItemIndex], diff --git a/UnitTests/Sources/VoiceMessageMediaManagerTests.swift b/UnitTests/Sources/VoiceMessageMediaManagerTests.swift index e7586d088..5690f549c 100644 --- a/UnitTests/Sources/VoiceMessageMediaManagerTests.swift +++ b/UnitTests/Sources/VoiceMessageMediaManagerTests.swift @@ -21,7 +21,7 @@ class VoiceMessageMediaManagerTests: XCTestCase { override func setUp() async throws { voiceMessageCache = VoiceMessageCacheMock() - mediaProvider = .mock + mediaProvider = MediaProviderMock(configuration: .init()) mediaProvider.loadFileFromSourceFilenameClosure = nil mediaProvider.loadFileFromSourceFilenameReturnValue = .failure(.failedRetrievingFile) voiceMessageMediaManager = VoiceMessageMediaManager(mediaProvider: mediaProvider,