feat: about us
This commit is contained in:
parent
c9a2f760d9
commit
b89b3b0cc4
9
wake/Assets/Svg/AboutIP.svg
Normal file
9
wake/Assets/Svg/AboutIP.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 18 KiB |
@ -12,6 +12,8 @@ enum AppRoute: Hashable {
|
|||||||
case memories
|
case memories
|
||||||
case subscribe
|
case subscribe
|
||||||
case userInfo
|
case userInfo
|
||||||
|
case account
|
||||||
|
case about
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
var view: some View {
|
var view: some View {
|
||||||
@ -36,6 +38,10 @@ enum AppRoute: Hashable {
|
|||||||
SubscribeView()
|
SubscribeView()
|
||||||
case .userInfo:
|
case .userInfo:
|
||||||
UserInfo()
|
UserInfo()
|
||||||
|
case .account:
|
||||||
|
AccountView()
|
||||||
|
case .about:
|
||||||
|
AboutUsView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
157
wake/View/Owner/AboutUsView.swift
Normal file
157
wake/View/Owner/AboutUsView.swift
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct AboutUsView: View {
|
||||||
|
// MARK: - Properties
|
||||||
|
|
||||||
|
private let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "1.0.0"
|
||||||
|
private let buildNumber = Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "1"
|
||||||
|
|
||||||
|
// MARK: - Body
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
// Background color
|
||||||
|
Color.themeTextWhiteSecondary
|
||||||
|
.edgesIgnoringSafeArea(.all)
|
||||||
|
|
||||||
|
VStack(spacing: 0) {
|
||||||
|
// Navigation Header
|
||||||
|
SimpleNaviHeader(title: "About Us") {
|
||||||
|
Router.shared.pop()
|
||||||
|
}
|
||||||
|
.padding(.top, UIApplication.shared.windows.first?.safeAreaInsets.top ?? 0)
|
||||||
|
|
||||||
|
// Main Content
|
||||||
|
VStack(spacing: 0) {
|
||||||
|
// IP Address Section
|
||||||
|
VStack(spacing: 12) {
|
||||||
|
SVGImage(svgName: "AboutIP")
|
||||||
|
.frame(width: 102, height: 102)
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.padding(.vertical, 32)
|
||||||
|
|
||||||
|
// Version & ICP Info
|
||||||
|
VStack(spacing: 12) {
|
||||||
|
Text("Version : 1.1.1")
|
||||||
|
.font(.system(size: 12))
|
||||||
|
.foregroundColor(.themeTextMessageMain)
|
||||||
|
|
||||||
|
Text("ICP 备案号: 京ICP备XXXXXXXX号")
|
||||||
|
.font(.system(size: 12))
|
||||||
|
.foregroundColor(.themeTextMessageMain)
|
||||||
|
}
|
||||||
|
.padding(.bottom, 32)
|
||||||
|
// Legal Links
|
||||||
|
VStack(spacing: 0) {
|
||||||
|
settingRow(
|
||||||
|
title: "Terms of Service",
|
||||||
|
action: {
|
||||||
|
withAnimation {
|
||||||
|
if let url = URL(string: "https://example.com/terms") {
|
||||||
|
UIApplication.shared.open(url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.padding()
|
||||||
|
settingRow(
|
||||||
|
title: "Privacy Policy",
|
||||||
|
action: {
|
||||||
|
withAnimation {
|
||||||
|
if let url = URL(string: "https://example.com/terms") {
|
||||||
|
UIApplication.shared.open(url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.padding()
|
||||||
|
settingRow(
|
||||||
|
title: "AI Usage Guidelines",
|
||||||
|
action: {
|
||||||
|
withAnimation {
|
||||||
|
if let url = URL(string: "https://example.com/terms") {
|
||||||
|
UIApplication.shared.open(url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.padding()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.background(Color.white)
|
||||||
|
.cornerRadius(16)
|
||||||
|
.padding()
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.navigationBarHidden(true)
|
||||||
|
.edgesIgnoringSafeArea(.all)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func settingRow(title: String, action: @escaping () -> Void) -> some View {
|
||||||
|
Button(action: action) {
|
||||||
|
HStack {
|
||||||
|
// 标题
|
||||||
|
Text(title)
|
||||||
|
.foregroundColor(.primary)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
// 右侧箭头
|
||||||
|
Image(systemName: "chevron.right")
|
||||||
|
.font(.system(size: 14))
|
||||||
|
.foregroundColor(.gray)
|
||||||
|
}
|
||||||
|
.padding(.vertical, 12) // 增加垂直内边距
|
||||||
|
.background(Color.white)
|
||||||
|
}
|
||||||
|
.buttonStyle(PlainButtonStyle())
|
||||||
|
.listRowBackground(Color.white)
|
||||||
|
.listRowSeparator(.hidden)
|
||||||
|
}
|
||||||
|
// MARK: - Private Methods
|
||||||
|
|
||||||
|
private func getIPAddress() -> String? {
|
||||||
|
var address: String?
|
||||||
|
var ifaddr: UnsafeMutablePointer<ifaddrs>?
|
||||||
|
|
||||||
|
if getifaddrs(&ifaddr) == 0 {
|
||||||
|
var ptr = ifaddr
|
||||||
|
while ptr != nil {
|
||||||
|
defer { ptr = ptr?.pointee.ifa_next }
|
||||||
|
|
||||||
|
let interface = ptr?.pointee
|
||||||
|
let addrFamily = interface?.ifa_addr.pointee.sa_family
|
||||||
|
|
||||||
|
if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6),
|
||||||
|
let name = interface?.ifa_name,
|
||||||
|
String(cString: name) == "en0",
|
||||||
|
let addr = interface?.ifa_addr {
|
||||||
|
|
||||||
|
var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
|
||||||
|
getnameinfo(addr, socklen_t(addr.pointee.sa_len),
|
||||||
|
&hostname, socklen_t(hostname.count),
|
||||||
|
nil, socklen_t(0),
|
||||||
|
NI_NUMERICHOST)
|
||||||
|
address = String(cString: hostname)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
freeifaddrs(ifaddr)
|
||||||
|
}
|
||||||
|
|
||||||
|
return address
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Preview
|
||||||
|
#Preview {
|
||||||
|
AboutUsView()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Dependencies
|
||||||
|
import Foundation
|
||||||
|
import SystemConfiguration
|
||||||
|
import Network
|
||||||
|
import Darwin
|
||||||
@ -1,112 +0,0 @@
|
|||||||
import SwiftUI
|
|
||||||
|
|
||||||
/// 设置页面视图
|
|
||||||
struct AccountView: View {
|
|
||||||
// MARK: - 属性
|
|
||||||
|
|
||||||
/// 环境变量 - 用于dismiss视图
|
|
||||||
@Environment(\.dismiss) private var dismiss
|
|
||||||
|
|
||||||
/// 状态 - 控制视图显示/隐藏
|
|
||||||
@Binding var isAccountPresented: Bool
|
|
||||||
|
|
||||||
// MARK: - 动画配置
|
|
||||||
|
|
||||||
/// 动画配置
|
|
||||||
private let animation = Animation.spring(
|
|
||||||
response: 0.6, // 响应时间
|
|
||||||
dampingFraction: 0.9, // 阻尼系数
|
|
||||||
blendDuration: 0.8 // 混合时间
|
|
||||||
)
|
|
||||||
|
|
||||||
// MARK: - 主体视图
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
ZStack {
|
|
||||||
// Theme background color
|
|
||||||
Color.themeTextWhiteSecondary.edgesIgnoringSafeArea(.all)
|
|
||||||
|
|
||||||
VStack(spacing: 0) {
|
|
||||||
// 简洁导航头
|
|
||||||
SimpleNaviHeader(title: "Account & Security") {
|
|
||||||
withAnimation(animation) {
|
|
||||||
isAccountPresented = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置项列表
|
|
||||||
List {
|
|
||||||
// 账号与安全
|
|
||||||
settingRow(
|
|
||||||
icon: "Account",
|
|
||||||
title: "Account & Security",
|
|
||||||
action: {}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
.background(Color.white)
|
|
||||||
.cornerRadius(12)
|
|
||||||
.padding()
|
|
||||||
.listStyle(PlainListStyle())
|
|
||||||
.listRowSeparator(.hidden)
|
|
||||||
.listRowInsets(EdgeInsets())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.background(Color.themeTextWhiteSecondary.edgesIgnoringSafeArea(.all))
|
|
||||||
.environment(\.horizontalSizeClass, .regular)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - 私有方法
|
|
||||||
|
|
||||||
/// 配置TableView外观
|
|
||||||
private func configureTableView() {
|
|
||||||
// 移除列表底部分隔线
|
|
||||||
UITableView.appearance().tableFooterView = UIView()
|
|
||||||
// 移除列表顶部分隔线
|
|
||||||
UITableView.appearance().tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: CGFloat.leastNonzeroMagnitude))
|
|
||||||
// 移除分隔线缩进
|
|
||||||
UITableView.appearance().separatorInset = .zero
|
|
||||||
// 移除列表顶部额外间距
|
|
||||||
UITableView.appearance().contentInset = .zero
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 创建设置项行视图
|
|
||||||
/// - Parameters:
|
|
||||||
/// - icon: 图标名称
|
|
||||||
/// - title: 标题
|
|
||||||
/// - action: 点击动作
|
|
||||||
/// - Returns: 返回设置项行视图
|
|
||||||
private func settingRow(icon: String, title: String, action: @escaping () -> Void) -> some View {
|
|
||||||
Button(action: action) {
|
|
||||||
HStack {
|
|
||||||
// 左侧图标
|
|
||||||
SVGImage(svgName: icon)
|
|
||||||
.frame(width: 24, height: 24)
|
|
||||||
|
|
||||||
// 标题
|
|
||||||
Text(title)
|
|
||||||
.foregroundColor(.primary)
|
|
||||||
|
|
||||||
Spacer()
|
|
||||||
|
|
||||||
// 右侧箭头
|
|
||||||
Image(systemName: "chevron.right")
|
|
||||||
.font(.system(size: 14))
|
|
||||||
.foregroundColor(.gray)
|
|
||||||
}
|
|
||||||
.padding(.vertical, 12) // 增加垂直内边距
|
|
||||||
.background(Color.white)
|
|
||||||
}
|
|
||||||
.buttonStyle(PlainButtonStyle())
|
|
||||||
.listRowBackground(Color.white)
|
|
||||||
.listRowSeparator(.hidden)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - 预览
|
|
||||||
#Preview {
|
|
||||||
NavigationView {
|
|
||||||
AccountView(isAccountPresented: .constant(true))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
187
wake/View/Owner/AccountView.swift
Normal file
187
wake/View/Owner/AccountView.swift
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
/// 设置页面视图
|
||||||
|
struct AccountView: View {
|
||||||
|
// MARK: - 属性
|
||||||
|
|
||||||
|
/// 环境变量 - 用于dismiss视图
|
||||||
|
@Environment(\.dismiss) private var dismiss
|
||||||
|
|
||||||
|
/// 控制删除确认弹窗显示
|
||||||
|
@State private var showDeleteConfirmation = false
|
||||||
|
|
||||||
|
// MARK: - 动画配置
|
||||||
|
|
||||||
|
/// 动画配置
|
||||||
|
private let animation = Animation.spring(
|
||||||
|
response: 0.6, // 响应时间
|
||||||
|
dampingFraction: 0.9, // 阻尼系数
|
||||||
|
blendDuration: 0.8 // 混合时间
|
||||||
|
)
|
||||||
|
|
||||||
|
// MARK: - 主体视图
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ZStack {
|
||||||
|
// Theme background color
|
||||||
|
Color.themeTextWhiteSecondary
|
||||||
|
.edgesIgnoringSafeArea(.all)
|
||||||
|
|
||||||
|
VStack(spacing: 0) {
|
||||||
|
// 自定义导航头
|
||||||
|
SimpleNaviHeader(title: "Account & Security") {
|
||||||
|
withAnimation(animation) {
|
||||||
|
Router.shared.pop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding(.top, UIApplication.shared.windows.first?.safeAreaInsets.top)
|
||||||
|
|
||||||
|
// 内容区域
|
||||||
|
ScrollView {
|
||||||
|
VStack(spacing: 0) {
|
||||||
|
// 删除账号
|
||||||
|
settingRow(
|
||||||
|
title: "Delete Account",
|
||||||
|
action: {
|
||||||
|
withAnimation {
|
||||||
|
showDeleteConfirmation = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.padding()
|
||||||
|
}
|
||||||
|
.background(Color.white)
|
||||||
|
.cornerRadius(12)
|
||||||
|
.padding(.horizontal)
|
||||||
|
}
|
||||||
|
.background(Color.themeTextWhiteSecondary)
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||||
|
.edgesIgnoringSafeArea(.top)
|
||||||
|
}
|
||||||
|
.edgesIgnoringSafeArea(.all)
|
||||||
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||||
|
.overlay(
|
||||||
|
// 删除确认弹窗
|
||||||
|
Group {
|
||||||
|
if showDeleteConfirmation {
|
||||||
|
ZStack {
|
||||||
|
// 半透明黑色遮罩
|
||||||
|
Color.black.opacity(0.6)
|
||||||
|
.edgesIgnoringSafeArea(.all)
|
||||||
|
.onTapGesture {
|
||||||
|
withAnimation {
|
||||||
|
showDeleteConfirmation = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认弹窗内容
|
||||||
|
VStack(spacing: 20) {
|
||||||
|
Text("Are you sure you want to delete this account?")
|
||||||
|
.font(.headline)
|
||||||
|
.font(.system(size: 14, weight: .medium))
|
||||||
|
.foregroundColor(.themeTextMessageMain)
|
||||||
|
|
||||||
|
|
||||||
|
Text("Once deleted, you can’t get it back.")
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
.font(.subheadline)
|
||||||
|
.font(.system(size: 12))
|
||||||
|
.foregroundColor(.themeTextMessage)
|
||||||
|
|
||||||
|
HStack(spacing: 20) {
|
||||||
|
Button(action: {
|
||||||
|
withAnimation {
|
||||||
|
showDeleteConfirmation = false
|
||||||
|
}
|
||||||
|
}) {
|
||||||
|
Text("Cancel")
|
||||||
|
.font(Typography.font(for: .subtitle, family: .quicksandBold))
|
||||||
|
.foregroundColor(.themeTextMessageMain)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.padding()
|
||||||
|
.background(Color.themePrimary)
|
||||||
|
.cornerRadius(32)
|
||||||
|
}
|
||||||
|
|
||||||
|
Button(action: {
|
||||||
|
// 处理删除账号逻辑
|
||||||
|
withAnimation {
|
||||||
|
showDeleteConfirmation = false
|
||||||
|
}
|
||||||
|
// TODO: 调用删除账号的API
|
||||||
|
}) {
|
||||||
|
Text("Confirm")
|
||||||
|
.foregroundColor(.themeTextMessage)
|
||||||
|
.font(.system(size: 12))
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.padding()
|
||||||
|
.background(Color.white)
|
||||||
|
.cornerRadius(32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
.frame(width: 300)
|
||||||
|
.background(Color.white)
|
||||||
|
.cornerRadius(12)
|
||||||
|
.shadow(radius: 10)
|
||||||
|
}
|
||||||
|
.transition(.opacity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.navigationBarBackButtonHidden(true) // 隐藏默认返回按钮
|
||||||
|
.navigationBarHidden(true) // 隐藏导航栏
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - 私有方法
|
||||||
|
|
||||||
|
/// 配置TableView外观
|
||||||
|
private func configureTableView() {
|
||||||
|
// 移除列表底部分隔线
|
||||||
|
UITableView.appearance().tableFooterView = UIView()
|
||||||
|
// 移除列表顶部分隔线
|
||||||
|
UITableView.appearance().tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: CGFloat.leastNonzeroMagnitude))
|
||||||
|
// 移除分隔线缩进
|
||||||
|
UITableView.appearance().separatorInset = .zero
|
||||||
|
// 移除列表顶部额外间距
|
||||||
|
UITableView.appearance().contentInset = .zero
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 创建设置项行视图
|
||||||
|
/// - Parameters:
|
||||||
|
/// - icon: 图标名称
|
||||||
|
/// - title: 标题
|
||||||
|
/// - action: 点击动作
|
||||||
|
/// - Returns: 返回设置项行视图
|
||||||
|
private func settingRow(title: String, action: @escaping () -> Void) -> some View {
|
||||||
|
Button(action: action) {
|
||||||
|
HStack {
|
||||||
|
|
||||||
|
// 标题
|
||||||
|
Text(title)
|
||||||
|
.foregroundColor(.primary)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
// 右侧箭头
|
||||||
|
Image(systemName: "chevron.right")
|
||||||
|
.font(.system(size: 14))
|
||||||
|
.foregroundColor(.gray)
|
||||||
|
}
|
||||||
|
.padding(.vertical, 12) // 增加垂直内边距
|
||||||
|
.background(Color.white)
|
||||||
|
}
|
||||||
|
.buttonStyle(PlainButtonStyle())
|
||||||
|
.listRowBackground(Color.white)
|
||||||
|
.listRowSeparator(.hidden)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - 预览
|
||||||
|
#Preview {
|
||||||
|
NavigationView {
|
||||||
|
AccountView()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,8 +9,7 @@ struct SettingsView: View {
|
|||||||
|
|
||||||
/// 状态 - 控制视图显示/隐藏
|
/// 状态 - 控制视图显示/隐藏
|
||||||
@Binding var isPresented: Bool
|
@Binding var isPresented: Bool
|
||||||
|
@State private var isShowingAccountView = false
|
||||||
@State private var showAccountView = false
|
|
||||||
|
|
||||||
// MARK: - 动画配置
|
// MARK: - 动画配置
|
||||||
|
|
||||||
@ -43,8 +42,8 @@ struct SettingsView: View {
|
|||||||
settingRow(
|
settingRow(
|
||||||
icon: "Account",
|
icon: "Account",
|
||||||
title: "Account & Security",
|
title: "Account & Security",
|
||||||
action: {
|
action: {
|
||||||
// Action will be handled by NavigationLink
|
Router.shared.navigate(to: .account)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -66,7 +65,9 @@ struct SettingsView: View {
|
|||||||
settingRow(
|
settingRow(
|
||||||
icon: "AboutUs",
|
icon: "AboutUs",
|
||||||
title: "About Us",
|
title: "About Us",
|
||||||
action: {}
|
action: {
|
||||||
|
Router.shared.navigate(to: .about)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.background(Color.white)
|
.background(Color.white)
|
||||||
@ -80,6 +81,7 @@ struct SettingsView: View {
|
|||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.navigationBarHidden(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user