229 lines
8.7 KiB
Swift
229 lines
8.7 KiB
Swift
//
|
|
// MessageView.swift
|
|
// PrivadoVPN
|
|
//
|
|
// Created by Zhandos Bolatbekov on 25.01.2021.
|
|
// Copyright © 2021 Privado LLC. All rights reserved.
|
|
//
|
|
|
|
import Foundation
|
|
import UIKit
|
|
|
|
protocol MessageViewInput: AnyObject {
|
|
func showMessage(text: String)
|
|
func setVisibility(hidden: Bool)
|
|
}
|
|
|
|
protocol MessageViewOutput: AnyObject {
|
|
func didTap()
|
|
func changeVisibility(isHidden: Bool)
|
|
func didTapViewButton()
|
|
func didTapClose()
|
|
}
|
|
|
|
final class MessageView: UIView, MessageViewInput {
|
|
|
|
private enum Constants {
|
|
enum Color {
|
|
static let background = UIColor.clear
|
|
static let messageContainerBackground = UIColor(rgb: 0x363f83)
|
|
static let messageText = UIColor(rgb: 0x28d799)
|
|
static let button = UIColor(rgb: 0x030f48)
|
|
static let buttonSeparator = UIColor(rgb: 0x363f83)
|
|
}
|
|
enum Geometry {
|
|
static let height: CGFloat = 53
|
|
static let messageIndent: CGFloat = 16
|
|
static let buttonsWidth: CGFloat = 158
|
|
static let buttonsSeparatorWidth: CGFloat = 1
|
|
static let buttonsIndentY: CGFloat = 6
|
|
static let cornerRadius: CGFloat = 5
|
|
}
|
|
enum LocalizedString {
|
|
static let viewButton = "messageView.button.view"
|
|
static let closeButton = "messageView.button.close"
|
|
}
|
|
static let messageFont = UIFont(name: "SFProText-Regular", size: 16.7)
|
|
static let swipeAnimationDuration: Double = 0.2
|
|
}
|
|
|
|
private let output: MessageViewOutput
|
|
private var messageLabel: UILabel?
|
|
|
|
private var messageContainerRightConstraint: NSLayoutConstraint?
|
|
|
|
// MARK: - Init
|
|
|
|
init(output: MessageViewOutput) {
|
|
self.output = output
|
|
super.init(frame: .zero)
|
|
self.configureUI()
|
|
}
|
|
|
|
required init?(coder: NSCoder) { nil }
|
|
|
|
// MARK: - View
|
|
|
|
private func configureUI() {
|
|
self.translatesAutoresizingMaskIntoConstraints = false
|
|
self.backgroundColor = Constants.Color.background
|
|
self.layer.cornerRadius = Constants.Geometry.cornerRadius
|
|
self.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
|
|
self.clipsToBounds = true
|
|
|
|
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.onTapGesture))
|
|
self.addGestureRecognizer(tapGesture)
|
|
|
|
let buttonsView = self.initializeButtons()
|
|
NSLayoutConstraint.activate([
|
|
buttonsView.widthAnchor.constraint(equalToConstant: Constants.Geometry.buttonsWidth),
|
|
buttonsView.topAnchor.constraint(equalTo: self.topAnchor),
|
|
buttonsView.bottomAnchor.constraint(equalTo: self.bottomAnchor),
|
|
buttonsView.rightAnchor.constraint(equalTo: self.rightAnchor)
|
|
])
|
|
|
|
let messageContainer = self.initializeMessageContainer()
|
|
self.addSubview(messageContainer)
|
|
self.messageContainerRightConstraint = messageContainer.rightAnchor.constraint(equalTo: self.rightAnchor)
|
|
NSLayoutConstraint.activate([
|
|
messageContainer.heightAnchor.constraint(equalToConstant: Constants.Geometry.height),
|
|
messageContainer.topAnchor.constraint(equalTo: self.topAnchor),
|
|
messageContainer.bottomAnchor.constraint(equalTo: self.bottomAnchor),
|
|
messageContainer.widthAnchor.constraint(equalTo: self.widthAnchor),
|
|
self.messageContainerRightConstraint!
|
|
])
|
|
|
|
let messageLabel = self.createMessageLabel()
|
|
messageContainer.addSubview(messageLabel)
|
|
NSLayoutConstraint.activate([
|
|
messageLabel.leftAnchor.constraint(equalTo: messageContainer.leftAnchor, constant: Constants.Geometry.messageIndent),
|
|
messageLabel.rightAnchor.constraint(equalTo: messageContainer.rightAnchor, constant: -Constants.Geometry.messageIndent),
|
|
messageLabel.centerYAnchor.constraint(equalTo: messageContainer.centerYAnchor)
|
|
])
|
|
}
|
|
|
|
// MARK: - MessageViewInput
|
|
|
|
func showMessage(text: String) {
|
|
self.messageLabel?.attributedText = NSAttributedString(
|
|
string: text,
|
|
attributes: [.underlineStyle: NSUnderlineStyle.single.rawValue, .kern: -1.0]
|
|
)
|
|
self.output.changeVisibility(isHidden: false)
|
|
}
|
|
|
|
func setVisibility(hidden: Bool) { }
|
|
|
|
// MARK: - Private
|
|
|
|
private func initializeMessageContainer() -> UIView {
|
|
let view = UIView()
|
|
view.translatesAutoresizingMaskIntoConstraints = false
|
|
view.backgroundColor = Constants.Color.messageContainerBackground
|
|
|
|
let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(self.leftSwipeAction))
|
|
leftSwipe.direction = .right
|
|
// view.addGestureRecognizer(leftSwipe)
|
|
|
|
let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(self.rightSwipeAction))
|
|
rightSwipe.direction = .left
|
|
// view.addGestureRecognizer(rightSwipe)
|
|
return view
|
|
}
|
|
|
|
private func createMessageLabel() -> UILabel {
|
|
let label = UILabel()
|
|
label.translatesAutoresizingMaskIntoConstraints = false
|
|
label.font = Constants.messageFont
|
|
label.lineBreakMode = .byTruncatingTail
|
|
label.textColor = Constants.Color.messageText
|
|
label.textAlignment = .center
|
|
self.messageLabel = label
|
|
return label
|
|
}
|
|
|
|
private func initializeButtons() -> UIView {
|
|
let view = UIView()
|
|
view.translatesAutoresizingMaskIntoConstraints = false
|
|
let separator: UIView = {
|
|
let view = UIView()
|
|
view.translatesAutoresizingMaskIntoConstraints = false
|
|
view.backgroundColor = Constants.Color.buttonSeparator
|
|
return view
|
|
}()
|
|
view.addSubview(separator)
|
|
NSLayoutConstraint.activate([
|
|
separator.centerXAnchor.constraint(equalTo: view.centerXAnchor),
|
|
separator.widthAnchor.constraint(equalToConstant: Constants.Geometry.buttonsSeparatorWidth),
|
|
separator.topAnchor.constraint(equalTo: view.topAnchor, constant: Constants.Geometry.buttonsIndentY),
|
|
separator.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -Constants.Geometry.buttonsIndentY)
|
|
])
|
|
|
|
let viewButtonTitle = NSLocalizedString(Constants.LocalizedString.viewButton, comment: "View")
|
|
let viewButton = self.createButton(title: viewButtonTitle)
|
|
viewButton.addTarget(self, action: #selector(self.didTapViewButton), for: .touchUpInside)
|
|
view.addSubview(viewButton)
|
|
|
|
NSLayoutConstraint.activate([
|
|
viewButton.topAnchor.constraint(equalTo: view.topAnchor),
|
|
viewButton.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
|
viewButton.trailingAnchor.constraint(equalTo: separator.leadingAnchor),
|
|
viewButton.bottomAnchor.constraint(equalTo: view.bottomAnchor)
|
|
])
|
|
|
|
let closeButtonTitle = NSLocalizedString(Constants.LocalizedString.closeButton, comment: "Close")
|
|
let closeButton = self.createButton(title: closeButtonTitle)
|
|
closeButton.addTarget(self, action: #selector(self.didTapCloseButton), for: .touchUpInside)
|
|
view.addSubview(closeButton)
|
|
|
|
NSLayoutConstraint.activate([
|
|
closeButton.topAnchor.constraint(equalTo: view.topAnchor),
|
|
closeButton.leadingAnchor.constraint(equalTo: separator.trailingAnchor),
|
|
closeButton.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
|
closeButton.bottomAnchor.constraint(equalTo: view.bottomAnchor)
|
|
])
|
|
|
|
self.addSubview(view)
|
|
return view
|
|
}
|
|
|
|
private func createButton(title: String) -> UIButton {
|
|
let button = UIButton()
|
|
button.translatesAutoresizingMaskIntoConstraints = false
|
|
button.setTitle(title, for: .normal)
|
|
button.backgroundColor = Constants.Color.button
|
|
return button
|
|
}
|
|
|
|
@objc
|
|
private func onTapGesture() {
|
|
self.output.didTap()
|
|
}
|
|
|
|
@objc
|
|
private func leftSwipeAction() {
|
|
UIView.animate(withDuration: Constants.swipeAnimationDuration) { [weak self] in
|
|
self?.messageContainerRightConstraint?.constant = 0
|
|
self?.layoutIfNeeded()
|
|
}
|
|
}
|
|
|
|
@objc
|
|
private func rightSwipeAction() {
|
|
UIView.animate(withDuration: Constants.swipeAnimationDuration) { [weak self] in
|
|
self?.messageContainerRightConstraint?.constant = -Constants.Geometry.buttonsWidth
|
|
self?.layoutIfNeeded()
|
|
}
|
|
}
|
|
|
|
@objc
|
|
private func didTapViewButton() {
|
|
self.output.didTapViewButton()
|
|
}
|
|
|
|
@objc
|
|
private func didTapCloseButton() {
|
|
self.output.didTapClose()
|
|
}
|
|
}
|