Parcourir la source

Refine paywall appearance for light mode and stabilize compilation.

Adapt PremiumFeaturesView colors to the active color scheme so text, cards, and controls
remain readable in light mode while preserving the existing dark-mode look.

Remove the bottom blue glow overlay from the paywall background and simplify price card
styling expressions to avoid Swift type-check timeouts during Debug builds.

Made-with: Cursor
Hussain Afzal il y a 3 mois
Parent
commit
dc6344dd1e
1 fichiers modifiés avec 49 ajouts et 30 suppressions
  1. 49 30
      google_apps/PremiumFeaturesView.swift

+ 49 - 30
google_apps/PremiumFeaturesView.swift

@@ -19,6 +19,7 @@ struct PremiumFeaturesView: View {
 
     @EnvironmentObject private var premiumStore: PremiumStore
     @Environment(\.dismiss) private var dismiss
+    @Environment(\.colorScheme) private var colorScheme
     @State private var selectedPlan: PlanOption = .perpetual
     @State private var showingSuccessAlert = false
 
@@ -57,30 +58,19 @@ struct PremiumFeaturesView: View {
     var body: some View {
         ZStack {
             LinearGradient(
-                colors: [Color.black.opacity(0.9), Color(red: 0.08, green: 0.1, blue: 0.14)],
+                colors: backgroundGradientColors,
                 startPoint: .topLeading,
                 endPoint: .bottomTrailing
             )
             .ignoresSafeArea()
 
-            Rectangle()
-                .fill(
-                    RadialGradient(
-                        colors: [Color.blue.opacity(0.25), .clear],
-                        center: .bottomTrailing,
-                        startRadius: 40,
-                        endRadius: 380
-                    )
-                )
-                .ignoresSafeArea()
-
             ScrollView {
                 VStack(alignment: .leading, spacing: 14) {
                     HStack {
                         Button(action: { dismissPremiumUI() }) {
                             Image(systemName: "xmark")
                                 .font(.system(size: 13, weight: .semibold))
-                                .foregroundStyle(.white.opacity(0.88))
+                                .foregroundStyle(primaryTextColor)
                         }
                         .buttonStyle(.plain)
 
@@ -91,12 +81,12 @@ struct PremiumFeaturesView: View {
                         } label: {
                             Text("Restore")
                                 .font(.system(size: 11, weight: .semibold))
-                                .foregroundStyle(.white.opacity(0.9))
+                                .foregroundStyle(primaryTextColor)
                                 .padding(.horizontal, 8)
                                 .padding(.vertical, 3)
                                 .background(
                                     RoundedRectangle(cornerRadius: 7, style: .continuous)
-                                        .fill(Color.white.opacity(0.16))
+                                        .fill(chipFillColor)
                                 )
                         }
                         .buttonStyle(.plain)
@@ -105,7 +95,7 @@ struct PremiumFeaturesView: View {
 
                     Text("Upgrade to unlock all\nPremium Features")
                         .font(.system(size: 20, weight: .bold))
-                        .foregroundStyle(.white)
+                        .foregroundStyle(primaryTextColor)
                         .lineSpacing(1)
 
                     if let err = premiumStore.loadError {
@@ -133,12 +123,12 @@ struct PremiumFeaturesView: View {
                         VStack(alignment: .leading, spacing: 10) {
                             Text("Store products not loaded")
                                 .font(.system(size: 14, weight: .bold))
-                                .foregroundStyle(.white)
+                                .foregroundStyle(primaryTextColor)
                             Text(
                                 "Prices and checkout need product metadata from App Store Connect, or a StoreKit Configuration file when running from Xcode. Product IDs must match exactly."
                             )
                             .font(.system(size: 11, weight: .medium))
-                            .foregroundStyle(.white.opacity(0.85))
+                            .foregroundStyle(secondaryTextColor)
                             .fixedSize(horizontal: false, vertical: true)
                             Button {
                                 Task { await premiumStore.loadProducts() }
@@ -220,15 +210,15 @@ struct PremiumFeaturesView: View {
                         Spacer()
                         Text("Privacy Policy")
                             .font(.system(size: 11, weight: .medium))
-                            .foregroundStyle(.white.opacity(0.7))
+                            .foregroundStyle(secondaryTextColor)
                         Spacer()
                         Text("Support")
                             .font(.system(size: 11, weight: .medium))
-                            .foregroundStyle(.white.opacity(0.7))
+                            .foregroundStyle(secondaryTextColor)
                         Spacer()
                         Text("Terms of Service")
                             .font(.system(size: 11, weight: .medium))
-                            .foregroundStyle(.white.opacity(0.7))
+                            .foregroundStyle(secondaryTextColor)
                         Spacer()
                     }
                     .padding(.top, 2)
@@ -262,6 +252,25 @@ struct PremiumFeaturesView: View {
         }
     }
 
+    private var backgroundGradientColors: [Color] {
+        if colorScheme == .dark {
+            return [Color.black.opacity(0.9), Color(red: 0.08, green: 0.1, blue: 0.14)]
+        }
+        return [Color.white.opacity(0.96), Color(red: 0.92, green: 0.95, blue: 1.0)]
+    }
+
+    private var primaryTextColor: Color {
+        colorScheme == .dark ? .white.opacity(0.92) : .primary.opacity(0.95)
+    }
+
+    private var secondaryTextColor: Color {
+        colorScheme == .dark ? .white.opacity(0.72) : .primary.opacity(0.70)
+    }
+
+    private var chipFillColor: Color {
+        colorScheme == .dark ? .white.opacity(0.16) : .black.opacity(0.08)
+    }
+
     private func featureCard(title: String, subtitle: String, color: Color) -> some View {
         HStack(alignment: .top, spacing: 10) {
             Circle()
@@ -276,11 +285,11 @@ struct PremiumFeaturesView: View {
             VStack(alignment: .leading, spacing: 3) {
                 Text(title)
                     .font(.system(size: 11.5, weight: .bold))
-                    .foregroundStyle(.white)
+                    .foregroundStyle(primaryTextColor)
                     .lineLimit(1)
                 Text(subtitle)
                     .font(.system(size: 9.5, weight: .medium))
-                    .foregroundStyle(.white.opacity(0.85))
+                    .foregroundStyle(secondaryTextColor)
                     .lineLimit(2)
             }
             Spacer(minLength: 0)
@@ -289,19 +298,29 @@ struct PremiumFeaturesView: View {
         .frame(maxWidth: .infinity, minHeight: 66, alignment: .leading)
         .background(
             RoundedRectangle(cornerRadius: 12, style: .continuous)
-                .fill(Color.white.opacity(0.14))
+                .fill(colorScheme == .dark ? Color.white.opacity(0.14) : Color.black.opacity(0.05))
         )
     }
 
     private func priceCard(title: String, price: String, subtitle: String, badgeText: String?, isSelected: Bool) -> some View {
-        HStack(alignment: .center) {
+        let cardStroke: Color = {
+            if isSelected { return Color.blue.opacity(0.95) }
+            return colorScheme == .dark ? Color.white.opacity(0.4) : Color.black.opacity(0.18)
+        }()
+        let cardFill: Color = {
+            if isSelected { return Color.blue.opacity(colorScheme == .dark ? 0.12 : 0.10) }
+            return colorScheme == .dark ? Color.white.opacity(0.05) : Color.black.opacity(0.025)
+        }()
+        let cardStrokeWidth: CGFloat = isSelected ? 2 : 1.5
+
+        return HStack(alignment: .center) {
             VStack(alignment: .leading, spacing: 5) {
                 Text(title)
                     .font(.system(size: 12, weight: .bold))
-                    .foregroundStyle(.white)
+                    .foregroundStyle(primaryTextColor)
                 Text(subtitle)
                     .font(.system(size: 7.5, weight: .medium))
-                    .foregroundStyle(.white.opacity(0.72))
+                    .foregroundStyle(secondaryTextColor)
             }
 
             Spacer()
@@ -309,7 +328,7 @@ struct PremiumFeaturesView: View {
             VStack(alignment: .trailing, spacing: 7) {
                 Text(price)
                     .font(.system(size: 10, weight: .bold))
-                    .foregroundStyle(.white)
+                    .foregroundStyle(primaryTextColor)
                     .minimumScaleFactor(0.7)
                     .lineLimit(1)
                 if let badgeText {
@@ -328,10 +347,10 @@ struct PremiumFeaturesView: View {
         .padding(10)
         .background(
             RoundedRectangle(cornerRadius: 14, style: .continuous)
-                .stroke(isSelected ? Color.blue.opacity(0.95) : Color.white.opacity(0.4), lineWidth: isSelected ? 2 : 1.5)
+                .stroke(cardStroke, lineWidth: cardStrokeWidth)
                 .background(
                     RoundedRectangle(cornerRadius: 14, style: .continuous)
-                        .fill(isSelected ? Color.blue.opacity(0.12) : Color.white.opacity(0.05))
+                        .fill(cardFill)
                 )
         )
         .contentShape(RoundedRectangle(cornerRadius: 14, style: .continuous))