Переглянути джерело

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 тиждень тому
батько
коміт
ff21fc441a
1 змінених файлів з 32 додано та 6 видалено
  1. 32 6
      meetings_app/ViewController.swift

+ 32 - 6
meetings_app/ViewController.swift

@@ -497,6 +497,12 @@ private extension ViewController {
497 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 506
     private func updatePaywallPlanSelection() {
501 507
         for (plan, view) in paywallPlanViews {
502 508
             applyPaywallPlanStyle(view, isSelected: plan == selectedPremiumPlan)
@@ -1219,13 +1225,21 @@ private extension ViewController {
1219 1225
         plan: PremiumPlan,
1220 1226
         strikePrice: String?
1221 1227
     ) -> NSView {
1222
-        let wrapper = HoverTrackingView()
1228
+        let wrapper = HoverButton(title: "", target: self, action: #selector(paywallPlanButtonClicked(_:)))
1223 1229
         wrapper.translatesAutoresizingMaskIntoConstraints = false
1230
+        wrapper.isBordered = false
1231
+        wrapper.bezelStyle = .regularSquare
1232
+        wrapper.wantsLayer = true
1233
+        wrapper.layer?.backgroundColor = NSColor.clear.cgColor
1224 1234
         wrapper.widthAnchor.constraint(greaterThanOrEqualToConstant: paywallContentWidth).isActive = true
1225 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 1239
         card.translatesAutoresizingMaskIntoConstraints = false
1240
+        card.wantsLayer = true
1241
+        card.layer?.cornerRadius = 16
1242
+        card.layer?.backgroundColor = palette.sectionCard.cgColor
1229 1243
         card.heightAnchor.constraint(equalToConstant: 82).isActive = true
1230 1244
         wrapper.addSubview(card)
1231 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 1306
         paywallPlanViews[plan] = card
1296 1307
         wrapper.onHoverChanged = { [weak self, weak card] hovering in
1297 1308
             guard let self, let card else { return }
@@ -1383,8 +1394,11 @@ private extension ViewController {
1383 1394
     }
1384 1395
 
1385 1396
     func paywallBenefitItem(icon: String, text: String) -> NSView {
1386
-        let card = roundedContainer(cornerRadius: 10, color: palette.inputBackground)
1397
+        let card = HoverTrackingView()
1387 1398
         card.translatesAutoresizingMaskIntoConstraints = false
1399
+        card.wantsLayer = true
1400
+        card.layer?.cornerRadius = 10
1401
+        card.layer?.backgroundColor = palette.inputBackground.cgColor
1388 1402
         card.heightAnchor.constraint(equalToConstant: 36).isActive = true
1389 1403
         styleSurface(card, borderColor: palette.inputBorder, borderWidth: 1, shadow: false)
1390 1404
 
@@ -1412,6 +1426,18 @@ private extension ViewController {
1412 1426
             title.centerYAnchor.constraint(equalTo: card.centerYAnchor),
1413 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 1441
         return card
1416 1442
     }
1417 1443