Quellcode durchsuchen

Refresh all pages on premium state changes and improve Share popup anchor.

Ensure purchase and downgrade flows immediately rebuild page caches, and anchor the Share menu to the exact clicked location in Settings actions.

Made-with: Cursor
huzaifahayat12 vor 1 Woche
Ursprung
Commit
91d83ff35c
1 geänderte Dateien mit 51 neuen und 25 gelöschten Zeilen
  1. 51 25
      meetings_app/ViewController.swift

+ 51 - 25
meetings_app/ViewController.swift

@@ -398,8 +398,8 @@ final class ViewController: NSViewController {
398
             onToggleDarkMode: { [weak self] enabled in
398
             onToggleDarkMode: { [weak self] enabled in
399
                 self?.setDarkMode(enabled)
399
                 self?.setDarkMode(enabled)
400
             },
400
             },
401
-            onAction: { [weak self] action in
402
-                self?.handleSettingsAction(action)
401
+            onAction: { [weak self] action, sourceView, clickPoint in
402
+                self?.handleSettingsAction(action, sourceView: sourceView, clickLocationInSourceView: clickPoint)
403
             }
403
             }
404
         )
404
         )
405
         return popover
405
         return popover
@@ -763,7 +763,7 @@ private extension ViewController {
763
         return nil
763
         return nil
764
     }
764
     }
765
 
765
 
