From aad5ae4024bc842d09b1baabd07d2f49af147619 Mon Sep 17 00:00:00 2001 From: Cilly Leang Date: Tue, 31 Mar 2026 20:53:21 +1100 Subject: [PATCH] refactor(ui/info): split up info panel state --- .../lava/banksia/ui/layout/info/InfoPanel.kt | 20 +++++++--- .../banksia/ui/layout/info/RouteInfoPanel.kt | 16 ++++++-- .../banksia/ui/layout/info/StopInfoPanel.kt | 20 ++++++++-- .../banksia/ui/layout/info/TripInfoPanel.kt | 17 +++++++-- .../lava/banksia/ui/screens/map/MapScreen.kt | 2 +- .../ui/screens/map/MapScreenViewModel.kt | 24 ++++++++---- .../lava/banksia/ui/state/InfoPanelState.kt | 38 ------------------- 7 files changed, 73 insertions(+), 64 deletions(-) delete mode 100644 ui/src/commonMain/kotlin/moe/lava/banksia/ui/state/InfoPanelState.kt diff --git a/ui/src/commonMain/kotlin/moe/lava/banksia/ui/layout/info/InfoPanel.kt b/ui/src/commonMain/kotlin/moe/lava/banksia/ui/layout/info/InfoPanel.kt index fa0354d..55eac69 100644 --- a/ui/src/commonMain/kotlin/moe/lava/banksia/ui/layout/info/InfoPanel.kt +++ b/ui/src/commonMain/kotlin/moe/lava/banksia/ui/layout/info/InfoPanel.kt @@ -30,15 +30,23 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.coerceAtMost import androidx.compose.ui.unit.dp import kotlinx.coroutines.delay -import moe.lava.banksia.ui.screens.map.MapScreenEvent -import moe.lava.banksia.ui.state.InfoPanelState import kotlin.time.Duration.Companion.milliseconds +sealed class InfoPanelEvent + +sealed class InfoPanelState { + abstract val loading: Boolean + + data object None : InfoPanelState() { + override val loading = false + } +} + @OptIn(ExperimentalMaterial3ExpressiveApi::class) @Composable fun InfoPanel( state: InfoPanelState, - onEvent: (MapScreenEvent) -> Unit, + onEvent: (InfoPanelEvent) -> Unit, onPeekHeightChange: (Dp) -> Unit, ) { if (state is InfoPanelState.None) @@ -66,9 +74,9 @@ fun InfoPanel( ) { Box { when (state) { - is InfoPanelState.Route -> RouteInfoPanel(state, onEvent) - is InfoPanelState.Stop -> StopInfoPanel(state, onEvent) - is InfoPanelState.Trip -> TripInfoPanel(state, onEvent) + is RouteInfoPanelState -> RouteInfoPanel(state, onEvent) + is StopInfoPanelState -> StopInfoPanel(state, onEvent) + is TripInfoPanelState -> TripInfoPanel(state, onEvent) is InfoPanelState.None -> throw UnsupportedOperationException() } diff --git a/ui/src/commonMain/kotlin/moe/lava/banksia/ui/layout/info/RouteInfoPanel.kt b/ui/src/commonMain/kotlin/moe/lava/banksia/ui/layout/info/RouteInfoPanel.kt index b55b7c1..655caca 100644 --- a/ui/src/commonMain/kotlin/moe/lava/banksia/ui/layout/info/RouteInfoPanel.kt +++ b/ui/src/commonMain/kotlin/moe/lava/banksia/ui/layout/info/RouteInfoPanel.kt @@ -9,14 +9,22 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign +import moe.lava.banksia.model.RouteType import moe.lava.banksia.ui.components.RouteIcon -import moe.lava.banksia.ui.screens.map.MapScreenEvent -import moe.lava.banksia.ui.state.InfoPanelState + +sealed class RouteInfoPanelEvent : InfoPanelEvent() + +data class RouteInfoPanelState( + val name: String, + val type: RouteType, +) : InfoPanelState() { + override val loading = false +} @Composable internal fun RouteInfoPanel( - state: InfoPanelState.Route, - onEvent: (MapScreenEvent) -> Unit, + state: RouteInfoPanelState, + onEvent: (RouteInfoPanelEvent) -> Unit, ) { Column(Modifier.fillMaxWidth()) { Row { diff --git a/ui/src/commonMain/kotlin/moe/lava/banksia/ui/layout/info/StopInfoPanel.kt b/ui/src/commonMain/kotlin/moe/lava/banksia/ui/layout/info/StopInfoPanel.kt index 731ef88..dbe3b29 100644 --- a/ui/src/commonMain/kotlin/moe/lava/banksia/ui/layout/info/StopInfoPanel.kt +++ b/ui/src/commonMain/kotlin/moe/lava/banksia/ui/layout/info/StopInfoPanel.kt @@ -16,13 +16,25 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp -import moe.lava.banksia.ui.screens.map.MapScreenEvent -import moe.lava.banksia.ui.state.InfoPanelState + +sealed class StopInfoPanelEvent : InfoPanelEvent() + +data class StopInfoPanelState( + val id: String, + val name: String, + val subname: String? = null, + val departures: List? = null, +) : InfoPanelState() { + override val loading: Boolean + get() = departures == null + + data class Departure(val directionName: String, val formattedTimes: String) +} @Composable internal fun StopInfoPanel( - state: InfoPanelState.Stop, - onEvent: (MapScreenEvent) -> Unit, + state: StopInfoPanelState, + onEvent: (StopInfoPanelEvent) -> Unit, ) { Column(Modifier.fillMaxWidth()) { Text( diff --git a/ui/src/commonMain/kotlin/moe/lava/banksia/ui/layout/info/TripInfoPanel.kt b/ui/src/commonMain/kotlin/moe/lava/banksia/ui/layout/info/TripInfoPanel.kt index 2d221b2..7b7dcf9 100644 --- a/ui/src/commonMain/kotlin/moe/lava/banksia/ui/layout/info/TripInfoPanel.kt +++ b/ui/src/commonMain/kotlin/moe/lava/banksia/ui/layout/info/TripInfoPanel.kt @@ -9,14 +9,23 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign +import moe.lava.banksia.model.RouteType import moe.lava.banksia.ui.components.RouteIcon -import moe.lava.banksia.ui.screens.map.MapScreenEvent -import moe.lava.banksia.ui.state.InfoPanelState + +sealed class TripInfoPanelEvent : InfoPanelEvent() + +data class TripInfoPanelState( + val direction: String, + val type: RouteType, + val routeName: String? = null, +) : InfoPanelState() { + override val loading = routeName == null +} @Composable internal fun TripInfoPanel( - state: InfoPanelState.Trip, - onEvent: (MapScreenEvent) -> Unit, + state: TripInfoPanelState, + onEvent: (TripInfoPanelEvent) -> Unit, ) { Column(Modifier.fillMaxWidth()) { Row { diff --git a/ui/src/commonMain/kotlin/moe/lava/banksia/ui/screens/map/MapScreen.kt b/ui/src/commonMain/kotlin/moe/lava/banksia/ui/screens/map/MapScreen.kt index 70b8ed4..f4319be 100644 --- a/ui/src/commonMain/kotlin/moe/lava/banksia/ui/screens/map/MapScreen.kt +++ b/ui/src/commonMain/kotlin/moe/lava/banksia/ui/screens/map/MapScreen.kt @@ -38,9 +38,9 @@ import moe.lava.banksia.ui.layout.AppBottomSheet import moe.lava.banksia.ui.layout.Searcher import moe.lava.banksia.ui.layout.SheetStateWrapper import moe.lava.banksia.ui.layout.info.InfoPanel +import moe.lava.banksia.ui.layout.info.InfoPanelState import moe.lava.banksia.ui.map.Maps import moe.lava.banksia.ui.platform.BanksiaTheme -import moe.lava.banksia.ui.state.InfoPanelState import org.jetbrains.compose.resources.painterResource import org.koin.compose.viewmodel.koinViewModel diff --git a/ui/src/commonMain/kotlin/moe/lava/banksia/ui/screens/map/MapScreenViewModel.kt b/ui/src/commonMain/kotlin/moe/lava/banksia/ui/screens/map/MapScreenViewModel.kt index a3435af..a65e0a7 100644 --- a/ui/src/commonMain/kotlin/moe/lava/banksia/ui/screens/map/MapScreenViewModel.kt +++ b/ui/src/commonMain/kotlin/moe/lava/banksia/ui/screens/map/MapScreenViewModel.kt @@ -21,10 +21,14 @@ import moe.lava.banksia.client.repository.StopTimeRepository import moe.lava.banksia.data.ptv.PtvService import moe.lava.banksia.model.Route import moe.lava.banksia.model.RouteType +import moe.lava.banksia.ui.layout.info.InfoPanelEvent +import moe.lava.banksia.ui.layout.info.InfoPanelState +import moe.lava.banksia.ui.layout.info.RouteInfoPanelState +import moe.lava.banksia.ui.layout.info.StopInfoPanelState +import moe.lava.banksia.ui.layout.info.TripInfoPanelState import moe.lava.banksia.ui.map.util.CameraPosition import moe.lava.banksia.ui.map.util.CameraPositionBounds import moe.lava.banksia.ui.map.util.Marker -import moe.lava.banksia.ui.state.InfoPanelState import moe.lava.banksia.ui.state.MapState import moe.lava.banksia.ui.state.SearchState import moe.lava.banksia.util.BoxedValue @@ -99,6 +103,12 @@ class MapScreenViewModel( } } + fun handleEvent(event: InfoPanelEvent) { + viewModelScope.launch { +// when (event) { } + } + } + fun bindTracker(locationTracker: LocationTracker) { locationTrackerJob = locationTracker.getLocationsFlow() .onEach { lastKnownLocation = Point(it.latitude, it.longitude) } @@ -162,7 +172,7 @@ class MapScreenViewModel( val route = routeRepository.get(routeId) // val gtfsRoute = ptvService.route(routeId) iInfoState.update { - InfoPanelState.Route( + RouteInfoPanelState( name = route.name, type = route.type, ) @@ -187,7 +197,7 @@ class MapScreenViewModel( .onEach { run -> if (routeName == null) { iInfoState.update { - InfoPanelState.Trip( + TripInfoPanelState( direction = run.destinationName, type = RouteType.MetroTrain, // XXX HACK TODO FIXME ) @@ -196,7 +206,7 @@ class MapScreenViewModel( } iInfoState.update { - InfoPanelState.Trip( + TripInfoPanelState( direction = run.destinationName, type = RouteType.MetroTrain, // FIXME HACK XXX TODO routeName = routeName, @@ -219,7 +229,7 @@ class MapScreenViewModel( val name = split[0] val subname = split.getOrNull(1) iInfoState.update { - InfoPanelState.Stop( + StopInfoPanelState( id = stop.id, name = name, subname = subname, @@ -242,10 +252,10 @@ class MapScreenViewModel( "${diff}mn" } } - InfoPanelState.Stop.Departure(headsign, times) + StopInfoPanelState.Departure(headsign, times) } iInfoState.update { - if (it !is InfoPanelState.Stop) + if (it !is StopInfoPanelState) it else it.copy(departures = departures) diff --git a/ui/src/commonMain/kotlin/moe/lava/banksia/ui/state/InfoPanelState.kt b/ui/src/commonMain/kotlin/moe/lava/banksia/ui/state/InfoPanelState.kt deleted file mode 100644 index 5b73914..0000000 --- a/ui/src/commonMain/kotlin/moe/lava/banksia/ui/state/InfoPanelState.kt +++ /dev/null @@ -1,38 +0,0 @@ -package moe.lava.banksia.ui.state - -import moe.lava.banksia.model.RouteType - -sealed class InfoPanelState { - abstract val loading: Boolean - - data object None : InfoPanelState() { - override val loading = false - } - - data class Route( - val name: String, - val type: RouteType, - ) : InfoPanelState() { - override val loading = false - } - - data class Stop( - val id: String, - val name: String, - val subname: String? = null, - val departures: List? = null, - ) : InfoPanelState() { - override val loading: Boolean - get() = departures == null - - data class Departure(val directionName: String, val formattedTimes: String) - } - - data class Trip( - val direction: String, - val type: RouteType, - val routeName: String? = null, - ) : InfoPanelState() { - override val loading = routeName == null - } -}