Selaa lähdekoodia

Pin paywall footer and spread footer actions.

Make the wide-layout footer stick to the bottom while content scrolls above it, and distribute the footer actions across the left panel width for a cleaner alignment.

Co-authored-by: Cursor <cursoragent@cursor.com>
huzaifahayat12 2 kuukautta sitten
vanhempi
sitoutus
2cc75eb975
1 muutettua tiedostoa jossa 74 lisäystä ja 28 poistoa
  1. 74 28
      google_apps/PremiumFeaturesView.swift

+ 74 - 28
google_apps/PremiumFeaturesView.swift

@@ -135,20 +135,29 @@ struct PremiumFeaturesView: View {
 
     private var desktopSplitContent: some View {
         HStack(alignment: .top, spacing: 0) {
-            ScrollView {
-                VStack(alignment: .leading, spacing: 18) {
-                    headlineBlock(useLargeType: true)
-                    messagesBlock
-                    featureGrid(desktop: true)
-                    if productsUnavailable {
-                        productsUnavailableBanner
+            VStack(spacing: 0) {
+                ScrollView {
+                    VStack(alignment: .leading, spacing: 18) {
+                        headlineBlock(useLargeType: true)
+                        messagesBlock
+                        featureGrid(desktop: true)
+                        if productsUnavailable {
+                            productsUnavailableBanner
+                        }
                     }
+                    .padding(.leading, 22)
+                    .padding(.trailing, 14)
+                    .padding(.top, 2)
+                    .padding(.bottom, 18)
                 }
-                .padding(.leading, 22)
-                .padding(.trailing, 14)
-                .padding(.bottom, 22)
+                .frame(maxWidth: .infinity, maxHeight: .infinity)
+
+                wideFooterLinks
+                    .padding(.leading, 22)
+                    .padding(.trailing, 14)
+                    .padding(.bottom, 14)
             }
-            .frame(maxWidth: .infinity, maxHeight: .infinity)
+            .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)
 
             Rectangle()
                 .fill(paywallDividerColor)
@@ -167,8 +176,6 @@ struct PremiumFeaturesView: View {
                     planCardsStack(compactPricing: false)
 
                     continuePurchaseButton
-
-                    sidebarFooterLinks
                 }
                 .padding(.leading, 18)
                 .padding(.trailing, 22)
@@ -340,28 +347,67 @@ struct PremiumFeaturesView: View {
     }
 
     private var sidebarFooterLinks: some View {
-        VStack(alignment: .leading, spacing: 8) {
-            linkButton("Privacy Policy", ExternalPage.privacy)
-            linkButton("Support", ExternalPage.support)
-            linkButton("Terms of Service", ExternalPage.terms)
-        }
-        .frame(maxWidth: .infinity, alignment: .leading)
-        .padding(.top, 4)
+        EmptyView()
     }
 
     private var compactFooterLinks: some View {
-        HStack {
-            Spacer()
-            linkButton("Privacy Policy", ExternalPage.privacy)
-            Spacer()
-            linkButton("Support", ExternalPage.support)
-            Spacer()
-            linkButton("Terms", ExternalPage.terms)
-            Spacer()
+        VStack(spacing: 10) {
+            continueWithFreeButton
+
+            HStack {
+                Spacer()
+                linkButton("Privacy Policy", ExternalPage.privacy)
+                Spacer()
+                linkButton("Support", ExternalPage.support)
+                Spacer()
+                linkButton("Terms of Service", ExternalPage.terms)
+                Spacer()
+            }
         }
         .padding(.top, 4)
     }
 
+    private var wideFooterLinks: some View {
+        VStack(spacing: 10) {
+            Rectangle()
+                .fill(paywallDividerColor)
+                .frame(height: 1)
+                .padding(.top, 6)
+
+            HStack {
+                footerActionButton("Continue with Free") { dismissPremiumUI() }
+                Spacer(minLength: 18)
+                footerActionButton("Privacy Policy") { openExternalPage(ExternalPage.privacy) }
+                Spacer(minLength: 18)
+                footerActionButton("Support") { openExternalPage(ExternalPage.support) }
+                Spacer(minLength: 18)
+                footerActionButton("Terms of Service") { openExternalPage(ExternalPage.terms) }
+            }
+            .frame(maxWidth: .infinity)
+        }
+        .padding(.top, 8)
+    }
+
+    private var continueWithFreeButton: some View {
+        Button("Continue with Free") {
+            dismissPremiumUI()
+        }
+        .buttonStyle(.plain)
+        .font(.system(size: 12, weight: .semibold))
+        .foregroundStyle(primaryTextColor.opacity(0.9))
+        .padding(.vertical, 6)
+        .frame(maxWidth: .infinity, alignment: .leading)
+        .contentShape(Rectangle())
+    }
+
+    private func footerActionButton(_ title: String, action: @escaping () -> Void) -> some View {
+        Button(title, action: action)
+            .buttonStyle(.plain)
+            .font(.system(size: 12, weight: .semibold))
+            .foregroundStyle(secondaryTextColor)
+            .contentShape(Rectangle())
+    }
+
     private func linkButton(_ title: String, _ url: String) -> some View {
         Button(title) {
             openExternalPage(url)