Correctly building image items for the timeline. Missing URL and way to load image.

This commit is contained in:
Stefan Ceriu 2022-03-16 18:01:42 +02:00
parent 439f09095a
commit 30378ae6a9
13 changed files with 83 additions and 31 deletions

View File

@ -28,6 +28,8 @@
18C5745427E1D88E00D70937 /* TextRoomMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18C5745327E1D88E00D70937 /* TextRoomMessage.swift */; };
18C5745627E1DCA800D70937 /* RoomMessageFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18C5745527E1DCA800D70937 /* RoomMessageFactory.swift */; };
18C5745827E1EB6E00D70937 /* TimelineItemFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18C5745727E1EB6E00D70937 /* TimelineItemFactory.swift */; };
18DF7C2A27E23E3A00291672 /* TimelineItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18DF7C2927E23E3A00291672 /* TimelineItemProtocol.swift */; };
18DF7C2C27E23EC000291672 /* TimelineViewFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18DF7C2B27E23EC000291672 /* TimelineViewFactory.swift */; };
18F2BADA27D25B4000DD1988 /* RoomTimelineProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA7727D25B4000DD1988 /* RoomTimelineProvider.swift */; };
18F2BADB27D25B4000DD1988 /* AuthenticationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA7927D25B4000DD1988 /* AuthenticationCoordinator.swift */; };
18F2BADC27D25B4000DD1988 /* UserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA7A27D25B4000DD1988 /* UserSession.swift */; };
@ -132,6 +134,8 @@
18C5745327E1D88E00D70937 /* TextRoomMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRoomMessage.swift; sourceTree = "<group>"; };
18C5745527E1DCA800D70937 /* RoomMessageFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMessageFactory.swift; sourceTree = "<group>"; };
18C5745727E1EB6E00D70937 /* TimelineItemFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemFactory.swift; sourceTree = "<group>"; };
18DF7C2927E23E3A00291672 /* TimelineItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemProtocol.swift; sourceTree = "<group>"; };
18DF7C2B27E23EC000291672 /* TimelineViewFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineViewFactory.swift; sourceTree = "<group>"; };
18F2BA7727D25B4000DD1988 /* RoomTimelineProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomTimelineProvider.swift; sourceTree = "<group>"; };
18F2BA7927D25B4000DD1988 /* AuthenticationCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthenticationCoordinator.swift; sourceTree = "<group>"; };
18F2BA7A27D25B4000DD1988 /* UserSession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserSession.swift; sourceTree = "<group>"; };
@ -303,6 +307,8 @@
isa = PBXGroup;
children = (
18C5745727E1EB6E00D70937 /* TimelineItemFactory.swift */,
18DF7C2927E23E3A00291672 /* TimelineItemProtocol.swift */,
18DF7C2B27E23EC000291672 /* TimelineViewFactory.swift */,
18A318DB27DA42C9000867CD /* RoomTimelineViewProvider.swift */,
18F9889727DB7473002F48B4 /* ImageRoomTimelineItem.swift */,
18F9889D27DB752B002F48B4 /* ImageRoomTimelineView.swift */,
@ -798,6 +804,7 @@
18F2BB1527D25B4000DD1988 /* LoginScreenViewModelProtocol.swift in Sources */,
18F2BAEB27D25B4000DD1988 /* LabelledActivityIndicatorView.swift in Sources */,
18F2BAE427D25B4000DD1988 /* Presentable.swift in Sources */,
18DF7C2A27E23E3A00291672 /* TimelineItemProtocol.swift in Sources */,
18F2BAF927D25B4000DD1988 /* SplashViewController.swift in Sources */,
18F2BAE327D25B4000DD1988 /* RootRouter.swift in Sources */,
18F2BAE527D25B4000DD1988 /* NavigationModule.swift in Sources */,
@ -853,6 +860,7 @@
18C5744E27E1D84000D70937 /* MockRoomProxy.swift in Sources */,
18F2BADC27D25B4000DD1988 /* UserSession.swift in Sources */,
18F2BAEF27D25B4000DD1988 /* ActivityRequest.swift in Sources */,
18DF7C2C27E23EC000291672 /* TimelineViewFactory.swift in Sources */,
18C5745827E1EB6E00D70937 /* TimelineItemFactory.swift in Sources */,
18F2BAEE27D25B4000DD1988 /* Activity.swift in Sources */,
18F2BAEC27D25B4000DD1988 /* ToastActivityPresenter.swift in Sources */,

View File

