瀏覽代碼

Make the paywall a full-window overlay with blurred background.

Hide window traffic lights while the paywall is shown so the premium screen matches the app size and feels like a dedicated full-screen state.

Co-authored-by: Cursor <cursoragent@cursor.com>
AhtashamShahzad1 1 月之前
父節點
當前提交
5e11cd0e2c
共有 2 個文件被更改,包括 68 次插入35 次删除
  1. 36 15
      smart_printer/PaywallView.swift
  2. 32 20
      smart_printer/ViewController.swift

+ 36 - 15
smart_printer/PaywallView.swift

@@ -351,8 +351,7 @@ final class PaywallView: NSView {
         translatesAutoresizingMaskIntoConstraints = false
         wantsLayer = true
         layer?.backgroundColor = NSColor.white.cgColor
-        layer?.cornerRadius = 20
-        applyCardShadow()
+        layer?.cornerRadius = 0
         setup()
     }
 
@@ -367,9 +366,6 @@ final class PaywallView: NSView {
         addSubview(rightPanel)
 
         NSLayoutConstraint.activate([
-            widthAnchor.constraint(equalToConstant: 780),
-            heightAnchor.constraint(equalToConstant: 500),
-
             leftPanel.leadingAnchor.constraint(equalTo: leadingAnchor),
             leftPanel.topAnchor.constraint(equalTo: topAnchor),
             leftPanel.bottomAnchor.constraint(equalTo: bottomAnchor),
@@ -574,6 +570,7 @@ final class PaywallOverlayView: NSView {
     var onDismiss: (() -> Void)?
 
     private let paywallView: PaywallView
+    private let blurView = NSVisualEffectView()
     private let backdrop = NSView()
 
     init() {
@@ -587,9 +584,14 @@ final class PaywallOverlayView: NSView {
     required init?(coder: NSCoder) { nil }
 
     private func setup() {
+        blurView.translatesAutoresizingMaskIntoConstraints = false
+        blurView.material = .underWindowBackground
+        blurView.blendingMode = .withinWindow
+        blurView.state = .active
+
         backdrop.translatesAutoresizingMaskIntoConstraints = false
         backdrop.wantsLayer = true
-        backdrop.layer?.backgroundColor = NSColor(calibratedWhite: 0.15, alpha: 0.45).cgColor
+        backdrop.layer?.backgroundColor = NSColor(calibratedWhite: 0.15, alpha: 0.22).cgColor
 
         let pattern = WavePatternView()
         pattern.translatesAutoresizingMaskIntoConstraints = false
@@ -604,11 +606,17 @@ final class PaywallOverlayView: NSView {
             NSLog("Restore purchases tapped")
         }
 
+        addSubview(blurView)
         addSubview(backdrop)
         backdrop.addSubview(pattern)
         addSubview(paywallView)
 
         NSLayoutConstraint.activate([
+            blurView.leadingAnchor.constraint(equalTo: leadingAnchor),
+            blurView.trailingAnchor.constraint(equalTo: trailingAnchor),
+            blurView.topAnchor.constraint(equalTo: topAnchor),
+            blurView.bottomAnchor.constraint(equalTo: bottomAnchor),
+
             backdrop.leadingAnchor.constraint(equalTo: leadingAnchor),
             backdrop.trailingAnchor.constraint(equalTo: trailingAnchor),
             backdrop.topAnchor.constraint(equalTo: topAnchor),
@@ -619,20 +627,33 @@ final class PaywallOverlayView: NSView {
             pattern.topAnchor.constraint(equalTo: backdrop.topAnchor),
             pattern.bottomAnchor.constraint(equalTo: backdrop.bottomAnchor),
 
-            paywallView.centerXAnchor.constraint(equalTo: centerXAnchor),
-            paywallView.centerYAnchor.constraint(equalTo: centerYAnchor),
+            paywallView.leadingAnchor.constraint(equalTo: leadingAnchor),
+            paywallView.trailingAnchor.constraint(equalTo: trailingAnchor),
+            paywallView.topAnchor.constraint(equalTo: topAnchor),
+            paywallView.bottomAnchor.constraint(equalTo: bottomAnchor),
         ])
     }
 
     func present(in parent: NSView) {
         guard superview == nil else { return }
-        parent.addSubview(self)
-        NSLayoutConstraint.activate([
-            leadingAnchor.constraint(equalTo: parent.leadingAnchor),
-            trailingAnchor.constraint(equalTo: parent.trailingAnchor),
-            topAnchor.constraint(equalTo: parent.topAnchor),
-            bottomAnchor.constraint(equalTo: parent.bottomAnchor),
-        ])
+        if let window = parent.window,
+           let windowFrameView = window.contentView?.superview {
+            windowFrameView.addSubview(self)
+            NSLayoutConstraint.activate([
+                leadingAnchor.constraint(equalTo: windowFrameView.leadingAnchor),
+                trailingAnchor.constraint(equalTo: windowFrameView.trailingAnchor),
+                topAnchor.constraint(equalTo: windowFrameView.topAnchor),
+                bottomAnchor.constraint(equalTo: windowFrameView.bottomAnchor),
+            ])
+        } else {
+            parent.addSubview(self)
+            NSLayoutConstraint.activate([
+                leadingAnchor.constraint(equalTo: parent.leadingAnchor),
+                trailingAnchor.constraint(equalTo: parent.trailingAnchor),
+                topAnchor.constraint(equalTo: parent.topAnchor),
+                bottomAnchor.constraint(equalTo: parent.bottomAnchor),
+            ])
+        }
         alphaValue = 0
         NSAnimationContext.runAnimationGroup { context in
             context.duration = 0.2

+ 32 - 20
smart_printer/ViewController.swift

@@ -8,6 +8,7 @@ import Cocoa
 class ViewController: NSViewController {
 
     private var sidebar: SidebarView!
+    private var mainContentView: NSView!
     private var homeContentView: NSView!
     private var scanContentView: NSView!
     private var scanAndHomeContentView: NSView!
@@ -30,10 +31,10 @@ class ViewController: NSViewController {
     private func setupLayout() {
         sidebar = SidebarView()
 
-        let mainContent = NSView()
-        mainContent.translatesAutoresizingMaskIntoConstraints = false
-        mainContent.wantsLayer = true
-        mainContent.layer?.backgroundColor = AppTheme.background.cgColor
+        mainContentView = NSView()
+        mainContentView.translatesAutoresizingMaskIntoConstraints = false
+        mainContentView.wantsLayer = true
+        mainContentView.layer?.backgroundColor = AppTheme.background.cgColor
 
         let header = makeHeader()
 
@@ -52,10 +53,10 @@ class ViewController: NSViewController {
         wavePattern.translatesAutoresizingMaskIntoConstraints = false
 
         view.addSubview(sidebar)
-        view.addSubview(mainContent)
-        mainContent.addSubview(header)
-        mainContent.addSubview(contentContainer)
-        mainContent.addSubview(wavePattern)
+        view.addSubview(mainContentView)
+        mainContentView.addSubview(header)
+        mainContentView.addSubview(contentContainer)
+        mainContentView.addSubview(wavePattern)
 
         sidebar.onDestinationSelected = { [weak self] destination in
             self?.showDestination(destination)
@@ -66,23 +67,23 @@ class ViewController: NSViewController {
             sidebar.topAnchor.constraint(equalTo: view.topAnchor),
             sidebar.bottomAnchor.constraint(equalTo: view.bottomAnchor),
 
-            mainContent.leadingAnchor.constraint(equalTo: sidebar.trailingAnchor),
-            mainContent.trailingAnchor.constraint(equalTo: view.trailingAnchor),
-            mainContent.topAnchor.constraint(equalTo: view.topAnchor),
-            mainContent.bottomAnchor.constraint(equalTo: view.bottomAnchor),
+            mainContentView.leadingAnchor.constraint(equalTo: sidebar.trailingAnchor),
+            mainContentView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
+            mainContentView.topAnchor.constraint(equalTo: view.topAnchor),
+            mainContentView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
 
-            header.leadingAnchor.constraint(equalTo: mainContent.leadingAnchor),
-            header.trailingAnchor.constraint(equalTo: mainContent.trailingAnchor),
-            header.topAnchor.constraint(equalTo: mainContent.topAnchor, constant: 16),
+            header.leadingAnchor.constraint(equalTo: mainContentView.leadingAnchor),
+            header.trailingAnchor.constraint(equalTo: mainContentView.trailingAnchor),
+            header.topAnchor.constraint(equalTo: mainContentView.topAnchor, constant: 16),
             header.heightAnchor.constraint(equalToConstant: 44),
 
-            contentContainer.leadingAnchor.constraint(equalTo: mainContent.leadingAnchor),
-            contentContainer.trailingAnchor.constraint(equalTo: mainContent.trailingAnchor),
+            contentContainer.leadingAnchor.constraint(equalTo: mainContentView.leadingAnchor),
+            contentContainer.trailingAnchor.constraint(equalTo: mainContentView.trailingAnchor),
             contentContainer.topAnchor.constraint(equalTo: header.bottomAnchor, constant: 8),
-            contentContainer.bottomAnchor.constraint(equalTo: mainContent.bottomAnchor),
+            contentContainer.bottomAnchor.constraint(equalTo: mainContentView.bottomAnchor),
 
-            wavePattern.trailingAnchor.constraint(equalTo: mainContent.trailingAnchor),
-            wavePattern.bottomAnchor.constraint(equalTo: mainContent.bottomAnchor),
+            wavePattern.trailingAnchor.constraint(equalTo: mainContentView.trailingAnchor),
+            wavePattern.bottomAnchor.constraint(equalTo: mainContentView.bottomAnchor),
             wavePattern.widthAnchor.constraint(equalToConstant: 200),
             wavePattern.heightAnchor.constraint(equalToConstant: 140),
         ])
@@ -116,8 +117,10 @@ class ViewController: NSViewController {
 
     private func presentPaywall() {
         guard paywallOverlay == nil else { return }
+        setTrafficLightsHidden(true)
         let overlay = PaywallOverlayView()
         overlay.onDismiss = { [weak self] in
+            self?.setTrafficLightsHidden(false)
             self?.paywallOverlay = nil
             self?.sidebar.select(.home)
             self?.showDestination(.home)
@@ -129,6 +132,15 @@ class ViewController: NSViewController {
     private func dismissPaywall() {
         paywallOverlay?.removeFromSuperview()
         paywallOverlay = nil
+        setTrafficLightsHidden(false)
+    }
+
+    private func setTrafficLightsHidden(_ isHidden: Bool) {
+        guard let window = view.window else { return }
+        let buttons: [NSWindow.ButtonType] = [.closeButton, .miniaturizeButton, .zoomButton]
+        for buttonType in buttons {
+            window.standardWindowButton(buttonType)?.isHidden = isHidden
+        }
     }
 
     private func makeHomeContentView() -> NSView {