|
@@ -497,6 +497,12 @@ private extension ViewController {
|
|
|
updatePaywallPlanSelection()
|
|
updatePaywallPlanSelection()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ @objc private func paywallPlanButtonClicked(_ sender: NSButton) {
|
|
|
|
|
+ guard let plan = PremiumPlan(rawValue: sender.tag) else { return }
|
|
|
|
|
+ selectedPremiumPlan = plan
|
|
|
|
|
+ updatePaywallPlanSelection()
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private func updatePaywallPlanSelection() {
|
|
private func updatePaywallPlanSelection() {
|
|
|
for (plan, view) in paywallPlanViews {
|
|
for (plan, view) in paywallPlanViews {
|
|
|
applyPaywallPlanStyle(view, isSelected: plan == selectedPremiumPlan)
|
|
applyPaywallPlanStyle(view, isSelected: plan == selectedPremiumPlan)
|
|
@@ -1219,13 +1225,21 @@ private extension ViewController {
|
|
|
plan: PremiumPlan,
|
|
plan: PremiumPlan,
|
|
|
strikePrice: String?
|
|
strikePrice: String?
|
|
|
) -> NSView {
|
|
) -> NSView {
|
|
|
- let wrapper = HoverTrackingView()
|
|
|
|
|
|
|
+ let wrapper = HoverButton(title: "", target: self, action: #selector(paywallPlanButtonClicked(_:)))
|
|
|
wrapper.translatesAutoresizingMaskIntoConstraints = false
|
|
wrapper.translatesAutoresizingMaskIntoConstraints = false
|
|
|
|
|
+ wrapper.isBordered = false
|
|
|
|
|
+ wrapper.bezelStyle = .regularSquare
|
|
|
|
|
+ wrapper.wantsLayer = true
|
|
|
|
|
+ wrapper.layer?.backgroundColor = NSColor.clear.cgColor
|
|
|
wrapper.widthAnchor.constraint(greaterThanOrEqualToConstant: paywallContentWidth).isActive = true
|
|
wrapper.widthAnchor.constraint(greaterThanOrEqualToConstant: paywallContentWidth).isActive = true
|
|
|
wrapper.heightAnchor.constraint(equalToConstant: 94).isActive = true
|
|
wrapper.heightAnchor.constraint(equalToConstant: 94).isActive = true
|
|
|
|
|
+ wrapper.tag = plan.rawValue
|
|
|
|
|
|
|
|
- let card = roundedContainer(cornerRadius: 16, color: palette.sectionCard)
|
|
|
|
|
|
|
+ let card = HoverTrackingView()
|
|
|
card.translatesAutoresizingMaskIntoConstraints = false
|
|
card.translatesAutoresizingMaskIntoConstraints = false
|
|
|
|
|
+ card.wantsLayer = true
|
|
|
|
|
+ card.layer?.cornerRadius = 16
|
|
|
|
|
+ card.layer?.backgroundColor = palette.sectionCard.cgColor
|
|
|
card.heightAnchor.constraint(equalToConstant: 82).isActive = true
|
|
card.heightAnchor.constraint(equalToConstant: 82).isActive = true
|
|
|
wrapper.addSubview(card)
|
|
wrapper.addSubview(card)
|
|
|
NSLayoutConstraint.activate([
|
|
NSLayoutConstraint.activate([
|
|
@@ -1289,9 +1303,6 @@ private extension ViewController {
|
|
|
])
|
|
])
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- let click = NSClickGestureRecognizer(target: self, action: #selector(paywallPlanClicked(_:)))
|
|
|
|
|
- wrapper.addGestureRecognizer(click)
|
|
|
|
|
- premiumPlanByView[ObjectIdentifier(wrapper)] = plan
|
|
|
|
|
paywallPlanViews[plan] = card
|
|
paywallPlanViews[plan] = card
|
|
|
wrapper.onHoverChanged = { [weak self, weak card] hovering in
|
|
wrapper.onHoverChanged = { [weak self, weak card] hovering in
|
|
|
guard let self, let card else { return }
|
|
guard let self, let card else { return }
|
|
@@ -1383,8 +1394,11 @@ private extension ViewController {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func paywallBenefitItem(icon: String, text: String) -> NSView {
|
|
func paywallBenefitItem(icon: String, text: String) -> NSView {
|
|
|
- let card = roundedContainer(cornerRadius: 10, color: palette.inputBackground)
|
|
|
|
|
|
|
+ let card = HoverTrackingView()
|
|
|
card.translatesAutoresizingMaskIntoConstraints = false
|
|
card.translatesAutoresizingMaskIntoConstraints = false
|
|
|
|
|
+ card.wantsLayer = true
|
|
|
|
|
+ card.layer?.cornerRadius = 10
|
|
|
|
|
+ card.layer?.backgroundColor = palette.inputBackground.cgColor
|
|
|
card.heightAnchor.constraint(equalToConstant: 36).isActive = true
|
|
card.heightAnchor.constraint(equalToConstant: 36).isActive = true
|
|
|
styleSurface(card, borderColor: palette.inputBorder, borderWidth: 1, shadow: false)
|
|
styleSurface(card, borderColor: palette.inputBorder, borderWidth: 1, shadow: false)
|
|
|
|
|
|
|
@@ -1412,6 +1426,18 @@ private extension ViewController {
|
|
|
title.centerYAnchor.constraint(equalTo: card.centerYAnchor),
|
|
title.centerYAnchor.constraint(equalTo: card.centerYAnchor),
|
|
|
title.trailingAnchor.constraint(lessThanOrEqualTo: card.trailingAnchor, constant: -8)
|
|
title.trailingAnchor.constraint(lessThanOrEqualTo: card.trailingAnchor, constant: -8)
|
|
|
])
|
|
])
|
|
|
|
|
+
|
|
|
|
|
+ let base = palette.inputBackground
|
|
|
|
|
+ let hoverBlend = darkModeEnabled ? NSColor.white : NSColor.black
|
|
|
|
|
+ let hover = base.blended(withFraction: 0.10, of: hoverBlend) ?? base
|
|
|
|
|
+ let hoverBorder = palette.primaryBlueBorder.withAlphaComponent(0.55)
|
|
|
|
|
+ card.onHoverChanged = { [weak card, weak iconWrap] hovering in
|
|
|
|
|
+ guard let card else { return }
|
|
|
|
|
+ card.layer?.backgroundColor = (hovering ? hover : base).cgColor
|
|
|
|
|
+ card.layer?.borderColor = (hovering ? hoverBorder : self.palette.inputBorder).cgColor
|
|
|
|
|
+ iconWrap?.layer?.borderColor = (hovering ? hoverBorder : self.palette.inputBorder).cgColor
|
|
|
|
|
+ }
|
|
|
|
|
+ card.onHoverChanged?(false)
|
|
|
return card
|
|
return card
|
|
|
}
|
|
}
|
|
|
|
|
|