168 lines
5.1 KiB
Swift
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 }
|
|
|
|
}
|