feat: stop info panel

This commit is contained in:
LavaDesu 2025-04-30 00:11:21 +10:00
parent b417118e3d
commit 339e8c802f
Signed by: cilly
GPG key ID: 6500251E087653C9
7 changed files with 258 additions and 13 deletions

View file

@ -13,6 +13,8 @@ import io.ktor.serialization.kotlinx.json.json
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import moe.lava.banksia.Constants
import moe.lava.banksia.api.ptv.structures.PtvDeparture
import moe.lava.banksia.api.ptv.structures.PtvDirection
import moe.lava.banksia.api.ptv.structures.PtvRoute
import moe.lava.banksia.api.ptv.structures.PtvRouteType
import moe.lava.banksia.api.ptv.structures.PtvStop
@ -27,9 +29,34 @@ object Responses {
@Serializable
data class PtvStopsResponse(val stops: List<PtvStop>)
@Serializable
data class PtvDeparturesResponse(val departures: List<PtvDeparture>, val routes: Map<String, PtvRoute>, val directions: Map<String, PtvDirection>)
@Serializable
data class PtvDirectionsResponse(val directions: List<PtvDirection>)
}
class PtvService {
class PtvCache(
private val service: PtvService,
private val directions: HashMap<Pair<Int, Int>, PtvDirection> = HashMap(),
) {
suspend fun direction(directionID: Int, routeID: Int): PtvDirection? {
val ret = directions[Pair(directionID, routeID)]
if (ret == null) {
val res = service.directionsByRoute(routeID)
for (dir in res)
directions[Pair(dir.directionId, dir.routeId)] = dir
}
return ret ?: directions[Pair(directionID, routeID)]
}
}
val cache = PtvCache(this)
private val client = HttpClient() {
install(ContentNegotiation) {
json(Json {
@ -68,9 +95,10 @@ class PtvService {
}
suspend fun stopsByRoute(routeId: Int, routeType: PtvRouteType): List<PtvStop> {
val response: Responses.PtvStopsResponse = client.get("stops/route") {
val response: Responses.PtvStopsResponse = client.get("stops") {
url {
appendPathSegments(
"route",
routeId.toString(),
"route_type",
routeType.ordinal.toString()
@ -79,4 +107,38 @@ class PtvService {
}.body()
return response.stops
}
suspend fun directionsByRoute(routeId: Int): List<PtvDirection> {
val response: Responses.PtvDirectionsResponse = client.get("directions") {
url {
appendPathSegments("route", routeId.toString())
}
}.body()
return response.directions
}
suspend fun direction(id: Int, routeType: PtvRouteType?): List<PtvDirection> {
val response: Responses.PtvDirectionsResponse = client.get("directions") {
url {
appendPathSegments(id.toString())
if (routeType != null)
appendPathSegments("route_type", routeType.ordinal.toString())
}
}.body()
return response.directions
}
suspend fun departures(routeType: PtvRouteType, stopId: Int): Responses.PtvDeparturesResponse =
client.get("departures") {
url {
appendPathSegments(
"route_type",
routeType.ordinal.toString(),
"stop",
stopId.toString()
)
parameter("expand", "Route")
parameter("expand", "Direction")
}
}.body()
}

View file

@ -0,0 +1,12 @@
package moe.lava.banksia.api.ptv.structures
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class PtvDeparture(
@SerialName("scheduled_departure_utc") val scheduledDepartureUtc: String,
@SerialName("estimated_departure_utc") val estimatedDepartureUtc: String?,
@SerialName("direction_id") val directionId: Int,
@SerialName("route_id") val routeId: Int,
)

View file

@ -0,0 +1,11 @@
package moe.lava.banksia.api.ptv.structures
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class PtvDirection(
@SerialName("direction_id") val directionId: Int,
@SerialName("direction_name") val directionName: String,
@SerialName("route_id") val routeId: Int,
)