Selaa lähdekoodia

Update premium unlock state to hide upgrade banner immediately.

Refresh entitlements when the premium sheet closes and persist local unlock state after verified purchases so the launcher UI removes the upgrade bar without delay.

Made-with: Cursor
huzaifahayat12 6 kuukautta sitten
vanhempi
sitoutus
689af75c0f
2 muutettua tiedostoa jossa 22 lisäystä ja 1 poistoa
  1. 9 0
      google_apps/LauncherRootView.swift
  2. 13 1
      google_apps/PremiumStore.swift

+ 9 - 0
google_apps/LauncherRootView.swift

@@ -144,6 +144,15 @@ struct LauncherRootView: View {
             }
             }
             .frame(minWidth: 760, minHeight: 420)
             .frame(minWidth: 760, minHeight: 420)
         }
         }
+        .task {
+            await premiumStore.refreshEntitlements()
+        }
+        .onChange(of: showingPremiumScreen) { isShowing in
+            guard !isShowing else { return }
+            Task {
+                await premiumStore.refreshEntitlements()
+            }
+        }
         .onAppear {
         .onAppear {
             loadCustomAppsFromStorage()
             loadCustomAppsFromStorage()
             loadAppOrderFromStorage()
             loadAppOrderFromStorage()

+ 13 - 1
google_apps/PremiumStore.swift

@@ -11,6 +11,7 @@ enum PremiumProductID: String, CaseIterable {
 @MainActor
 @MainActor
 final class PremiumStore: ObservableObject {
 final class PremiumStore: ObservableObject {
     static let shared = PremiumStore()
     static let shared = PremiumStore()
+    private static let localPremiumUnlockKey = "premiumUnlockedLocal"
 
 
     @Published private(set) var products: [Product] = []
     @Published private(set) var products: [Product] = []
     @Published private(set) var isPremiumUnlocked = false
     @Published private(set) var isPremiumUnlocked = false
@@ -22,6 +23,8 @@ final class PremiumStore: ObservableObject {
     private var transactionListener: Task<Void, Never>?
     private var transactionListener: Task<Void, Never>?
 
 
     private init() {
     private init() {
+        // Keep UI in sync immediately after a successful purchase.
+        isPremiumUnlocked = UserDefaults.standard.bool(forKey: Self.localPremiumUnlockKey)
         transactionListener = Task { await listenForTransactions() }
         transactionListener = Task { await listenForTransactions() }
         Task { await refreshEntitlements() }
         Task { await refreshEntitlements() }
     }
     }
@@ -76,6 +79,10 @@ final class PremiumStore: ObservableObject {
             case .success(let verification):
             case .success(let verification):
                 switch verification {
                 switch verification {
                 case .verified(let transaction):
                 case .verified(let transaction):
+                    if PremiumProductID(rawValue: transaction.productID) != nil {
+                        isPremiumUnlocked = true
+                        UserDefaults.standard.set(true, forKey: Self.localPremiumUnlockKey)
+                    }
                     await transaction.finish()
                     await transaction.finish()
                     await refreshEntitlements()
                     await refreshEntitlements()
                     return true
                     return true
@@ -119,7 +126,12 @@ final class PremiumStore: ObservableObject {
             }
             }
         }
         }
 
 
-        isPremiumUnlocked = unlocked
+        let cachedUnlock = UserDefaults.standard.bool(forKey: Self.localPremiumUnlockKey)
+        let finalUnlock = unlocked || cachedUnlock
+        isPremiumUnlocked = finalUnlock
+        if finalUnlock {
+            UserDefaults.standard.set(true, forKey: Self.localPremiumUnlockKey)
+        }
     }
     }
 
 
     private func listenForTransactions() async {
     private func listenForTransactions() async {