@ -117,10 +117,6 @@ class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
let parameters = RoomScreenCoordinatorParameters(roomProxy: roomProxy)
let coordinator = RoomScreenCoordinator(parameters: parameters)
coordinator.completion = { _ in
}
self.add(childCoordinator: coordinator)
self.navigationRouter.push(coordinator) { [weak self] in
guard let self = self else { return }

View File

@ -34,7 +34,6 @@ final class RoomScreenCoordinator: Coordinator, Presentable {
// Must be used only internally
var childCoordinators: [Coordinator] = []
var completion: ((RoomScreenViewModelResult) -> Void)?
// MARK: - Setup
@ -43,7 +42,9 @@ final class RoomScreenCoordinator: Coordinator, Presentable {
self.parameters = parameters
let timelineProvider = RoomTimelineProvider(roomProxy: parameters.roomProxy)
let timelineController = RoomTimelineController(timelineProvider: timelineProvider)
let timelineController = RoomTimelineController(timelineProvider: timelineProvider,
timelineItemFactory: TimelineItemFactory(),
timelineViewFactory: TimelineViewFactory())
let viewModel = RoomScreenViewModel(roomProxy: parameters.roomProxy, timelineController: timelineController)
let view = RoomScreen(context: viewModel.context)
@ -53,12 +54,7 @@ final class RoomScreenCoordinator: Coordinator, Presentable {
// MARK: - Public
func start() {
MXLog.debug("[RoomScreenCoordinator] did start.")
roomScreenViewModel.completion = { [weak self] result in
MXLog.debug("[RoomScreenCoordinator] RoomScreenViewModel did complete with result: \(result).")
guard let self = self else { return }
self.completion?(result)
}
}
func toPresentable() -> UIViewController {

View File

@ -30,8 +30,6 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
private let roomProxy: RoomProxyProtocol
private let timelineController: RoomTimelineControllerProtocol
var completion: ((RoomScreenViewModelResult) -> Void)?
// MARK: - Setup
init(roomProxy: RoomProxyProtocol, timelineController: RoomTimelineControllerProtocol) {

View File

@ -17,8 +17,5 @@
import Foundation
protocol RoomScreenViewModelProtocol {
var completion: ((RoomScreenViewModelResult) -> Void)? { get set }
@available(iOS 14, *)
var context: RoomScreenViewModelType.Context { get }
}

View File

@ -12,14 +12,20 @@ import MatrixRustSDK
class RoomTimelineController: RoomTimelineControllerProtocol {
private let timelineProvider: RoomTimelineProvider
private let timelineItemFactory: TimelineItemFactory
private let timelineViewFactory: TimelineViewFactory
private var cancellables = Set<AnyCancellable>()
let callbacks = PassthroughSubject<RoomTimelineControllerCallback, Never>()
private(set) var timelineItems = [RoomTimelineViewProvider]()
init(timelineProvider: RoomTimelineProvider) {
init(timelineProvider: RoomTimelineProvider,
timelineItemFactory: TimelineItemFactory,
timelineViewFactory: TimelineViewFactory) {
self.timelineProvider = timelineProvider
self.timelineItemFactory = timelineItemFactory
self.timelineViewFactory = timelineViewFactory
self.timelineProvider.callbacks.sink { [weak self] callback in
guard let self = self else { return }
@ -63,13 +69,8 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
let areMessagesFromTheSameSender = (previousMessage?.sender == message.sender)
let shouldShowSenderDetails = !areMessagesFromTheSameSender || !areMessagesFromTheSameDay
let item = TextRoomTimelineItem(id: message.id,
senderDisplayName: message.sender,
text: message.content,
timestamp: message.originServerTs.formatted(date: .omitted, time: .shortened),
shouldShowSenderDetails: shouldShowSenderDetails)
newTimelineItems.append(RoomTimelineViewProvider.text(item))
let timelineItem = timelineItemFactory.buildTimelineItemFor(message, showSenderDetails: shouldShowSenderDetails)
newTimelineItems.append(timelineViewFactory.buildTimelineViewFor(timelineItem))
previousMessage = message
}

View File

@ -8,7 +8,10 @@
import Foundation
struct ImageRoomTimelineItem: Identifiable, Equatable {
struct ImageRoomTimelineItem: TimelineItemProtocol, Identifiable, Equatable {
let id: String
let senderDisplayName: String
let text: String
let timestamp: String
let shouldShowSenderDetails: Bool
}

View File

@ -17,7 +17,10 @@ struct ImageRoomTimelineView: View {
if let loadedImage = loadedImage {
Image(uiImage: loadedImage)
} else {
ProgressView()
VStack {
Image(systemName: "photo")
ProgressView()
}
}
}
}

View File

@ -8,7 +8,7 @@
import Foundation
struct SeparatorRoomTimelineItem: Identifiable, Equatable {
struct SeparatorRoomTimelineItem: TimelineItemProtocol, Identifiable, Equatable {
let id: String
let text: String
}

View File

@ -8,7 +8,7 @@
import Foundation
struct TextRoomTimelineItem: Identifiable, Equatable {
struct TextRoomTimelineItem: TimelineItemProtocol, Identifiable, Equatable {
let id: String
let senderDisplayName: String
let text: String

View File

@ -9,7 +9,22 @@
import Foundation
struct TimelineItemFactory {
func buildTimelineItemFor(_ message: RoomMessageProtocol) {
func buildTimelineItemFor(_ roomMessage: RoomMessageProtocol, showSenderDetails: Bool) -> TimelineItemProtocol {
switch roomMessage {
case let message as TextRoomMessage:
return TextRoomTimelineItem(id: message.id,
senderDisplayName: message.sender,
text: message.content,
timestamp: message.originServerTs.formatted(date: .omitted, time: .shortened),
shouldShowSenderDetails: showSenderDetails)
case let message as ImageRoomMessage:
return ImageRoomTimelineItem(id: message.id,
senderDisplayName: message.sender,
text: message.content,
timestamp: message.originServerTs.formatted(date: .omitted, time: .shortened),
shouldShowSenderDetails: showSenderDetails)
default:
fatalError("Unknown room message.")
}
}
}

View File

@ -0,0 +1,13 @@
//
// TimelineItemProtocol.swift
// ElementX
//
// Created by Stefan Ceriu on 16/03/2022.
// Copyright © 2022 Element. All rights reserved.
//
import Foundation
protocol TimelineItemProtocol {
}

View File

@ -0,0 +1,22 @@
//
// TimelineViewFactory.swift
// ElementX
//
// Created by Stefan Ceriu on 16/03/2022.
// Copyright © 2022 Element. All rights reserved.
//
import Foundation
struct TimelineViewFactory {
func buildTimelineViewFor(_ timelineItem: TimelineItemProtocol) -> RoomTimelineViewProvider {
switch timelineItem {
case let textItem as TextRoomTimelineItem:
return .text(textItem)
case let imageItem as ImageRoomTimelineItem:
return .image(imageItem)
default:
fatalError("Unknown timeline item")
}
}
}