// // ConnectionPanelPresenter.swift // PrivadoVPN // // Created by Juraldinio on 1/31/21. // Copyright © 2021 Privado LLC. All rights reserved. // import Foundation enum ConnectionPanelState: Equatable { case undefined case connecting case connected(ip: String, secured: Bool) case disconnecting case disconnected(ip: String, city: String, country: String) case reconnecting } protocol ConnectionPanelOutput: AnyObject { var updateEmitter: Emitter { get } func connectServer() func disconnectServer() func update(for panel: ConnectionPanelInput) func navigate(to route: Route) } protocol ConnectionPanelInput { func update(state: ConnectionPanelState) } final class ConnectionPanelPresenter { private enum Constants { enum LocalizedString { static let connecting = "connection.status.connecting" static let connected = "connection.status.connected" static let disconnecting = "connection.status.disconnecting" static let disconnected = "connection.status.disconnected" static let reconnecting = "connection.status.reconnecting" } } private weak var output: ConnectionPanelOutput? weak var viewInput: ConnectionPanelViewInput? private var state: ConnectionPanelState = .undefined // MARK: - Init init(output: ConnectionPanelOutput?) { self.output = output self.output?.updateEmitter.addReaction { [weak self] _ -> ShouldContinueReceiveNotifications in guard let self = self else { return false } self.output?.update(for: self) return true } } } // MARK: - ConnectionPanelInput extension ConnectionPanelPresenter: ConnectionPanelInput { func update(state: ConnectionPanelState) { self.state = state guard let viewInput = self.viewInput else { return } switch state { case .undefined: viewInput.hide() case .connecting: viewInput.interactionEnabled(false) viewInput.progress(status: NSLocalizedString(Constants.LocalizedString.connecting, comment: ""), type: .connecting) case .disconnecting: viewInput.interactionEnabled(false) viewInput.progress(status: NSLocalizedString(Constants.LocalizedString.disconnecting, comment: ""), type: .disconnecting) case let .connected(ip: ip, secured: secured): viewInput.location(connected: true, ip: "IP \(ip)", city: "", secured: secured, status: NSLocalizedString(Constants.LocalizedString.connected, comment: "")) viewInput.interactionEnabled(true) self.output?.navigate(to: .show) case let .disconnected(ip: ip, city: city, country: country): viewInput.location(connected: false, ip: "IP \(ip)", city: city.isEmpty ? country : "\(city), \(CountryResolver.code(from: country))", secured: false, status: NSLocalizedString(Constants.LocalizedString.disconnected, comment: "")) viewInput.interactionEnabled(true) case .reconnecting: viewInput.interactionEnabled(false) viewInput.progress(status: NSLocalizedString(Constants.LocalizedString.reconnecting, comment: ""), type: .reconnecting) } } } // MARK: - ConnectionPanelViewOutput extension ConnectionPanelPresenter: ConnectionPanelViewOutput { func viewIsReady() { self.output?.update(for: self) } func viewWillDisappear() { } func viewConnectButtonClicked() { switch self.state { case .connected: self.output?.disconnectServer() case .disconnected: self.output?.connectServer() default: break } } }