// // IAPView.swift // AIGrammar // // Created by oscar on 2024/7/9. // import SwiftUI import FirebaseAnalytics struct VIPPaymentView: View { @Environment(\.presentationMode) var presentationMode @State private var showingToast = false @State private var toastText = "" let features = ["Grammar Check & Spelling Correction", "Words & Dictionary", "Translate"] let freeValues = ["2 Times / Day", "2 Times / Day", "2 Times / Day"] let premiumValues = ["Unlimited", "Unlimited", "Unlimited"] let products = [ ("Weekly", "$4.99 / week", "Billed as one payment of $4.99", "weekly", IAPProduct.premiumFeature1, "Billed Weekly"), ("Monthly", "$9.99 / month", "Billed as one payment of $9.99", "monthly", IAPProduct.premiumFeature2, "Billed Monthly"), ("Annual", "$4.16 / month", "Billed as one payment of $49.99", "yearly", IAPProduct.premiumFeature3, "Billed Yearly") ] @State private var selectedProductIndex: Int = 1 // 默认选择第二个商品 @State private var selectedPlanText: String = "Billed Monthly" @EnvironmentObject var iapManager: IAPManager // 确保在上级视图中已提供 IAPManager var body: some View { NavigationView { VStack { HStack { Text("PREMIUM") .bold() .foregroundColor(Color(red: 1.0, green: 0.8, blue: 0.0)) // 自定义更亮的黄色 //.foregroundColor(.yellow) .padding() .background(Color.orange) .cornerRadius(20) Spacer() Button("Close") { presentationMode.wrappedValue.dismiss() } } .padding() List { Section(header: Text("Get Premium Features").font(.headline)) { HStack { Text("Features") .frame(width: 120, alignment: .leading) Spacer() Text("Free") .frame(width: 120, alignment: .center) Spacer() Text("Premium") .frame(width: 80, alignment: .center) } .font(.headline) ForEach(Array(zip(features, zip(freeValues, premiumValues))), id: \.0) { item in HStack { Text(item.0) .frame(width: 120, alignment: .leading) Spacer() Text(item.1.0) // Free values .frame(width: 120, alignment: .center) Spacer() Text(item.1.1) // Premium values .frame(width: 80, alignment: .center) } .font(.subheadline) } } } VStack(alignment: .leading) { // 使用 VStack 包装整个 ForEach 循环,并指定左对齐 ForEach(products.indices, id: \.self) { index in Button(action: { // do someting }) { HStack() { Image(systemName: selectedProductIndex == index ? "checkmark.circle.fill" : "circle") .foregroundColor(selectedProductIndex == index ? .green : .secondary) .padding(.horizontal, 4) VStack(alignment: .leading) { if products[index].0 == "Annual" { // 特别为 "Premium Yearly" 添加图标和折扣信息 Text(products[index].0) + Text(" ⚡️") + Text(" 58% off") .bold() .foregroundColor(.red) // 折扣信息使用红色 .font(.subheadline) } else { Text(products[index].0) } Text(products[index].1) .font(.caption) Text(products[index].2) .font(.subheadline) } .frame(maxWidth: .infinity, alignment: .leading) // 使每个 HStack 占据整个宽度,并左对齐 } .padding(.vertical, 10) .background(self.selectedProductIndex == index ? Color.yellow : Color.clear) .cornerRadius(5) .padding(.horizontal, 20) // 增加水平缩进 .onTapGesture { self.selectedProductIndex = index self.selectedPlanText = products[index].5 } } .frame(maxWidth: .infinity, alignment: .leading) // 使每个 HStack 占据整个宽度,并左对齐 } } .padding(.horizontal, 5) // 增加水平缩进 Button("Purchase") { // Handle purchase logic here buyProduct() } .padding(.vertical, 15) .padding(.horizontal, 80) .foregroundColor(.white) .background(Color.green) .cornerRadius(15) .frame(minWidth: 0, maxWidth: .infinity) .shadow(radius: 2) // 添加阴影效果 .font(.headline) // 调整字体大小为标题大小 .padding(.top, 20) Text((selectedPlanText ) + ", Cancel Anytime") .font(.footnote) .padding(.vertical, 5) } .navigationBarHidden(true) } .frame(maxWidth: .infinity, maxHeight: .infinity) .background(Color(.systemBackground)) .toast(isPresented: $showingToast, dismissAfter: globalEnvironment.toastPresentMsNormal, onDismiss: { // Toast 消失后执行的动作 presentationMode.wrappedValue.dismiss() // 关闭当前视图 }) { HStack { Image(systemName: "exclamationmark.bubble") .foregroundColor(.yellow) Text(toastText) .foregroundColor(.black) } .padding() .background(Color.white) .cornerRadius(8) .shadow(radius: 10) } } private func buyProduct() { let productId = products[selectedProductIndex].4 logger.info("selected productId: \(productId.rawValue)") // 记录事件 Analytics.logEvent(globalAnalyticsEvents.eventPurchase, parameters: [ globalAnalyticsEvents.keyPurchaseItem: productId.rawValue as NSObject, globalAnalyticsEvents.keyDeviceID: globalEnvironment.deviceID as NSObject ]) if let product = iapManager.products.first(where: { $0.id == productId.rawValue }) { Task { await iapManager.buy(product: product) { result in switch result { case .success(let message): self.toastText = message self.showingToast = true presentationMode.wrappedValue.dismiss() // 刷新用户的vip状态 InitApp.shared.refreshUserInfo() case .failure(let error): self.toastText = error.localizedDescription self.showingToast = true } } } } else { logger.error("Product not found") toastText = "Error loading product list, please try again later" self.showingToast = true } } } struct VIPPaymentView_Previews: PreviewProvider { static var previews: some View { VIPPaymentView() } }