mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-22 01:22:46 +02:00
Fix review remarks
This commit is contained in:
@@ -24,7 +24,7 @@ protocol ThreadListCoordinatorDelegate: AnyObject {
|
||||
func threadListCoordinatorDidCancel(_ coordinator: ThreadListCoordinatorProtocol)
|
||||
}
|
||||
|
||||
/// `ThreadListCoordinatorProtocol` is a protocol describing a Coordinator that handle xxxxxxx navigation flow.
|
||||
/// `ThreadListCoordinatorProtocol` is a protocol describing a Coordinator that handle thread list navigation flow.
|
||||
protocol ThreadListCoordinatorProtocol: Coordinator, Presentable {
|
||||
var delegate: ThreadListCoordinatorDelegate? { get }
|
||||
}
|
||||
|
||||
@@ -20,12 +20,6 @@ import UIKit
|
||||
|
||||
final class ThreadListViewController: UIViewController {
|
||||
|
||||
// MARK: - Constants
|
||||
|
||||
private enum Constants {
|
||||
static let aConstant: Int = 666
|
||||
}
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
// MARK: Outlets
|
||||
@@ -172,7 +166,7 @@ final class ThreadListViewController: UIViewController {
|
||||
navigationItem.rightBarButtonItem?.isEnabled = true
|
||||
}
|
||||
|
||||
private func renderEmptyView(withViewModel emptyViewModel: ThreadListEmptyViewModel) {
|
||||
private func renderEmptyView(withViewModel emptyViewModel: ThreadListEmptyModel) {
|
||||
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
|
||||
emptyView.configure(withViewModel: emptyViewModel)
|
||||
threadsTableView.isHidden = true
|
||||
|
||||
@@ -83,14 +83,14 @@ final class ThreadListViewModel: ThreadListViewModelProtocol {
|
||||
return threads.count
|
||||
}
|
||||
|
||||
func threadViewModel(at index: Int) -> ThreadViewModel? {
|
||||
func threadViewModel(at index: Int) -> ThreadModel? {
|
||||
guard index < threads.count else {
|
||||
return nil
|
||||
}
|
||||
return viewModel(forThread: threads[index])
|
||||
}
|
||||
|
||||
var titleViewModel: ThreadRoomTitleViewModel {
|
||||
var titleViewModel: ThreadRoomTitleModel {
|
||||
guard let room = session.room(withRoomId: roomId) else {
|
||||
return .empty
|
||||
}
|
||||
@@ -109,33 +109,33 @@ final class ThreadListViewModel: ThreadListViewModelProtocol {
|
||||
encrpytionBadge = nil
|
||||
}
|
||||
|
||||
return ThreadRoomTitleViewModel(roomAvatar: avatarViewData,
|
||||
roomEncryptionBadge: encrpytionBadge,
|
||||
roomDisplayName: room.displayName)
|
||||
return ThreadRoomTitleModel(roomAvatar: avatarViewData,
|
||||
roomEncryptionBadge: encrpytionBadge,
|
||||
roomDisplayName: room.displayName)
|
||||
}
|
||||
|
||||
private var emptyViewModel: ThreadListEmptyViewModel {
|
||||
private var emptyViewModel: ThreadListEmptyModel {
|
||||
switch selectedFilterType {
|
||||
case .all:
|
||||
return ThreadListEmptyViewModel(icon: Asset.Images.roomContextMenuReplyInThread.image,
|
||||
title: VectorL10n.threadsEmptyTitle,
|
||||
info: VectorL10n.threadsEmptyInfoAll,
|
||||
tip: VectorL10n.threadsEmptyTip,
|
||||
showAllThreadsButtonTitle: VectorL10n.threadsEmptyShowAllThreads,
|
||||
showAllThreadsButtonHidden: true)
|
||||
return ThreadListEmptyModel(icon: Asset.Images.roomContextMenuReplyInThread.image,
|
||||
title: VectorL10n.threadsEmptyTitle,
|
||||
info: VectorL10n.threadsEmptyInfoAll,
|
||||
tip: VectorL10n.threadsEmptyTip,
|
||||
showAllThreadsButtonTitle: VectorL10n.threadsEmptyShowAllThreads,
|
||||
showAllThreadsButtonHidden: true)
|
||||
case .myThreads:
|
||||
return ThreadListEmptyViewModel(icon: Asset.Images.roomContextMenuReplyInThread.image,
|
||||
title: VectorL10n.threadsEmptyTitle,
|
||||
info: VectorL10n.threadsEmptyInfoMy,
|
||||
tip: VectorL10n.threadsEmptyTip,
|
||||
showAllThreadsButtonTitle: VectorL10n.threadsEmptyShowAllThreads,
|
||||
showAllThreadsButtonHidden: false)
|
||||
return ThreadListEmptyModel(icon: Asset.Images.roomContextMenuReplyInThread.image,
|
||||
title: VectorL10n.threadsEmptyTitle,
|
||||
info: VectorL10n.threadsEmptyInfoMy,
|
||||
tip: VectorL10n.threadsEmptyTip,
|
||||
showAllThreadsButtonTitle: VectorL10n.threadsEmptyShowAllThreads,
|
||||
showAllThreadsButtonHidden: false)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func viewModel(forThread thread: MXThread) -> ThreadViewModel {
|
||||
private func viewModel(forThread thread: MXThread) -> ThreadModel {
|
||||
let rootAvatarViewData: AvatarViewData?
|
||||
let rootMessageSender: MXUser?
|
||||
let lastAvatarViewData: AvatarViewData?
|
||||
@@ -175,15 +175,15 @@ final class ThreadListViewModel: ThreadListViewModelProtocol {
|
||||
lastMessageSender = nil
|
||||
}
|
||||
|
||||
let summaryViewModel = ThreadSummaryViewModel(numberOfReplies: thread.numberOfReplies,
|
||||
lastMessageSenderAvatar: lastAvatarViewData,
|
||||
lastMessageText: lastMessageText)
|
||||
let summaryViewModel = ThreadSummaryModel(numberOfReplies: thread.numberOfReplies,
|
||||
lastMessageSenderAvatar: lastAvatarViewData,
|
||||
lastMessageText: lastMessageText)
|
||||
|
||||
return ThreadViewModel(rootMessageSenderAvatar: rootAvatarViewData,
|
||||
rootMessageSenderDisplayName: rootMessageSender?.displayname,
|
||||
rootMessageText: rootMessageText,
|
||||
lastMessageTime: lastMessageTime,
|
||||
summaryViewModel: summaryViewModel)
|
||||
return ThreadModel(rootMessageSenderAvatar: rootAvatarViewData,
|
||||
rootMessageSenderDisplayName: rootMessageSender?.displayname,
|
||||
rootMessageText: rootMessageText,
|
||||
lastMessageTime: lastMessageTime,
|
||||
summaryViewModel: summaryViewModel)
|
||||
}
|
||||
|
||||
private func rootMessageText(forThread thread: MXThread) -> String? {
|
||||
|
||||
@@ -38,10 +38,10 @@ protocol ThreadListViewModelProtocol {
|
||||
|
||||
var viewState: ThreadListViewState { get }
|
||||
|
||||
var titleViewModel: ThreadRoomTitleViewModel { get }
|
||||
var titleViewModel: ThreadRoomTitleModel { get }
|
||||
var selectedFilterType: ThreadListFilterType { get }
|
||||
var numberOfThreads: Int { get }
|
||||
func threadViewModel(at index: Int) -> ThreadViewModel?
|
||||
func threadViewModel(at index: Int) -> ThreadModel?
|
||||
}
|
||||
|
||||
enum ThreadListFilterType {
|
||||
|
||||
@@ -23,7 +23,7 @@ enum ThreadListViewState {
|
||||
case idle
|
||||
case loading
|
||||
case loaded
|
||||
case empty(_ viewModel: ThreadListEmptyViewModel)
|
||||
case empty(_ viewModel: ThreadListEmptyModel)
|
||||
case showingFilterTypes
|
||||
case error(Error)
|
||||
}
|
||||
|
||||
+6
-6
@@ -16,10 +16,10 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
struct ThreadViewModel {
|
||||
var rootMessageSenderAvatar: AvatarViewDataProtocol?
|
||||
var rootMessageSenderDisplayName: String?
|
||||
var rootMessageText: String?
|
||||
var lastMessageTime: String?
|
||||
var summaryViewModel: ThreadSummaryViewModel?
|
||||
struct ThreadModel {
|
||||
let rootMessageSenderAvatar: AvatarViewDataProtocol?
|
||||
let rootMessageSenderDisplayName: String?
|
||||
let rootMessageText: String?
|
||||
let lastMessageTime: String?
|
||||
let summaryViewModel: ThreadSummaryModel?
|
||||
}
|
||||
@@ -35,7 +35,7 @@ class ThreadTableViewCell: UITableViewCell {
|
||||
separatorInset = Constants.separatorInset
|
||||
}
|
||||
|
||||
func configure(withViewModel viewModel: ThreadViewModel) {
|
||||
func configure(withViewModel viewModel: ThreadModel) {
|
||||
if let rootAvatar = viewModel.rootMessageSenderAvatar {
|
||||
rootMessageAvatarView.fill(with: rootAvatar)
|
||||
} else {
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
struct ThreadListEmptyViewModel {
|
||||
struct ThreadListEmptyModel {
|
||||
let icon: UIImage?
|
||||
let title: String?
|
||||
let info: String?
|
||||
@@ -22,6 +22,7 @@ protocol ThreadListEmptyViewDelegate: AnyObject {
|
||||
func threadListEmptyViewTappedShowAllThreads(_ emptyView: ThreadListEmptyView)
|
||||
}
|
||||
|
||||
/// View to be shown on the thread list screen when no thread is available. Use a `ThreadListEmptyModel` instance to configure.
|
||||
class ThreadListEmptyView: UIView {
|
||||
|
||||
@IBOutlet weak var delegate: ThreadListEmptyViewDelegate?
|
||||
@@ -38,7 +39,7 @@ class ThreadListEmptyView: UIView {
|
||||
loadNibContent()
|
||||
}
|
||||
|
||||
func configure(withViewModel viewModel: ThreadListEmptyViewModel) {
|
||||
func configure(withViewModel viewModel: ThreadListEmptyModel) {
|
||||
iconView.image = viewModel.icon
|
||||
titleLabel.text = viewModel.title
|
||||
infoLabel.text = viewModel.info
|
||||
|
||||
@@ -54,7 +54,12 @@ final class ThreadsCoordinator: NSObject, ThreadsCoordinatorProtocol {
|
||||
|
||||
func start() {
|
||||
|
||||
let rootCoordinator = self.createThreadListCoordinator()
|
||||
let rootCoordinator: Coordinator & Presentable
|
||||
if let threadId = parameters.threadId {
|
||||
rootCoordinator = createThreadCoordinator(forThreadId: threadId)
|
||||
} else {
|
||||
rootCoordinator = createThreadListCoordinator()
|
||||
}
|
||||
|
||||
rootCoordinator.start()
|
||||
|
||||
@@ -77,6 +82,10 @@ final class ThreadsCoordinator: NSObject, ThreadsCoordinatorProtocol {
|
||||
func stop() {
|
||||
if selectedThreadCoordinator != nil {
|
||||
let modules = self.navigationRouter.modules
|
||||
// if a thread is selected from the thread list coordinator, then navigation stack will look like:
|
||||
// ... -> Screen A -> Thread List Screen -> Thread Screen
|
||||
// we'll try to pop to Screen A here
|
||||
// sanity check: navigation stack contains at least 3 items
|
||||
guard modules.count >= 3 else {
|
||||
return
|
||||
}
|
||||
@@ -116,13 +125,13 @@ final class ThreadsCoordinator: NSObject, ThreadsCoordinatorProtocol {
|
||||
return coordinator
|
||||
}
|
||||
|
||||
private func createThreadCoordinator(forThread thread: MXThread) -> RoomCoordinator {
|
||||
private func createThreadCoordinator(forThreadId threadId: String) -> RoomCoordinator {
|
||||
let parameters = RoomCoordinatorParameters(navigationRouter: navigationRouter,
|
||||
navigationRouterStore: nil,
|
||||
session: parameters.session,
|
||||
roomId: parameters.roomId,
|
||||
eventId: nil,
|
||||
threadId: thread.id,
|
||||
threadId: threadId,
|
||||
displayConfiguration: .forThreads)
|
||||
let coordinator = RoomCoordinator(parameters: parameters)
|
||||
coordinator.delegate = self
|
||||
@@ -145,7 +154,7 @@ extension ThreadsCoordinator: ThreadListCoordinatorDelegate {
|
||||
}
|
||||
|
||||
func threadListCoordinatorDidSelectThread(_ coordinator: ThreadListCoordinatorProtocol, thread: MXThread) {
|
||||
let roomCoordinator = createThreadCoordinator(forThread: thread)
|
||||
let roomCoordinator = createThreadCoordinator(forThreadId: thread.id)
|
||||
selectedThreadCoordinator = roomCoordinator
|
||||
roomCoordinator.start()
|
||||
self.add(childCoordinator: roomCoordinator)
|
||||
|
||||
@@ -45,6 +45,7 @@ final class ThreadsCoordinatorBridgePresenter: NSObject {
|
||||
|
||||
private let session: MXSession
|
||||
private let roomId: String
|
||||
private let threadId: String?
|
||||
private var navigationType: NavigationType = .present
|
||||
private var coordinator: ThreadsCoordinator?
|
||||
|
||||
@@ -53,11 +54,18 @@ final class ThreadsCoordinatorBridgePresenter: NSObject {
|
||||
weak var delegate: ThreadsCoordinatorBridgePresenterDelegate?
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
|
||||
/// Initializer
|
||||
/// - Parameters:
|
||||
/// - session: Session instance
|
||||
/// - roomId: Room identifier
|
||||
/// - threadId: Thread identifier. Specified thread will be opened if provided, the thread list otherwise
|
||||
init(session: MXSession,
|
||||
roomId: String) {
|
||||
roomId: String,
|
||||
threadId: String?) {
|
||||
self.session = session
|
||||
self.roomId = roomId
|
||||
self.threadId = threadId
|
||||
super.init()
|
||||
}
|
||||
|
||||
@@ -71,7 +79,8 @@ final class ThreadsCoordinatorBridgePresenter: NSObject {
|
||||
func present(from viewController: UIViewController, animated: Bool) {
|
||||
|
||||
let threadsCoordinatorParameters = ThreadsCoordinatorParameters(session: self.session,
|
||||
roomId: self.roomId)
|
||||
roomId: self.roomId,
|
||||
threadId: self.threadId)
|
||||
|
||||
let threadsCoordinator = ThreadsCoordinator(parameters: threadsCoordinatorParameters)
|
||||
threadsCoordinator.delegate = self
|
||||
@@ -89,6 +98,7 @@ final class ThreadsCoordinatorBridgePresenter: NSObject {
|
||||
|
||||
let threadsCoordinatorParameters = ThreadsCoordinatorParameters(session: self.session,
|
||||
roomId: self.roomId,
|
||||
threadId: self.threadId,
|
||||
navigationRouter: navigationRouter)
|
||||
|
||||
let threadsCoordinator = ThreadsCoordinator(parameters: threadsCoordinatorParameters)
|
||||
|
||||
@@ -26,15 +26,20 @@ struct ThreadsCoordinatorParameters {
|
||||
|
||||
/// Room identifier
|
||||
let roomId: String
|
||||
|
||||
/// Thread identifier. Specified thread will be opened if provided, the thread list otherwise
|
||||
let threadId: String?
|
||||
|
||||
/// The navigation router that manage physical navigation
|
||||
let navigationRouter: NavigationRouterType
|
||||
|
||||
init(session: MXSession,
|
||||
roomId: String,
|
||||
threadId: String?,
|
||||
navigationRouter: NavigationRouterType? = nil) {
|
||||
self.session = session
|
||||
self.roomId = roomId
|
||||
self.threadId = threadId
|
||||
self.navigationRouter = navigationRouter ?? NavigationRouter(navigationController: RiotNavigationController())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user