Files
MatchLiveTv/native/ios/MatchLiveTv/UI/Navigation/AppNavHost.swift
T
Emiliano FrascaroandCursor ea5da1eb86 Allinea iOS a i18n Android 2.0.5 e aggiunge monitoraggio termico nativo.
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>
2026-07-24 11:19:37 +02:00

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)
}
}