diff --git a/ElementX/Sources/Mocks/ClientProxyMock.swift b/ElementX/Sources/Mocks/ClientProxyMock.swift index 0b2211c60..91aa74ee4 100644 --- a/ElementX/Sources/Mocks/ClientProxyMock.swift +++ b/ElementX/Sources/Mocks/ClientProxyMock.swift @@ -81,11 +81,9 @@ extension ClientProxyMock { recentlyVisitedRoomsReturnValue = .success([]) recentConversationCounterpartsReturnValue = [] - let mediaLoader = MediaLoaderMock() - mediaLoader.loadMediaContentForSourceThrowableError = ClientProxyError.sdkError(ClientProxyMockError.generic) - mediaLoader.loadMediaThumbnailForSourceWidthHeightThrowableError = ClientProxyError.sdkError(ClientProxyMockError.generic) - mediaLoader.loadMediaFileForSourceFilenameThrowableError = ClientProxyError.sdkError(ClientProxyMockError.generic) - self.mediaLoader = mediaLoader + loadMediaContentForSourceThrowableError = ClientProxyError.sdkError(ClientProxyMockError.generic) + loadMediaThumbnailForSourceWidthHeightThrowableError = ClientProxyError.sdkError(ClientProxyMockError.generic) + loadMediaFileForSourceFilenameThrowableError = ClientProxyError.sdkError(ClientProxyMockError.generic) 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 a0b672c21..ec760a56b 100644 --- a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift @@ -2125,11 +2125,6 @@ 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,6 +5199,228 @@ 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 6137a2445..b9c8ea601 100644 --- a/ElementX/Sources/Mocks/MediaProviderMock.swift +++ b/ElementX/Sources/Mocks/MediaProviderMock.swift @@ -7,11 +7,17 @@ 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 6f5794518..7ce0400e0 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 = MediaProviderMock(configuration: .init()) + mediaProvider = .mock 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 3c0dac2e6..94090a0d7 100644 --- a/ElementX/Sources/Other/Pills/PillView.swift +++ b/ElementX/Sources/Other/Pills/PillView.swift @@ -42,8 +42,6 @@ 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 25e49d5c6..b4ff484aa 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: MediaProviderMock(configuration: .init())) { _ in } + HomeScreenRoomCell(room: .placeholder(), isSelected: false, mediaProvider: .mock) { _ in } } } .redacted(reason: .placeholder) diff --git a/ElementX/Sources/Other/SwiftUI/ViewModel/StateStoreViewModel.swift b/ElementX/Sources/Other/SwiftUI/ViewModel/StateStoreViewModel.swift index 00b0ff198..8ab2fc3d0 100644 --- a/ElementX/Sources/Other/SwiftUI/ViewModel/StateStoreViewModel.swift +++ b/ElementX/Sources/Other/SwiftUI/ViewModel/StateStoreViewModel.swift @@ -65,7 +65,12 @@ class StateStoreViewModel { /// An optional image loading service so that views can manage themselves /// Intentionally non-generic so that it doesn't grow uncontrollably - let mediaProvider: MediaProviderProtocol? + /// + /// 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? /// 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 eca817e93..e386de1eb 100644 --- a/ElementX/Sources/Other/SwiftUI/ViewModel/StateStoreViewModelV2.swift +++ b/ElementX/Sources/Other/SwiftUI/ViewModel/StateStoreViewModelV2.swift @@ -67,7 +67,12 @@ class StateStoreViewModelV2 { /// An optional image loading service so that views can manage themselves /// Intentionally non-generic so that it doesn't grow uncontrollably - let mediaProvider: MediaProviderProtocol? + /// + /// 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? /// 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 b3f9a1970..92b655533 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: MediaProviderMock(configuration: .init())) { + mediaProvider: .mock) { 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: MediaProviderMock(configuration: .init())) { + mediaProvider: .mock) { 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: MediaProviderMock(configuration: .init())) { Text("") } + mediaProvider: .mock) { Text("") } AvatarHeaderView(member: RoomMemberDetails(withProxy: RoomMemberProxyMock.mockBob), isVerified: true, avatarSize: .room(on: .details), - mediaProvider: MediaProviderMock(configuration: .init())) { Text("") } + mediaProvider: .mock) { Text("") } AvatarHeaderView(member: RoomMemberDetails(withProxy: RoomMemberProxyMock.mockBanned[3]), avatarSize: .room(on: .details), - mediaProvider: MediaProviderMock(configuration: .init())) { Text("") } + mediaProvider: .mock) { 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 0d46166f5..cda63312f 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(configuration: .init()) + let mediaProvider = MediaProviderMock(.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 0e865eb66..df1933517 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: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) RoomAvatarImage(avatar: .room(id: "!2:server.com", name: "Room", avatarURL: .mockMXCAvatar), avatarSize: .room(on: .chats), - mediaProvider: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) RoomAvatarImage(avatar: .space(id: "!space:server.com", name: "Room", avatarURL: nil), avatarSize: .room(on: .chats), - mediaProvider: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) RoomAvatarImage(avatar: .space(id: "!otherspace:server.com", name: "Room", avatarURL: .mockMXCAvatar), avatarSize: .room(on: .chats), - mediaProvider: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) - RoomAvatarImage(avatar: .tombstoned, avatarSize: .room(on: .chats), mediaProvider: MediaProviderMock(configuration: .init())) + RoomAvatarImage(avatar: .tombstoned, avatarSize: .room(on: .chats), mediaProvider: .mock) } HStack(spacing: 12) { @@ -161,18 +161,18 @@ struct RoomAvatarImage_Previews: PreviewProvider, TestablePreview { displayName: "User", avatarURL: nil)]), avatarSize: .room(on: .chats), - mediaProvider: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) RoomAvatarImage(avatar: .heroes([.init(userID: "@user:server.com", displayName: "User", avatarURL: .mockMXCAvatar)]), avatarSize: .room(on: .chats), - mediaProvider: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) 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: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) } } } diff --git a/ElementX/Sources/Other/SwiftUI/Views/RoomHeaderView.swift b/ElementX/Sources/Other/SwiftUI/Views/RoomHeaderView.swift index 68b27e4a9..e3567d87d 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: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) .padding() } } diff --git a/ElementX/Sources/Other/SwiftUI/Views/RoomInviterLabel.swift b/ElementX/Sources/Other/SwiftUI/Views/RoomInviterLabel.swift index d735c8feb..cbd65c54c 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: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) RoomInviterLabel(inviter: .init(member: RoomMemberProxyMock.mockDan), - mediaProvider: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) RoomInviterLabel(inviter: .init(member: RoomMemberProxyMock.mockNoName), - mediaProvider: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) RoomInviterLabel(inviter: .init(member: RoomMemberProxyMock.mockCharlie), - mediaProvider: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) .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 95fea362f..b8e1617c5 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: MediaProviderMock()) + mediaProvider: .mock) StackedAvatarsView(overlap: 16, lineWidth: 2, shouldStackFromLast: true, avatars: avatars, avatarSize: .user(on: .knockingUsersBannerStack), - mediaProvider: MediaProviderMock()) + mediaProvider: .mock) } } } diff --git a/ElementX/Sources/Other/SwiftUI/Views/UserProfileListRow.swift b/ElementX/Sources/Other/SwiftUI/Views/UserProfileListRow.swift index 02dc0ba0b..406de9632 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: MediaProviderMock(configuration: .init()), + UserProfileListRow(user: .mockAlice, membership: nil, mediaProvider: .mock, kind: .multiSelection(isSelected: true, action: action)) - UserProfileListRow(user: .mockBob, membership: nil, mediaProvider: MediaProviderMock(configuration: .init()), + UserProfileListRow(user: .mockBob, membership: nil, mediaProvider: .mock, kind: .multiSelection(isSelected: false, action: action)) - UserProfileListRow(user: .mockCharlie, membership: .join, mediaProvider: MediaProviderMock(configuration: .init()), + UserProfileListRow(user: .mockCharlie, membership: .join, mediaProvider: .mock, kind: .multiSelection(isSelected: true, action: action)) .disabled(true) - UserProfileListRow(user: .init(userID: "@someone:matrix.org"), membership: .join, mediaProvider: MediaProviderMock(configuration: .init()), + UserProfileListRow(user: .init(userID: "@someone:matrix.org"), membership: .join, mediaProvider: .mock, kind: .multiSelection(isSelected: false, action: action)) .disabled(true) - UserProfileListRow(user: .init(userID: "@someone:matrix.org"), membership: nil, mediaProvider: MediaProviderMock(configuration: .init()), + UserProfileListRow(user: .init(userID: "@someone:matrix.org"), membership: nil, mediaProvider: .mock, kind: .multiSelection(isSelected: false, action: action)) } .compoundList() diff --git a/ElementX/Sources/Screens/FilePreviewScreen/TimelineMediaPreviewModifier.swift b/ElementX/Sources/Screens/FilePreviewScreen/TimelineMediaPreviewModifier.swift index fb784ea24..02ba7f6c4 100644 --- a/ElementX/Sources/Screens/FilePreviewScreen/TimelineMediaPreviewModifier.swift +++ b/ElementX/Sources/Screens/FilePreviewScreen/TimelineMediaPreviewModifier.swift @@ -135,9 +135,12 @@ private struct MediaPreviewViewController: UIViewControllerRepresentable { // MARK: - Previews struct TimelineMediaPreviewModifier_Previews: PreviewProvider { - static let viewModel = makeViewModel() - static let downloadingViewModel = makeViewModel(isDownloading: true) - static let downloadErrorViewModel = makeViewModel(isDownloadError: true) + 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 var previews: some View { MediaPreviewViewController(viewModel: viewModel, dismissalPublisher: .init()) { } @@ -148,7 +151,7 @@ struct TimelineMediaPreviewModifier_Previews: PreviewProvider { .previewDisplayName("Download Error") } - static func makeViewModel(isDownloading: Bool = false, isDownloadError: Bool = false) -> TimelineMediaPreviewViewModel { + static func makeViewModel(isDownloading: Bool = false, isDownloadError: Bool = false, mediaProvider: MediaProviderMock) -> TimelineMediaPreviewViewModel { let item = FileRoomTimelineItem(id: .randomEvent, timestamp: .mock, isOutgoing: false, @@ -165,8 +168,6 @@ 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 48da4fa89..7020d292f 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, 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 4673d300b..24b8416f1 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, 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 76f18a86b..cab900a51 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: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) 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 1300dff95..986a4d15e 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: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) 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 d9926f368..866d89c78 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: MediaProviderMock(configuration: .init())) { _ in } + HomeScreenRoomCell(room: room, isSelected: false, mediaProvider: .mock) { _ in } } - HomeScreenRoomCell(room: .placeholder(), isSelected: false, mediaProvider: MediaProviderMock(configuration: .init())) { _ in } + HomeScreenRoomCell(room: .placeholder(), isSelected: false, mediaProvider: .mock) { _ in } .redacted(reason: .placeholder) } .previewDisplayName("Generic") VStack(spacing: 0) { ForEach(notificationsStateRooms) { room in - HomeScreenRoomCell(room: room, isSelected: false, mediaProvider: MediaProviderMock(configuration: .init())) { _ in } + HomeScreenRoomCell(room: room, isSelected: false, mediaProvider: .mock) { _ in } } } .previewLayout(.sizeThatFits) diff --git a/ElementX/Sources/Screens/InviteUsersScreen/View/InviteUsersScreenSelectedItem.swift b/ElementX/Sources/Screens/InviteUsersScreen/View/InviteUsersScreenSelectedItem.swift index 02e64fdfd..f08b0ea74 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: MediaProviderMock(configuration: .init())) { } + InviteUsersScreenSelectedItem(user: user, mediaProvider: .mock) { } .frame(width: 72) } } diff --git a/ElementX/Sources/Screens/KnockRequestsListScreen/View/KnockRequestsListScreen.swift b/ElementX/Sources/Screens/KnockRequestsListScreen/View/KnockRequestsListScreen.swift index 1ab45e435..59be0c7b4 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: MediaProviderMock(), + mediaProvider: .mock, userIndicatorController: UserIndicatorControllerMock()) } } diff --git a/ElementX/Sources/Screens/ManageRoomMemberSheet/View/ManageRoomMemberSheetView.swift b/ElementX/Sources/Screens/ManageRoomMemberSheet/View/ManageRoomMemberSheetView.swift index 83bd19e8e..f1b1f2217 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: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) } } diff --git a/ElementX/Sources/Screens/MediaEventsTimelineScreen/View/MediaEventsTimelineScreen.swift b/ElementX/Sources/Screens/MediaEventsTimelineScreen/View/MediaEventsTimelineScreen.swift index 7bfce42a0..bb66789bc 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, 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 d7011d1fe..7a7ecd78e 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: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) .padding() .previewDisplayName("User") SessionVerificationRequestDetailsView(details: details, isUserVerification: false, - mediaProvider: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) .padding() .previewDisplayName("Device") } diff --git a/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/View/SessionVerificationScreen.swift b/ElementX/Sources/Screens/Onboarding/SessionVerificationScreen/View/SessionVerificationScreen.swift index 59f7be832..f726cc2b3 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, 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 5b10e2a93..60e11e521 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, 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 3a37623e0..f181de025 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, isSelected: true, action: action) RoomChangeRolesScreenRow(member: .init(withProxy: RoomMemberProxyMock.mockBob), - mediaProvider: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, isSelected: false, action: action) RoomChangeRolesScreenRow(member: .init(withProxy: RoomMemberProxyMock.mockInvited), - mediaProvider: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, isSelected: false, action: action) RoomChangeRolesScreenRow(member: .init(withProxy: RoomMemberProxyMock.mockCharlie), - mediaProvider: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, isSelected: true, action: action) .disabled(true) RoomChangeRolesScreenRow(member: .init(withProxy: RoomMemberProxyMock(with: .init(userID: "@someone:matrix.org", membership: .join))), - mediaProvider: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, isSelected: false, action: action) .disabled(true) RoomChangeRolesScreenRow(member: .init(withProxy: RoomMemberProxyMock(with: .init(userID: "@someone:matrix.org", membership: .join))), - mediaProvider: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, isSelected: false, action: action) } diff --git a/ElementX/Sources/Screens/RoomChangeRolesScreen/View/RoomChangeRolesScreenSelectedItem.swift b/ElementX/Sources/Screens/RoomChangeRolesScreen/View/RoomChangeRolesScreenSelectedItem.swift index 0d8ca8ebf..3bfc65bd1 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: MediaProviderMock(configuration: .init())) { } + mediaProvider: .mock) { } .frame(width: 72) } } diff --git a/ElementX/Sources/Screens/RoomDirectorySearchScreen/View/RoomDirectoryCell.swift b/ElementX/Sources/Screens/RoomDirectorySearchScreen/View/RoomDirectoryCell.swift index 6258161ee..ec74ed6eb 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: MediaProviderMock(configuration: .init())) { } + mediaProvider: .mock) { } 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: MediaProviderMock(configuration: .init())) { } + mediaProvider: .mock) { } 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: MediaProviderMock(configuration: .init())) { } + mediaProvider: .mock) { } 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: MediaProviderMock(configuration: .init())) { } + mediaProvider: .mock) { } 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: MediaProviderMock(configuration: .init())) { } + mediaProvider: .mock) { } 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: MediaProviderMock(configuration: .init())) { } + mediaProvider: .mock) { } 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: MediaProviderMock(configuration: .init())) { } + mediaProvider: .mock) { } 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: MediaProviderMock(configuration: .init())) { } + mediaProvider: .mock) { } } .compoundList() } diff --git a/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/CompletionSuggestionView.swift b/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/CompletionSuggestionView.swift index 28dce8003..1f8256f99 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: MediaProviderMock(configuration: .init()), + CompletionSuggestionView(mediaProvider: .mock, 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: MediaProviderMock(configuration: .init()), + CompletionSuggestionView(mediaProvider: .mock, items: multipleItems) { _ in } } } diff --git a/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/ComposerToolbar.swift b/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/ComposerToolbar.swift index 06ca0e994..1beda995b 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, 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 789b54568..bbc61683a 100644 --- a/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/MentionSuggestionItemView.swift +++ b/ElementX/Sources/Screens/RoomScreen/ComposerToolbar/View/MentionSuggestionItemView.swift @@ -45,16 +45,14 @@ struct MentionSuggestionItemView: View { } struct MentionSuggestionItemView_Previews: PreviewProvider, TestablePreview { - static let mockMediaProvider = MediaProviderMock(configuration: .init()) - static var previews: some View { - MentionSuggestionItemView(mediaProvider: mockMediaProvider, item: .init(suggestionType: .user(.init(id: "test", displayName: "Test", avatarURL: .mockMXCUserAvatar)), range: .init(), rawSuggestionText: "")) + MentionSuggestionItemView(mediaProvider: .mock, item: .init(suggestionType: .user(.init(id: "test", displayName: "Test", avatarURL: .mockMXCUserAvatar)), range: .init(), rawSuggestionText: "")) .previewDisplayName("User") - MentionSuggestionItemView(mediaProvider: mockMediaProvider, item: .init(suggestionType: .user(.init(id: "test2", displayName: nil, avatarURL: nil)), range: .init(), rawSuggestionText: "")) + MentionSuggestionItemView(mediaProvider: .mock, item: .init(suggestionType: .user(.init(id: "test2", displayName: nil, avatarURL: nil)), range: .init(), rawSuggestionText: "")) .previewDisplayName("User no display name") - MentionSuggestionItemView(mediaProvider: mockMediaProvider, item: .init(suggestionType: .allUsers(.room(id: "room", name: "Room", avatarURL: .mockMXCAvatar)), range: .init(), rawSuggestionText: "")) + MentionSuggestionItemView(mediaProvider: .mock, item: .init(suggestionType: .allUsers(.room(id: "room", name: "Room", avatarURL: .mockMXCAvatar)), range: .init(), rawSuggestionText: "")) .previewDisplayName("All users") - MentionSuggestionItemView(mediaProvider: mockMediaProvider, + MentionSuggestionItemView(mediaProvider: .mock, 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 c22be2d49..1de0b90db 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, 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 0a48b0ca4..b6440e9a9 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: MediaProviderMock(configuration: .init())) { _ in } + RoomScreenFooterView(details: bobDetails, mediaProvider: .mock) { _ in } .previewDisplayName("With displayname") - RoomScreenFooterView(details: noNameDetails, mediaProvider: MediaProviderMock(configuration: .init())) { _ in } + RoomScreenFooterView(details: noNameDetails, mediaProvider: .mock) { _ in } .previewDisplayName("Without displayname") - RoomScreenFooterView(details: verificationViolationDetails, mediaProvider: MediaProviderMock(configuration: .init())) { _ in } + RoomScreenFooterView(details: verificationViolationDetails, mediaProvider: .mock) { _ in } .previewDisplayName("Verification Violation") } } diff --git a/ElementX/Sources/Screens/Spaces/Common/SpaceHeaderView.swift b/ElementX/Sources/Screens/Spaces/Common/SpaceHeaderView.swift index fad316a57..3d2e94ed9 100644 --- a/ElementX/Sources/Screens/Spaces/Common/SpaceHeaderView.swift +++ b/ElementX/Sources/Screens/Spaces/Common/SpaceHeaderView.swift @@ -151,14 +151,12 @@ 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: mediaProvider) + SpaceHeaderView(spaceRoomProxy: space, mediaProvider: .mock) } } } diff --git a/ElementX/Sources/Screens/Spaces/Common/SpaceRoomCell.swift b/ElementX/Sources/Screens/Spaces/Common/SpaceRoomCell.swift index 402e1ab78..59ce045e3 100644 --- a/ElementX/Sources/Screens/Spaces/Common/SpaceRoomCell.swift +++ b/ElementX/Sources/Screens/Spaces/Common/SpaceRoomCell.swift @@ -134,8 +134,6 @@ struct SpaceRoomCellButtonStyle: ButtonStyle { } struct SpaceRoomCell_Previews: PreviewProvider, TestablePreview { - static let mediaProvider = MediaProviderMock(configuration: .init()) - static let spaces = [SpaceRoomProxyProtocol].mockSpaceList static var previews: some View { @@ -143,7 +141,7 @@ struct SpaceRoomCell_Previews: PreviewProvider, TestablePreview { ForEach(spaces, id: \.id) { space in SpaceRoomCell(spaceRoomProxy: space, isSelected: false, - mediaProvider: mediaProvider) { _ in } + mediaProvider: .mock) { _ in } } } } diff --git a/ElementX/Sources/Screens/Spaces/SpaceScreen/View/SpaceScreen.swift b/ElementX/Sources/Screens/Spaces/SpaceScreen/View/SpaceScreen.swift index e3a87aa2c..45e93b8d9 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, 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 1d5423291..aeb794bb5 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: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) .previewDisplayName("No Image") ReadReceiptCell(readReceipt: .init(userID: "@test:matrix.org", formattedTimestamp: "10:00"), memberState: .init(displayName: "Test", avatarURL: .mockMXCUserAvatar), - mediaProvider: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) .previewDisplayName("With Image") ReadReceiptCell(readReceipt: .init(userID: "@test:matrix.org", formattedTimestamp: "10:00"), memberState: nil, - mediaProvider: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) .previewDisplayName("Loading Member") } } diff --git a/ElementX/Sources/Screens/Timeline/View/Supplementary/ReactionsSummaryView.swift b/ElementX/Sources/Screens/Timeline/View/Supplementary/ReactionsSummaryView.swift index 97ea6c1db..f02d9e83e 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, selectedReactionKey: AggregatedReaction.mockReactions[0].key) } } diff --git a/ElementX/Sources/Services/Client/ClientProxy.swift b/ElementX/Sources/Services/Client/ClientProxy.swift index 847100f44..dfb79dd39 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 - let mediaLoader: MediaLoaderProtocol + private let mediaLoader: MediaLoaderProtocol private let clientQueue: DispatchQueue private var roomListService: RoomListService @@ -1113,6 +1113,20 @@ 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 af6ba8ed4..a4bc00157 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 { +protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol { var actionsPublisher: AnyPublisher { get } var loadingStatePublisher: CurrentValuePublisher { get } @@ -103,8 +103,6 @@ protocol ClientProxyProtocol: AnyObject { 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 702ff3735..89478fc6c 100644 --- a/ElementX/Sources/Services/Media/Provider/MediaLoader.swift +++ b/ElementX/Sources/Services/Media/Provider/MediaLoader.swift @@ -16,17 +16,7 @@ private final class MediaRequest { } actor MediaLoader: MediaLoaderProtocol { - // Something is holding onto our MediaProvider (and therefore this MediaLoader) which means - // when attempting to clear the caches, the SDK's Client hangs around and we end up with 2. - // I have spent a long time trying to understand what's going on – there's instances of both - // TimelineViewModel.Context and ComposerToolbarViewModel.Context still hanging around and - // a closure captures the media provider from both of those as far as I can tell, but I was - // unable to break the reference. Possibly related to the ElementTextView too. - // - // In lieu of the real fix, lets use a weak reference to the Client here so that it can be - // released and hopefully that will solve our logs files exploding in size when encountering - // a corrupt/missing database file. - private weak var client: ClientProtocol? + private let client: ClientProtocol private var ongoingRequests = [MediaSourceProxy: MediaRequest]() init(client: ClientProtocol) { @@ -34,21 +24,18 @@ actor MediaLoader: MediaLoaderProtocol { } func loadMediaContentForSource(_ source: MediaSourceProxy) async throws -> Data { - try await enqueueLoadMediaRequest(forSource: source) { [weak client] in - guard let client else { throw MediaLoaderError.missingClient } - return try await client.getMediaContent(mediaSource: source.underlyingSource) + try await enqueueLoadMediaRequest(forSource: source) { + try await self.client.getMediaContent(mediaSource: source.underlyingSource) } } func loadMediaThumbnailForSource(_ source: MediaSourceProxy, width: UInt, height: UInt) async throws -> Data { - 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)) + try await enqueueLoadMediaRequest(forSource: source) { + try await self.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 b1274ead2..55666713b 100644 --- a/ElementX/Sources/Services/Media/Provider/MediaLoaderProtocol.swift +++ b/ElementX/Sources/Services/Media/Provider/MediaLoaderProtocol.swift @@ -7,10 +7,6 @@ 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 3eb3c0848..11dd30869 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 -struct MediaProvider: MediaProviderProtocol { +class MediaProvider: MediaProviderProtocol { private let mediaLoader: MediaLoaderProtocol private let imageCache: Kingfisher.ImageCache private let networkMonitor: NetworkMonitorProtocol? diff --git a/ElementX/Sources/Services/Media/Provider/MediaProviderProtocol.swift b/ElementX/Sources/Services/Media/Provider/MediaProviderProtocol.swift index 1fe98f16d..16611d28e 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 { +protocol MediaProviderProtocol: AnyObject { 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 dbc5f2b10..55f2f3f6b 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.mediaLoader, + let mediaProvider = MediaProvider(mediaLoader: clientProxy, imageCache: .onlyInMemory, networkMonitor: networkMonitor) diff --git a/ElementX/Sources/UITests/UITestsAppCoordinator.swift b/ElementX/Sources/UITests/UITestsAppCoordinator.swift index 12b487ab8..df2602486 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: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, appSettings: ServiceLocator.shared.settings) let flowCoordinator = ChatsFlowCoordinator(isNewLogin: false, diff --git a/UnitTests/Sources/ComposerToolbarViewModelTests.swift b/UnitTests/Sources/ComposerToolbarViewModelTests.swift index cecc4cafe..4f6c3bb3f 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, mentionDisplayHelper: ComposerMentionDisplayHelper.mock, appSettings: ServiceLocator.shared.settings, analyticsService: ServiceLocator.shared.analytics, diff --git a/UnitTests/Sources/GlobalSearchScreenViewModelTests.swift b/UnitTests/Sources/GlobalSearchScreenViewModelTests.swift index 148ff2543..479259c5c 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: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) context = viewModel.context } diff --git a/UnitTests/Sources/KnockRequestsListScreenViewModelTests.swift b/UnitTests/Sources/KnockRequestsListScreenViewModelTests.swift index 1aedacc49..cc36abf3e 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: MediaProviderMock(), + mediaProvider: .mock, 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: MediaProviderMock(), + mediaProvider: .mock, 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: MediaProviderMock(), + mediaProvider: .mock, 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: MediaProviderMock(), + mediaProvider: .mock, 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: MediaProviderMock(), + mediaProvider: .mock, 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: MediaProviderMock(), + mediaProvider: .mock, userIndicatorController: UserIndicatorControllerMock()) let deferred = deferFulfillment(context.$viewState) { state in diff --git a/UnitTests/Sources/ManageRoomMemberSheetViewModelTests.swift b/UnitTests/Sources/ManageRoomMemberSheetViewModelTests.swift index ee14d978e..dd2b27646 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: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) 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: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) 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: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) let deferredAction = deferFulfillment(viewModel.actions) { action in action == .dismiss(shouldShowDetails: true) diff --git a/UnitTests/Sources/RoomChangeRolesScreenViewModelTests.swift b/UnitTests/Sources/RoomChangeRolesScreenViewModelTests.swift index bd09fc429..d3589fe6f 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, userIndicatorController: UserIndicatorControllerMock(), analytics: ServiceLocator.shared.analytics) } diff --git a/UnitTests/Sources/SessionVerificationViewModelTests.swift b/UnitTests/Sources/SessionVerificationViewModelTests.swift index 149c77232..b69371e18 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: MediaProviderMock(configuration: .init())) + mediaProvider: .mock) context = viewModel.context } diff --git a/UnitTests/Sources/SpaceScreenViewModelTests.swift b/UnitTests/Sources/SpaceScreenViewModelTests.swift index 980436fba..755b90625 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: MediaProviderMock(configuration: .init()), + mediaProvider: .mock, userIndicatorController: UserIndicatorControllerMock()) } } diff --git a/UnitTests/Sources/TimelineMediaPreviewViewModelTests.swift b/UnitTests/Sources/TimelineMediaPreviewViewModelTests.swift index 0958198a7..072754dac 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(configuration: .init()) + mediaProvider = MediaProviderMock(.init()) photoLibraryManager = PhotoLibraryManagerMock(.init(authorizationDenied: photoLibraryAuthorizationDenied)) viewModel = TimelineMediaPreviewViewModel(initialItem: initialItems[initialItemIndex], diff --git a/UnitTests/Sources/VoiceMessageMediaManagerTests.swift b/UnitTests/Sources/VoiceMessageMediaManagerTests.swift index 5690f549c..e7586d088 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 = MediaProviderMock(configuration: .init()) + mediaProvider = .mock mediaProvider.loadFileFromSourceFilenameClosure = nil mediaProvider.loadFileFromSourceFilenameReturnValue = .failure(.failedRetrievingFile) voiceMessageMediaManager = VoiceMessageMediaManager(mediaProvider: mediaProvider,