refactor(ui/info): split up info panel state

This commit is contained in:
Cilly Leang 2026-03-31 20:53:21 +11:00
parent f0ce780bba
commit aad5ae4024
Signed by: cilly
GPG key ID: 6500251E087653C9
7 changed files with 73 additions and 64 deletions

View file

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

View file

@ -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 {

View file

@ -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<Departure>? = 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(

View file

@ -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 {

View file

@ -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

View file

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

View file

@ -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<Departure>? = 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
}
}