766
-    private func shareAppFromSettingsMenu() {
766
+    private func shareAppFromSettingsMenu(sourceView: NSView? = nil, clickLocationInSourceView: NSPoint? = nil) {
767
         let appName = Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String
767
         let appName = Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String
768
             ?? Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as? String
768
             ?? Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as? String
769
             ?? "Meetings App"
769
             ?? "Meetings App"
@@ -772,8 +772,11 @@ private extension ViewController {
772
         let shareItems: [Any] = appURL.map { [message, $0] } ?? [message]
772
         let shareItems: [Any] = appURL.map { [message, $0] } ?? [message]
773
 
773
 
774
         let picker = NSSharingServicePicker(items: shareItems)
774
         let picker = NSSharingServicePicker(items: shareItems)
775
-        let anchorView = sidebarRowViews[.settings] ?? view
776
-        picker.show(relativeTo: anchorView.bounds, of: anchorView, preferredEdge: .maxX)
775
+        let anchorView = sourceView ?? sidebarRowViews[.settings] ?? view
776
+        let anchorPoint = clickLocationInSourceView
777
+            ?? NSPoint(x: anchorView.bounds.midX, y: anchorView.bounds.midY)
778
+        let anchorRect = NSRect(x: anchorPoint.x, y: anchorPoint.y, width: 1, height: 1)
779
+        picker.show(relativeTo: anchorRect, of: anchorView, preferredEdge: .minY)
777
 
780
 
778
         let clipboardText = ([message, appURL?.absoluteString].compactMap { $0 }).joined(separator: "\n")
781
         let clipboardText = ([message, appURL?.absoluteString].compactMap { $0 }).joined(separator: "\n")
779
         NSPasteboard.general.clearContents()
782
         NSPasteboard.general.clearContents()
@@ -855,7 +858,7 @@ private extension ViewController {
855
         showSidebarPage(selectedSidebarPage)
858
         showSidebarPage(selectedSidebarPage)
856
     }
859
     }
857
 
860
 
858
-    private func handleSettingsAction(_ action: SettingsAction) {
861
+    private func handleSettingsAction(_ action: SettingsAction, sourceView: NSView? = nil, clickLocationInSourceView: NSPoint? = nil) {
859
         switch action {
862
         switch action {
860
         case .restore:
863
         case .restore:
861
             Task { [weak self] in
864
             Task { [weak self] in
@@ -878,7 +881,7 @@ private extension ViewController {
878
                 openInAppBrowser(with: url, policy: inAppBrowserDefaultPolicy)
881
                 openInAppBrowser(with: url, policy: inAppBrowserDefaultPolicy)
879
             }
882
             }
880
         case .shareApp:
883
         case .shareApp:
881
-            shareAppFromSettingsMenu()
884
+            shareAppFromSettingsMenu(sourceView: sourceView, clickLocationInSourceView: clickLocationInSourceView)
882
         case .upgrade:
885
         case .upgrade:
883
             showPaywall(upgradeFlow: true, preferredPlan: .lifetime)
886
             showPaywall(upgradeFlow: true, preferredPlan: .lifetime)
884
         }
887
         }
@@ -1228,13 +1231,9 @@ private extension ViewController {
1228
         premiumUpgradeRatingPromptWorkItem?.cancel()
1231
         premiumUpgradeRatingPromptWorkItem?.cancel()
1229
         refreshPaywallStoreUI()
1232
         refreshPaywallStoreUI()
1230
         refreshScheduleCardsForPremiumStateChange()
1233
         refreshScheduleCardsForPremiumStateChange()
1231
-
1232
-        pageCache[.joinMeetings] = nil
1233
-        pageCache[.video] = nil
1234
-        if selectedSidebarPage == .joinMeetings {
1235
-            showSidebarPage(.joinMeetings)
1236
-        } else if selectedSidebarPage == .video {
1237
-            showSidebarPage(.video)
1234
+        refreshPagesAfterPremiumStateUpdate()
1235
+        Task { [weak self] in
1236
+            await self?.loadSchedule()
1238
         }
1237
         }
1239
 
1238
 
1240
         if !hadPremiumAccess && hasPremiumAccess {
1239
         if !hadPremiumAccess && hasPremiumAccess {
@@ -1254,6 +1253,14 @@ private extension ViewController {
1254
         }
1253
         }
1255
     }
1254
     }
1256
 
1255
 
1256
+    private func refreshPagesAfterPremiumStateUpdate() {
1257
+        pageCache[.joinMeetings] = nil
1258
+        pageCache[.photo] = nil
1259
+        pageCache[.video] = nil
1260
+        pageCache[.settings] = nil
1261
+        showSidebarPage(selectedSidebarPage)
1262
+    }
1263
+
1257
     private var userHasRated: Bool {
1264
     private var userHasRated: Bool {
1258
         UserDefaults.standard.bool(forKey: userHasRatedDefaultsKey)
1265
         UserDefaults.standard.bool(forKey: userHasRatedDefaultsKey)
1259
     }
1266
     }
@@ -1426,6 +1433,10 @@ private extension ViewController {
1426
             self.refreshPaywallStoreUI()
1433
             self.refreshPaywallStoreUI()
1427
             switch result {
1434
             switch result {
1428
             case .success:
1435
             case .success:
1436
+                self.refreshPagesAfterPremiumStateUpdate()
1437
+                Task { [weak self] in
1438
+                    await self?.loadSchedule()
1439
+                }
1429
                 self.showSimpleAlert(title: "Purchase Complete", message: "Premium has been unlocked successfully.")
1440
                 self.showSimpleAlert(title: "Purchase Complete", message: "Premium has been unlocked successfully.")
1430
                 self.paywallWindow?.performClose(nil)
1441
                 self.paywallWindow?.performClose(nil)
1431
                 self.scheduleRatingPromptAfterPremiumUpgrade()
1442
                 self.scheduleRatingPromptAfterPremiumUpgrade()
@@ -1583,7 +1594,14 @@ private extension ViewController {
1583
         let shareButton = makeSettingsActionButton(icon: "⤴︎", title: "Share App", action: .shareApp)
1594
         let shareButton = makeSettingsActionButton(icon: "⤴︎", title: "Share App", action: .shareApp)
1584
         stack.addArrangedSubview(shareButton)
1595
         stack.addArrangedSubview(shareButton)
1585
         shareButton.widthAnchor.constraint(equalTo: stack.widthAnchor).isActive = true
1596
         shareButton.widthAnchor.constraint(equalTo: stack.widthAnchor).isActive = true
1586
-        stack.setCustomSpacing(24, after: shareButton)
1597
+        if storeKitCoordinator.hasPremiumAccess && !storeKitCoordinator.hasLifetimeAccess {
1598
+            let upgradeButton = makeSettingsActionButton(icon: "⬆︎", title: "Upgrade", action: .upgrade)
1599
+            stack.addArrangedSubview(upgradeButton)
1600
+            upgradeButton.widthAnchor.constraint(equalTo: stack.widthAnchor).isActive = true
1601
+            stack.setCustomSpacing(24, after: upgradeButton)
1602
+        } else {
1603
+            stack.setCustomSpacing(24, after: shareButton)
1604
+        }
1587
 
1605
 
1588
         let legalTitle = textLabel("Help & Legal", font: typography.joinWithURLTitle, color: palette.textPrimary)
1606
         let legalTitle = textLabel("Help & Legal", font: typography.joinWithURLTitle, color: palette.textPrimary)
1589
         stack.addArrangedSubview(legalTitle)
1607
         stack.addArrangedSubview(legalTitle)
@@ -1596,12 +1614,6 @@ private extension ViewController {
1596
         let termsButton = makeSettingsActionButton(icon: "📄", title: "Terms of Services", action: .termsOfServices)
1614
         let termsButton = makeSettingsActionButton(icon: "📄", title: "Terms of Services", action: .termsOfServices)
1597
         stack.addArrangedSubview(termsButton)
1615
         stack.addArrangedSubview(termsButton)
1598
         termsButton.widthAnchor.constraint(equalTo: stack.widthAnchor).isActive = true
1616
         termsButton.widthAnchor.constraint(equalTo: stack.widthAnchor).isActive = true
1599
-        if storeKitCoordinator.hasPremiumAccess && !storeKitCoordinator.hasLifetimeAccess {
1600
-            let upgradeButton = makeSettingsActionButton(icon: "⬆︎", title: "Upgrade", action: .upgrade)
1601
-            stack.addArrangedSubview(upgradeButton)
1602
-            upgradeButton.widthAnchor.constraint(equalTo: stack.widthAnchor).isActive = true
1603
-        }
1604
-
1605
         NSLayoutConstraint.activate([
1617
         NSLayoutConstraint.activate([
1606
             scroll.leadingAnchor.constraint(equalTo: panel.leadingAnchor),
1618
             scroll.leadingAnchor.constraint(equalTo: panel.leadingAnchor),
1607
             scroll.trailingAnchor.constraint(equalTo: panel.trailingAnchor),
1619
             scroll.trailingAnchor.constraint(equalTo: panel.trailingAnchor),
@@ -1725,7 +1737,14 @@ private extension ViewController {
1725
 
1737
 
1726
     @objc private func settingsPageActionButtonClicked(_ sender: NSButton) {
1738
     @objc private func settingsPageActionButtonClicked(_ sender: NSButton) {
1727
         guard let action = SettingsAction(rawValue: sender.tag) else { return }
1739
         guard let action = SettingsAction(rawValue: sender.tag) else { return }
1728
-        handleSettingsAction(action)
1740
+        let clickPoint: NSPoint?
1741
+        if let event = NSApp.currentEvent {
1742
+            let pointInWindow = event.locationInWindow
1743
+            clickPoint = sender.convert(pointInWindow, from: nil)
1744
+        } else {
1745
+            clickPoint = nil
1746
+        }
1747
+        handleSettingsAction(action, sourceView: sender, clickLocationInSourceView: clickPoint)
1729
     }
1748
     }
1730
 
1749
 
1731
     @objc private func settingsGoogleActionButtonClicked(_ sender: NSButton) {
1750
     @objc private func settingsGoogleActionButtonClicked(_ sender: NSButton) {
@@ -4503,7 +4522,7 @@ private final class SettingsMenuViewController: NSViewController {
4503
     private let palette: Palette
4522
     private let palette: Palette
4504
     private let typography: Typography
4523
     private let typography: Typography
4505
     private let onToggleDarkMode: (Bool) -> Void
4524
     private let onToggleDarkMode: (Bool) -> Void
4506
-    private let onAction: (SettingsAction) -> Void
4525
+    private let onAction: (SettingsAction, NSView?, NSPoint?) -> Void
4507
 
4526
 
4508
     private var darkToggle: NSSwitch?
4527
     private var darkToggle: NSSwitch?
4509
 
4528
 
@@ -4514,7 +4533,7 @@ private final class SettingsMenuViewController: NSViewController {
4514
         showRateUsInSettings: Bool,
4533
         showRateUsInSettings: Bool,
4515
         showUpgradeInSettings: Bool,
4534
         showUpgradeInSettings: Bool,
4516
         onToggleDarkMode: @escaping (Bool) -> Void,
4535
         onToggleDarkMode: @escaping (Bool) -> Void,
4517
-        onAction: @escaping (SettingsAction) -> Void
4536
+        onAction: @escaping (SettingsAction, NSView?, NSPoint?) -> Void
4518
     ) {
4537
     ) {
4519
         self.palette = palette
4538
         self.palette = palette
4520
         self.typography = typography
4539
         self.typography = typography
@@ -4690,7 +4709,14 @@ private final class SettingsMenuViewController: NSViewController {
4690
 
4709
 
4691
     @objc private func settingsActionButtonPressed(_ sender: NSButton) {
4710
     @objc private func settingsActionButtonPressed(_ sender: NSButton) {
4692
         guard let action = SettingsAction(rawValue: sender.tag) else { return }
4711
         guard let action = SettingsAction(rawValue: sender.tag) else { return }
4693
-        onAction(action)
4712
+        let clickPoint: NSPoint?
4713
+        if let event = NSApp.currentEvent {
4714
+            let pointInWindow = event.locationInWindow
4715
+            clickPoint = sender.convert(pointInWindow, from: nil)
4716
+        } else {
4717
+            clickPoint = nil
4718
+        }
4719
+        onAction(action, sender, clickPoint)
4694
     }
4720
     }
4695
 
4721
 
4696
 }
4722
 }