mirror of
https://github.com/lux-tel/session-ios.git
synced 2026-10-30 20:38:32 +00:00
198 lines
6.9 KiB
Swift
198 lines
6.9 KiB
Swift
// Copyright © 2025 Rangeproof Pty Ltd. All rights reserved.
|
|
|
|
import UIKit
|
|
import SessionUIKit
|
|
|
|
class AppReviewPromptDialog: UIView {
|
|
var onCloseTapped: (() -> Void)?
|
|
var onPrimaryTapped: ((AppReviewPromptState) -> Void)?
|
|
var onSecondaryTapped: ((AppReviewPromptState) -> Void)?
|
|
|
|
private static let closeSize: CGFloat = 24
|
|
|
|
private lazy var closeButton: UIButton = UIButton(primaryAction: UIAction { [weak self] _ in self?.close() })
|
|
.withConfiguration(
|
|
UIButton.Configuration
|
|
.plain()
|
|
.withImage(UIImage(named: "X")?.withRenderingMode(.alwaysTemplate))
|
|
.withContentInsets(NSDirectionalEdgeInsets(top: 6, leading: 6, bottom: 6, trailing: 6))
|
|
)
|
|
.withConfigurationUpdateHandler { button in
|
|
switch button.state {
|
|
case .highlighted: button.imageView?.tintAdjustmentMode = .dimmed
|
|
default: button.imageView?.tintAdjustmentMode = .normal
|
|
}
|
|
}
|
|
.withImageViewContentMode(.scaleAspectFit)
|
|
.withThemeTintColor(.textPrimary)
|
|
.withAccessibility(
|
|
identifier: "Close button"
|
|
)
|
|
.with(.width, of: AppReviewPromptDialog.closeSize)
|
|
.with(.height, of: AppReviewPromptDialog.closeSize)
|
|
|
|
private lazy var titleLabel: UILabel = {
|
|
let result = UILabel()
|
|
result.textAlignment = .center
|
|
result.numberOfLines = 0
|
|
result.themeTextColor = .alert_text
|
|
result.font = .boldSystemFont(ofSize: Values.mediumFontSize)
|
|
|
|
return result
|
|
}()
|
|
|
|
private lazy var messageLabel: UILabel = {
|
|
let result = UILabel()
|
|
result.textAlignment = .center
|
|
result.numberOfLines = 0
|
|
result.themeTextColor = .alert_text
|
|
result.font = ConfirmationModal.explanationFont
|
|
|
|
return result
|
|
}()
|
|
|
|
private lazy var primaryButton: UIButton = {
|
|
let result = UIButton(type: .custom)
|
|
result.setThemeTitleColor(.sessionButton_text, for: .normal)
|
|
result.setThemeTitleColor(.highlighted(.sessionButton_text, alwaysDarken: false), for: .highlighted)
|
|
result.titleLabel?.font = .boldSystemFont(ofSize: Values.mediumFontSize)
|
|
result.titleLabel?.numberOfLines = 0
|
|
result.titleLabel?.textAlignment = .center
|
|
result.addTarget(self, action: #selector(primaryEvent), for: .touchUpInside)
|
|
|
|
return result
|
|
}()
|
|
|
|
private lazy var secondaryButton: UIButton = {
|
|
let result = UIButton(type: .custom)
|
|
result.setThemeTitleColor(.textPrimary, for: .normal)
|
|
result.setThemeTitleColor(.highlighted(.textPrimary, alwaysDarken: false), for: .highlighted)
|
|
result.titleLabel?.font = .boldSystemFont(ofSize: Values.mediumFontSize)
|
|
result.titleLabel?.numberOfLines = 0
|
|
result.titleLabel?.textAlignment = .center
|
|
result.addTarget(self, action: #selector(secondaryEvent), for: .touchUpInside)
|
|
|
|
return result
|
|
}()
|
|
|
|
private lazy var buttonStack: UIStackView = {
|
|
let result = UIStackView(arrangedSubviews: [
|
|
primaryButton,
|
|
secondaryButton
|
|
])
|
|
result.axis = .horizontal
|
|
result.distribution = .fillEqually
|
|
result.alignment = .fill
|
|
result.isLayoutMarginsRelativeArrangement = true
|
|
|
|
return result
|
|
}()
|
|
|
|
private lazy var contentStack: UIStackView = {
|
|
let result = UIStackView(arrangedSubviews: [
|
|
titleLabel,
|
|
messageLabel,
|
|
buttonStack
|
|
])
|
|
result.axis = .vertical
|
|
result.distribution = .fill
|
|
result.spacing = 8
|
|
result.isLayoutMarginsRelativeArrangement = true
|
|
result.layoutMargins = UIEdgeInsets(
|
|
top: Values.largeSpacing,
|
|
left: Values.veryLargeSpacing,
|
|
bottom: Values.verySmallSpacing,
|
|
right: Values.veryLargeSpacing
|
|
)
|
|
|
|
return result
|
|
}()
|
|
|
|
private var prompt: AppReviewPromptState?
|
|
|
|
override init(frame: CGRect) {
|
|
super.init(frame: frame)
|
|
|
|
setupHierarchy()
|
|
setupLayout()
|
|
|
|
setReviewPrompt(nil)
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
func setReviewPrompt(_ prompt: AppReviewPromptState?) {
|
|
self.prompt = prompt
|
|
|
|
isHidden = prompt == nil
|
|
|
|
titleLabel.text = prompt?.promptContent.title
|
|
titleLabel.accessibilityIdentifier = "Modal heading"
|
|
titleLabel.accessibilityLabel = titleLabel.text
|
|
|
|
messageLabel.text = prompt?.promptContent.message
|
|
messageLabel.accessibilityIdentifier = "Modal description"
|
|
messageLabel.accessibilityLabel = messageLabel.text
|
|
|
|
primaryButton.isHidden = prompt?.promptContent.primaryButtonTitle == nil
|
|
primaryButton.setTitle(prompt?.promptContent.primaryButtonTitle, for: .normal)
|
|
primaryButton.setThemeTitleColor(prompt?.promptContent.primaryButtonColor, for: .normal)
|
|
primaryButton.setThemeTitleColor(
|
|
(prompt?.promptContent.primaryButtonColor).map { .highlighted($0, alwaysDarken: false) },
|
|
for: .highlighted
|
|
)
|
|
primaryButton.accessibilityIdentifier = prompt?.promptContent.primaryButtonAccessibilityIdentifier
|
|
|
|
secondaryButton.isHidden = prompt?.promptContent.secondaryButtonTitle == nil
|
|
secondaryButton.setTitle(prompt?.promptContent.secondaryButtonTitle, for: .normal)
|
|
secondaryButton.setThemeTitleColor(prompt?.promptContent.secondaryButtonColor, for: .normal)
|
|
secondaryButton.setThemeTitleColor(
|
|
(prompt?.promptContent.secondaryButtonColor).map { .highlighted($0, alwaysDarken: false) },
|
|
for: .highlighted
|
|
)
|
|
secondaryButton.accessibilityIdentifier = prompt?.promptContent.secondaryButtonAccessibilityIdentifier
|
|
|
|
let isButtonsHidden = primaryButton.isHidden && secondaryButton.isHidden
|
|
|
|
buttonStack.layoutMargins = .init(
|
|
top: isButtonsHidden ? 0: Values.mediumSpacing,
|
|
left: 0,
|
|
bottom: Values.mediumSpacing,
|
|
right: 0
|
|
)
|
|
}
|
|
|
|
@objc
|
|
func close() {
|
|
onCloseTapped?()
|
|
}
|
|
|
|
@objc
|
|
func primaryEvent() {
|
|
let current = prompt ?? .enjoyingSession
|
|
onPrimaryTapped?(current)
|
|
}
|
|
|
|
@objc
|
|
func secondaryEvent() {
|
|
let current = prompt ?? .enjoyingSession
|
|
onSecondaryTapped?(current)
|
|
}
|
|
}
|
|
|
|
private extension AppReviewPromptDialog {
|
|
func setupHierarchy() {
|
|
addSubview(contentStack)
|
|
addSubview(closeButton)
|
|
}
|
|
|
|
func setupLayout() {
|
|
closeButton.pin(.top, to: .top, of: self, withInset: Values.smallSpacing)
|
|
closeButton.pin(.right, to: .right, of: self, withInset: -Values.smallSpacing)
|
|
|
|
contentStack.pin(to: self)
|
|
}
|
|
}
|