refactor(ui): split up infopanel into files

This commit is contained in:
Cilly Leang 2026-03-31 20:21:39 +11:00
parent 72b9fb2757
commit f0ce780bba
Signed by: cilly
GPG key ID: 6500251E087653C9
7 changed files with 140 additions and 101 deletions

View file

@ -1,4 +1,4 @@
package moe.lava.banksia.ui.layout package moe.lava.banksia.ui.layout.info
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeIn
@ -7,19 +7,15 @@ import androidx.compose.animation.scaleIn
import androidx.compose.animation.scaleOut import androidx.compose.animation.scaleOut
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeContent import androidx.compose.foundation.layout.safeContent
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.windowInsetsBottomHeight import androidx.compose.foundation.layout.windowInsetsBottomHeight
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.LoadingIndicator import androidx.compose.material3.LoadingIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
@ -28,17 +24,12 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
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 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.components.RouteIcon
import moe.lava.banksia.ui.screens.map.MapScreenEvent import moe.lava.banksia.ui.screens.map.MapScreenEvent
import moe.lava.banksia.ui.state.InfoPanelState import moe.lava.banksia.ui.state.InfoPanelState
import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.milliseconds
@ -77,7 +68,7 @@ fun InfoPanel(
when (state) { when (state) {
is InfoPanelState.Route -> RouteInfoPanel(state, onEvent) is InfoPanelState.Route -> RouteInfoPanel(state, onEvent)
is InfoPanelState.Stop -> StopInfoPanel(state, onEvent) is InfoPanelState.Stop -> StopInfoPanel(state, onEvent)
is InfoPanelState.Run -> RunInfoPanel(state, onEvent) is InfoPanelState.Trip -> TripInfoPanel(state, onEvent)
is InfoPanelState.None -> throw UnsupportedOperationException() is InfoPanelState.None -> throw UnsupportedOperationException()
} }
@ -96,82 +87,3 @@ fun InfoPanel(
Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.safeContent)) Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.safeContent))
} }
} }
@Composable
private inline fun RouteInfoPanel(
state: InfoPanelState.Route,
onEvent: (MapScreenEvent) -> Unit,
) {
Column(Modifier.fillMaxWidth()) {
Row {
RouteIcon(routeType = state.type)
Text(
state.name,
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.SemiBold,
textAlign = TextAlign.Start
)
}
}
}
@Composable
private inline fun RunInfoPanel(
state: InfoPanelState.Run,
onEvent: (MapScreenEvent) -> Unit,
) {
Column(Modifier.fillMaxWidth()) {
Row {
RouteIcon(routeType = state.type)
Text(
"${state.direction} via ${state.routeName ?: "..."}",
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.SemiBold,
textAlign = TextAlign.Start
)
}
}
}
@Composable
private inline fun StopInfoPanel(
state: InfoPanelState.Stop,
onEvent: (MapScreenEvent) -> Unit,
) {
Column(Modifier.fillMaxWidth()) {
Text(
state.name,
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.SemiBold,
textAlign = TextAlign.Start
)
state.subname?.let {
Text(
"/ $it",
modifier = Modifier.padding(start = 5.dp),
style = MaterialTheme.typography.titleSmall,
color = Color.Gray,
fontWeight = FontWeight.SemiBold,
textAlign = TextAlign.Start
)
}
state.departures?.let {
Spacer(Modifier.height(5.dp))
it.forEach { (name, formatted) ->
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
name,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold
)
Text(
formatted,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.padding(horizontal = 5.dp)
)
}
}
}
}
}

View file

@ -0,0 +1,32 @@
package moe.lava.banksia.ui.layout.info
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
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.ui.components.RouteIcon
import moe.lava.banksia.ui.screens.map.MapScreenEvent
import moe.lava.banksia.ui.state.InfoPanelState
@Composable
internal fun RouteInfoPanel(
state: InfoPanelState.Route,
onEvent: (MapScreenEvent) -> Unit,
) {
Column(Modifier.fillMaxWidth()) {
Row {
RouteIcon(routeType = state.type)
Text(
state.name,
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.SemiBold,
textAlign = TextAlign.Start
)
}
}
}

View file

@ -0,0 +1,63 @@
package moe.lava.banksia.ui.layout.info
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
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
@Composable
internal fun StopInfoPanel(
state: InfoPanelState.Stop,
onEvent: (MapScreenEvent) -> Unit,
) {
Column(Modifier.fillMaxWidth()) {
Text(
state.name,
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.SemiBold,
textAlign = TextAlign.Start
)
state.subname?.let {
Text(
"/ $it",
modifier = Modifier.padding(start = 5.dp),
style = MaterialTheme.typography.titleSmall,
color = Color.Gray,
fontWeight = FontWeight.SemiBold,
textAlign = TextAlign.Start
)
}
state.departures?.let {
Spacer(Modifier.height(5.dp))
it.forEach { (name, formatted) ->
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
name,
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.SemiBold
)
Text(
formatted,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.padding(horizontal = 5.dp)
)
}
}
}
}
}

View file

@ -0,0 +1,32 @@
package moe.lava.banksia.ui.layout.info
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
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.ui.components.RouteIcon
import moe.lava.banksia.ui.screens.map.MapScreenEvent
import moe.lava.banksia.ui.state.InfoPanelState
@Composable
internal fun TripInfoPanel(
state: InfoPanelState.Trip,
onEvent: (MapScreenEvent) -> Unit,
) {
Column(Modifier.fillMaxWidth()) {
Row {
RouteIcon(routeType = state.type)
Text(
"${state.direction} via ${state.routeName ?: "..."}",
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.SemiBold,
textAlign = TextAlign.Start
)
}
}
}

View file

@ -35,9 +35,9 @@ import kotlinx.coroutines.launch
import moe.lava.banksia.resources.Res import moe.lava.banksia.resources.Res
import moe.lava.banksia.resources.my_location_24 import moe.lava.banksia.resources.my_location_24
import moe.lava.banksia.ui.layout.AppBottomSheet import moe.lava.banksia.ui.layout.AppBottomSheet
import moe.lava.banksia.ui.layout.InfoPanel
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.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 moe.lava.banksia.ui.state.InfoPanelState

View file

@ -187,7 +187,7 @@ class MapScreenViewModel(
.onEach { run -> .onEach { run ->
if (routeName == null) { if (routeName == null) {
iInfoState.update { iInfoState.update {
InfoPanelState.Run( InfoPanelState.Trip(
direction = run.destinationName, direction = run.destinationName,
type = RouteType.MetroTrain, // XXX HACK TODO FIXME type = RouteType.MetroTrain, // XXX HACK TODO FIXME
) )
@ -196,7 +196,7 @@ class MapScreenViewModel(
} }
iInfoState.update { iInfoState.update {
InfoPanelState.Run( InfoPanelState.Trip(
direction = run.destinationName, direction = run.destinationName,
type = RouteType.MetroTrain, // FIXME HACK XXX TODO type = RouteType.MetroTrain, // FIXME HACK XXX TODO
routeName = routeName, routeName = routeName,

View file

@ -16,14 +16,6 @@ sealed class InfoPanelState {
override val loading = false override val loading = false
} }
data class Run(
val direction: String,
val type: RouteType,
val routeName: String? = null,
) : InfoPanelState() {
override val loading = routeName == null
}
data class Stop( data class Stop(
val id: String, val id: String,
val name: String, val name: String,
@ -35,4 +27,12 @@ sealed class InfoPanelState {
data class Departure(val directionName: String, val formattedTimes: String) 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
}
} }