MystBin
/5b4f14e9cedbdae306 Created 1 day ago...
Raw
RCStoreManager.swift Hide Copy Raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@MainActor @Observable class RCStoreManager { var hasActiveSubscription: Bool = false var isPurchasing: Bool = false init(apiKey: String) { Task { await restorePurchases() } } private func updateSubscriptionStatus(from customerInfo: CustomerInfo) { let activeEntitlements = customerInfo.entitlements.active hasActiveSubscription = !activeEntitlements.isEmpty } func restorePurchases() async { isLoading = true defer { isLoading = false } do { let customerInfo = try await Purchases.shared.restorePurchases() updateSubscriptionStatus(from: customerInfo) } catch { statusMessage = "Unable to restore purchases: \(error.localizedDescription)" } } }
OnboardingMainView Hide Copy Raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
struct OnboardingMainView: View { @Environment(RCStoreManager.self) private var rcStoreManager var body: some View { VStack { OnboardingWelcomeView { ... } if coordinator.currentScreen == .paywall { Button { dismiss() } label: { Text(rcStoreManager.hasActiveSubscription ? " " : "Continue without pro features") } .disabled(rcStoreManager.hasActiveSubscription) } Button { if rcStoreManager.hasActiveSubscription { print("Attempting to dismiss onboarding") dismiss() } else { print("Trying to purchase subscription") rcStoreManager.purchaseSelectedPackage() } } label: { Text( rcStoreManager.isPurchasing ? "Purchasing" : rcStoreManager.hasActiveSubscription ? "Close" : "Start Free Trial" ) } } .onAppear { DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { withAnimation { isShowingNextButton = true isShowingPageIndicatorView = true } } } }
OnboardingWelcomeView Hide Copy Raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
struct OnboardingWelcomeView: View { let onNext: () -> Void @State private var showingWelcomeText = false @State private var showingTitleText = false @State private var showingDescriptionText = false var body: some View { VStack { Text("Welcome to") .font(.title) .opacity(showingWelcomeText ? 1 : 0) .offset(y: showingWelcomeText ? 0 : 50) .animation(.spring(response: 0.4, dampingFraction: 0.4, blendDuration: 0.6), value: showingWelcomeText) Text("Redacted") .opacity(showingTitleText ? 1 : 0) .offset(y: showingTitleText ? 0 : 50) .animation(.spring(response: 0.4, dampingFraction: 0.4, blendDuration: 1.0), value: showingTitleText) Text("The ultimate companion for minipainters") .opacity(showingDescriptionText ? 0.5 : 0) .offset(y: showingDescriptionText ? 0 : 50) .animation(.spring(response: 0.5, dampingFraction: 0.6), value: showingDescriptionText) } .onAppear { withAnimation { showingWelcomeText = true } DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { withAnimation { showingTitleText = true } } DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { withAnimation { showingDescriptionText = true } } } } }