|
|
@@ -280,12 +280,12 @@ class ViewController: NSViewController {
|
|
|
private weak var joinIDFieldsContainer: NSView?
|
|
|
private weak var joinModeSegment: NSSegmentedControl?
|
|
|
private let paywallContentWidth: CGFloat = 520
|
|
|
- private var selectedPremiumPlan: PremiumPlan = .monthly
|
|
|
- private var paywallPlanViews: [PremiumPlan: NSView] = [:]
|
|
|
+ private var selectedPremiumPlan: PremiumPlan = .yearly
|
|
|
+ private var paywallPlanViews: [PremiumPlan: [NSView]] = [:]
|
|
|
private var premiumPlanByView = [ObjectIdentifier: PremiumPlan]()
|
|
|
- private var paywallPlanPriceLabels: [PremiumPlan: NSTextField] = [:]
|
|
|
- private var paywallPlanSubtitleLabels: [PremiumPlan: NSTextField] = [:]
|
|
|
- private var paywallPlanStrikeLabels: [PremiumPlan: NSTextField] = [:]
|
|
|
+ private var paywallPlanPriceLabels: [PremiumPlan: [NSTextField]] = [:]
|
|
|
+ private var paywallPlanSubtitleLabels: [PremiumPlan: [NSTextField]] = [:]
|
|
|
+ private var paywallPlanStrikeLabels: [PremiumPlan: [NSTextField]] = [:]
|
|
|
private weak var paywallOfferLabel: NSTextField?
|
|
|
private weak var paywallContinueLabel: NSTextField?
|
|
|
private weak var paywallContinueButton: NSView?
|
|
|
@@ -3931,6 +3931,11 @@ class ViewController: NSViewController {
|
|
|
updatePaywallPlanSelection()
|
|
|
planColumn.setCustomSpacing(16, after: plansGridNarrow)
|
|
|
|
|
|
+ let trustRow = paywallTrustRow()
|
|
|
+ planColumn.addArrangedSubview(trustRow)
|
|
|
+ trustRow.widthAnchor.constraint(equalTo: planColumn.widthAnchor).isActive = true
|
|
|
+ planColumn.setCustomSpacing(14, after: trustRow)
|
|
|
+
|
|
|
let offer = textLabel(paywallOfferText(for: selectedPremiumPlan), font: NSFont.systemFont(ofSize: 13, weight: .semibold), color: primaryText)
|
|
|
offer.alignment = .center
|
|
|
paywallOfferLabel = offer
|
|
|
@@ -3946,11 +3951,6 @@ class ViewController: NSViewController {
|
|
|
offerWrap.widthAnchor.constraint(equalTo: planColumn.widthAnchor).isActive = true
|
|
|
planColumn.setCustomSpacing(14, after: offerWrap)
|
|
|
|
|
|
- let trustRow = paywallTrustRow()
|
|
|
- planColumn.addArrangedSubview(trustRow)
|
|
|
- trustRow.widthAnchor.constraint(equalTo: planColumn.widthAnchor).isActive = true
|
|
|
- planColumn.setCustomSpacing(14, after: trustRow)
|
|
|
-
|
|
|
let continueButton = HoverButton(title: "", target: self, action: #selector(paywallContinueClicked(_:)))
|
|
|
continueButton.translatesAutoresizingMaskIntoConstraints = false
|
|
|
continueButton.isBordered = false
|
|
|
@@ -3959,7 +3959,7 @@ class ViewController: NSViewController {
|
|
|
continueButton.layer?.cornerRadius = 14
|
|
|
continueButton.normalColor = NSColor(calibratedRed: 0.16, green: 0.49, blue: 0.98, alpha: 1)
|
|
|
continueButton.hoverColor = NSColor(calibratedRed: 0.16, green: 0.49, blue: 0.98, alpha: 0.92)
|
|
|
- continueButton.heightAnchor.constraint(equalToConstant: 44).isActive = true
|
|
|
+ continueButton.heightAnchor.constraint(equalToConstant: 36).isActive = true
|
|
|
styleSurface(continueButton, borderColor: NSColor.black.withAlphaComponent(0.12), borderWidth: 1, shadow: true)
|
|
|
let continueLabel = textLabel("Continue", font: NSFont.systemFont(ofSize: 16, weight: .bold), color: .white)
|
|
|
continueButton.addSubview(continueLabel)
|
|
|
@@ -3969,9 +3969,19 @@ class ViewController: NSViewController {
|
|
|
])
|
|
|
paywallContinueButton = continueButton
|
|
|
paywallContinueLabel = continueLabel
|
|
|
- planColumn.addArrangedSubview(continueButton)
|
|
|
- continueButton.widthAnchor.constraint(equalTo: planColumn.widthAnchor).isActive = true
|
|
|
- planColumn.setCustomSpacing(16, after: continueButton)
|
|
|
+ let continueButtonWrap = NSView()
|
|
|
+ continueButtonWrap.translatesAutoresizingMaskIntoConstraints = false
|
|
|
+ continueButtonWrap.addSubview(continueButton)
|
|
|
+ planColumn.addArrangedSubview(continueButtonWrap)
|
|
|
+ NSLayoutConstraint.activate([
|
|
|
+ continueButtonWrap.widthAnchor.constraint(equalTo: planColumn.widthAnchor),
|
|
|
+ continueButton.topAnchor.constraint(equalTo: continueButtonWrap.topAnchor),
|
|
|
+ continueButton.bottomAnchor.constraint(equalTo: continueButtonWrap.bottomAnchor),
|
|
|
+ continueButton.centerXAnchor.constraint(equalTo: continueButtonWrap.centerXAnchor),
|
|
|
+ continueButton.widthAnchor.constraint(equalToConstant: 400),
|
|
|
+ continueButton.widthAnchor.constraint(lessThanOrEqualTo: continueButtonWrap.widthAnchor, constant: -40)
|
|
|
+ ])
|
|
|
+ planColumn.setCustomSpacing(16, after: continueButtonWrap)
|
|
|
|
|
|
let secure = textLabel("Secured by Apple. Cancel anytime.", font: NSFont.systemFont(ofSize: 12, weight: .semibold), color: secondaryText)
|
|
|
secure.alignment = .center
|
|
|
@@ -4319,7 +4329,7 @@ class ViewController: NSViewController {
|
|
|
card.addSubview(titleLabel)
|
|
|
let priceLabel = textLabel(price, font: NSFont.systemFont(ofSize: 15, weight: .bold), color: primaryText)
|
|
|
card.addSubview(priceLabel)
|
|
|
- paywallPlanPriceLabels[plan] = priceLabel
|
|
|
+ paywallPlanPriceLabels[plan, default: []].append(priceLabel)
|
|
|
|
|
|
NSLayoutConstraint.activate([
|
|
|
badgeWrap.leadingAnchor.constraint(equalTo: card.leadingAnchor, constant: 14),
|
|
|
@@ -4335,7 +4345,7 @@ class ViewController: NSViewController {
|
|
|
if let subtitle {
|
|
|
let sub = textLabel(subtitle, font: NSFont.systemFont(ofSize: 11, weight: .regular), color: secondaryText)
|
|
|
card.addSubview(sub)
|
|
|
- paywallPlanSubtitleLabels[plan] = sub
|
|
|
+ paywallPlanSubtitleLabels[plan, default: []].append(sub)
|
|
|
NSLayoutConstraint.activate([
|
|
|
sub.leadingAnchor.constraint(equalTo: priceLabel.leadingAnchor),
|
|
|
sub.topAnchor.constraint(equalTo: priceLabel.bottomAnchor, constant: 2),
|
|
|
@@ -4346,14 +4356,14 @@ class ViewController: NSViewController {
|
|
|
if let strikePrice {
|
|
|
let strike = textLabel(strikePrice, font: NSFont.systemFont(ofSize: 12, weight: .medium), color: NSColor.systemRed)
|
|
|
card.addSubview(strike)
|
|
|
- paywallPlanStrikeLabels[plan] = strike
|
|
|
+ paywallPlanStrikeLabels[plan, default: []].append(strike)
|
|
|
NSLayoutConstraint.activate([
|
|
|
strike.trailingAnchor.constraint(equalTo: priceLabel.trailingAnchor),
|
|
|
strike.topAnchor.constraint(equalTo: priceLabel.bottomAnchor, constant: 4)
|
|
|
])
|
|
|
}
|
|
|
|
|
|
- paywallPlanViews[plan] = card
|
|
|
+ paywallPlanViews[plan, default: []].append(card)
|
|
|
premiumPlanByView[ObjectIdentifier(card)] = plan
|
|
|
wrapper.onHoverChanged = { [weak self, weak card] hovering in
|
|
|
guard let self, let card else { return }
|
|
|
@@ -4370,8 +4380,10 @@ class ViewController: NSViewController {
|
|
|
}
|
|
|
|
|
|
private func updatePaywallPlanSelection() {
|
|
|
- for (plan, view) in paywallPlanViews {
|
|
|
- applyPaywallPlanStyle(view, isSelected: plan == selectedPremiumPlan)
|
|
|
+ for (plan, views) in paywallPlanViews {
|
|
|
+ for view in views {
|
|
|
+ applyPaywallPlanStyle(view, isSelected: plan == selectedPremiumPlan)
|
|
|
+ }
|
|
|
}
|
|
|
paywallOfferLabel?.stringValue = paywallOfferText(for: selectedPremiumPlan)
|
|
|
updatePaywallContinueState(isLoading: false)
|
|
|
@@ -4398,7 +4410,8 @@ class ViewController: NSViewController {
|
|
|
|
|
|
private func refreshPaywallPlanPrices() {
|
|
|
for plan in PremiumPlan.allCases {
|
|
|
- paywallPlanPriceLabels[plan]?.stringValue = paywallDisplayPrice(for: plan)
|
|
|
+ let price = paywallDisplayPrice(for: plan)
|
|
|
+ paywallPlanPriceLabels[plan]?.forEach { $0.stringValue = price }
|
|
|
}
|
|
|
}
|
|
|
|