Completa L10n su login/hub/wizard/broadcast e introduce ThermalStateManager su iOS/Android con degradazione qualità e indicatore in overlay. Co-authored-by: Cursor <cursoragent@cursor.com>
98 lines
3.6 KiB
Swift
98 lines
3.6 KiB
Swift
import SwiftUI
|
|
|
|
struct AppNavHost: View {
|
|
@StateObject private var container = AppContainer()
|
|
@State private var path: [Routes] = []
|
|
@State private var wizardRoute: WizardRoute?
|
|
@State private var broadcastRoute: BroadcastRoute?
|
|
/// Incrementato al ritorno da wizard/broadcast per ricaricare l'hub partite.
|
|
@State private var matchesRefreshToken = 0
|
|
@State private var languageTick = 0
|
|
|
|
/// Locale SwiftUI (DatePicker, ecc.) aggiornata al cambio lingua senza resettare la NavigationStack.
|
|
private var appLocale: Locale {
|
|
_ = languageTick
|
|
return AppLanguage.locale
|
|
}
|
|
|
|
var body: some View {
|
|
NavigationStack(path: $path) {
|
|
SplashScreen(
|
|
container: container,
|
|
onAuthenticated: { path = [.matches] },
|
|
onUnauthenticated: { path = [.login] }
|
|
)
|
|
.navigationDestination(for: Routes.self) { route in
|
|
switch route {
|
|
case .splash:
|
|
EmptyView()
|
|
case .login:
|
|
LoginScreen(container: container) { path = [.matches] }
|
|
case .matches:
|
|
MatchesScreen(
|
|
container: container,
|
|
refreshToken: matchesRefreshToken,
|
|
onOpenSetup: { matchId in
|
|
wizardRoute = WizardRoute(matchId: matchId, step: 1)
|
|
},
|
|
onOpenBroadcast: { sessionId in
|
|
broadcastRoute = BroadcastRoute(sessionId: sessionId)
|
|
},
|
|
onLogout: { path = [.login] }
|
|
)
|
|
.lockPortraitOrientation()
|
|
case .setup, .broadcast:
|
|
EmptyView()
|
|
}
|
|
}
|
|
}
|
|
.environment(\.locale, appLocale)
|
|
.onReceive(NotificationCenter.default.publisher(for: .appLanguageDidChange)) { _ in
|
|
languageTick += 1
|
|
}
|
|
.lockPortraitOrientation()
|
|
.fullScreenCover(item: $wizardRoute) { route in
|
|
WizardShellScreen(
|
|
container: container,
|
|
matchId: route.matchId,
|
|
step: route.step,
|
|
onClose: {
|
|
container.wizardSession.reset()
|
|
wizardRoute = nil
|
|
matchesRefreshToken += 1
|
|
},
|
|
onStartLive: { sessionId in
|
|
wizardRoute = nil
|
|
broadcastRoute = BroadcastRoute(sessionId: sessionId)
|
|
}
|
|
)
|
|
.lockPortraitOrientation()
|
|
}
|
|
.fullScreenCover(item: $broadcastRoute, onDismiss: {
|
|
Task { @MainActor in
|
|
container.sessionCable.disconnect()
|
|
await container.broadcastCoordinator.forceStopBroadcast()
|
|
}
|
|
AppOrientation.lockPortrait()
|
|
matchesRefreshToken += 1
|
|
}) { route in
|
|
BroadcastScreen(container: container, sessionId: route.sessionId) {
|
|
Task { @MainActor in
|
|
await container.broadcastCoordinator.stopBroadcast(sessionId: route.sessionId)
|
|
}
|
|
AppOrientation.lockPortrait()
|
|
container.wizardSession.reset()
|
|
broadcastRoute = nil
|
|
path = [.matches]
|
|
}
|
|
.keepScreenOn()
|
|
}
|
|
.onChange(of: broadcastRoute?.sessionId) { sessionId in
|
|
if sessionId == nil {
|
|
AppOrientation.lockPortrait()
|
|
}
|
|
}
|
|
.environmentObject(container)
|
|
}
|
|
}
|