Просмотр исходного кода

Fix AI Companion premium card gating.

Blur/lock AI Companion meeting cards for non-premium users and route clicks to the paywall.

Co-authored-by: Cursor <cursoragent@cursor.com>
huzaifahayat12 1 месяц назад
Родитель
Сommit
40a43b78e8
1 измененных файлов с 57 добавлено и 0 удалено
  1. 57 0
      meetings_app/ViewController.swift

+ 57 - 0
meetings_app/ViewController.swift

@@ -3235,6 +3235,59 @@ private extension ViewController {
3235 3235
             stack.bottomAnchor.constraint(equalTo: card.bottomAnchor, constant: -14)
3236 3236
         ])
3237 3237
 
3238
+        if !storeKitCoordinator.hasPremiumAccess {
3239
+            // Keep the content present (so layout stays stable), but visually lock it and route clicks to the paywall.
3240
+            notesButton.isEnabled = false
3241
+
3242
+            let lockOverlay = NSVisualEffectView()
3243
+            lockOverlay.translatesAutoresizingMaskIntoConstraints = false
3244
+            lockOverlay.material = darkModeEnabled ? .hudWindow : .popover
3245
+            lockOverlay.blendingMode = .withinWindow
3246
+            lockOverlay.state = .active
3247
+            lockOverlay.wantsLayer = true
3248
+            lockOverlay.layer?.cornerRadius = 14
3249
+            lockOverlay.layer?.masksToBounds = true
3250
+            lockOverlay.layer?.backgroundColor = NSColor.black.withAlphaComponent(darkModeEnabled ? 0.30 : 0.12).cgColor
3251
+            card.addSubview(lockOverlay)
3252
+
3253
+            let message = textLabel(
3254
+                "Premium required. Click to unlock AI Companion notes.",
3255
+                font: NSFont.systemFont(ofSize: 13, weight: .semibold),
3256
+                color: darkModeEnabled ? .white : .black
3257
+            )
3258
+            message.alignment = .center
3259
+            message.maximumNumberOfLines = 2
3260
+            message.lineBreakMode = .byWordWrapping
3261
+            lockOverlay.addSubview(message)
3262
+
3263
+            let hit = HoverTrackingView()
3264
+            hit.translatesAutoresizingMaskIntoConstraints = false
3265
+            hit.wantsLayer = true
3266
+            hit.layer?.backgroundColor = NSColor.clear.cgColor
3267
+            hit.onClick = { [weak self] in
3268
+                self?.showPaywall()
3269
+            }
3270
+            hit.toolTip = "Premium required. Click to open paywall."
3271
+            lockOverlay.addSubview(hit)
3272
+
3273
+            NSLayoutConstraint.activate([
3274
+                lockOverlay.leadingAnchor.constraint(equalTo: card.leadingAnchor),
3275
+                lockOverlay.trailingAnchor.constraint(equalTo: card.trailingAnchor),
3276
+                lockOverlay.topAnchor.constraint(equalTo: card.topAnchor),
3277
+                lockOverlay.bottomAnchor.constraint(equalTo: card.bottomAnchor),
3278
+
3279
+                message.centerXAnchor.constraint(equalTo: lockOverlay.centerXAnchor),
3280
+                message.centerYAnchor.constraint(equalTo: lockOverlay.centerYAnchor),
3281
+                message.leadingAnchor.constraint(greaterThanOrEqualTo: lockOverlay.leadingAnchor, constant: 18),
3282
+                message.trailingAnchor.constraint(lessThanOrEqualTo: lockOverlay.trailingAnchor, constant: -18),
3283
+
3284
+                hit.leadingAnchor.constraint(equalTo: lockOverlay.leadingAnchor),
3285
+                hit.trailingAnchor.constraint(equalTo: lockOverlay.trailingAnchor),
3286
+                hit.topAnchor.constraint(equalTo: lockOverlay.topAnchor),
3287
+                hit.bottomAnchor.constraint(equalTo: lockOverlay.bottomAnchor)
3288
+            ])
3289
+        }
3290
+
3238 3291
         return card
3239 3292
     }
3240 3293
 
@@ -3706,6 +3759,10 @@ private extension ViewController {
3706 3759
     }
3707 3760
 
3708 3761
     @objc private func aiCompanionNotesTapped(_ sender: NSButton) {
3762
+        guard storeKitCoordinator.hasPremiumAccess else {
3763
+            showPaywall()
3764
+            return
3765
+        }
3709 3766
         let senderId = ObjectIdentifier(sender)
3710 3767
         guard let meetingId = aiCompanionNotesMeetingIdByView[senderId] else { return }
3711 3768
         guard let recording = aiCompanionLocalRecordings.first(where: { $0.id == meetingId }) else {