Skip to content

Commit

Permalink
Refactor alerts to be presented on their respective coordinator
Browse files Browse the repository at this point in the history
  • Loading branch information
Jon Petersson committed Sep 1, 2023
1 parent 26a812b commit 2a26e42
Show file tree
Hide file tree
Showing 18 changed files with 122 additions and 46 deletions.
2 changes: 2 additions & 0 deletions ios/.swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ line_length:
ignores_interpolated_strings: true
warning: 120
error: 300
cyclomatic_complexity:
ignores_case_statements: true

type_name:
min_length: 4
Expand Down
2 changes: 1 addition & 1 deletion ios/MullvadVPN/Classes/AppRoutes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ enum AppRoute: AppRouteProtocol {
/**
Alert route.
*/
case alert(AlertPresentation)
case alert(AlertPresentation, Coordinator)

/**
Routes that are part of primary horizontal navigation group.
Expand Down
19 changes: 14 additions & 5 deletions ios/MullvadVPN/Coordinators/AccountCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ final class AccountCoordinator: Coordinator, Presentable, Presenting {

let accountController = AccountViewController(
interactor: interactor,
errorPresenter: PaymentAlertPresenter(coordinator: self)
errorPresenter: PaymentAlertPresenter(alertContext: self)
)

accountController.actionHandler = handleViewControllerAction
Expand Down Expand Up @@ -133,18 +133,25 @@ final class AccountCoordinator: Coordinator, Presentable, Presenting {
// MARK: - Alerts

private func logOut() {
let presentation = AlertPresentation(icon: .spinner, message: nil, buttons: [])
let presentation = AlertPresentation(
id: "account-logout-alert",
icon: .spinner,
message: nil,
buttons: []
)

let alertPresenter = AlertPresenter(context: self)

interactor.logout {
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) { [weak self] in
guard let self else { return }

applicationRouter?.dismiss(.alert(presentation), animated: true)
alertPresenter.dismissAlert(presentation: presentation, animated: true)
self.didFinish?(self, .userLoggedOut)
}
}

applicationRouter?.present(.alert(presentation))
alertPresenter.showAlert(presentation: presentation, animated: true)
}

private func showAccountDeviceInfo() {
Expand All @@ -164,6 +171,7 @@ final class AccountCoordinator: Coordinator, Presentable, Presenting {
)

let presentation = AlertPresentation(
id: "account-device-info-alert",
message: message,
buttons: [AlertAction(
title: NSLocalizedString(
Expand All @@ -176,6 +184,7 @@ final class AccountCoordinator: Coordinator, Presentable, Presenting {
)]
)

applicationRouter?.present(.alert(presentation), animated: true)
let presenter = AlertPresenter(context: self)
presenter.showAlert(presentation: presentation, animated: true)
}
}
15 changes: 8 additions & 7 deletions ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,8 @@ final class ApplicationCoordinator: Coordinator, Presenting, RootContainerViewCo
case .welcome:
presentWelcome(animated: animated, completion: completion)

case let .alert(presentation):
presentAlert(presentation: presentation, animated: animated, completion: completion)
case let .alert(presentation, context):
presentAlert(presentation: presentation, context: context, animated: animated, completion: completion)
}
}

Expand Down Expand Up @@ -564,11 +564,10 @@ final class ApplicationCoordinator: Coordinator, Presenting, RootContainerViewCo
)

coordinator.didFinishPayment = { [weak self] _ in
guard let self else { return }
guard let self = self else { return }

if shouldDismissOutOfTime() {
router.dismiss(.outOfTime, animated: true)

continueFlow(animated: true)
}
}
Expand All @@ -589,7 +588,7 @@ final class ApplicationCoordinator: Coordinator, Presenting, RootContainerViewCo
)

coordinator.didFinish = { [weak self] _ in
guard let self else { return }
guard let self = self else { return }
appPreferences.isShownOnboarding = true
router.dismiss(.welcome, animated: false)
continueFlow(animated: false)
Expand Down Expand Up @@ -643,18 +642,20 @@ final class ApplicationCoordinator: Coordinator, Presenting, RootContainerViewCo

private func presentAlert(
presentation: AlertPresentation,
context: Coordinator,
animated: Bool,
completion: @escaping (Coordinator) -> Void
) {
let coordinator = AlertCoordinator(presentation: presentation)

coordinator.didFinish = { [weak self] in
self?.router.dismiss(.alert(presentation))
self?.router.dismiss(.alert(presentation, context))
}

coordinator.start()

presentChild(coordinator, animated: animated) {
let context = (context as? (any Presenting))
presentChild(coordinator, context: context, animated: animated) {
completion(coordinator)
}
}
Expand Down
10 changes: 8 additions & 2 deletions ios/MullvadVPN/Coordinators/InAppPurchaseCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@ import Routing
import StoreKit
import UIKit

class InAppPurchaseCoordinator: Coordinator, Presentable {
class InAppPurchaseCoordinator: Coordinator, Presenting, Presentable {
private let navigationController: RootContainerViewController
private let interactor: InAppPurchaseInteractor

var didFinish: ((InAppPurchaseCoordinator) -> Void)?
var didCancel: ((InAppPurchaseCoordinator) -> Void)?

var presentationContext: UIViewController {
navigationController
}

var presentedViewController: UIViewController {
navigationController
}
Expand Down Expand Up @@ -50,6 +54,7 @@ class InAppPurchaseCoordinator: Coordinator, Presentable {

case let .failure(failure):
let presentation = AlertPresentation(
id: "in-app-purchase-error-alert",
icon: .alert,
message: failure.error.localizedDescription,
buttons: [
Expand All @@ -69,7 +74,8 @@ class InAppPurchaseCoordinator: Coordinator, Presentable {
]
)

applicationRouter?.present(.alert(presentation), animated: true)
let presenter = AlertPresenter(context: self)
presenter.showAlert(presentation: presentation, animated: true)
}
}
}
Expand Down
11 changes: 8 additions & 3 deletions ios/MullvadVPN/Coordinators/LoginCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Operations
import Routing
import UIKit

final class LoginCoordinator: Coordinator, DeviceManagementViewControllerDelegate {
final class LoginCoordinator: Coordinator, Presenting, DeviceManagementViewControllerDelegate {
private let tunnelManager: TunnelManager
private let devicesProxy: REST.DevicesProxy

Expand All @@ -22,6 +22,10 @@ final class LoginCoordinator: Coordinator, DeviceManagementViewControllerDelegat
var didFinish: ((LoginCoordinator) -> Void)?
var didCreateAccount: (() -> Void)?

var presentationContext: UIViewController {
navigationController
}

let navigationController: RootContainerViewController

init(
Expand Down Expand Up @@ -107,11 +111,12 @@ final class LoginCoordinator: Coordinator, DeviceManagementViewControllerDelegat
)
let controller = DeviceManagementViewController(
interactor: interactor,
alertPresenter: AlertPresenter(coordinator: self)
alertPresenter: AlertPresenter(context: self)
)
controller.delegate = self

controller.fetchDevices(animateUpdates: false) { [weak self] result in
guard let self else { return }
guard let self = self else { return }

switch result {
case .success:
Expand Down
8 changes: 6 additions & 2 deletions ios/MullvadVPN/Coordinators/OutOfTimeCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@
import Routing
import UIKit

class OutOfTimeCoordinator: Coordinator, OutOfTimeViewControllerDelegate {
class OutOfTimeCoordinator: Coordinator, Presenting, OutOfTimeViewControllerDelegate {
let navigationController: RootContainerViewController
let storePaymentManager: StorePaymentManager
let tunnelManager: TunnelManager

var didFinishPayment: ((OutOfTimeCoordinator) -> Void)?

var presentationContext: UIViewController {
navigationController
}

private(set) var isMakingPayment = false
private var viewController: OutOfTimeViewController?

Expand All @@ -42,7 +46,7 @@ class OutOfTimeCoordinator: Coordinator, OutOfTimeViewControllerDelegate {

let controller = OutOfTimeViewController(
interactor: interactor,
errorPresenter: PaymentAlertPresenter(coordinator: self)
errorPresenter: PaymentAlertPresenter(alertContext: self)
)

controller.delegate = self
Expand Down
4 changes: 2 additions & 2 deletions ios/MullvadVPN/Coordinators/SettingsCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,13 @@ final class SettingsCoordinator: Coordinator, Presentable, Presenting, SettingsV
case .preferences:
return PreferencesViewController(
interactor: interactorFactory.makePreferencesInteractor(),
alertPresenter: AlertPresenter(coordinator: self)
alertPresenter: AlertPresenter(context: self)
)

case .problemReport:
return ProblemReportViewController(
interactor: interactorFactory.makeProblemReportInteractor(),
alertPresenter: AlertPresenter(coordinator: self)
alertPresenter: AlertPresenter(context: self)
)

case .faq:
Expand Down
10 changes: 8 additions & 2 deletions ios/MullvadVPN/Coordinators/TunnelCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@
import Routing
import UIKit

class TunnelCoordinator: Coordinator {
class TunnelCoordinator: Coordinator, Presenting {
private let tunnelManager: TunnelManager
private let controller: TunnelViewController

private var tunnelObserver: TunnelObserver?

var presentationContext: UIViewController {
controller
}

var rootViewController: UIViewController {
controller
}
Expand Down Expand Up @@ -59,6 +63,7 @@ class TunnelCoordinator: Coordinator {

private func showCancelTunnelAlert() {
let presentation = AlertPresentation(
id: "main-cancel-tunnel-alert",
icon: .alert,
message: NSLocalizedString(
"CANCEL_TUNNEL_ALERT_MESSAGE",
Expand Down Expand Up @@ -91,6 +96,7 @@ class TunnelCoordinator: Coordinator {
]
)

applicationRouter?.present(.alert(presentation), animated: true)
let presenter = AlertPresenter(context: self)
presenter.showAlert(presentation: presentation, animated: true)
}
}
6 changes: 4 additions & 2 deletions ios/MullvadVPN/Coordinators/WelcomeCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ extension WelcomeCoordinator: WelcomeViewControllerDelegate {
)

let presentation = AlertPresentation(
id: "welcome-device-name-alert",
icon: .info,
message: message,
buttons: [
Expand All @@ -117,7 +118,8 @@ extension WelcomeCoordinator: WelcomeViewControllerDelegate {
]
)

applicationRouter?.present(.alert(presentation), animated: true)
let presenter = AlertPresenter(context: self)
presenter.showAlert(presentation: presentation, animated: true)
}

func didRequestToPurchaseCredit(controller: WelcomeViewController, accountNumber: String, product: SKProduct) {
Expand Down Expand Up @@ -150,7 +152,7 @@ extension WelcomeCoordinator: WelcomeViewControllerDelegate {
)

coordinator.didCancel = { [weak self] coordinator in
guard let self else { return }
guard let self = self else { return }
navigationController.popViewController(animated: true)
coordinator.removeFromParent()
}
Expand Down
10 changes: 9 additions & 1 deletion ios/MullvadVPN/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, SettingsMigrationUIHand
private var tunnelObserver: TunnelObserver?

private var appDelegate: AppDelegate {
// swiftlint:disable:next force_cast
UIApplication.shared.delegate as! AppDelegate
}

Expand Down Expand Up @@ -185,7 +186,13 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, SettingsMigrationUIHand
// MARK: - SettingsMigrationUIHandler

func showMigrationError(_ error: Error, completionHandler: @escaping () -> Void) {
guard let appCoordinator else {
completionHandler()
return
}

let presentation = AlertPresentation(
id: "settings-migration-error-alert",
title: NSLocalizedString(
"ALERT_TITLE",
tableName: "SettingsMigrationUI",
Expand All @@ -204,7 +211,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, SettingsMigrationUIHand
]
)

appCoordinator?.router.present(.alert(presentation), animated: true) ?? completionHandler()
let presenter = AlertPresenter(context: appCoordinator)
presenter.showAlert(presentation: presentation, animated: true)
}

private static func migrationErrorReason(_ error: Error) -> String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@ import MullvadREST
import Routing

struct PaymentAlertPresenter {
let coordinator: Coordinator
let alertContext: any Presenting

func showAlertForError(
_ error: StorePaymentManagerError,
context: REST.CreateApplePaymentResponse.Context,
completion: (() -> Void)? = nil
) {
let presentation = AlertPresentation(
id: "payment-error-alert",
title: context.errorTitle,
message: error.displayErrorDescription,
buttons: [
Expand All @@ -31,7 +32,8 @@ struct PaymentAlertPresenter {
]
)

coordinator.applicationRouter?.present(.alert(presentation), animated: true)
let presenter = AlertPresenter(context: alertContext)
presenter.showAlert(presentation: presentation, animated: true)
}

func showAlertForResponse(
Expand All @@ -45,6 +47,7 @@ struct PaymentAlertPresenter {
}

let presentation = AlertPresentation(
id: "payment-response-alert",
title: response.alertTitle(context: context),
message: response.alertMessage(context: context),
buttons: [
Expand All @@ -58,7 +61,8 @@ struct PaymentAlertPresenter {
]
)

coordinator.applicationRouter?.present(.alert(presentation), animated: true)
let presenter = AlertPresenter(context: alertContext)
presenter.showAlert(presentation: presentation, animated: true)
}

private func okButtonTextForKey(_ key: String) -> String {
Expand Down
Loading

0 comments on commit 2a26e42

Please sign in to comment.