Kaynağa Gözat

Make paywall plan cards reliably selectable

Replace gesture-based plan card wrappers with borderless NSButton wrappers (HoverButton) and handle selection via button tags, keeping existing hover/selected styling.

Made-with: Cursor
huzaifahayat12 1 hafta önce
ebeveyn
işleme
ff21fc441a
1 değiştirilmiş dosya ile 32 ekleme ve 6 silme
  1. 32 6
      meetings_app/ViewController.swift

+ 32 - 6
meetings_app/ViewController.swift

@@ -497,6 +497,12 @@ private extension ViewController {
497
         updatePaywallPlanSelection()
497
         updatePaywallPlanSelection()
498
     }
498
     }
499
 
499
 
500
+    @objc private func paywallPlanButtonClicked(_ sender: NSButton) {
501
+        guard let plan = PremiumPlan(rawValue: sender.tag) else { return }
502
+        selectedPremiumPlan = plan
503
+        updatePaywallPlanSelection()
504
+    }
505
+
500
     private func updatePaywallPlanSelection() {
506
     private func updatePaywallPlanSelection() {
501
         for (plan, view) in paywallPlanViews {
507
         for (plan, view) in paywallPlanViews {
502
             applyPaywallPlanStyle(view, isSelected: plan == selectedPremiumPlan)
508
             applyPaywallPlanStyle(view, isSelected: plan == selectedPremiumPlan)
@@ -1219,13 +1225,21 @@ private extension ViewController {
1219
         plan: PremiumPlan,
1225
         plan: PremiumPlan,
1220
         strikePrice: String?
1226
         strikePrice: String?
1221
     ) -> NSView {
1227
     ) -> NSView {
1222
-        let wrapper = HoverTrackingView()
1228
+        let wrapper = HoverButton(title: "", target: self, action: #selector(paywallPlanButtonClicked(_:)))
1223
         wrapper.translatesAutoresizingMaskIntoConstraints = false
1229
         wrapper.translatesAutoresizingMaskIntoConstraints = false
1230
+        wrapper.isBordered = false
1231
+        wrapper.bezelStyle = .regularSquare
1232
+        wrapper.wantsLayer = true
1233
+        wrapper.layer?.backgroundColor = NSColor.clear.cgColor
1224
         wrapper.widthAnchor.constraint(greaterThanOrEqualToConstant: paywallContentWidth).isActive = true
1234
         wrapper.widthAnchor.constraint(greaterThanOrEqualToConstant: paywallContentWidth).isActive = true
1225
         wrapper.heightAnchor.constraint(equalToConstant: 94).isActive = true
1235
         wrapper.heightAnchor.constraint(equalToConstant: 94).isActive = true
1236
+        wrapper.tag = plan.rawValue
1226
 
1237
 
1227
-        let card = roundedContainer(cornerRadius: 16, color: palette.sectionCard)
1238
+        let card = HoverTrackingView()
1228
         card.translatesAutoresizingMaskIntoConstraints = false
1239
         card.translatesAutoresizingMaskIntoConstraints = false
1240
+        card.wantsLayer = true
1241
+        card.layer?.cornerRadius = 16
1242
+        card.layer?.backgroundColor = palette.sectionCard.cgColor
1229
         card.heightAnchor.constraint(equalToConstant: 82).isActive = true
1243
         card.heightAnchor.constraint(equalToConstant: 82).isActive = true
1230
         wrapper.addSubview(card)
1244
         wrapper.addSubview(card)
1231
         NSLayoutConstraint.activate([
1245
         NSLayoutConstraint.activate([
@@ -1289,9 +1303,6 @@ private extension ViewController {
1289
             ])
1303
             ])
1290
         }
1304
         }
1291
 
1305
 
1292
-        let click = NSClickGestureRecognizer(target: self, action: #selector(paywallPlanClicked(_:)))
1293
-        wrapper.addGestureRecognizer(click)
1294
-        premiumPlanByView[ObjectIdentifier(wrapper)] = plan
1295
         paywallPlanViews[plan] = card
1306
         paywallPlanViews[plan] = card
1296
         wrapper.onHoverChanged = { [weak self, weak card] hovering in
1307
         wrapper.onHoverChanged = { [weak self, weak card] hovering in
1297
             guard let self, let card else { return }
1308
             guard let self, let card else { return }
@@ -1383,8 +1394,11 @@ private extension ViewController {
1383
     }
1394
     }
1384
 
1395
 
1385
     func paywallBenefitItem(icon: String, text: String) -> NSView {
1396
     func paywallBenefitItem(icon: String, text: String) -> NSView {
1386
-        let card = roundedContainer(cornerRadius: 10, color: palette.inputBackground)
1397
+        let card = HoverTrackingView()
1387
         card.translatesAutoresizingMaskIntoConstraints = false
1398
         card.translatesAutoresizingMaskIntoConstraints = false
1399
+        card.wantsLayer = true
1400
+        card.layer?.cornerRadius = 10
1401
+        card.layer?.backgroundColor = palette.inputBackground.cgColor
1388
         card.heightAnchor.constraint(equalToConstant: 36).isActive = true
1402
         card.heightAnchor.constraint(equalToConstant: 36).isActive = true
1389
         styleSurface(card, borderColor: palette.inputBorder, borderWidth: 1, shadow: false)
1403
         styleSurface(card, borderColor: palette.inputBorder, borderWidth: 1, shadow: false)
1390
 
1404
 
@@ -1412,6 +1426,18 @@ private extension ViewController {
1412
             title.centerYAnchor.constraint(equalTo: card.centerYAnchor),
1426
             title.centerYAnchor.constraint(equalTo: card.centerYAnchor),
1413
             title.trailingAnchor.constraint(lessThanOrEqualTo: card.trailingAnchor, constant: -8)
1427
             title.trailingAnchor.constraint(lessThanOrEqualTo: card.trailingAnchor, constant: -8)
1414
         ])
1428
         ])
1429
+
1430
+        let base = palette.inputBackground
1431
+        let hoverBlend = darkModeEnabled ? NSColor.white : NSColor.black
1432
+        let hover = base.blended(withFraction: 0.10, of: hoverBlend) ?? base
1433
+        let hoverBorder = palette.primaryBlueBorder.withAlphaComponent(0.55)
1434
+        card.onHoverChanged = { [weak card, weak iconWrap] hovering in
1435
+            guard let card else { return }
1436
+            card.layer?.backgroundColor = (hovering ? hover : base).cgColor
1437
+            card.layer?.borderColor = (hovering ? hoverBorder : self.palette.inputBorder).cgColor
1438
+            iconWrap?.layer?.borderColor = (hovering ? hoverBorder : self.palette.inputBorder).cgColor
1439
+        }
1440
+        card.onHoverChanged?(false)
1415
         return card
1441
         return card
1416
     }
1442
     }
1417
 
1443