109 lines
4.4 KiB
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)
|
|
}
|