Signal-iOS/SignalMessaging/ViewControllers/ApprovalFooterView.swift
2019-10-24 12:04:25 -03:00

139 lines
3.8 KiB
Swift

//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
import Foundation
// Outgoing message approval can be a multi-step process.
@objc
public enum ApprovalMode: UInt {
// This is the final step of approval; continuing will send.
case send
// This is not the final step of approval; continuing will not send.
case next
}
// MARK: -
public protocol ApprovalFooterDelegate: AnyObject {
func approvalFooterDelegateDidRequestProceed(_ approvalFooterView: ApprovalFooterView)
func approvalMode(_ approvalFooterView: ApprovalFooterView) -> ApprovalMode
}
// MARK: -
public class ApprovalFooterView: UIView {
public weak var delegate: ApprovalFooterDelegate? {
didSet {
updateContents()
}
}
private var approvalMode: ApprovalMode {
guard let delegate = delegate else {
return .send
}
return delegate.approvalMode(self)
}
override init(frame: CGRect) {
super.init(frame: frame)
autoresizingMask = .flexibleHeight
translatesAutoresizingMaskIntoConstraints = false
backgroundColor = Theme.keyboardBackgroundColor
layoutMargins = UIEdgeInsets(top: 10, left: 16, bottom: 10, right: 16)
let topStrokeView = UIView()
topStrokeView.backgroundColor = Theme.hairlineColor
addSubview(topStrokeView)
topStrokeView.autoPinEdgesToSuperviewEdges(with: .zero, excludingEdge: .bottom)
topStrokeView.autoSetDimension(.height, toSize: CGHairlineWidth())
let stackView = UIStackView(arrangedSubviews: [labelScrollView, proceedButton])
stackView.spacing = 12
stackView.alignment = .center
addSubview(stackView)
stackView.autoPinEdgesToSuperviewMargins()
updateContents()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public override var intrinsicContentSize: CGSize {
return CGSize.zero
}
// MARK: public
private var namesText: String? {
get {
return namesLabel.text
}
}
public func setNamesText(_ newValue: String?, animated: Bool) {
let changes = {
self.namesLabel.text = newValue
self.layoutIfNeeded()
let offset = max(0, self.labelScrollView.contentSize.width - self.labelScrollView.bounds.width)
let trailingEdge = CGPoint(x: offset, y: 0)
self.labelScrollView.setContentOffset(trailingEdge, animated: false)
}
if animated {
UIView.animate(withDuration: 0.1, animations: changes)
} else {
changes()
}
}
// MARK: private subviews
lazy var labelScrollView: UIScrollView = {
let scrollView = UIScrollView()
scrollView.showsHorizontalScrollIndicator = false
scrollView.addSubview(namesLabel)
namesLabel.autoPinEdgesToSuperviewEdges()
namesLabel.autoMatch(.height, to: .height, of: scrollView)
return scrollView
}()
lazy var namesLabel: UILabel = {
let label = UILabel()
label.font = UIFont.ows_dynamicTypeBody
label.textColor = Theme.secondaryTextAndIconColor
label.setContentHuggingLow()
return label
}()
lazy var proceedButton: OWSButton = {
let button = OWSButton.sendButton(imageName: proceedImageName) { [weak self] in
guard let self = self else { return }
self.delegate?.approvalFooterDelegateDidRequestProceed(self)
}
return button
}()
private var proceedImageName: String {
return approvalMode == .send ? "send-solid-24" : "arrow-right-24"
}
private func updateContents() {
proceedButton.setImage(imageName: proceedImageName)
}
}