feat: 更新API相关逻辑及视图结构

- 在Info.plist中新增API签名密钥配置。
- 将Splash视图替换为SplashV2,优化启动逻辑和用户体验。
- 更新API请求中的User-Agent逻辑,使用UserAgentProvider提供的动态值。
- 在APILogger中添加敏感信息脱敏处理,增强安全性。
- 新增CreateFeedPage视图,支持用户发布动态功能。
- 更新MainPage和Splash视图的导航逻辑,整合统一的AppRoute管理。
- 移除冗余的SplashFeature视图,提升代码整洁性和可维护性。
This commit is contained in:
edwinQQQ
2025-09-17 16:37:21 +08:00
parent c57bde4525
commit 8b4eb9cb7e
23 changed files with 640 additions and 646 deletions

View File

@@ -16,6 +16,7 @@ class LoginViewModel: ObservableObject {
// MARK: - Callbacks
var onLoginSuccess: (() -> Void)?
private var hasSentSuccess: Bool = false
// MARK: - Public Methods
func onIDLoginTapped() {
@@ -47,22 +48,20 @@ class LoginViewModel: ObservableObject {
}
func onLoginCompleted() {
guard !hasSentSuccess else { return }
isAnyLoginCompleted = true
showIDLogin = false
showEmailLogin = false
hasSentSuccess = true
onLoginSuccess?()
}
func onBackFromIDLogin() {
showIDLogin = false
if isAnyLoginCompleted {
onLoginSuccess?()
}
}
func onBackFromEmailLogin() {
showEmailLogin = false
if isAnyLoginCompleted {
onLoginSuccess?()
}
}
}
@@ -73,78 +72,76 @@ struct LoginPage: View {
let onLoginSuccess: () -> Void
var body: some View {
NavigationStack {
GeometryReader { geometry in
ZStack {
backgroundView
VStack(spacing: 0) {
Image("top")
.resizable()
.aspectRatio(375/400, contentMode: .fit)
.frame(maxWidth: .infinity)
GeometryReader { geometry in
ZStack {
backgroundView
VStack(spacing: 0) {
Image("top")
.resizable()
.aspectRatio(375/400, contentMode: .fit)
.frame(maxWidth: .infinity)
HStack {
Text(LocalizedString("login.app_title", comment: ""))
.font(FontManager.adaptedFont(.bayonRegular, designSize: 56, for: geometry.size.width))
.foregroundColor(.white)
.padding(.leading, 20)
Spacer()
}
.padding(.bottom, 20) // top
HStack {
Text(LocalizedString("login.app_title", comment: ""))
.font(FontManager.adaptedFont(.bayonRegular, designSize: 56, for: geometry.size.width))
.foregroundColor(.white)
.padding(.leading, 20)
Spacer()
bottomSection
}
.padding(.bottom, 20)
// -
languageSettingsButton
.position(x: geometry.size.width - 40, y: 60)
Spacer()
APILoadingEffectView()
bottomSection
}
// -
languageSettingsButton
.position(x: geometry.size.width - 40, y: 60)
APILoadingEffectView()
}
.ignoresSafeArea()
}
.ignoresSafeArea()
.navigationBarHidden(true)
.navigationDestination(isPresented: $viewModel.showIDLogin) {
IDLoginPage(
onBack: {
viewModel.onBackFromIDLogin()
},
onLoginSuccess: {
viewModel.onLoginCompleted()
}
)
.navigationBarHidden(true)
.navigationDestination(isPresented: $viewModel.showIDLogin) {
IDLoginPage(
onBack: {
viewModel.onBackFromIDLogin()
},
onLoginSuccess: {
viewModel.onLoginCompleted()
}
)
.navigationBarHidden(true)
}
.navigationDestination(isPresented: $viewModel.showEmailLogin) {
EMailLoginPage(
onBack: {
viewModel.onBackFromEmailLogin()
},
onLoginSuccess: {
viewModel.onLoginCompleted()
}
)
.navigationBarHidden(true)
}
.sheet(isPresented: $viewModel.showLanguageSettings) {
LanguageSettingsView(isPresented: $viewModel.showLanguageSettings)
}
.webView(
isPresented: $viewModel.showUserAgreement,
url: APIConfiguration.webURL(for: .userAgreement)
}
.navigationDestination(isPresented: $viewModel.showEmailLogin) {
EMailLoginPage(
onBack: {
viewModel.onBackFromEmailLogin()
},
onLoginSuccess: {
viewModel.onLoginCompleted()
}
)
.webView(
isPresented: $viewModel.showPrivacyPolicy,
url: APIConfiguration.webURL(for: .privacyPolicy)
)
.alert(LocalizedString("login.agreement_alert_title", comment: ""), isPresented: $viewModel.showAgreementAlert) {
Button(LocalizedString("login.agreement_alert_confirm", comment: "")) { }
} message: {
Text(LocalizedString("login.agreement_alert_message", comment: ""))
}
.navigationBarHidden(true)
}
.sheet(isPresented: $viewModel.showLanguageSettings) {
LanguageSettingsView(isPresented: $viewModel.showLanguageSettings)
}
.webView(
isPresented: $viewModel.showUserAgreement,
url: APIConfiguration.webURL(for: .userAgreement)
)
.webView(
isPresented: $viewModel.showPrivacyPolicy,
url: APIConfiguration.webURL(for: .privacyPolicy)
)
.alert(LocalizedString("login.agreement_alert_title", comment: ""), isPresented: $viewModel.showAgreementAlert) {
Button(LocalizedString("login.agreement_alert_confirm", comment: "")) { }
} message: {
Text(LocalizedString("login.agreement_alert_message", comment: ""))
}
.onAppear {
viewModel.onLoginSuccess = onLoginSuccess