Files
2022-05-31 18:34:44 +04:00

263 lines
9.5 KiB
Swift

//
// ServerPanelView.swift
// PrivadoVPN
//
// Created by Juraldinio on 1/31/21.
// Copyright © 2021 Privado LLC. All rights reserved.
//
import Foundation
import AppKit
protocol ServerPanelViewInput: AnyObject {
func hide()
func show(country: String, city: String, flag: String)
func useHandCursor(enable: Bool)
func countryCircle(isHighlited: Bool)
}
protocol ServerPanelViewOutput: AnyObject {
func viewIsReady()
func viewWillDisappear()
func serverSelectRequired()
}
final class ServerPanelView: View {
private enum Constants {
enum LocalizedString {
static let serverSelected = "serverlist.location.selected"
}
enum Image {
static let map = "map.serverlist"
static let arrow = "main-arrow"
}
enum Color {
static let line = NSColor(red: 25, green: 33, blue: 71)
static let header = NSColor(red: 61, green: 69, blue: 111)
static let country = NSColor.white
static let city = NSColor.white
static let background = NSColor(red: 21, green: 25, blue: 53)
}
enum Font {
// swiftlint:disable nesting
enum Name {
static let medium = PrivadoConstants.Font.medium
static let black = PrivadoConstants.Font.bold
static let light = PrivadoConstants.Font.light
}
enum Size {
static let header: CGFloat = 12.0
static let country: CGFloat = 12.0
static let city: CGFloat = 12.0
}
// swiftlint:enable nesting
}
enum Geometry {
static let height: CGFloat = 110
static let headerWidth: CGFloat = 110
static let headerHeight: CGFloat = 16
static let headerLeading: CGFloat = 22
static let lineHeight: CGFloat = 2
static let mapImageWidth: CGFloat = 113
static let mapImageHeight: CGFloat = 65
static let mapBetweenLine: CGFloat = 6
static let arrowImageWidth: CGFloat = 7
static let arrowImageHeight: CGFloat = 12
static let arrowBetweenMap: CGFloat = 14
static let arrowTrailing: CGFloat = 21
static let countryTrailingMap: CGFloat = 21
static let cityTrailingMap: CGFloat = 21
static let cityTop: CGFloat = 5.0
}
}
private let output: ServerPanelViewOutput
private var headerField: NSTextField?
private var countryField: NSTextField?
private var cityField: NSTextField?
private var arrowView: ImageView?
private var backView: View?
private var countryImageView: ImageView?
private var countryCircleImageView: ImageView?
// MARK: - Init
init(output: ServerPanelViewOutput) {
self.output = output
super.init(frame: .zero)
self.isHidden = true
self.translatesAutoresizingMaskIntoConstraints = false
self.createUI()
self.activateLayout()
self.target = self
self.action = #selector(self.onClick)
}
// MARK: - Lyfecycle
override func viewDidMoveToSuperview() {
super.viewDidMoveToSuperview()
if self.superview.isExist {
self.output.viewIsReady()
}
}
override func removeFromSuperview() {
self.output.viewWillDisappear()
super.removeFromSuperview()
}
// MARK: - on methods
@objc
private func onClick() {
self.output.serverSelectRequired()
}
// MARK: - Private
private func createUI() {
let backgroundView = View(frame: .zero)
backgroundView.translatesAutoresizingMaskIntoConstraints = false
backgroundView.viewBackgroundColor = NSColor(red: 105, green: 112, blue: 208)
backgroundView.layer?.cornerRadius = 8
self.backView = backgroundView
self.addSubview(backgroundView)
let headerFont = NSFont(name: PrivadoConstants.Font.bold, size: 11)
let headerField = self.initializeTextField(color: NSColor(red: 218, green: 219, blue: 243), font: headerFont, alignment: .left, backgroundExist: false)
headerField.backgroundColor = .clear
headerField.stringValue = NSLocalizedString(Constants.LocalizedString.serverSelected, comment: "")
self.headerField = headerField
backgroundView.addSubview(headerField)
let countryImageView = ImageView(frame: .zero)
countryImageView.translatesAutoresizingMaskIntoConstraints = false
self.countryImageView = countryImageView
backgroundView.addSubview(countryImageView)
let countryCircleView = ImageView(frame: .zero)
countryCircleView.translatesAutoresizingMaskIntoConstraints = false
if let image = NSImage(named: "country-circle-disconnected") {
countryCircleView.image = image
}
self.countryCircleImageView = countryCircleView
backgroundView.addSubview(countryCircleView)
let cityFont = NSFont(name: PrivadoConstants.Font.bold, size: 16)
let cityField = self.initializeTextField(color: .white, font: cityFont, alignment: .left, backgroundExist: false)
self.cityField = cityField
backgroundView.addSubview(cityField)
let countryFont = NSFont(name: PrivadoConstants.Font.semiBold, size: 13)
let countryField = self.initializeTextField(color: .white, font: countryFont, alignment: .left, backgroundExist: false)
self.countryField = countryField
backgroundView.addSubview(countryField)
let arrowView = self.initializeImageView(resource: Constants.Image.arrow)
self.arrowView = arrowView
backgroundView.addSubview(arrowView)
}
private func activateLayout() {
guard let headerField = self.headerField
, let backgroundView = self.backView
, let countyImageView = self.countryImageView
, let countryCircleView = self.countryCircleImageView
, let countryField = self.countryField
, let cityField = self.cityField
, let arrowView = self.arrowView else {
return
}
NSLayoutConstraint.activate([
self.heightAnchor.constraint(equalToConstant: Constants.Geometry.height),
//
backgroundView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 20),
backgroundView.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -20),
backgroundView.topAnchor.constraint(equalTo: self.topAnchor),
backgroundView.bottomAnchor.constraint(equalTo: self.bottomAnchor),
//
headerField.topAnchor.constraint(equalTo: backgroundView.topAnchor, constant: 20),
headerField.leadingAnchor.constraint(equalTo: backgroundView.leadingAnchor, constant: 20),
headerField.widthAnchor.constraint(equalToConstant: 133),
headerField.heightAnchor.constraint(equalToConstant: 13),
//
countryCircleView.heightAnchor.constraint(equalToConstant: 48),
countryCircleView.widthAnchor.constraint(equalToConstant: 48),
countryCircleView.leadingAnchor.constraint(equalTo: backgroundView.leadingAnchor, constant: 20),
countryCircleView.topAnchor.constraint(equalTo: headerField.bottomAnchor, constant: 13),
//
countyImageView.heightAnchor.constraint(equalToConstant: 30),
countyImageView.widthAnchor.constraint(equalToConstant: 30),
countyImageView.centerXAnchor.constraint(equalTo: countryCircleView.centerXAnchor),
countyImageView.centerYAnchor.constraint(equalTo: countryCircleView.centerYAnchor),
cityField.leadingAnchor.constraint(equalTo: countryCircleView.trailingAnchor, constant: 10),
cityField.topAnchor.constraint(equalTo: headerField.bottomAnchor, constant: 17),
countryField.leadingAnchor.constraint(equalTo: cityField.leadingAnchor),
countryField.topAnchor.constraint(equalTo: cityField.bottomAnchor, constant: 7),
arrowView.widthAnchor.constraint(equalToConstant: 22),
arrowView.heightAnchor.constraint(equalToConstant: 22),
arrowView.trailingAnchor.constraint(equalTo: backgroundView.trailingAnchor, constant: -20),
arrowView.bottomAnchor.constraint(equalTo: backgroundView.bottomAnchor, constant: -33)
])
}
}
// MARK: - ServerPanelViewInput
extension ServerPanelView: ServerPanelViewInput {
func hide() {
self.isHidden = true
}
func show(country: String, city: String, flag: String) {
self.countryField?.stringValue = country
self.cityField?.stringValue = city
self.countryImageView?.image = NSImage(named: flag)
self.isHidden = false
}
func useHandCursor(enable: Bool) {
self.useHandCursor = enable
self.arrowView?.isHidden = !enable
}
func countryCircle(isHighlited: Bool) {
self.countryCircleImageView?.image = isHighlited ? NSImage(named: "country-circle-connected") : NSImage(named: "country-circle-disconnected")
}
}