
- 在APIEndpoints.swift中新增tcToken端点以支持腾讯云COS Token获取。 - 在APIModels.swift中新增TcTokenRequest和TcTokenResponse模型,处理Token请求和响应。 - 在COSManager.swift中实现Token的获取、缓存和过期管理逻辑,提升API请求的安全性。 - 在LanguageSettingsView中添加调试功能,允许测试COS Token获取。 - 在多个视图中更新状态管理和导航逻辑,确保用户体验一致性。 - 在FeedFeature和HomeFeature中优化状态管理,简化视图逻辑。
204 lines
9.3 KiB
Swift
204 lines
9.3 KiB
Swift
import SwiftUI
|
||
import ComposableArchitecture
|
||
import Perception
|
||
|
||
// PreferenceKey 用于传递图片高度
|
||
struct ImageHeightPreferenceKey: PreferenceKey {
|
||
static let defaultValue: CGFloat = 0
|
||
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
|
||
value = max(value, nextValue())
|
||
}
|
||
}
|
||
|
||
struct LoginView: View {
|
||
let store: StoreOf<LoginFeature>
|
||
let onLoginSuccess: () -> Void // 新增:登录成功回调
|
||
@State private var topImageHeight: CGFloat = 120 // 默认值
|
||
// @ObservedObject private var localizationManager = LocalizationManager.shared
|
||
@State private var showLanguageSettings = false
|
||
@State private var isAgreedToTerms = true
|
||
@State private var showUserAgreement = false
|
||
@State private var showPrivacyPolicy = false
|
||
@State private var showIDLogin = false // 使用SwiftUI的@State管理导航
|
||
@State private var showEmailLogin = false // 新增:邮箱登录导航状态
|
||
|
||
var body: some View {
|
||
WithViewStore(self.store, observe: { $0.isAnyLoginCompleted }) { viewStore in
|
||
NavigationStack {
|
||
GeometryReader { geometry in
|
||
WithPerceptionTracking {
|
||
ZStack {
|
||
// 使用与 splash 相同的背景图片
|
||
Image("bg")
|
||
.resizable()
|
||
.aspectRatio(contentMode: .fill)
|
||
.ignoresSafeArea(.all)
|
||
VStack(spacing: 0) {
|
||
// 上半部分的"top"图片
|
||
ZStack {
|
||
Image("top")
|
||
.resizable()
|
||
.aspectRatio(contentMode: .fit)
|
||
.frame(maxWidth: .infinity)
|
||
.padding(.top, -100)
|
||
.background(
|
||
GeometryReader { topImageGeometry in
|
||
Color.clear.preference(key: ImageHeightPreferenceKey.self, value: topImageGeometry.size.height)
|
||
}
|
||
)
|
||
// E-PARTI 文本,底部对齐"top"图片底部,间距20
|
||
HStack {
|
||
Text(NSLocalizedString("login.app_title", comment: ""))
|
||
.font(FontManager.adaptedFont(.bayonRegular, designSize: 56, for: geometry.size.width))
|
||
.foregroundColor(.white)
|
||
.padding(.leading, 20)
|
||
Spacer()
|
||
}
|
||
.padding(.top, max(0, topImageHeight - 100)) // top图片高度 - 140
|
||
|
||
// 语言切换按钮(右上角)- 仅在 Debug 环境下显示
|
||
#if DEBUG
|
||
VStack {
|
||
HStack {
|
||
Spacer()
|
||
Button(action: {
|
||
showLanguageSettings = true
|
||
}) {
|
||
Image(systemName: "globe")
|
||
.frame(width: 40, height: 40)
|
||
.font(.system(size: 20))
|
||
.foregroundColor(.white)
|
||
.background(Color.black.opacity(0.3))
|
||
.clipShape(Circle())
|
||
}
|
||
.padding(.trailing, 16)
|
||
}
|
||
Spacer()
|
||
}
|
||
#endif
|
||
|
||
VStack(spacing: 24) {
|
||
// ID Login 按钮
|
||
LoginButton(
|
||
iconName: "person.circle.fill",
|
||
iconColor: .green,
|
||
title: NSLocalizedString("login.id_login", comment: "")
|
||
) {
|
||
showIDLogin = true // 直接设置SwiftUI状态
|
||
}
|
||
// Email Login 按钮
|
||
LoginButton(
|
||
iconName: "envelope.fill",
|
||
iconColor: .blue,
|
||
title: NSLocalizedString("login.email_login", comment: "")
|
||
) {
|
||
showEmailLogin = true // 显示邮箱登录界面
|
||
}
|
||
}.padding(.top, max(0, topImageHeight+140))
|
||
}
|
||
.onPreferenceChange(ImageHeightPreferenceKey.self) { imageHeight in
|
||
topImageHeight = imageHeight
|
||
}
|
||
|
||
// 间距,使登录按钮区域顶部距离"top"图片底部40pt
|
||
Spacer()
|
||
.frame(height: 120)
|
||
|
||
// 用户协议组件
|
||
UserAgreementView(
|
||
isAgreed: $isAgreedToTerms,
|
||
onUserServiceTapped: {
|
||
showUserAgreement = true
|
||
},
|
||
onPrivacyPolicyTapped: {
|
||
showPrivacyPolicy = true
|
||
}
|
||
)
|
||
.padding(.horizontal, 28)
|
||
.padding(.bottom, 140)
|
||
}
|
||
|
||
// 移除旧的 NavigationLink,改用 navigationDestination
|
||
}
|
||
}
|
||
}
|
||
.navigationBarHidden(true)
|
||
// 新增:适配 iOS 16 的 navigationDestination
|
||
.navigationDestination(isPresented: $showIDLogin) {
|
||
WithPerceptionTracking {
|
||
IDLoginView(
|
||
store: store.scope(
|
||
state: \.idLoginState,
|
||
action: \.idLogin
|
||
),
|
||
onBack: {
|
||
showIDLogin = false
|
||
},
|
||
showIDLogin: $showIDLogin // 新增:传递Binding
|
||
)
|
||
.navigationBarHidden(true)
|
||
}
|
||
}
|
||
.navigationDestination(isPresented: $showEmailLogin) {
|
||
WithPerceptionTracking {
|
||
EMailLoginView(
|
||
store: store.scope(
|
||
state: \.emailLoginState,
|
||
action: \.emailLogin
|
||
),
|
||
onBack: {
|
||
showEmailLogin = false
|
||
},
|
||
showEmailLogin: $showEmailLogin // 新增:传递Binding
|
||
)
|
||
.navigationBarHidden(true)
|
||
}
|
||
}
|
||
// 移除:HomeView 的 navigationDestination
|
||
}
|
||
.sheet(isPresented: $showLanguageSettings) {
|
||
WithPerceptionTracking {
|
||
LanguageSettingsView(isPresented: $showLanguageSettings)
|
||
}
|
||
}
|
||
.webView(
|
||
isPresented: $showUserAgreement,
|
||
url: APIConfiguration.webURL(for: .userAgreement)
|
||
)
|
||
.webView(
|
||
isPresented: $showPrivacyPolicy,
|
||
url: APIConfiguration.webURL(for: .privacyPolicy)
|
||
)
|
||
// 新增:监听登录成功,调用回调
|
||
.onChange(of: viewStore.state) { completed in
|
||
if completed {
|
||
onLoginSuccess()
|
||
}
|
||
}
|
||
// 新增:监听showIDLogin关闭时,若已登录则跳转首页
|
||
.onChange(of: showIDLogin) { newValue in
|
||
if newValue == false && viewStore.state {
|
||
onLoginSuccess()
|
||
}
|
||
}
|
||
// 新增:监听showEmailLogin关闭时,若已登录则跳转首页
|
||
.onChange(of: showEmailLogin) { newValue in
|
||
if newValue == false && viewStore.state {
|
||
onLoginSuccess()
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//#Preview {
|
||
// LoginView(
|
||
// store: Store(
|
||
// initialState: LoginFeature.State()
|
||
// ) {
|
||
// LoginFeature()
|
||
// },
|
||
// onLoginSuccess: {}
|
||
// )
|
||
//}
|