From 5772fae6ff03b79004a745d9dc5c02a90be70041 Mon Sep 17 00:00:00 2001 From: ismailgulek Date: Fri, 23 Sep 2022 17:52:08 +0300 Subject: [PATCH] Fix room avatars on timeline (#213) --- ElementX/Sources/AppCoordinator.swift | 3 ++- .../RoomScreen/RoomScreenCoordinator.swift | 6 ++++-- .../Screens/RoomScreen/RoomScreenViewModel.swift | 16 ++++++++++++++-- .../Screens/RoomScreen/View/RoomHeaderView.swift | 6 ++++-- .../Screens/RoomScreen/View/RoomScreen.swift | 1 + .../RoomScreen/View/TimelineItemList.swift | 1 + .../Screens/RoomScreen/View/TimelineView.swift | 1 + .../Services/Media/MockMediaProvider.swift | 16 ++++++++++++---- ElementX/Sources/UITestsAppCoordinator.swift | 6 ++++-- 9 files changed, 43 insertions(+), 13 deletions(-) diff --git a/ElementX/Sources/AppCoordinator.swift b/ElementX/Sources/AppCoordinator.swift index db09d1f6f..8e064f17e 100644 --- a/ElementX/Sources/AppCoordinator.swift +++ b/ElementX/Sources/AppCoordinator.swift @@ -369,8 +369,9 @@ class AppCoordinator: Coordinator { roomProxy: roomProxy) let parameters = RoomScreenCoordinatorParameters(timelineController: timelineController, + mediaProvider: userSession.mediaProvider, roomName: roomProxy.displayName ?? roomProxy.name, - roomAvatar: userSession.mediaProvider.imageFromURLString(roomProxy.avatarURL, avatarSize: .room(on: .timeline))) + roomAvatarUrl: roomProxy.avatarURL) let coordinator = RoomScreenCoordinator(parameters: parameters) add(childCoordinator: coordinator) diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift index 81755d2f5..4b13171ef 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift @@ -18,8 +18,9 @@ import SwiftUI struct RoomScreenCoordinatorParameters { let timelineController: RoomTimelineControllerProtocol + let mediaProvider: MediaProviderProtocol let roomName: String? - let roomAvatar: UIImage? + let roomAvatarUrl: String? } final class RoomScreenCoordinator: Coordinator, Presentable { @@ -43,8 +44,9 @@ final class RoomScreenCoordinator: Coordinator, Presentable { let viewModel = RoomScreenViewModel(timelineController: parameters.timelineController, timelineViewFactory: RoomTimelineViewFactory(), + mediaProvider: parameters.mediaProvider, roomName: parameters.roomName, - roomAvatar: parameters.roomAvatar) + roomAvatarUrl: parameters.roomAvatarUrl) let view = RoomScreen(context: viewModel.context) roomScreenViewModel = viewModel diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift index bdc4da95e..2bf14f807 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift @@ -25,20 +25,23 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol private let timelineController: RoomTimelineControllerProtocol private let timelineViewFactory: RoomTimelineViewFactoryProtocol + private let mediaProvider: MediaProviderProtocol // MARK: - Setup init(timelineController: RoomTimelineControllerProtocol, timelineViewFactory: RoomTimelineViewFactoryProtocol, + mediaProvider: MediaProviderProtocol, roomName: String?, - roomAvatar: UIImage? = nil, + roomAvatarUrl: String? = nil, roomEncryptionBadge: UIImage? = nil) { self.timelineController = timelineController self.timelineViewFactory = timelineViewFactory + self.mediaProvider = mediaProvider super.init(initialViewState: RoomScreenViewState(roomId: timelineController.roomId, roomTitle: roomName ?? "Unknown room 💥", - roomAvatar: roomAvatar, + roomAvatar: nil, roomEncryptionBadge: roomEncryptionBadge, bindings: .init(composerText: "", composerFocused: false))) @@ -64,6 +67,15 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol state.contextMenuBuilder = buildContexMenuForItemId(_:) buildTimelineViews() + + if let roomAvatarUrl = roomAvatarUrl { + Task { + if case let .success(avatar) = await mediaProvider.loadImageFromURLString(roomAvatarUrl, + avatarSize: .room(on: .timeline)) { + state.roomAvatar = avatar + } + } + } } // MARK: - Public diff --git a/ElementX/Sources/Screens/RoomScreen/View/RoomHeaderView.swift b/ElementX/Sources/Screens/RoomScreen/View/RoomHeaderView.swift index c1faf365a..9ed0590e6 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/RoomHeaderView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/RoomHeaderView.swift @@ -72,8 +72,9 @@ struct RoomHeaderView_Previews: PreviewProvider { static var bodyPlain: some View { let viewModel = RoomScreenViewModel(timelineController: MockRoomTimelineController(), timelineViewFactory: RoomTimelineViewFactory(), + mediaProvider: MockMediaProvider(), roomName: "Some Room name", - roomAvatar: Asset.Images.appLogo.image) + roomAvatarUrl: "mock_url") RoomHeaderView(context: viewModel.context) .previewLayout(.sizeThatFits) @@ -84,8 +85,9 @@ struct RoomHeaderView_Previews: PreviewProvider { static var bodyEncrypted: some View { let viewModel = RoomScreenViewModel(timelineController: MockRoomTimelineController(), timelineViewFactory: RoomTimelineViewFactory(), + mediaProvider: MockMediaProvider(), roomName: "Some Room name", - roomAvatar: nil, + roomAvatarUrl: nil, roomEncryptionBadge: Asset.Images.encryptionTrusted.image) RoomHeaderView(context: viewModel.context) diff --git a/ElementX/Sources/Screens/RoomScreen/View/RoomScreen.swift b/ElementX/Sources/Screens/RoomScreen/View/RoomScreen.swift index f6db3ce66..4e55f40de 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/RoomScreen.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/RoomScreen.swift @@ -64,6 +64,7 @@ struct RoomScreen_Previews: PreviewProvider { static var body: some View { let viewModel = RoomScreenViewModel(timelineController: MockRoomTimelineController(), timelineViewFactory: RoomTimelineViewFactory(), + mediaProvider: MockMediaProvider(), roomName: "Preview room") NavigationView { diff --git a/ElementX/Sources/Screens/RoomScreen/View/TimelineItemList.swift b/ElementX/Sources/Screens/RoomScreen/View/TimelineItemList.swift index ec0e13ced..76d2d40a7 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/TimelineItemList.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/TimelineItemList.swift @@ -172,6 +172,7 @@ struct TimelineItemList_Previews: PreviewProvider { static var body: some View { let viewModel = RoomScreenViewModel(timelineController: MockRoomTimelineController(), timelineViewFactory: RoomTimelineViewFactory(), + mediaProvider: MockMediaProvider(), roomName: nil) TimelineItemList(bottomVisiblePublisher: PassthroughSubject(), scrollToBottomPublisher: PassthroughSubject()) diff --git a/ElementX/Sources/Screens/RoomScreen/View/TimelineView.swift b/ElementX/Sources/Screens/RoomScreen/View/TimelineView.swift index 20bbb4175..c471fa0fa 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/TimelineView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/TimelineView.swift @@ -59,6 +59,7 @@ struct TimelineView_Previews: PreviewProvider { static var body: some View { let viewModel = RoomScreenViewModel(timelineController: MockRoomTimelineController(), timelineViewFactory: RoomTimelineViewFactory(), + mediaProvider: MockMediaProvider(), roomName: nil) TimelineView() diff --git a/ElementX/Sources/Services/Media/MockMediaProvider.swift b/ElementX/Sources/Services/Media/MockMediaProvider.swift index 1487989cf..89531ac75 100644 --- a/ElementX/Sources/Services/Media/MockMediaProvider.swift +++ b/ElementX/Sources/Services/Media/MockMediaProvider.swift @@ -27,11 +27,19 @@ struct MockMediaProvider: MediaProviderProtocol { } func imageFromURLString(_ urlString: String?, avatarSize: AvatarSize?) -> UIImage? { - if urlString != nil { - return UIImage(systemName: "photo") + guard urlString != nil else { + return nil } - - return nil + + if let avatarSize = avatarSize { + switch avatarSize { + case .room: + return Asset.Images.appLogo.image + default: + return UIImage(systemName: "photo") + } + } + return UIImage(systemName: "photo") } func loadImageFromURLString(_ urlString: String, avatarSize: AvatarSize?) async -> Result { diff --git a/ElementX/Sources/UITestsAppCoordinator.swift b/ElementX/Sources/UITestsAppCoordinator.swift index 1be01ce9a..1e3ca490a 100644 --- a/ElementX/Sources/UITestsAppCoordinator.swift +++ b/ElementX/Sources/UITestsAppCoordinator.swift @@ -116,13 +116,15 @@ class MockScreen: Identifiable { return SplashScreenCoordinator() case .roomPlainNoAvatar: let parameters = RoomScreenCoordinatorParameters(timelineController: MockRoomTimelineController(), + mediaProvider: MockMediaProvider(), roomName: "Some room name", - roomAvatar: nil) + roomAvatarUrl: nil) return RoomScreenCoordinator(parameters: parameters) case .roomEncryptedWithAvatar: let parameters = RoomScreenCoordinatorParameters(timelineController: MockRoomTimelineController(), + mediaProvider: MockMediaProvider(), roomName: "Some room name", - roomAvatar: Asset.Images.appLogo.image) + roomAvatarUrl: "mock_url") return RoomScreenCoordinator(parameters: parameters) case .sessionVerification: let parameters = SessionVerificationCoordinatorParameters(sessionVerificationControllerProxy: MockSessionVerificationControllerProxy())