浏览代码

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 3 月之前
父节点
当前提交
dc6344dd1e
共有 1 个文件被更改,包括 49 次插入30 次删除
  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))