refactor: split out searchstate
This commit is contained in:
parent
c26e522a2e
commit
c526269e5d
5 changed files with 153 additions and 94 deletions
|
|
@ -72,9 +72,9 @@ fun App(
|
||||||
viewModel.bindTracker(locationTracker)
|
viewModel.bindTracker(locationTracker)
|
||||||
scope.launch { locationTracker.startTracking() }
|
scope.launch { locationTracker.startTracking() }
|
||||||
|
|
||||||
val state by viewModel.state.collectAsStateWithLifecycle()
|
|
||||||
val infoState by viewModel.infoState.collectAsStateWithLifecycle()
|
val infoState by viewModel.infoState.collectAsStateWithLifecycle()
|
||||||
val mapState by viewModel.mapState.collectAsStateWithLifecycle()
|
val mapState by viewModel.mapState.collectAsStateWithLifecycle()
|
||||||
|
val searchState by viewModel.searchState.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
val scaffoldState = rememberBottomSheetScaffoldState(
|
val scaffoldState = rememberBottomSheetScaffoldState(
|
||||||
bottomSheetState = rememberStandardBottomSheetState(
|
bottomSheetState = rememberStandardBottomSheetState(
|
||||||
|
|
@ -100,7 +100,6 @@ fun App(
|
||||||
scope.launch { scaffoldState.bottomSheetState.hide() }
|
scope.launch { scaffoldState.bottomSheetState.hide() }
|
||||||
}
|
}
|
||||||
|
|
||||||
var searchTextState by rememberSaveable { mutableStateOf("") }
|
|
||||||
var searchExpandedState by rememberSaveable { mutableStateOf(false) }
|
var searchExpandedState by rememberSaveable { mutableStateOf(false) }
|
||||||
var sheetSwipeEnabled by rememberSaveable { mutableStateOf(true) }
|
var sheetSwipeEnabled by rememberSaveable { mutableStateOf(true) }
|
||||||
var handleHeight by remember { mutableStateOf(0.dp) }
|
var handleHeight by remember { mutableStateOf(0.dp) }
|
||||||
|
|
@ -145,16 +144,14 @@ fun App(
|
||||||
polylines = mapState.polylines,
|
polylines = mapState.polylines,
|
||||||
)
|
)
|
||||||
Searcher(
|
Searcher(
|
||||||
routes = state.routes,
|
state = searchState,
|
||||||
|
onEvent = viewModel::handleEvent,
|
||||||
expanded = searchExpandedState,
|
expanded = searchExpandedState,
|
||||||
onExpandedChange = {
|
onExpandedChange = {
|
||||||
searchExpandedState = it
|
searchExpandedState = it
|
||||||
if (it)
|
if (it)
|
||||||
scope.launch { scaffoldState.bottomSheetState.hide() }
|
scope.launch { scaffoldState.bottomSheetState.hide() }
|
||||||
},
|
},
|
||||||
text = searchTextState,
|
|
||||||
onTextChange = { searchTextState = it },
|
|
||||||
onRouteChange = { viewModel.switchRoute(it) }
|
|
||||||
)
|
)
|
||||||
|
|
||||||
PredictiveBackHandler(scaffoldState.bottomSheetState.currentValue != SheetValue.Hidden) { progress ->
|
PredictiveBackHandler(scaffoldState.bottomSheetState.currentValue != SheetValue.Hidden) { progress ->
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import kotlinx.datetime.Clock
|
||||||
import kotlinx.datetime.Instant
|
import kotlinx.datetime.Instant
|
||||||
import moe.lava.banksia.api.ptv.PtvService
|
import moe.lava.banksia.api.ptv.PtvService
|
||||||
import moe.lava.banksia.api.ptv.structures.PtvRoute
|
import moe.lava.banksia.api.ptv.structures.PtvRoute
|
||||||
import moe.lava.banksia.api.ptv.structures.PtvStop
|
import moe.lava.banksia.api.ptv.structures.PtvRouteType
|
||||||
import moe.lava.banksia.api.ptv.structures.getProperties
|
import moe.lava.banksia.api.ptv.structures.getProperties
|
||||||
import moe.lava.banksia.log
|
import moe.lava.banksia.log
|
||||||
import moe.lava.banksia.native.maps.CameraPosition
|
import moe.lava.banksia.native.maps.CameraPosition
|
||||||
|
|
@ -27,19 +27,18 @@ import moe.lava.banksia.native.maps.Point
|
||||||
import moe.lava.banksia.native.maps.Polyline
|
import moe.lava.banksia.native.maps.Polyline
|
||||||
import moe.lava.banksia.ui.state.InfoPanelState
|
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.util.BoxedValue
|
import moe.lava.banksia.util.BoxedValue
|
||||||
import moe.lava.banksia.util.BoxedValue.Companion.box
|
import moe.lava.banksia.util.BoxedValue.Companion.box
|
||||||
|
|
||||||
sealed class BanksiaEvent {}
|
sealed class BanksiaEvent {
|
||||||
|
data class SelectRoute(val id: Int?) : BanksiaEvent()
|
||||||
|
data class SelectStop(val routeType: PtvRouteType, val stopId: Int?) : BanksiaEvent()
|
||||||
|
|
||||||
data class BanksiaViewState(
|
data class SearchUpdate(val text: String) : BanksiaEvent()
|
||||||
val routes: List<PtvRoute> = listOf(),
|
}
|
||||||
)
|
|
||||||
|
|
||||||
class BanksiaViewModel : ViewModel() {
|
class BanksiaViewModel : ViewModel() {
|
||||||
private val iState = MutableStateFlow(BanksiaViewState())
|
|
||||||
val state = iState.asStateFlow()
|
|
||||||
|
|
||||||
private val iInfoState = MutableStateFlow<InfoPanelState>(InfoPanelState.None)
|
private val iInfoState = MutableStateFlow<InfoPanelState>(InfoPanelState.None)
|
||||||
val infoState = iInfoState.asStateFlow()
|
val infoState = iInfoState.asStateFlow()
|
||||||
|
|
||||||
|
|
@ -48,17 +47,26 @@ class BanksiaViewModel : ViewModel() {
|
||||||
private val iCameraChangeEmitter = MutableSharedFlow<BoxedValue<CameraPosition>>()
|
private val iCameraChangeEmitter = MutableSharedFlow<BoxedValue<CameraPosition>>()
|
||||||
val cameraChangeEmitter = iCameraChangeEmitter.asSharedFlow()
|
val cameraChangeEmitter = iCameraChangeEmitter.asSharedFlow()
|
||||||
|
|
||||||
|
private val iSearchState = MutableStateFlow(SearchState())
|
||||||
|
val searchState = iSearchState.asStateFlow()
|
||||||
|
|
||||||
private val ptvService = PtvService()
|
private val ptvService = PtvService()
|
||||||
private var locationTrackerJob: Job? = null
|
private var locationTrackerJob: Job? = null
|
||||||
private var lastKnownLocation: Point? = null
|
private var lastKnownLocation: Point? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch { searchUpdate("") }
|
||||||
requestRoutes()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun handleEvent(event: BanksiaEvent) {}
|
fun handleEvent(event: BanksiaEvent) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
when (event) {
|
||||||
|
is BanksiaEvent.SelectRoute -> switchRoute(event.id)
|
||||||
|
is BanksiaEvent.SelectStop -> switchStop(event.routeType, event.stopId)
|
||||||
|
is BanksiaEvent.SearchUpdate -> searchUpdate(event.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun bindTracker(locationTracker: LocationTracker) {
|
fun bindTracker(locationTracker: LocationTracker) {
|
||||||
locationTrackerJob = locationTracker.getLocationsFlow()
|
locationTrackerJob = locationTracker.getLocationsFlow()
|
||||||
|
|
@ -79,43 +87,57 @@ class BanksiaViewModel : ViewModel() {
|
||||||
lastKnownLocation = location
|
lastKnownLocation = location
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun requestRoutes() {
|
private suspend fun searchUpdate(text: String) {
|
||||||
val routes = ptvService.routes().sortedWith(
|
val entries = ptvService.routes()
|
||||||
compareBy(
|
.sortedWith(
|
||||||
{ it.gtfsSubType()?.ordinal },
|
compareBy(
|
||||||
{ it.routeNumber.toIntOrNull() },
|
{ it.gtfsSubType()?.ordinal },
|
||||||
{ it.routeName }
|
{ it.routeNumber.toIntOrNull() },
|
||||||
)
|
{ it.routeName }
|
||||||
)
|
|
||||||
iState.update { it.copy(routes = routes) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun switchRoute(route: PtvRoute?) {
|
|
||||||
iMapState.update { MapState() }
|
|
||||||
iInfoState.update {
|
|
||||||
if (route == null)
|
|
||||||
InfoPanelState.None
|
|
||||||
else
|
|
||||||
InfoPanelState.Route(
|
|
||||||
name = route.routeName,
|
|
||||||
type = route.routeType,
|
|
||||||
)
|
)
|
||||||
}
|
)
|
||||||
|
.filter { it.routeNumber.contains(text) || it.routeName.lowercase().contains(text.lowercase()) }
|
||||||
|
.map { route ->
|
||||||
|
val (main, sub) = if (route.routeNumber.isNotEmpty()) {
|
||||||
|
route.routeNumber to route.routeName
|
||||||
|
} else {
|
||||||
|
route.routeName to null
|
||||||
|
}
|
||||||
|
|
||||||
if (route != null) {
|
SearchState.SearchEntry(main, sub, route.routeId, route.routeType)
|
||||||
viewModelScope.launch { buildPolylines(route) }
|
}
|
||||||
viewModelScope.launch { buildStops(route) }
|
|
||||||
// viewModelScope.launch { buildDepartures() }
|
iSearchState.update { SearchState(entries, text) }
|
||||||
// viewModelScope.launch { buildRuns() }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// [TODO]: Cleanup
|
private suspend fun switchRoute(routeId: Int?) {
|
||||||
suspend fun switchStop(stop: PtvStop?) {
|
iMapState.update { MapState() }
|
||||||
if (stop == null) {
|
if (routeId == null) {
|
||||||
iInfoState.update { InfoPanelState.None }
|
iInfoState.update { InfoPanelState.None }
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val route = ptvService.route(routeId)
|
||||||
|
iInfoState.update {
|
||||||
|
InfoPanelState.Route(
|
||||||
|
name = route.routeName,
|
||||||
|
type = route.routeType,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModelScope.launch { buildPolylines(route) }
|
||||||
|
viewModelScope.launch { buildStops(route) }
|
||||||
|
// viewModelScope.launch { buildDepartures() }
|
||||||
|
// viewModelScope.launch { buildRuns() }
|
||||||
|
}
|
||||||
|
|
||||||
|
// [TODO]: Cleanup
|
||||||
|
private suspend fun switchStop(routeType: PtvRouteType, stopId: Int?) {
|
||||||
|
if (stopId == null) {
|
||||||
|
iInfoState.update { InfoPanelState.None }
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val stop = ptvService.stop(routeType, stopId)
|
||||||
val split = stop.stopName.split("/")
|
val split = stop.stopName.split("/")
|
||||||
val name = split[0]
|
val name = split[0]
|
||||||
val subname = split.getOrNull(1)
|
val subname = split.getOrNull(1)
|
||||||
|
|
@ -229,7 +251,7 @@ class BanksiaViewModel : ViewModel() {
|
||||||
type = MarkerType.GENERIC_STOP,
|
type = MarkerType.GENERIC_STOP,
|
||||||
colour = colour,
|
colour = colour,
|
||||||
onClick = {
|
onClick = {
|
||||||
viewModelScope.launch { switchStop(stop) }
|
viewModelScope.launch { switchStop(route.routeType, stop.stopId) }
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
package moe.lava.banksia.ui
|
package moe.lava.banksia.ui
|
||||||
|
|
||||||
import androidx.compose.animation.core.animateDpAsState
|
import androidx.compose.animation.core.animateDpAsState
|
||||||
import androidx.compose.animation.core.animateFloatAsState
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
|
@ -21,28 +19,20 @@ import androidx.compose.material3.SearchBarDefaults
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableFloatStateOf
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
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.draw.alpha
|
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import moe.lava.banksia.api.ptv.structures.ComposableIcon
|
import moe.lava.banksia.api.ptv.structures.ComposableRouteIcon
|
||||||
import moe.lava.banksia.api.ptv.structures.PtvRoute
|
import moe.lava.banksia.ui.state.SearchState
|
||||||
import kotlin.math.pow
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun Searcher(
|
fun Searcher(
|
||||||
routes: List<PtvRoute>,
|
state: SearchState,
|
||||||
|
onEvent: (BanksiaEvent) -> Unit,
|
||||||
expanded: Boolean,
|
expanded: Boolean,
|
||||||
onExpandedChange: (Boolean) -> Unit,
|
onExpandedChange: (Boolean) -> Unit,
|
||||||
text: String,
|
|
||||||
onTextChange: (String) -> Unit,
|
|
||||||
onRouteChange: (PtvRoute?) -> Unit,
|
|
||||||
) {
|
) {
|
||||||
val animatedPadding by animateDpAsState(
|
val animatedPadding by animateDpAsState(
|
||||||
if (expanded) {
|
if (expanded) {
|
||||||
|
|
@ -61,32 +51,20 @@ fun Searcher(
|
||||||
.padding(horizontal = animatedPadding),
|
.padding(horizontal = animatedPadding),
|
||||||
shadowElevation = 6.dp, // Elevation level 3
|
shadowElevation = 6.dp, // Elevation level 3
|
||||||
inputField = {
|
inputField = {
|
||||||
var backProgress by remember { mutableFloatStateOf(1f) }
|
|
||||||
var backEdgeIsLeft by remember { mutableStateOf<Boolean?>(null) }
|
|
||||||
val routeInfoOpacity by animateFloatAsState((1f - backProgress).pow(3))
|
|
||||||
val slideState by animateDpAsState((50 * backProgress).dp)
|
|
||||||
val slidePadding = when (backEdgeIsLeft) {
|
|
||||||
true -> PaddingValues(start = slideState)
|
|
||||||
false -> PaddingValues(end = slideState)
|
|
||||||
null -> PaddingValues()
|
|
||||||
}
|
|
||||||
|
|
||||||
SearchBarDefaults.InputField(
|
SearchBarDefaults.InputField(
|
||||||
modifier = Modifier
|
modifier = Modifier.padding(horizontal = 20.dp - animatedPadding),
|
||||||
.alpha(1f - routeInfoOpacity)
|
query = state.text,
|
||||||
.padding(horizontal = 20.dp - animatedPadding),
|
onQueryChange = { onEvent(BanksiaEvent.SearchUpdate(it)) },
|
||||||
query = text,
|
|
||||||
onQueryChange = onTextChange,
|
|
||||||
onSearch = {},
|
onSearch = {},
|
||||||
expanded = expanded,
|
expanded = expanded,
|
||||||
onExpandedChange = onExpandedChange,
|
onExpandedChange = onExpandedChange,
|
||||||
leadingIcon = { Icon(Icons.Default.Search, null) },
|
leadingIcon = { Icon(Icons.Default.Search, null) },
|
||||||
trailingIcon = {
|
trailingIcon = {
|
||||||
if (expanded && text.isNotEmpty())
|
if (expanded && state.text.isNotEmpty())
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Default.Clear,
|
imageVector = Icons.Default.Clear,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
modifier = Modifier.clickable { onTextChange("") }
|
modifier = Modifier.clickable { onEvent(BanksiaEvent.SearchUpdate("")) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -95,27 +73,20 @@ fun Searcher(
|
||||||
onExpandedChange = onExpandedChange,
|
onExpandedChange = onExpandedChange,
|
||||||
) {
|
) {
|
||||||
LazyColumn(modifier = Modifier.fillMaxWidth()) {
|
LazyColumn(modifier = Modifier.fillMaxWidth()) {
|
||||||
for (route in routes) {
|
for (entry in state.entries) {
|
||||||
if (!route.routeNumber.contains(text) &&
|
|
||||||
!route.routeName.lowercase().contains(text.lowercase()))
|
|
||||||
continue
|
|
||||||
item {
|
item {
|
||||||
ListItem(
|
ListItem(
|
||||||
headlineContent = { Text(route.routeNumber.ifEmpty { route.routeName }) },
|
headlineContent = { Text(entry.mainText) },
|
||||||
supportingContent = {
|
supportingContent = { entry.subText?.let { Text(it) } },
|
||||||
if (route.routeNumber.isNotEmpty()) {
|
leadingContent = { ComposableRouteIcon(entry.routeType) },
|
||||||
Text(route.routeName)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
leadingContent = { route.routeType.ComposableIcon() },
|
|
||||||
colors = ListItemDefaults.colors(containerColor = Color.Transparent),
|
colors = ListItemDefaults.colors(containerColor = Color.Transparent),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(horizontal = 16.dp, vertical = 4.dp)
|
.padding(horizontal = 16.dp, vertical = 4.dp)
|
||||||
.clickable {
|
.clickable {
|
||||||
onTextChange("")
|
|
||||||
onExpandedChange(false)
|
onExpandedChange(false)
|
||||||
onRouteChange(route)
|
onEvent(BanksiaEvent.SearchUpdate(""))
|
||||||
|
onEvent(BanksiaEvent.SelectRoute(entry.routeId))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package moe.lava.banksia.ui.state
|
||||||
|
|
||||||
|
import moe.lava.banksia.api.ptv.structures.PtvRouteType
|
||||||
|
|
||||||
|
data class SearchState(
|
||||||
|
val entries: List<SearchEntry> = listOf(),
|
||||||
|
val text: String = "",
|
||||||
|
) {
|
||||||
|
data class SearchEntry(
|
||||||
|
val mainText: String,
|
||||||
|
val subText: String?,
|
||||||
|
val routeId: Int,
|
||||||
|
val routeType: PtvRouteType,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -28,6 +28,8 @@ object Responses {
|
||||||
@Serializable
|
@Serializable
|
||||||
data class PtvRoutesResponse(val routes: List<PtvRoute>)
|
data class PtvRoutesResponse(val routes: List<PtvRoute>)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class PtvStopResponse(val stop: PtvStop)
|
||||||
@Serializable
|
@Serializable
|
||||||
data class PtvStopsResponse(val stops: List<PtvStop>)
|
data class PtvStopsResponse(val stops: List<PtvStop>)
|
||||||
|
|
||||||
|
|
@ -43,6 +45,8 @@ class PtvService {
|
||||||
class PtvCache(
|
class PtvCache(
|
||||||
private val service: PtvService,
|
private val service: PtvService,
|
||||||
private val directions: HashMap<Pair<Int, Int>, PtvDirection> = HashMap(),
|
private val directions: HashMap<Pair<Int, Int>, PtvDirection> = HashMap(),
|
||||||
|
private val routes: HashMap<Int, PtvRoute> = HashMap(),
|
||||||
|
private val stops: HashMap<Int, PtvStop> = HashMap(),
|
||||||
) {
|
) {
|
||||||
suspend fun direction(directionID: Int, routeID: Int): PtvDirection? {
|
suspend fun direction(directionID: Int, routeID: Int): PtvDirection? {
|
||||||
val ret = directions[Pair(directionID, routeID)]
|
val ret = directions[Pair(directionID, routeID)]
|
||||||
|
|
@ -54,6 +58,23 @@ class PtvService {
|
||||||
|
|
||||||
return ret ?: directions[Pair(directionID, routeID)]
|
return ret ?: directions[Pair(directionID, routeID)]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setRoutes(routes: Iterable<PtvRoute>) {
|
||||||
|
routes.forEach {
|
||||||
|
this.routes[it.routeId] = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getRoute(routeId: Int) = routes[routeId]
|
||||||
|
fun getRoutes() = routes.values.toList()
|
||||||
|
|
||||||
|
fun addStops(stops: Iterable<PtvStop>) {
|
||||||
|
stops.forEach {
|
||||||
|
this.stops[it.stopId] = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getStop(stopId: Int) = stops[stopId]
|
||||||
}
|
}
|
||||||
|
|
||||||
val cache = PtvCache(this)
|
val cache = PtvCache(this)
|
||||||
|
|
@ -83,17 +104,28 @@ class PtvService {
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun route(id: Int, includeGeopath: Boolean = false): PtvRoute {
|
suspend fun route(id: Int, includeGeopath: Boolean = false): PtvRoute {
|
||||||
|
val cached = cache.getRoute(id)
|
||||||
|
// TODO: im braindead so clean this up later
|
||||||
|
if (cached != null && (!includeGeopath || (includeGeopath && cached.geopath.isNotEmpty())))
|
||||||
|
return cached
|
||||||
|
|
||||||
val response: Responses.PtvRouteResponse = client.get("routes") {
|
val response: Responses.PtvRouteResponse = client.get("routes") {
|
||||||
url {
|
url {
|
||||||
appendPathSegments(id.toString())
|
appendPathSegments(id.toString())
|
||||||
parameters.append("include_geopath", if (includeGeopath) "true" else "false")
|
parameters.append("include_geopath", if (includeGeopath) "true" else "false")
|
||||||
}
|
}
|
||||||
}.body()
|
}.body()
|
||||||
|
cache.setRoutes(listOf(response.route))
|
||||||
return response.route
|
return response.route
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun routes(): List<PtvRoute> {
|
suspend fun routes(): List<PtvRoute> {
|
||||||
|
val cached = cache.getRoutes()
|
||||||
|
if (cached.isNotEmpty())
|
||||||
|
return cached
|
||||||
|
|
||||||
val response: Responses.PtvRoutesResponse = client.get("routes").body()
|
val response: Responses.PtvRoutesResponse = client.get("routes").body()
|
||||||
|
cache.setRoutes(response.routes)
|
||||||
return response.routes
|
return response.routes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,7 +140,29 @@ class PtvService {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}.body()
|
}.body()
|
||||||
return response.stops
|
val stops = response.stops
|
||||||
|
cache.addStops(stops)
|
||||||
|
return stops
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun stop(routeType: PtvRouteType, stopId: Int): PtvStop {
|
||||||
|
val cached = cache.getStop(stopId)
|
||||||
|
if (cached != null)
|
||||||
|
return cached
|
||||||
|
|
||||||
|
val response: Responses.PtvStopResponse = client.get() {
|
||||||
|
url {
|
||||||
|
appendPathSegments(
|
||||||
|
"stops",
|
||||||
|
stopId.toString(),
|
||||||
|
"route_type",
|
||||||
|
routeType.ordinal.toString(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}.body()
|
||||||
|
val stop = response.stop
|
||||||
|
cache.addStops(listOf(stop))
|
||||||
|
return stop
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun directionsByRoute(routeId: Int): List<PtvDirection> {
|
suspend fun directionsByRoute(routeId: Int): List<PtvDirection> {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue