mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-05-05 07:27:42 +02:00
SP4: space settings (#5730)
* SP4: Space Settings - Space settings screen implemented - No space upgrade available as per Element web - Need more insights for the space address field - Added settings live update - Added local alias implementation
This commit is contained in:
+183
@@ -0,0 +1,183 @@
|
||||
//
|
||||
// Copyright 2021 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
/// Actions returned by the coordinator callback
|
||||
enum SpaceSettingsModalCoordinatorAction {
|
||||
case done(_ spaceId: String)
|
||||
case cancel(_ spaceId: String)
|
||||
}
|
||||
|
||||
@objcMembers
|
||||
@available(iOS 14.0, *)
|
||||
final class SpaceSettingsModalCoordinator: Coordinator {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let parameters: SpaceSettingsModalCoordinatorParameters
|
||||
private var upgradedRoomId: String?
|
||||
private var currentRoomId: String {
|
||||
upgradedRoomId ?? parameters.spaceId
|
||||
}
|
||||
|
||||
private var navigationRouter: NavigationRouterType {
|
||||
return self.parameters.navigationRouter
|
||||
}
|
||||
|
||||
// MARK: Public
|
||||
|
||||
// Must be used only internally
|
||||
var childCoordinators: [Coordinator] = []
|
||||
|
||||
var callback: ((SpaceSettingsModalCoordinatorAction) -> Void)?
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
init(parameters: SpaceSettingsModalCoordinatorParameters) {
|
||||
self.parameters = parameters
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
|
||||
func start() {
|
||||
MXLog.debug("[SpaceSettingsModalCoordinator] did start.")
|
||||
let rootCoordinator = self.createSpaceSettingsCoordinator()
|
||||
rootCoordinator.start()
|
||||
|
||||
self.add(childCoordinator: rootCoordinator)
|
||||
|
||||
if self.navigationRouter.modules.isEmpty == false {
|
||||
self.navigationRouter.push(rootCoordinator, animated: true, popCompletion: { [weak self] in
|
||||
self?.remove(childCoordinator: rootCoordinator)
|
||||
})
|
||||
} else {
|
||||
self.navigationRouter.setRootModule(rootCoordinator) { [weak self] in
|
||||
self?.remove(childCoordinator: rootCoordinator)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func toPresentable() -> UIViewController {
|
||||
return self.navigationRouter.toPresentable()
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
func pushScreen(with coordinator: Coordinator & Presentable) {
|
||||
add(childCoordinator: coordinator)
|
||||
|
||||
self.navigationRouter.push(coordinator, animated: true, popCompletion: { [weak self] in
|
||||
self?.remove(childCoordinator: coordinator)
|
||||
})
|
||||
|
||||
coordinator.start()
|
||||
}
|
||||
|
||||
private func createSpaceSettingsCoordinator() -> SpaceSettingsCoordinator {
|
||||
let coordinator = SpaceSettingsCoordinator(parameters: SpaceSettingsCoordinatorParameters(session: parameters.session, spaceId: parameters.spaceId))
|
||||
coordinator.completion = { [weak self] result in
|
||||
guard let self = self else { return }
|
||||
|
||||
switch result {
|
||||
case .cancel:
|
||||
self.callback?(.cancel(self.currentRoomId))
|
||||
case .done:
|
||||
self.callback?(.done(self.currentRoomId))
|
||||
case .optionScreen(let optionType):
|
||||
self.pushOptionScreen(ofType: optionType)
|
||||
}
|
||||
}
|
||||
return coordinator
|
||||
}
|
||||
|
||||
private func pushOptionScreen(ofType optionType: SpaceSettingsOptionType) {
|
||||
switch optionType {
|
||||
case .rooms:
|
||||
exploreRooms(ofSpaceWithId: self.parameters.spaceId)
|
||||
case .members:
|
||||
showMembers(ofSpaceWithId: self.parameters.spaceId)
|
||||
case .visibility:
|
||||
showAccess(ofSpaceWithId: self.parameters.spaceId)
|
||||
}
|
||||
}
|
||||
|
||||
private func exploreRooms(ofSpaceWithId spaceId: String) {
|
||||
let coordinator = ExploreRoomCoordinator(session: parameters.session, spaceId: spaceId)
|
||||
coordinator.delegate = self
|
||||
add(childCoordinator: coordinator)
|
||||
coordinator.start()
|
||||
self.navigationRouter.present(coordinator.toPresentable(), animated: true)
|
||||
}
|
||||
|
||||
private func showMembers(ofSpaceWithId spaceId: String) {
|
||||
let coordinator = SpaceMembersCoordinator(parameters: SpaceMembersCoordinatorParameters(userSessionsService: UserSessionsService.shared, session: parameters.session, spaceId: spaceId))
|
||||
coordinator.delegate = self
|
||||
add(childCoordinator: coordinator)
|
||||
coordinator.start()
|
||||
self.navigationRouter.present(coordinator.toPresentable(), animated: true)
|
||||
}
|
||||
|
||||
private func showAccess(ofSpaceWithId spaceId: String) {
|
||||
guard let room = parameters.session.room(withRoomId: spaceId) else {
|
||||
return
|
||||
}
|
||||
// Needed more tests on synaose side before starting space upgrade implementation
|
||||
let coordinator = RoomAccessCoordinator(parameters: RoomAccessCoordinatorParameters(room: room, allowsRoomUpgrade: false))
|
||||
coordinator.callback = { [weak self] result in
|
||||
guard let self = self else { return }
|
||||
|
||||
switch result {
|
||||
case .cancel(let roomId), .done(let roomId):
|
||||
if roomId != spaceId {
|
||||
// TODO: room has been upgraded
|
||||
self.upgradedRoomId = roomId
|
||||
}
|
||||
|
||||
self.navigationRouter.dismissModule(animated: true, completion: {
|
||||
self.remove(childCoordinator: coordinator)
|
||||
})
|
||||
}
|
||||
}
|
||||
add(childCoordinator: coordinator)
|
||||
coordinator.start()
|
||||
self.navigationRouter.present(coordinator.toPresentable(), animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - ExploreRoomCoordinatorDelegate
|
||||
@available(iOS 14.0, *)
|
||||
extension SpaceSettingsModalCoordinator: ExploreRoomCoordinatorDelegate {
|
||||
func exploreRoomCoordinatorDidComplete(_ coordinator: ExploreRoomCoordinatorType) {
|
||||
self.navigationRouter.dismissModule(animated: true, completion: {
|
||||
self.remove(childCoordinator: coordinator)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - SpaceMembersCoordinatorDelegate
|
||||
@available(iOS 14.0, *)
|
||||
extension SpaceSettingsModalCoordinator: SpaceMembersCoordinatorDelegate {
|
||||
func spaceMembersCoordinatorDidCancel(_ coordinator: SpaceMembersCoordinatorType) {
|
||||
self.navigationRouter.dismissModule(animated: true, completion: {
|
||||
self.remove(childCoordinator: coordinator)
|
||||
})
|
||||
}
|
||||
}
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
//
|
||||
// Copyright 2021 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
@objc protocol SpaceSettingsModalCoordinatorBridgePresenterDelegate {
|
||||
func spaceSettingsModalCoordinatorBridgePresenterDelegateDidCancel(_ coordinatorBridgePresenter: SpaceSettingsModalCoordinatorBridgePresenter)
|
||||
func spaceSettingsModalCoordinatorBridgePresenterDelegateDidFinish(_ coordinatorBridgePresenter: SpaceSettingsModalCoordinatorBridgePresenter)
|
||||
}
|
||||
|
||||
/// SpaceSettingsModalCoordinatorBridgePresenter enables to start SpaceSettingsModalCoordinator from a view controller.
|
||||
/// This bridge is used while waiting for global usage of coordinator pattern.
|
||||
/// It breaks the Coordinator abstraction and it has been introduced for Objective-C compatibility (mainly for integration in legacy view controllers).
|
||||
/// Each bridge should be removed once the underlying Coordinator has been integrated by another Coordinator.
|
||||
@objcMembers
|
||||
@available(iOS 14.0, *)
|
||||
final class SpaceSettingsModalCoordinatorBridgePresenter: NSObject {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let spaceId: String
|
||||
private let session: MXSession
|
||||
private var coordinator: SpaceSettingsModalCoordinator?
|
||||
|
||||
// MARK: Public
|
||||
|
||||
weak var delegate: SpaceSettingsModalCoordinatorBridgePresenterDelegate?
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
init(spaceId: String, session: MXSession) {
|
||||
self.spaceId = spaceId
|
||||
self.session = session
|
||||
super.init()
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
func present(from viewController: UIViewController, animated: Bool) {
|
||||
let navigationRouter = NavigationRouter()
|
||||
let coordinator = SpaceSettingsModalCoordinator(parameters: SpaceSettingsModalCoordinatorParameters(session: session, spaceId: spaceId, navigationRouter: navigationRouter))
|
||||
coordinator.callback = { [weak self] result in
|
||||
guard let self = self else { return }
|
||||
|
||||
switch result {
|
||||
case .cancel:
|
||||
self.delegate?.spaceSettingsModalCoordinatorBridgePresenterDelegateDidCancel(self)
|
||||
case .done:
|
||||
self.delegate?.spaceSettingsModalCoordinatorBridgePresenterDelegateDidFinish(self)
|
||||
}
|
||||
}
|
||||
let presentable = coordinator.toPresentable()
|
||||
presentable.presentationController?.delegate = self
|
||||
navigationRouter.setRootModule(presentable)
|
||||
viewController.present(navigationRouter.toPresentable(), animated: animated, completion: nil)
|
||||
coordinator.start()
|
||||
|
||||
self.coordinator = coordinator
|
||||
}
|
||||
|
||||
func dismiss(animated: Bool, completion: (() -> Void)?) {
|
||||
guard let coordinator = self.coordinator else {
|
||||
return
|
||||
}
|
||||
coordinator.toPresentable().dismiss(animated: animated) {
|
||||
self.coordinator = nil
|
||||
|
||||
if let completion = completion {
|
||||
completion()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - UIAdaptivePresentationControllerDelegate
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
extension SpaceSettingsModalCoordinatorBridgePresenter: UIAdaptivePresentationControllerDelegate {
|
||||
|
||||
func roomNotificationSettingsCoordinatorDidComplete(_ presentationController: UIPresentationController) {
|
||||
self.delegate?.spaceSettingsModalCoordinatorBridgePresenterDelegateDidCancel(self)
|
||||
}
|
||||
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
//
|
||||
// Copyright 2021 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// SpaceSettingsModalCoordinator input parameters
|
||||
struct SpaceSettingsModalCoordinatorParameters {
|
||||
|
||||
/// The Matrix session
|
||||
let session: MXSession
|
||||
|
||||
/// The ID of the space
|
||||
let spaceId: String
|
||||
|
||||
/// The navigation router that manage physical navigation
|
||||
let navigationRouter: NavigationRouterType
|
||||
|
||||
init(session: MXSession,
|
||||
spaceId: String,
|
||||
navigationRouter: NavigationRouterType? = nil) {
|
||||
self.session = session
|
||||
self.spaceId = spaceId
|
||||
self.navigationRouter = navigationRouter ?? NavigationRouter(navigationController: RiotNavigationController())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user