wake-ios/wake/View/Gate/GateView.swift

109 lines
4.4 KiB
Swift

import SwiftUI
struct GateView: View {
@EnvironmentObject private var router: Router
@State private var isNavigated = false
@State private var isLoading = true
@State private var errorMessage: String? = nil
var body: some View {
ZStack {
Color.themeTextWhiteSecondary.ignoresSafeArea()
if isLoading {
VStack(spacing: 16) {
ProgressView()
Text("Loading...")
.font(Typography.font(for: .body))
.foregroundColor(.themeTextMessage)
}
} else if let error = errorMessage {
// Briefly inform the user, then auto-navigate to avatar page
VStack(spacing: 12) {
Text("Network error, going to Avatar setup...")
.font(Typography.font(for: .subtitle, family: .quicksandBold))
.foregroundColor(.themeTextMessageMain)
Text(error)
.font(.caption)
.foregroundColor(.themeTextMessage)
.multilineTextAlignment(.center)
.padding(.horizontal)
}
} else {
// Should not be seen because we auto-route when done
EmptyView()
}
}
.onAppear(perform: queryAndRoute)
.navigationBarBackButtonHidden(true)
}
private func queryAndRoute() {
guard !isNavigated else { return }
isLoading = true
errorMessage = nil
print("[Gate] Start queryAndRoute")
NetworkService.shared.get(
path: "/blind_boxs/query",
parameters: nil
) { (result: Result<APIResponse<[BlindList]>, NetworkError>) in
print("Query result: \(result)")
DispatchQueue.main.async {
isLoading = false
switch result {
case .success(let response):
let list = response.data ?? []
print("[Gate] Success, list count: \(list.count)")
let lowered = list.map { ($0.boxType).lowercased() }
let hasFirst = lowered.contains(where: { $0 == "first" })
let hasSecond = lowered.contains(where: { $0 == "second" })
let hasRetrieval = lowered.contains(where: { $0 == "retrievalgeneration" })
print("hasFirst: \(hasFirst), hasSecond: \(hasSecond), hasRetrieval: \(hasRetrieval)")
// Routing rules (updated):
// - If has 'second' OR 'retrievalgeneration' -> normal home
// - Else if only 'first' exists -> second onboarding page
// - Else -> avatar upload page
if hasSecond || hasRetrieval {
print("[Gate] Route -> BlindBox .all")
navigateOnce(to: .blindBox(mediaType: .all))
} else if hasFirst {
print("[Gate] Route -> SecondOnboardingView")
navigateOnce(to: .secondOnboarding)
} else {
print("[Gate] Route -> UserInfo (no first/second/retrieval)")
navigateOnce(to: .userInfo)
}
// Defensive fallback: if for any reason not navigated, push avatar after small delay
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
if !isNavigated {
print("[Gate] Fallback routing -> UserInfo")
navigateOnce(to: .userInfo)
}
}
case .failure(let error):
// Show an error briefly, then route to avatar page automatically
errorMessage = error.localizedDescription
print("Error: \(error.localizedDescription)")
DispatchQueue.main.asyncAfter(deadline: .now() + 0.8) {
navigateOnce(to: .userInfo)
}
}
}
}
}
private func navigateOnce(to destination: AppRoute) {
guard !isNavigated else { return }
isNavigated = true
router.navigate(to: destination)
}
}
#Preview {
GateView().environmentObject(Router.shared)
}