// // NotificationsController.swift // PrivadoVPN // // Created by Zhandos Bolatbekov on 11.01.2021. // Copyright © 2021 Privado LLC. All rights reserved. // import Foundation import UIKit protocol NotificationsControllerInput: AnyObject { func display(notificationCells: [NotificationCellAdapter]) } protocol NotificationsControllerOutput: AnyObject { func viewIsReady() func backClick() } final class NotificationsController: UIViewController, NotificationsControllerInput { private enum Constants { static let backgroundColor = UIColor(rgb: 0x202864) static let statusBarColor = UIColor(red: 18, green: 23, blue: 45) static let backImage = "navigation_back" static let backWidth: CGFloat = 60 static let backHeight: CGFloat = 40 static let backLeft: CGFloat = 14 static let statusBarHeight: CGFloat = UIApplication.shared.statusBarFrame.height static let estimatedCellHeight: CGFloat = 250 static let emptyLabelTop: CGFloat = 92 } private let output: NotificationsControllerOutput var navigationBar: UIView? private lazy var notificationsTableViewManager = NotificationsTableViewManager(tableView: self.notificationsTableView) private lazy var notificationsTableView: UITableView = { let tableView = UITableView() tableView.translatesAutoresizingMaskIntoConstraints = false tableView.separatorStyle = .none tableView.backgroundColor = .clear tableView.estimatedRowHeight = Constants.estimatedCellHeight tableView.showsVerticalScrollIndicator = true tableView.indicatorStyle = .white if #available(iOS 11.1, *) { tableView.verticalScrollIndicatorInsets = .init(top: 8, left: 0, bottom: 0, right: 8) } return tableView }() private let notificationsEmptyLabel: UILabel = { let label = UILabel() label.font = UIFont(name: "SFProText-Light", size: 20) label.textAlignment = .center label.numberOfLines = 0 label.text = NSLocalizedString("notificationCenter.empty", comment: "There are currently no notifications.") label.isHidden = true label.translatesAutoresizingMaskIntoConstraints = false label.textColor = UIColor(red: 122, green: 134, blue: 190) return label }() // MARK: - Init init(output: NotificationsControllerOutput) { self.output = output super.init(nibName: nil, bundle: nil) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } // MARK: - Lifecycle override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent // .default } override func loadView() { let view = UIView(frame: .zero) view.autoresizesSubviews = true view.backgroundColor = Constants.backgroundColor self.view = view } override func viewDidLoad() { super.viewDidLoad() self.configureUI() self.output.viewIsReady() } // MARK: - NotificationsControllerInput func display(notificationCells: [NotificationCellAdapter]) { self.notificationsTableViewManager.display(notificationCells: notificationCells) if notificationCells.isEmpty { self.notificationsTableView.isHidden = true self.notificationsEmptyLabel.isHidden = false } else { self.notificationsTableView.isHidden = false self.notificationsEmptyLabel.isHidden = true } } // MARK: - UI private func configureUI() { let backButton = self.initializeBackButton() self.view.addSubview(backButton) NSLayoutConstraint.activate([ backButton.heightAnchor.constraint(equalToConstant: Constants.backHeight), backButton.widthAnchor.constraint(equalToConstant: Constants.backWidth), backButton.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: Constants.backLeft), backButton.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor) ]) // Status bar let statusBarView = UIView() statusBarView.backgroundColor = Constants.statusBarColor statusBarView.translatesAutoresizingMaskIntoConstraints = false self.view.addSubview(statusBarView) NSLayoutConstraint.activate([ statusBarView.heightAnchor.constraint(equalToConstant: Constants.statusBarHeight), statusBarView.topAnchor.constraint(equalTo: self.view.topAnchor), statusBarView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), statusBarView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor) ]) if let navigationBar = navigationBar { self.view.addSubview(navigationBar) NSLayoutConstraint.activate([ navigationBar.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor), navigationBar.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), navigationBar.trailingAnchor.constraint(equalTo: self.view.trailingAnchor) ]) } self.view.addSubview(self.notificationsTableView) NSLayoutConstraint.activate([ self.notificationsTableView.topAnchor.constraint( equalTo: self.navigationBar?.bottomAnchor ?? self.view.safeAreaLayoutGuide.topAnchor ), self.notificationsTableView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor), self.notificationsTableView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor), self.notificationsTableView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor) ]) self.view.addSubview(self.notificationsEmptyLabel) NSLayoutConstraint.activate([ self.notificationsEmptyLabel.topAnchor.constraint( equalTo: self.navigationBar?.bottomAnchor ?? self.view.safeAreaLayoutGuide.topAnchor, constant: Constants.emptyLabelTop ), self.notificationsEmptyLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor) ]) } private func initializeBackButton() -> UIButton { let backButton = UIButton(frame: .zero) backButton.translatesAutoresizingMaskIntoConstraints = false backButton.addTarget(self, action: #selector(self.backClick), for: .touchUpInside) let image = UIImage(imageLiteralResourceName: Constants.backImage) let imageView = UIImageView(image: image) imageView.translatesAutoresizingMaskIntoConstraints = false backButton.addSubview(imageView) NSLayoutConstraint.activate([ imageView.heightAnchor.constraint(equalToConstant: image.size.height), imageView.widthAnchor.constraint(equalToConstant: image.size.width), imageView.centerYAnchor.constraint(equalTo: backButton.centerYAnchor), imageView.centerXAnchor.constraint(equalTo: backButton.centerXAnchor) ]) return backButton } @objc func backClick() { self.output.backClick() } } extension NotificationsController: ViewModuleControllerType { }