242 lines
8.5 KiB
Swift
242 lines
8.5 KiB
Swift
//
|
||
// SettingsView.swift
|
||
// AIGrammar
|
||
//
|
||
// Created by oscar on 2024/3/27.
|
||
//
|
||
|
||
import SwiftUI
|
||
import ToastUI
|
||
|
||
import SafariServices
|
||
|
||
struct FullScreenSafariView: UIViewControllerRepresentable {
|
||
let url: URL
|
||
var onDismiss: (() -> Void)?
|
||
|
||
func makeUIViewController(context: UIViewControllerRepresentableContext<FullScreenSafariView>) -> SFSafariViewController {
|
||
let safariViewController = SFSafariViewController(url: url)
|
||
safariViewController.delegate = context.coordinator
|
||
return safariViewController
|
||
}
|
||
|
||
func updateUIViewController(_ uiViewController: SFSafariViewController, context: UIViewControllerRepresentableContext<FullScreenSafariView>) {
|
||
// 无需更新
|
||
}
|
||
|
||
func makeCoordinator() -> Coordinator {
|
||
Coordinator(self)
|
||
}
|
||
|
||
class Coordinator: NSObject, SFSafariViewControllerDelegate {
|
||
var parent: FullScreenSafariView
|
||
|
||
init(_ parent: FullScreenSafariView) {
|
||
self.parent = parent
|
||
}
|
||
|
||
func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
|
||
parent.onDismiss?()
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
struct SettingsView: View {
|
||
@EnvironmentObject var globalEnv: GlobalEnvironment // 引入环境对象
|
||
|
||
@State private var isLoading = false // 控制加载指示器的显示
|
||
@State private var showingToast = false // 控制是否显示toast
|
||
@State private var toastText = ""
|
||
@State private var showVIPPaymentView = false
|
||
|
||
@EnvironmentObject var iapManager: IAPManager // 确保在上级视图中已提供 IAPManager
|
||
|
||
@State private var showingFullSafari = false
|
||
@State private var currentSafariURL = globalEnvironment.userTermsURL
|
||
|
||
|
||
@State private var showingAdvancedSettings = false // 控制高级设置显示的状态
|
||
@State private var useSandboxEnvironment = false
|
||
@State private var useDevelopmentEnvironment = false
|
||
|
||
|
||
var body: some View {
|
||
NavigationView {
|
||
ScrollView {
|
||
VStack(spacing: 0) {
|
||
// Upgrade to Premium
|
||
settingItem(icon: "arrow.up.circle", text: "Upgrade to Premium", isBold: true)
|
||
.onTapGesture {
|
||
showVIPPaymentView = true
|
||
}
|
||
|
||
// Feedback
|
||
settingItem(icon: "bubble.left", text: "Feedback")
|
||
.onTapGesture {
|
||
// Assuming there's a way to open App Store Feedback
|
||
openAppStoreFeedback()
|
||
}
|
||
|
||
// About
|
||
settingItem(icon: "info.circle", text: "Terms of Use")
|
||
.onTapGesture {
|
||
// Code to show About View
|
||
self.showingFullSafari = true
|
||
currentSafariURL = globalEnvironment.userTermsURL
|
||
}
|
||
|
||
// About
|
||
settingItem(icon: "info.circle", text: "Privacy Policy")
|
||
.onTapGesture {
|
||
// Code to show About View
|
||
self.showingFullSafari = true
|
||
currentSafariURL = globalEnvironment.userPrivacyURL
|
||
}
|
||
|
||
// Restore Purchases
|
||
settingItem(icon: "arrow.clockwise.circle", text: "Restore Purchases", isBold: true)
|
||
.onTapGesture {
|
||
restorePurchase()
|
||
}
|
||
|
||
}
|
||
.fullScreenCover(isPresented: $showingFullSafari) {
|
||
FullScreenSafariView(url: URL(string: currentSafariURL)!, onDismiss: {
|
||
self.showingFullSafari = false
|
||
})
|
||
}
|
||
|
||
// 留出手势操作的空间,但UI上隐藏掉
|
||
gestureArea
|
||
|
||
if showingAdvancedSettings {
|
||
VStack {
|
||
Toggle("Sandbox", isOn: $useSandboxEnvironment)
|
||
Toggle("TestEnv", isOn: $useDevelopmentEnvironment)
|
||
Button("Save") {
|
||
saveSettings()
|
||
showingAdvancedSettings = false
|
||
}
|
||
}
|
||
.padding(.vertical,10)
|
||
.padding(.horizontal, 20)
|
||
.background(Color.white) // Ensure background fills the view
|
||
.cornerRadius(5)
|
||
}
|
||
|
||
}
|
||
.background(Color.pink.opacity(0.2)) // Ensure background fills the view
|
||
.navigationBarTitle("Settings", displayMode: .inline)
|
||
.fullScreenCover(isPresented: $showVIPPaymentView) {
|
||
VIPPaymentView()
|
||
}
|
||
.onDisappear {
|
||
self.showingAdvancedSettings = false // 确保隐藏组件在视图消失时不显示
|
||
}
|
||
}
|
||
.toast(isPresented: $showingToast, dismissAfter: globalEnvironment.toastPresentMsNormal) {
|
||
HStack {
|
||
Image(systemName: "exclamationmark.bubble")
|
||
.foregroundColor(.yellow)
|
||
Text(toastText)
|
||
.foregroundColor(.black)
|
||
}
|
||
.padding()
|
||
.background(Color.white)
|
||
.cornerRadius(8)
|
||
.shadow(radius: 10)
|
||
}
|
||
// 加载指示器
|
||
if isLoading {
|
||
LoadingView()
|
||
}
|
||
}
|
||
|
||
// 定义隐藏功能
|
||
private var gestureArea: some View {
|
||
Color.clear
|
||
.contentShape(Rectangle()) // 为透明色定义一个矩形可命中区域
|
||
.frame(height: 150) // 可以根据需要调整手势区域的大小
|
||
.gesture(
|
||
DragGesture(minimumDistance: 50, coordinateSpace: .global)
|
||
.onEnded { value in
|
||
// 检查水平移动距离是否足够长,同时限制垂直移动不太大
|
||
if abs(value.translation.width) > 50 && abs(value.translation.height) < 100 {
|
||
// 切换高级设置的显示状态
|
||
logger.info("Advanced Settings.")
|
||
showingAdvancedSettings.toggle()
|
||
}
|
||
}
|
||
)
|
||
}
|
||
|
||
// 实现保存设置的逻辑
|
||
private func saveSettings() {
|
||
globalEnvironment.SetEnv(isSandBox: useSandboxEnvironment, isTestEnv: useDevelopmentEnvironment)
|
||
}
|
||
|
||
@ViewBuilder
|
||
private func settingItem(icon: String, text: String, isBold: Bool = false) -> some View {
|
||
HStack {
|
||
Image(systemName: icon) // Icon on the left side
|
||
.foregroundColor(.gray)
|
||
Text(text)
|
||
.font(.subheadline)
|
||
.fontWeight(isBold ? .bold : .regular) // Conditional bold based on isBold parameter
|
||
.padding(4)
|
||
Spacer()
|
||
}
|
||
.padding()
|
||
.background(Color.white) // Background for each setting item
|
||
.padding(.horizontal, 0) // Add some horizontal padding
|
||
|
||
// Indent divider to align with the text and extend to the edge
|
||
Divider()
|
||
.padding(.leading, 30)
|
||
.padding(.trailing, 10)
|
||
}
|
||
|
||
private func openAppStoreFeedback() {
|
||
let appID = globalEnvironment.APPID // 替换为您的应用ID
|
||
let urlStr = "https://apps.apple.com/app/id\(appID)?action=write-review"
|
||
if let url = URL(string: urlStr) {
|
||
UIApplication.shared.open(url, options: [:], completionHandler: nil)
|
||
}
|
||
}
|
||
|
||
func restorePurchase(){
|
||
Task {
|
||
await iapManager.restorePurchases() { result in
|
||
switch result {
|
||
case .success(_):
|
||
self.toastText = "Restored Sucess!"
|
||
self.showingToast = true
|
||
case .failure(_):
|
||
self.toastText = "Oh, something went wrong, please try again later."
|
||
self.showingToast = true
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// 模拟加载数据
|
||
func loadData() {
|
||
isLoading = true
|
||
}
|
||
func loadComplete(){
|
||
isLoading = false
|
||
}
|
||
|
||
}
|
||
|
||
struct SettingsView_Previews: PreviewProvider {
|
||
static var previews: some View {
|
||
SettingsView()
|
||
}
|
||
}
|
||
|
||
|
||
#Preview {
|
||
SettingsView()
|
||
}
|