diff --git a/composeApp/src/commonMain/composeResources/drawable/bus.xml b/composeApp/src/commonMain/composeResources/drawable/bus.xml new file mode 100644 index 0000000..cb06d1c --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/bus.xml @@ -0,0 +1,14 @@ + + + + \ No newline at end of file diff --git a/composeApp/src/commonMain/composeResources/drawable/bus_background.xml b/composeApp/src/commonMain/composeResources/drawable/bus_background.xml new file mode 100644 index 0000000..1ad33d6 --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/bus_background.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/composeApp/src/commonMain/composeResources/drawable/bus_icon.xml b/composeApp/src/commonMain/composeResources/drawable/bus_icon.xml new file mode 100644 index 0000000..e81bef2 --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/bus_icon.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/composeApp/src/commonMain/composeResources/drawable/train.xml b/composeApp/src/commonMain/composeResources/drawable/train.xml new file mode 100644 index 0000000..5ee2abb --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/train.xml @@ -0,0 +1,14 @@ + + + + \ No newline at end of file diff --git a/composeApp/src/commonMain/composeResources/drawable/train_background.xml b/composeApp/src/commonMain/composeResources/drawable/train_background.xml new file mode 100644 index 0000000..48a906a --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/train_background.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/composeApp/src/commonMain/composeResources/drawable/train_icon.xml b/composeApp/src/commonMain/composeResources/drawable/train_icon.xml new file mode 100644 index 0000000..bd0fcf3 --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/train_icon.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/composeApp/src/commonMain/composeResources/drawable/tram.xml b/composeApp/src/commonMain/composeResources/drawable/tram.xml new file mode 100644 index 0000000..90fc96a --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/tram.xml @@ -0,0 +1,14 @@ + + + + \ No newline at end of file diff --git a/composeApp/src/commonMain/composeResources/drawable/tram_background.xml b/composeApp/src/commonMain/composeResources/drawable/tram_background.xml new file mode 100644 index 0000000..3287598 --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/tram_background.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/composeApp/src/commonMain/composeResources/drawable/tram_icon.xml b/composeApp/src/commonMain/composeResources/drawable/tram_icon.xml new file mode 100644 index 0000000..2edc27c --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/tram_icon.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/composeApp/src/commonMain/kotlin/moe/lava/banksia/api/ptv/RouteType.kt b/composeApp/src/commonMain/kotlin/moe/lava/banksia/api/ptv/RouteType.kt new file mode 100644 index 0000000..7174378 --- /dev/null +++ b/composeApp/src/commonMain/kotlin/moe/lava/banksia/api/ptv/RouteType.kt @@ -0,0 +1,56 @@ +package moe.lava.banksia.api.ptv + +import androidx.compose.foundation.Image +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.drawBehind +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import moe.lava.banksia.resources.Res +import moe.lava.banksia.resources.bus +import moe.lava.banksia.resources.bus_background +import moe.lava.banksia.resources.bus_icon +import moe.lava.banksia.resources.train +import moe.lava.banksia.resources.train_background +import moe.lava.banksia.resources.train_icon +import moe.lava.banksia.resources.tram +import moe.lava.banksia.resources.tram_background +import moe.lava.banksia.resources.tram_icon +import org.jetbrains.compose.resources.DrawableResource +import org.jetbrains.compose.resources.painterResource + +data class RouteTypeProperties( + val colour: Color, + val drawable: DrawableResource, + val background: DrawableResource, + val icon: DrawableResource, +) +fun RouteType.getProperties(): RouteTypeProperties { + val colour = when (this) { + RouteType.TRAIN -> Color(0xFF0072CE) + RouteType.TRAM -> Color(0xFF78BE20) + RouteType.BUS, RouteType.NIGHT_BUS -> Color(0xFFFF8200) + RouteType.VLINE -> Color(0xFF8F1A95) + } + val (drawable, background, icon) = when (this) { + RouteType.TRAM -> Triple( + Res.drawable.tram, Res.drawable.tram_background, Res.drawable.tram_icon) + RouteType.TRAIN, RouteType.VLINE -> Triple( + Res.drawable.train, Res.drawable.train_background, Res.drawable.train_icon) + RouteType.BUS, RouteType.NIGHT_BUS -> Triple( + Res.drawable.bus, Res.drawable.bus_background, Res.drawable.bus_icon) + } + return RouteTypeProperties(colour, drawable, background, icon) +} +@Composable +fun RouteType.ComposableIcon() { + val properties = this.getProperties() + Image( + painter = painterResource(properties.icon), + contentDescription = null, + modifier = Modifier + .drawBehind { + drawCircle(properties.colour, radius = (this.size.minDimension + 10.dp.toPx()) / 2f) + } + ) +} diff --git a/composeApp/src/commonMain/kotlin/moe/lava/banksia/ui/Searcher.kt b/composeApp/src/commonMain/kotlin/moe/lava/banksia/ui/Searcher.kt index c8f43ca..8c746d3 100644 --- a/composeApp/src/commonMain/kotlin/moe/lava/banksia/ui/Searcher.kt +++ b/composeApp/src/commonMain/kotlin/moe/lava/banksia/ui/Searcher.kt @@ -30,6 +30,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp +import moe.lava.banksia.api.ptv.ComposableIcon import moe.lava.banksia.api.ptv.PtvService import moe.lava.banksia.api.ptv.Route @@ -58,7 +59,7 @@ fun Searcher( val localRoutes = ptvService.routes() routes = localRoutes.sortedWith( compareBy( -// { it.routeType.ordinal }, + { it.gtfsSubType()?.ordinal }, { it.routeNumber.toIntOrNull() }, { it.routeName } ) @@ -104,7 +105,7 @@ fun Searcher( Text(route.routeName) } }, -// leadingContent = { route.route_type.ComposableIcon() }, + leadingContent = { route.routeType.ComposableIcon() }, colors = ListItemDefaults.colors(containerColor = Color.Transparent), modifier = Modifier .fillMaxWidth() diff --git a/shared/src/commonMain/kotlin/moe/lava/banksia/api/ptv/PtvService.kt b/shared/src/commonMain/kotlin/moe/lava/banksia/api/ptv/PtvService.kt index 0a42c39..a35ec10 100644 --- a/shared/src/commonMain/kotlin/moe/lava/banksia/api/ptv/PtvService.kt +++ b/shared/src/commonMain/kotlin/moe/lava/banksia/api/ptv/PtvService.kt @@ -18,12 +18,34 @@ import moe.lava.banksia.Constants import moe.lava.banksia.log import okio.ByteString.Companion.encodeUtf8 +// Ordinals used for sorting in searcher +enum class GtfsSubType(val value: Int) { + MetroTrain(2), + MetroTram(3), + MetroBus(4), + RegionalTrain(1), + RegionalCoach(5), + RegionalBus(6), + SkyBus(11), + Interstate(10), +} + @Serializable data class Route( + @SerialName("route_type") val routeType: RouteType, @SerialName("route_id") val routeId: Int, @SerialName("route_number") val routeNumber: String, @SerialName("route_name") val routeName: String, -) + @SerialName("route_gtfs_id") val routeGtfsId: String, +) { + fun gtfsSubType(): GtfsSubType? { + GtfsSubType.entries.forEach { + if (routeGtfsId.startsWith(it.value.toString())) + return it + } + return null + } +} @Serializable data class RouteResponse(val routes: List) diff --git a/shared/src/commonMain/kotlin/moe/lava/banksia/api/ptv/RouteType.kt b/shared/src/commonMain/kotlin/moe/lava/banksia/api/ptv/RouteType.kt new file mode 100644 index 0000000..6dc9f1c --- /dev/null +++ b/shared/src/commonMain/kotlin/moe/lava/banksia/api/ptv/RouteType.kt @@ -0,0 +1,34 @@ +package moe.lava.banksia.api.ptv + +import kotlinx.serialization.KSerializer +import kotlinx.serialization.Serializable +import kotlinx.serialization.descriptors.PrimitiveKind +import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder + +private object RouteTypeSerializer : KSerializer { + override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(RouteType::class.qualifiedName!!, + PrimitiveKind.INT) + + override fun serialize(encoder: Encoder, value: RouteType) { + encoder.encodeInt(value.ordinal) + } + + override fun deserialize(decoder: Decoder): RouteType { + val index = decoder.decodeInt() + return RouteType.entries[index] + } + + override fun toString(): String = "EnumOrdinalSerializer<${descriptor.serialName}>" +} + +@Serializable(with = RouteTypeSerializer::class) +enum class RouteType { + TRAIN, + TRAM, + BUS, + VLINE, + NIGHT_BUS, +}