Ver Fonte

Fix settings links placeholders and Rate Us action reliability.

Move settings and paywall links to plist-configured placeholders, show Rate Us for all users, and route Rate Us through robust App Store fallbacks with button-based settings row actions.

Made-with: Cursor
huzaifahayat12 há 3 meses atrás
pai
commit
634f9ee6d7
2 ficheiros alterados com 78 adições e 18 exclusões
  1. 14 0
      Info.plist
  2. 64 18
      meetings_app/ViewController.swift

+ 14 - 0
Info.plist

@@ -30,6 +30,20 @@
 	<string>Camera is used for video meetings you open inside this app.</string>
 	<key>NSMicrophoneUsageDescription</key>
 	<string>Microphone is used for audio in meetings you open inside this app.</string>
+	<key>AppLaunchPlaceholderURL</key>
+	<string>https://example.com/app-link-coming-soon</string>
+	<key>AppShareURL</key>
+	<string>https://example.com/app-link-coming-soon</string>
+	<key>SupportURL</key>
+	<string>https://example.com/app-link-coming-soon</string>
+	<key>MoreAppsURL</key>
+	<string>https://example.com/app-link-coming-soon</string>
+	<key>PrivacyPolicyURL</key>
+	<string>https://example.com/app-link-coming-soon</string>
+	<key>TermsOfServiceURL</key>
+	<string>https://example.com/app-link-coming-soon</string>
+	<key>RateUsURL</key>
+	<string>https://apps.apple.com/pk/app/meeting-app-for-google-meet/id6654920763?mt=12</string>
 
 	<key>CFBundleURLTypes</key>
 	<array>

+ 64 - 18
meetings_app/ViewController.swift

@@ -696,6 +696,51 @@ private extension ViewController {
         }
     }
 
+    private func openRateUsDestination() {
+        let configured = (Bundle.main.object(forInfoDictionaryKey: "RateUsURL") as? String)?
+            .trimmingCharacters(in: .whitespacesAndNewlines)
+        let placeholder = (Bundle.main.object(forInfoDictionaryKey: "AppLaunchPlaceholderURL") as? String)?
+            .trimmingCharacters(in: .whitespacesAndNewlines)
+        let hardcodedRateUsURL = "https://apps.apple.com/pk/app/meeting-app-for-google-meet/id6654920763?mt=12"
+
+        var candidateStrings = [String]()
+        if let configured, !configured.isEmpty {
+            candidateStrings.append(configured)
+            if let appID = extractAppleAppID(from: configured) {
+                candidateStrings.append("macappstore://apps.apple.com/app/id\(appID)")
+                candidateStrings.append("macappstore://itunes.apple.com/app/id\(appID)")
+            }
+        }
+        candidateStrings.append(hardcodedRateUsURL)
+        candidateStrings.append("macappstore://apps.apple.com/app/id6654920763")
+        candidateStrings.append("macappstore://itunes.apple.com/app/id6654920763")
+        if let placeholder, !placeholder.isEmpty {
+            candidateStrings.append(placeholder)
+        }
+
+        for candidate in candidateStrings {
+            guard let url = URL(string: candidate) else { continue }
+            if NSWorkspace.shared.open(url) {
+                return
+            }
+        }
+
+        showSimpleAlert(
+            title: "Unable to Open Rate Page",
+            message: "Could not open the App Store rating page. Please try again."
+        )
+
+        requestAppRatingIfEligible(markAsRated: true)
+    }
+
+    private func extractAppleAppID(from urlString: String) -> String? {
+        guard let match = urlString.range(of: "id[0-9]+", options: .regularExpression) else {
+            return nil
+        }
+        let token = String(urlString[match])
+        return String(token.dropFirst())
+    }
+
     private func openInSafari(url: URL) {
         guard let safariAppURL = NSWorkspace.shared.urlForApplication(withBundleIdentifier: "com.apple.Safari") else {
             NSWorkspace.shared.open(url)
@@ -836,18 +881,19 @@ private extension ViewController {
         case .rateUs:
             settingsPopover?.performClose(nil)
             settingsPopover = nil
-            requestAppRatingIfEligible(markAsRated: true)
+            openRateUsDestination()
         case .support:
             settingsPopover?.performClose(nil)
             settingsPopover = nil
-            if let url = URL(string: "https://support.google.com/meet") {
+            if let supportURL = Bundle.main.object(forInfoDictionaryKey: "SupportURL") as? String,
+               let url = URL(string: supportURL) {
                 openInAppBrowser(with: url, policy: inAppBrowserDefaultPolicy)
             }
         case .moreApps:
             settingsPopover?.performClose(nil)
             settingsPopover = nil
-            // Replace with your App Store developer page URL.
-            if let url = URL(string: "https://apps.apple.com/developer/id0000000000") {
+            if let moreAppsURL = Bundle.main.object(forInfoDictionaryKey: "MoreAppsURL") as? String,
+               let url = URL(string: moreAppsURL) {
                 openInAppBrowser(with: url, policy: inAppBrowserDefaultPolicy)
             }
         case .shareApp:
@@ -1056,10 +1102,11 @@ private extension ViewController {
     @objc private func paywallFooterLinkClicked(_ sender: NSClickGestureRecognizer) {
         guard let view = sender.view else { return }
         let text = (view.subviews.first { $0 is NSTextField } as? NSTextField)?.stringValue ?? "Link"
+        let defaultURL = (Bundle.main.object(forInfoDictionaryKey: "AppLaunchPlaceholderURL") as? String) ?? "https://example.com/app-link-coming-soon"
         let map: [String: String] = [
-            "Privacy Policy": "https://policies.google.com/privacy",
-            "Support": "https://support.google.com/meet",
-            "Terms of Services": "https://policies.google.com/terms"
+            "Privacy Policy": (Bundle.main.object(forInfoDictionaryKey: "PrivacyPolicyURL") as? String) ?? defaultURL,
+            "Support": (Bundle.main.object(forInfoDictionaryKey: "SupportURL") as? String) ?? defaultURL,
+            "Terms of Services": (Bundle.main.object(forInfoDictionaryKey: "TermsOfServiceURL") as? String) ?? defaultURL
         ]
         if let urlString = map[text], let url = URL(string: urlString) {
             openInAppBrowser(with: url, policy: inAppBrowserDefaultPolicy)
@@ -1251,7 +1298,7 @@ private extension ViewController {
     }
 
     private var shouldShowRateUsInSettings: Bool {
-        storeKitCoordinator.hasPremiumAccess && !userHasRated && hasReachedRatingUsageThreshold
+        true
     }
 
     private func migrateLegacyRatingStateIfNeeded() {
@@ -4360,9 +4407,14 @@ private final class SettingsMenuViewController: NSViewController {
     }
 
     private func settingsActionRow(icon: String, title: String, action: SettingsAction) -> NSView {
-        let row = HoverTrackingView()
+        let row = HoverButton(title: "", target: self, action: #selector(settingsActionButtonPressed(_:)))
+        row.tag = action.rawValue
+        row.isBordered = false
         row.translatesAutoresizingMaskIntoConstraints = false
         row.heightAnchor.constraint(equalToConstant: 42).isActive = true
+        row.wantsLayer = true
+        row.layer?.cornerRadius = 10
+        row.layer?.backgroundColor = NSColor.clear.cgColor
 
         let iconLabel = NSTextField(labelWithString: icon)
         iconLabel.translatesAutoresizingMaskIntoConstraints = false
@@ -4384,12 +4436,7 @@ private final class SettingsMenuViewController: NSViewController {
             titleLabel.centerYAnchor.constraint(equalTo: row.centerYAnchor)
         ])
 
-        let click = NSClickGestureRecognizer(target: self, action: #selector(settingsActionClicked(_:)))
-        row.addGestureRecognizer(click)
-        row.identifier = NSUserInterfaceItemIdentifier(rawValue: "\(action.rawValue)")
         row.onHoverChanged = { hovering in
-            row.wantsLayer = true
-            row.layer?.cornerRadius = 10
             row.layer?.backgroundColor = (hovering ? self.palette.inputBackground : NSColor.clear).cgColor
         }
         row.onHoverChanged?(false)
@@ -4401,12 +4448,11 @@ private final class SettingsMenuViewController: NSViewController {
         onToggleDarkMode(sender.state == .on)
     }
 
-    @objc private func settingsActionClicked(_ sender: NSClickGestureRecognizer) {
-        guard let view = sender.view,
-              let raw = Int(view.identifier?.rawValue ?? ""),
-              let action = SettingsAction(rawValue: raw) else { return }
+    @objc private func settingsActionButtonPressed(_ sender: NSButton) {
+        guard let action = SettingsAction(rawValue: sender.tag) else { return }
         onAction(action)
     }
+
 }
 
 private extension ViewController {