Files

168 lines
5.1 KiB
Swift

//
// NotificationPresenter.swift
// PrivadoVPN
//
// Created by Juraldinio on 3/28/21.
// Copyright © 2021 Privado LLC. All rights reserved.
//
import Foundation
struct NotificationAction {
enum Action: String {
case outPeriod = "OUT_PERIOD"
case outTraffic = "OUT_TRAFFIC"
}
let action: Action
let urlPath: String?
}
struct NotificationLocal {
enum Kind {
case calendar
case interval
case location
}
enum Action: String {
case passReset = "PASSRESET"
case conlimit = "CONNLIMIT"
}
let subject: String
let date: Date
let kind: Kind
let actions: [String]
let title: String
let body: String
let isVPNActive: Bool
let loginUrlPath: String?
let trafficTotalMb: UInt
let trafficLeftMb: UInt
let localIp: String?
}
protocol NotificationModuleOutput: AnyObject {
var scheduler: Emitter<[NotificationLocal]> { get }
//
func navigate(to route: Route)
func closeNotifications()
//
func notification(with actions: [NotificationAction])
//
func deliver(notifications: [NotificationLocal])
}
protocol NotificationModuleInput: AnyObject {
var hasUnreadEmitter: Emitter<Bool> { get }
}
final class NotificationPresenter: NotificationControllerOutput, NotificationModuleInput {
private weak var output: NotificationModuleOutput?
private let interactor: NotificationInteractorInput
private let customerModule: CustomerModuleInput
weak var viewInput: NotificationControllerInput?
// MARK: - Init
init(interactor: NotificationInteractorInput, customer: CustomerModuleInput, output: NotificationModuleOutput?) {
self.interactor = interactor
self.customerModule = customer
self.output = output
self.bind()
}
// MARK: - Private
func bind() {
self.interactor.serviceReceiving.addReaction { [weak self] receiving -> ShouldContinueReceiveNotifications in
guard let self = self else { return false }
guard receiving
, self.customerModule.customer.isExist else {
return true
}
self.customerModule
.requireCustomerInfo()
.onFinish()
return true
}
self.interactor.notificationsEmitter.addReaction { [weak self] notifications -> ShouldContinueReceiveNotifications in
let actions = notifications.map { notification -> [NotificationAction] in
let actions = notification.actions.compactMap { NotificationAction.Action(rawValue: $0) }
return actions.map { NotificationAction(action: $0, urlPath: notification.urlPath) }
}.reduce([], +)
self?.output?.notification(with: actions)
return self.isExist
}
self.interactor.localNotificationsEmitter.addReaction { [weak self] notifications -> ShouldContinueReceiveNotifications in
let localNotifications = notifications.map {
NotificationLocal(subject: $0.subject,
date: $0.sentDate,
kind: .interval,
actions: $0.actions,
title: $0.subject,
body: $0.body,
isVPNActive: $0.isVpnActive,
loginUrlPath: $0.urlPath,
trafficTotalMb: $0.trafficTotalMb,
trafficLeftMb: $0.trafficLeftMb,
localIp: $0.localIp)
}
self?.output?.scheduler.invoke(localNotifications)
return self.isExist
}
}
// MARK: - NotificationControllerOutput
func notificationListReady(_ view: NotificationControllerInput) {
view.refreshView(exists: self.interactor.notifications.count > 0)
if !self.interactor.notifications.isEmpty {
self.interactor.ungear()
}
}
func notificationLostClose(_ view: NotificationControllerInput) {
self.output?.closeNotifications()
}
func notificationEmptyMessage(_ view: NotificationControllerInput) -> String { NSLocalizedString("notifications.list.empty", comment: "") }
func notificationRecordsCount(in view: NotificationControllerInput) -> Int { self.interactor.notifications.count }
func notificationRecord(in view: NotificationControllerInput, at index: Int) -> NotificationCellModel? {
guard let model = self.interactor.notifications[safe: index] else { return nil }
return NotificationCellModel(title: model.subject, sentDate: model.sentDate, body: model.body)
}
func viewDidAppear() {
self.hasUnreadEmitter.invoke(false)
}
// MARK: - NotificationModuleInput
var hasUnreadEmitter: Emitter<Bool> { self.interactor.hasUnreadEmitter }
}