Add Lottie-based global loading overlay across key flows.

Introduce GlobalLoadingCenter with reference counting, wire it through RootView and major auth/order/profile screens, and add the loading animation asset plus unit tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-23 11:25:56 +08:00
parent 1d1eb46ed8
commit 7fd964fe19
17 changed files with 514 additions and 139 deletions

View File

@ -15,6 +15,7 @@ struct RootView: View {
@State private var scenicSpotContext = ScenicSpotContext()
@State private var appRouter = AppRouter()
@State private var toastCenter = ToastCenter()
@State private var globalLoading = GlobalLoadingCenter()
@State private var snapshotStore: AccountSnapshotStore
@State private var apiClient: APIClient
@State private var authAPI: AuthAPI
@ -66,12 +67,14 @@ struct RootView: View {
var body: some View {
rootContent
.globalToastOverlay()
.globalLoadingOverlay(loadingCenter: globalLoading)
.environment(appSession)
.environment(accountContext)
.environment(permissionContext)
.environment(scenicSpotContext)
.environment(appRouter)
.environment(toastCenter)
.environment(\.globalLoading, globalLoading)
.environment(snapshotStore)
.environment(apiClient)
.environment(authAPI)
@ -87,14 +90,16 @@ struct RootView: View {
.environment(authSessionCoordinator)
.task {
apiClient.bindAuthTokenProvider { appSession.token }
await sessionBootstrapper.restore(
appSession: appSession,
accountContext: accountContext,
permissionContext: permissionContext,
profileAPI: profileAPI,
accountContextAPI: accountContextAPI,
toastCenter: toastCenter
)
await globalLoading.withLoading {
await sessionBootstrapper.restore(
appSession: appSession,
accountContext: accountContext,
permissionContext: permissionContext,
profileAPI: profileAPI,
accountContextAPI: accountContextAPI,
toastCenter: toastCenter
)
}
}
.task(id: scenicSpotTaskID) {
guard appSession.isLoggedIn else {
@ -122,9 +127,8 @@ struct RootView: View {
case .loggedOut:
LoginView()
case .restoring:
ProgressView()
Color(.systemBackground)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color(.systemBackground))
case .loggedIn:
MainTabsView()
}