Merge pull request #2799 from vector-im/riot_2504

BF: selecting 'start verification' from a keyshare request wedges you in an entirely blank verification screen
This commit is contained in:
SBiOSoftWhare 2019-10-24 10:55:12 +02:00 committed by GitHub
commit c656a56eba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 78 additions and 21 deletions

View file

@ -6,6 +6,7 @@ Bug fix:
* Pasteboard: Fix a crash when passing a nil object to UIPasteboard.
* RoomVC: Fix crash occurring when tap on an unsent media with retrieved event equal to nil.
* Emoji Picker: Background color is not white (#2630).
* Device Verification: Selecting 'start verification' from a keyshare request wedges you in an entirely blank verification screen (#2504).
Changes in 0.10.0 (2019-10-11)
===============================================

View file

@ -73,7 +73,9 @@ final class DeviceVerificationCoordinator: DeviceVerificationCoordinatorType {
rootCoordinator.start()
self.add(childCoordinator: rootCoordinator)
self.navigationRouter.setRootModule(rootCoordinator)
self.navigationRouter.setRootModule(rootCoordinator) { [weak self] in
self?.remove(childCoordinator: rootCoordinator)
}
}
func toPresentable() -> UIViewController {
@ -96,7 +98,9 @@ final class DeviceVerificationCoordinator: DeviceVerificationCoordinatorType {
coordinator.start()
self.add(childCoordinator: coordinator)
self.navigationRouter.setRootModule(coordinator)
self.navigationRouter.setRootModule(coordinator) { [weak self] in
self?.remove(childCoordinator: coordinator)
}
}
private func showIncoming(otherUser: MXUser, transaction: MXIncomingSASTransaction) {
@ -105,7 +109,9 @@ final class DeviceVerificationCoordinator: DeviceVerificationCoordinatorType {
coordinator.start()
self.add(childCoordinator: coordinator)
self.navigationRouter.setRootModule(coordinator)
self.navigationRouter.setRootModule(coordinator) { [weak self] in
self?.remove(childCoordinator: coordinator)
}
}
private func showVerify(transaction: MXSASTransaction, animated: Bool) {

View file

@ -76,6 +76,12 @@ final class DeviceVerificationIncomingViewController: UIViewController {
self.viewModel.viewDelegate = self
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.avatarImageView.layer.cornerRadius = avatarImageView.frame.size.width / 2
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return self.theme.statusBarStyle
}
@ -129,7 +135,6 @@ final class DeviceVerificationIncomingViewController: UIViewController {
avatarImageView.enableInMemoryCache = true
avatarImageView.setImageURI(self.viewModel.avatarUrl, withType: nil, andImageOrientation: .up, previewImage: defaultavatarImage, mediaManager: self.viewModel.mediaManager)
avatarImageView.layer.cornerRadius = avatarImageView.frame.size.width / 2
avatarImageView.clipsToBounds = true
}
@ -175,6 +180,8 @@ final class DeviceVerificationIncomingViewController: UIViewController {
self.errorPresenter.presentError(from: self, title: "", message: VectorL10n.deviceVerificationCancelledByMe(reason.humanReadable), animated: true) {
self.viewModel.process(viewAction: .cancel)
}
} else {
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
}
}

View file

@ -20,5 +20,6 @@ import Foundation
/// DeviceVerificationDataLoadingViewController view actions exposed to view model
enum DeviceVerificationDataLoadingViewAction {
case loadData
case cancel
}

View file

@ -59,6 +59,7 @@ final class DeviceVerificationDataLoadingViewController: UIViewController {
self.update(theme: self.theme)
self.viewModel.viewDelegate = self
self.viewModel.process(viewAction: .loadData)
}
override var preferredStatusBarStyle: UIStatusBarStyle {

View file

@ -18,6 +18,10 @@
import Foundation
enum DeviceVerificationDataLoadingViewModelError: Error {
case unknown
}
final class DeviceVerificationDataLoadingViewModel: DeviceVerificationDataLoadingViewModelType {
// MARK: - Properties
@ -39,8 +43,6 @@ final class DeviceVerificationDataLoadingViewModel: DeviceVerificationDataLoadin
self.session = session
self.otherUserId = otherUserId
self.otherDeviceId = otherDeviceId
self.loadData()
}
deinit {
@ -50,6 +52,8 @@ final class DeviceVerificationDataLoadingViewModel: DeviceVerificationDataLoadin
func process(viewAction: DeviceVerificationDataLoadingViewAction) {
switch viewAction {
case .loadData:
self.loadData()
case .cancel:
self.coordinatorDelegate?.deviceVerificationDataLoadingViewModelDidCancel(self)
}
@ -58,28 +62,36 @@ final class DeviceVerificationDataLoadingViewModel: DeviceVerificationDataLoadin
// MARK: - Private
private func loadData() {
self.update(viewState: .loading)
guard let crypto = self.session.crypto else {
self.update(viewState: .errorMessage(VectorL10n.deviceVerificationErrorCannotLoadDevice))
NSLog("[DeviceVerificationDataLoadingViewModel] Error session.crypto is nil")
return
}
if let otherUser = self.session.user(withUserId: otherUserId) {
self.session.crypto?.downloadKeys([self.otherUserId], forceDownload: false, success: { [weak self] (usersDevicesMap) in
self.update(viewState: .loading)
crypto.downloadKeys([self.otherUserId], forceDownload: false, success: { [weak self] (usersDevicesMap) in
guard let sself = self else {
return
}
sself.update(viewState: .loaded)
if let otherDevice = usersDevicesMap?.object(forDevice: sself.otherDeviceId, forUser: sself.otherUserId) {
sself.update(viewState: .loaded)
sself.coordinatorDelegate?.deviceVerificationDataLoadingViewModel(sself, didLoadUser: otherUser, device: otherDevice)
} else {
sself.update(viewState: .errorMessage(VectorL10n.deviceVerificationErrorCannotLoadDevice))
}
}, failure: { [weak self] (error) in
guard let sself = self, let error = error else {
return
}
sself.update(viewState: .error(error))
}, failure: { [weak self] (error) in
guard let sself = self else {
return
}
let finalError = error ?? DeviceVerificationDataLoadingViewModelError.unknown
sself.update(viewState: .error(finalError))
})
} else {

View file

@ -189,6 +189,8 @@ final class DeviceVerificationStartViewController: UIViewController {
self.errorPresenter.presentError(from: self, title: "", message: VectorL10n.deviceVerificationCancelledByMe(reason.humanReadable), animated: true) {
self.viewModel.process(viewAction: .cancel)
}
} else {
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
}
}

View file

@ -81,8 +81,8 @@ final class DeviceVerificationStartViewModel: DeviceVerificationStartViewModelTy
sself.transaction = sasTransaction
sself.registerTransactionDidStateChangeNotification(transaction: sasTransaction)
sself.update(viewState: .loaded)
sself.registerTransactionDidStateChangeNotification(transaction: sasTransaction)
}, failure: {[weak self] error in
self?.update(viewState: .error(error))
})
@ -106,11 +106,17 @@ final class DeviceVerificationStartViewModel: DeviceVerificationStartViewModelTy
private func registerTransactionDidStateChangeNotification(transaction: MXOutgoingSASTransaction) {
NotificationCenter.default.addObserver(self, selector: #selector(transactionDidStateChange(notification:)), name: NSNotification.Name.MXDeviceVerificationTransactionDidChange, object: transaction)
}
private func unregisterTransactionDidStateChangeNotification() {
NotificationCenter.default.removeObserver(self, name: .MXDeviceVerificationTransactionDidChange, object: nil)
}
@objc private func transactionDidStateChange(notification: Notification) {
guard let transaction = notification.object as? MXOutgoingSASTransaction else {
return
}
self.unregisterTransactionDidStateChangeNotification()
switch transaction.state {
case MXSASTransactionStateShowSAS:

View file

@ -180,6 +180,8 @@ final class DeviceVerificationVerifyViewController: UIViewController {
self.errorPresenter.presentError(from: self, title: "", message: VectorL10n.deviceVerificationCancelledByMe(reason.humanReadable), animated: true) {
self.viewModel.process(viewAction: .cancel)
}
} else {
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
}
}

View file

@ -48,10 +48,23 @@ final class NavigationRouter: NSObject, NavigationRouterType {
navigationController.dismiss(animated: animated, completion: completion)
}
func setRootModule(_ module: Presentable, hideNavigationBar: Bool = false) {
func setRootModule(_ module: Presentable, hideNavigationBar: Bool = false, animated: Bool = false, popCompletion: (() -> Void)? = nil) {
let controller = module.toPresentable()
// Avoid setting a UINavigationController onto stack
guard controller is UINavigationController == false else {
return
}
// Call all completions so all coordinators can be deallocated
completions.forEach { $0.value() }
navigationController.setViewControllers([module.toPresentable()], animated: false)
if let popCompletion = popCompletion {
completions[controller] = popCompletion
}
navigationController.setViewControllers([controller], animated: animated)
navigationController.isNavigationBarHidden = hideNavigationBar
}

View file

@ -36,7 +36,9 @@ protocol NavigationRouterType: class, Presentable {
///
/// - Parameter module: The Presentable to set as root.
/// - Parameter hideNavigationBar: Specify true to hide the UINavigationBar.
func setRootModule(_ module: Presentable, hideNavigationBar: Bool)
/// - Parameter animated: Specify true to animate the transition.
/// - Parameter popCompletion: Completion called when `module` is removed from the navigation stack.
func setRootModule(_ module: Presentable, hideNavigationBar: Bool, animated: Bool, popCompletion: (() -> Void)?)
/// Pop to root view controller of navigation controller and remove all others
///
@ -64,6 +66,10 @@ protocol NavigationRouterType: class, Presentable {
// `NavigationRouterType` default implementation
extension NavigationRouterType {
func setRootModule(_ module: Presentable) {
setRootModule(module, hideNavigationBar: false)
setRootModule(module, hideNavigationBar: false, animated: false, popCompletion: nil)
}
func setRootModule(_ module: Presentable, popCompletion: (() -> Void)?) {
setRootModule(module, hideNavigationBar: false, animated: false, popCompletion: popCompletion)
}
}