Dashboard: surface the nearest hazard and the next signal change
Two cards below the status cards, each shown only when there is something to show and each opening the V2X screen when tapped. Hazard: cause name, distance, and a count of the others behind it, ranked closest first. A hazard whose distance cannot be resolved, because there is no fix yet, sorts last rather than being dropped. Traffic light: the intersection changing soonest, its leading phase with a countdown, and every signal group as a colour-coded chip. The countdown runs on its own 500 ms clock rather than on SPATEM arrivals, so it cannot freeze mid-count and keep claiming a light is about to change after the RSU stops transmitting. Signals are ranked by time-to-change rather than by distance because SPATEM carries no position at all. Placing an intersection needs MAPEM geometry, which nothing on air is currently sending. Also fixes bottom-nav taps. One rule now applies to every tab: a tap lands on that tab's own screen, popping back to it when it is still on the stack so the gesture behaves exactly like Back or a back swipe. saveState/restoreState are gone, since on this flat graph a restored back stack brought back the sub-screen the rider was on instead of the tab root, which is the opposite of what the tap asked for. Tabs also now stay lit on the screens that belong to them.
This commit is contained in:
@@ -87,6 +87,12 @@ class MainActivity : AppCompatActivity() {
|
||||
val useCaseEnabledMap by mqttViewModel.useCaseEnabledMap.collectAsState()
|
||||
val obuHardware by mqttViewModel.obuHardware.collectAsState()
|
||||
val usbSerialState by mqttViewModel.usbSerialState.collectAsState()
|
||||
// Received hazards and live signal state, for the Dashboard's V2X summary cards.
|
||||
// Both flows already expire their own entries on a clock, so nothing here has to
|
||||
// decide when a hazard or a traffic light has gone stale.
|
||||
val denmEvents by mqttViewModel.denmEvents.collectAsState()
|
||||
val spatIntersections by mqttViewModel.spatIntersections.collectAsState()
|
||||
val ownCamPosition by mqttViewModel.ownCamPosition.collectAsState()
|
||||
|
||||
MicrOBUTheme(darkTheme = state.darkTheme) {
|
||||
val view = LocalView.current
|
||||
@@ -150,20 +156,29 @@ class MainActivity : AppCompatActivity() {
|
||||
usbCableConnected = usbConnected,
|
||||
obuStationTypeWarning = obuStationTypeWarning,
|
||||
obuStationType = obuStationType,
|
||||
hazards = denmEvents,
|
||||
signals = spatIntersections,
|
||||
ownPosition = ownCamPosition,
|
||||
onNavigateToConnection = { navController.navigate(Screen.Connection.route) },
|
||||
onNavigateToSensors = {
|
||||
navController.navigate(Screen.Sensors.route) {
|
||||
popUpTo(Screen.Dashboard.route) { saveState = true }
|
||||
popUpTo(Screen.Dashboard.route)
|
||||
launchSingleTop = true
|
||||
restoreState = true
|
||||
}
|
||||
},
|
||||
onNavigateToMap = { navController.navigate(Screen.Map.route) },
|
||||
onNavigateToRecord = {
|
||||
navController.navigate(Screen.Record.route) {
|
||||
popUpTo(Screen.Dashboard.route) { saveState = true }
|
||||
popUpTo(Screen.Dashboard.route)
|
||||
launchSingleTop = true
|
||||
}
|
||||
},
|
||||
// Same options the bottom bar uses, so arriving at V2X from a
|
||||
// Dashboard card leaves the same back stack as tapping the tab.
|
||||
onNavigateToV2x = {
|
||||
navController.navigate(Screen.MqttViewer.route) {
|
||||
popUpTo(Screen.Dashboard.route)
|
||||
launchSingleTop = true
|
||||
restoreState = true
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user