#53 - Refactored various components:

- updated the authentication coordinator to use async await
- replaced the UserSession with a ClientProxy (similar to the RoomProxy)
- renamed `completion` to `callback` on the coordinators and view models
- renamed `viewModelResult` to `viewModelAction`
- introduced back UserSession as a user specific service container
This commit is contained in:
Stefan Ceriu
2022-05-26 16:04:48 +03:00
committed by Stefan Ceriu
parent edf765b7cd
commit 1b4d3a650e
33 changed files with 312 additions and 214 deletions
@@ -18,13 +18,12 @@ import SwiftUI
import Combine
struct HomeScreenCoordinatorParameters {
let userSession: UserSession
let mediaProvider: MediaProviderProtocol
let userSession: UserSessionProtocol
let attributedStringBuilder: AttributedStringBuilderProtocol
let memberDetailProviderManager: MemberDetailProviderManager
}
enum HomeScreenCoordinatorResult {
enum HomeScreenCoordinatorAction {
case logout
case selectRoom(roomIdentifier: String)
}
@@ -47,7 +46,7 @@ final class HomeScreenCoordinator: Coordinator, Presentable {
// Must be used only internally
var childCoordinators: [Coordinator] = []
var completion: ((HomeScreenCoordinatorResult) -> Void)?
var callback: ((HomeScreenCoordinatorAction) -> Void)?
// MARK: - Setup
@@ -59,22 +58,22 @@ final class HomeScreenCoordinator: Coordinator, Presentable {
let view = HomeScreen(context: viewModel.context)
hostingController = UIHostingController(rootView: view)
viewModel.completion = { [weak self] result in
viewModel.callback = { [weak self] action in
guard let self = self else { return }
switch result {
switch action {
case .logout:
self.completion?(.logout)
self.callback?(.logout)
case .selectRoom(let roomIdentifier):
self.completion?(.selectRoom(roomIdentifier: roomIdentifier))
self.callback?(.selectRoom(roomIdentifier: roomIdentifier))
}
}
parameters.userSession
parameters.userSession.clientProxy
.callbacks
.receive(on: DispatchQueue.main)
.sink { [weak self] result in
switch result {
.sink { [weak self] action in
switch action {
case .updatedRoomsList:
self?.updateRoomsList()
}
@@ -83,13 +82,13 @@ final class HomeScreenCoordinator: Coordinator, Presentable {
updateRoomsList()
Task {
if case let .success(userAvatarURL) = await parameters.userSession.loadUserAvatarURL() {
if case let .success(avatar) = await parameters.mediaProvider.loadImageFromURL(userAvatarURL) {
if case let .success(userAvatarURLString) = await parameters.userSession.clientProxy.loadUserAvatarURLString() {
if case let .success(avatar) = await parameters.userSession.mediaProvider.loadImageFromURLString(userAvatarURLString) {
self.viewModel.updateWithUserAvatar(avatar)
}
}
if case let .success(userDisplayName) = await parameters.userSession.loadUserDisplayName() {
if case let .success(userDisplayName) = await parameters.userSession.clientProxy.loadUserDisplayName() {
self.viewModel.updateWithUserDisplayName(userDisplayName)
}
}
@@ -107,7 +106,7 @@ final class HomeScreenCoordinator: Coordinator, Presentable {
// MARK: - Private
func updateRoomsList() {
self.roomSummaries = parameters.userSession.rooms.compactMap { roomProxy in
roomSummaries = parameters.userSession.clientProxy.rooms.compactMap { roomProxy in
guard !roomProxy.isSpace, !roomProxy.isTombstoned else {
return nil
}
@@ -119,10 +118,10 @@ final class HomeScreenCoordinator: Coordinator, Presentable {
let memberDetailProvider = parameters.memberDetailProviderManager.memberDetailProviderForRoomProxy(roomProxy)
return RoomSummary(roomProxy: roomProxy,
mediaProvider: parameters.mediaProvider,
mediaProvider: parameters.userSession.mediaProvider,
eventBriefFactory: EventBriefFactory(memberDetailProvider: memberDetailProvider))
}
self.viewModel.updateWithRoomList(roomSummaries)
viewModel.updateWithRoomSummaries(roomSummaries)
}
}
@@ -17,7 +17,7 @@
import Foundation
import UIKit
enum HomeScreenViewModelResult {
enum HomeScreenViewModelAction {
case logout
case selectRoom(roomIdentifier: String)
}
@@ -25,13 +25,13 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
private var roomUpdateListeners = Set<AnyCancellable>()
private var roomList: [RoomSummaryProtocol]? {
private var roomSummaries: [RoomSummaryProtocol]? {
didSet {
self.state.isLoadingRooms = (roomList?.count ?? 0 == 0)
self.state.isLoadingRooms = (roomSummaries?.count ?? 0 == 0)
}
}
var completion: ((HomeScreenViewModelResult) -> Void)?
var callback: ((HomeScreenViewModelAction) -> Void)?
// MARK: - Setup
@@ -46,24 +46,24 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
override func process(viewAction: HomeScreenViewAction) async {
switch viewAction {
case .logout:
completion?(.logout)
callback?(.logout)
case .loadRoomData(let roomIdentifier):
loadRoomDataForIdentifier(roomIdentifier)
case .selectRoom(let roomIdentifier):
completion?(.selectRoom(roomIdentifier: roomIdentifier))
callback?(.selectRoom(roomIdentifier: roomIdentifier))
}
}
func updateWithRoomList(_ roomList: [RoomSummaryProtocol]) {
self.roomList = roomList
func updateWithRoomSummaries(_ roomSummaries: [RoomSummaryProtocol]) {
self.roomSummaries = roomSummaries
state.rooms = roomList.map { roomSummary in
state.rooms = roomSummaries.map { roomSummary in
buildOrUpdateRoomFromSummary(roomSummary)
}
roomUpdateListeners.removeAll()
roomList.forEach({ roomSummary in
roomSummaries.forEach({ roomSummary in
roomSummary.callbacks
.receive(on: DispatchQueue.main)
.sink { [weak self] callback in
@@ -94,7 +94,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
// MARK: - Private
private func loadRoomDataForIdentifier(_ roomIdentifier: String) {
guard let roomSummary = roomList?.first(where: { $0.id == roomIdentifier }) else {
guard let roomSummary = roomSummaries?.first(where: { $0.id == roomIdentifier }) else {
MXLog.error("Invalid room identifier")
return
}
@@ -19,11 +19,11 @@ import UIKit
@MainActor
protocol HomeScreenViewModelProtocol {
var completion: ((HomeScreenViewModelResult) -> Void)? { get set }
var callback: ((HomeScreenViewModelAction) -> Void)? { get set }
var context: HomeScreenViewModelType.Context { get }
func updateWithUserAvatar(_ avatar: UIImage)
func updateWithUserDisplayName(_ displayName: String)
func updateWithRoomList(_ roomList: [RoomSummaryProtocol])
func updateWithRoomSummaries(_ roomSummaries: [RoomSummaryProtocol])
}
@@ -176,11 +176,11 @@ struct HomeScreen_Previews: PreviewProvider {
htmlBody: nil,
date: .now)
let rooms = [MockRoomSummary(topic: "Topic", displayName: "Alpha"),
MockRoomSummary(displayName: "Beta"),
MockRoomSummary(displayName: "Omega", lastMessage: eventBrief)]
let roomSummaries = [MockRoomSummary(displayName: "Alpha", topic: "Topic"),
MockRoomSummary(displayName: "Beta"),
MockRoomSummary(displayName: "Omega", lastMessage: eventBrief)]
viewModel.updateWithRoomList(rooms)
viewModel.updateWithRoomSummaries(roomSummaries)
if let avatarImage = UIImage(systemName: "person.fill.questionmark") {
viewModel.updateWithUserAvatar(avatarImage)