refactor(ui/info): split up info panel state
This commit is contained in:
parent
f0ce780bba
commit
aad5ae4024
7 changed files with 73 additions and 64 deletions
|
|
@ -30,15 +30,23 @@ import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.coerceAtMost
|
import androidx.compose.ui.unit.coerceAtMost
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import kotlinx.coroutines.delay
|
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
|
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)
|
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun InfoPanel(
|
fun InfoPanel(
|
||||||
state: InfoPanelState,
|
state: InfoPanelState,
|
||||||
onEvent: (MapScreenEvent) -> Unit,
|
onEvent: (InfoPanelEvent) -> Unit,
|
||||||
onPeekHeightChange: (Dp) -> Unit,
|
onPeekHeightChange: (Dp) -> Unit,
|
||||||
) {
|
) {
|
||||||
if (state is InfoPanelState.None)
|
if (state is InfoPanelState.None)
|
||||||
|
|
@ -66,9 +74,9 @@ fun InfoPanel(
|
||||||
) {
|
) {
|
||||||
Box {
|
Box {
|
||||||
when (state) {
|
when (state) {
|
||||||
is InfoPanelState.Route -> RouteInfoPanel(state, onEvent)
|
is RouteInfoPanelState -> RouteInfoPanel(state, onEvent)
|
||||||
is InfoPanelState.Stop -> StopInfoPanel(state, onEvent)
|
is StopInfoPanelState -> StopInfoPanel(state, onEvent)
|
||||||
is InfoPanelState.Trip -> TripInfoPanel(state, onEvent)
|
is TripInfoPanelState -> TripInfoPanel(state, onEvent)
|
||||||
is InfoPanelState.None -> throw UnsupportedOperationException()
|
is InfoPanelState.None -> throw UnsupportedOperationException()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,14 +9,22 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
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.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
|
@Composable
|
||||||
internal fun RouteInfoPanel(
|
internal fun RouteInfoPanel(
|
||||||
state: InfoPanelState.Route,
|
state: RouteInfoPanelState,
|
||||||
onEvent: (MapScreenEvent) -> Unit,
|
onEvent: (RouteInfoPanelEvent) -> Unit,
|
||||||
) {
|
) {
|
||||||
Column(Modifier.fillMaxWidth()) {
|
Column(Modifier.fillMaxWidth()) {
|
||||||
Row {
|
Row {
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,25 @@ import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
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
|
@Composable
|
||||||
internal fun StopInfoPanel(
|
internal fun StopInfoPanel(
|
||||||
state: InfoPanelState.Stop,
|
state: StopInfoPanelState,
|
||||||
onEvent: (MapScreenEvent) -> Unit,
|
onEvent: (StopInfoPanelEvent) -> Unit,
|
||||||
) {
|
) {
|
||||||
Column(Modifier.fillMaxWidth()) {
|
Column(Modifier.fillMaxWidth()) {
|
||||||
Text(
|
Text(
|
||||||
|
|
|
||||||
|
|
@ -9,14 +9,23 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
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.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
|
@Composable
|
||||||
internal fun TripInfoPanel(
|
internal fun TripInfoPanel(
|
||||||
state: InfoPanelState.Trip,
|
state: TripInfoPanelState,
|
||||||
onEvent: (MapScreenEvent) -> Unit,
|
onEvent: (TripInfoPanelEvent) -> Unit,
|
||||||
) {
|
) {
|
||||||
Column(Modifier.fillMaxWidth()) {
|
Column(Modifier.fillMaxWidth()) {
|
||||||
Row {
|
Row {
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,9 @@ import moe.lava.banksia.ui.layout.AppBottomSheet
|
||||||
import moe.lava.banksia.ui.layout.Searcher
|
import moe.lava.banksia.ui.layout.Searcher
|
||||||
import moe.lava.banksia.ui.layout.SheetStateWrapper
|
import moe.lava.banksia.ui.layout.SheetStateWrapper
|
||||||
import moe.lava.banksia.ui.layout.info.InfoPanel
|
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.map.Maps
|
||||||
import moe.lava.banksia.ui.platform.BanksiaTheme
|
import moe.lava.banksia.ui.platform.BanksiaTheme
|
||||||
import moe.lava.banksia.ui.state.InfoPanelState
|
|
||||||
import org.jetbrains.compose.resources.painterResource
|
import org.jetbrains.compose.resources.painterResource
|
||||||
import org.koin.compose.viewmodel.koinViewModel
|
import org.koin.compose.viewmodel.koinViewModel
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,14 @@ import moe.lava.banksia.client.repository.StopTimeRepository
|
||||||
import moe.lava.banksia.data.ptv.PtvService
|
import moe.lava.banksia.data.ptv.PtvService
|
||||||
import moe.lava.banksia.model.Route
|
import moe.lava.banksia.model.Route
|
||||||
import moe.lava.banksia.model.RouteType
|
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.CameraPosition
|
||||||
import moe.lava.banksia.ui.map.util.CameraPositionBounds
|
import moe.lava.banksia.ui.map.util.CameraPositionBounds
|
||||||
import moe.lava.banksia.ui.map.util.Marker
|
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.MapState
|
||||||
import moe.lava.banksia.ui.state.SearchState
|
import moe.lava.banksia.ui.state.SearchState
|
||||||
import moe.lava.banksia.util.BoxedValue
|
import moe.lava.banksia.util.BoxedValue
|
||||||
|
|
@ -99,6 +103,12 @@ class MapScreenViewModel(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun handleEvent(event: InfoPanelEvent) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
// when (event) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun bindTracker(locationTracker: LocationTracker) {
|
fun bindTracker(locationTracker: LocationTracker) {
|
||||||
locationTrackerJob = locationTracker.getLocationsFlow()
|
locationTrackerJob = locationTracker.getLocationsFlow()
|
||||||
.onEach { lastKnownLocation = Point(it.latitude, it.longitude) }
|
.onEach { lastKnownLocation = Point(it.latitude, it.longitude) }
|
||||||
|
|
@ -162,7 +172,7 @@ class MapScreenViewModel(
|
||||||
val route = routeRepository.get(routeId)
|
val route = routeRepository.get(routeId)
|
||||||
// val gtfsRoute = ptvService.route(routeId)
|
// val gtfsRoute = ptvService.route(routeId)
|
||||||
iInfoState.update {
|
iInfoState.update {
|
||||||
InfoPanelState.Route(
|
RouteInfoPanelState(
|
||||||
name = route.name,
|
name = route.name,
|
||||||
type = route.type,
|
type = route.type,
|
||||||
)
|
)
|
||||||
|
|
@ -187,7 +197,7 @@ class MapScreenViewModel(
|
||||||
.onEach { run ->
|
.onEach { run ->
|
||||||
if (routeName == null) {
|
if (routeName == null) {
|
||||||
iInfoState.update {
|
iInfoState.update {
|
||||||
InfoPanelState.Trip(
|
TripInfoPanelState(
|
||||||
direction = run.destinationName,
|
direction = run.destinationName,
|
||||||
type = RouteType.MetroTrain, // XXX HACK TODO FIXME
|
type = RouteType.MetroTrain, // XXX HACK TODO FIXME
|
||||||
)
|
)
|
||||||
|
|
@ -196,7 +206,7 @@ class MapScreenViewModel(
|
||||||
}
|
}
|
||||||
|
|
||||||
iInfoState.update {
|
iInfoState.update {
|
||||||
InfoPanelState.Trip(
|
TripInfoPanelState(
|
||||||
direction = run.destinationName,
|
direction = run.destinationName,
|
||||||
type = RouteType.MetroTrain, // FIXME HACK XXX TODO
|
type = RouteType.MetroTrain, // FIXME HACK XXX TODO
|
||||||
routeName = routeName,
|
routeName = routeName,
|
||||||
|
|
@ -219,7 +229,7 @@ class MapScreenViewModel(
|
||||||
val name = split[0]
|
val name = split[0]
|
||||||
val subname = split.getOrNull(1)
|
val subname = split.getOrNull(1)
|
||||||
iInfoState.update {
|
iInfoState.update {
|
||||||
InfoPanelState.Stop(
|
StopInfoPanelState(
|
||||||
id = stop.id,
|
id = stop.id,
|
||||||
name = name,
|
name = name,
|
||||||
subname = subname,
|
subname = subname,
|
||||||
|
|
@ -242,10 +252,10 @@ class MapScreenViewModel(
|
||||||
"${diff}mn"
|
"${diff}mn"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InfoPanelState.Stop.Departure(headsign, times)
|
StopInfoPanelState.Departure(headsign, times)
|
||||||
}
|
}
|
||||||
iInfoState.update {
|
iInfoState.update {
|
||||||
if (it !is InfoPanelState.Stop)
|
if (it !is StopInfoPanelState)
|
||||||
it
|
it
|
||||||
else
|
else
|
||||||
it.copy(departures = departures)
|
it.copy(departures = departures)
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue