Skip to content

Commit 4c9d515

Browse files
committed
refactor: use own model types to be able to support other public transport APIs
1 parent caccd0a commit 4c9d515

36 files changed

+624
-322
lines changed

app/src/main/java/net/youapps/transport/MainActivity.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,9 @@ class MainActivity : ComponentActivity() {
8787
composable<NavRoutes.TripDetails> { backStackEntry ->
8888
val tripDetails: NavRoutes.TripDetails = backStackEntry.toRoute()
8989

90-
val tripWrapper = directionsModel.trips.collectAsState().value
90+
val trip = directionsModel.trips.collectAsState().value
9191
.find { it.id == tripDetails.tripId }!!
92-
TripDetailsScreen(navController, directionsModel, tripWrapper.trip)
92+
TripDetailsScreen(navController, directionsModel, trip)
9393
}
9494

9595
composable<NavRoutes.Home> {

app/src/main/java/net/youapps/transport/NavRoutes.kt

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
package net.youapps.transport
22

33
import android.os.Parcelable
4-
import de.schildbach.pte.dto.Location
5-
import de.schildbach.pte.dto.LocationType
6-
import de.schildbach.pte.dto.Point
7-
import de.schildbach.pte.dto.Product
84
import kotlinx.parcelize.Parcelize
95
import kotlinx.serialization.Serializable
6+
import net.youapps.transport.data.transport.model.GeoCoordinate
7+
import net.youapps.transport.data.transport.model.Location
8+
import net.youapps.transport.data.transport.model.LocationType
109

1110
object NavRoutes {
1211
@Serializable
@@ -18,28 +17,25 @@ object NavRoutes {
1817
@Serializable
1918
@Parcelize
2019
data class DeparturesFromLocation(
21-
val type: LocationType? = null,
22-
val id: String? = null,
20+
val id: String?,
21+
val name: String,
22+
val type: LocationType,
2323
val coordLat: Double? = null,
2424
val coordLon: Double? = null,
25-
val place: String? = null,
26-
val name: String? = null,
27-
val products: List<String>? = null
2825
): Parcelable {
2926
constructor(location: Location) : this(
30-
location.type,
31-
location.id,
32-
location.coord?.latAsDouble,
33-
location.coord?.lonAsDouble,
34-
location.place,
35-
location.name,
36-
location.products?.map { it.name }
27+
id = location.id,
28+
name = location.name,
29+
type = location.type,
30+
coordLat = location.position?.latitude,
31+
coordLon = location.position?.longitude,
3732
)
3833

3934
fun toLocation() = Location(
40-
type, id, if (coordLon != null && coordLat != null) {
41-
Point.fromDouble(coordLat, coordLon)
42-
} else null, place, name, products?.map { Product.valueOf(it) }?.toSet()
35+
id = id,
36+
name = name,
37+
type = type,
38+
position = if (coordLon != null && coordLat != null) GeoCoordinate(coordLon, coordLat) else null
4339
)
4440
}
4541

app/src/main/java/net/youapps/transport/TextUtils.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import java.time.ZoneId
88
import java.time.ZonedDateTime
99
import java.time.format.DateTimeFormatter
1010
import java.time.format.FormatStyle
11+
import java.time.temporal.ChronoUnit
1112
import java.util.Date
1213
import java.util.Locale
1314

@@ -67,20 +68,20 @@ object TextUtils {
6768
return "%.1f".format(distance.toFloat() / 1000) + " km"
6869
}
6970

70-
private fun formatTimeDiff(planned: Date, actual: Date): String {
71-
val diffMillis = actual.time - planned.time
71+
private fun formatTimeDiff(planned: ZonedDateTime, actual: ZonedDateTime): String {
72+
val diffMillis = ChronoUnit.MILLIS.between(planned, actual)
7273
var diffMinutes = (diffMillis / 1000 / 60).toString()
7374

7475
if (!diffMinutes.startsWith("-")) diffMinutes = "+$diffMinutes"
7576
return diffMinutes
7677
}
7778

78-
fun displayDepartureTimeWithDelay(planned: Date?, predicted: Date?): String {
79+
fun displayDepartureTimeWithDelay(planned: ZonedDateTime?, predicted: ZonedDateTime?): String {
7980
if (planned != null && predicted != null) {
8081
val timeDiff = formatTimeDiff(planned, predicted)
81-
return formatTime(planned.toZonedDateTime()) + " ($timeDiff)"
82+
return formatTime(planned) + " ($timeDiff)"
8283
}
8384

84-
return (planned ?: predicted)?.let { formatTime(it.toZonedDateTime()) }.orEmpty()
85+
return (planned ?: predicted)?.let { formatTime(it) }.orEmpty()
8586
}
8687
}

app/src/main/java/net/youapps/transport/components/LocationSearchBar.kt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@ import androidx.compose.runtime.collectAsState
66
import androidx.compose.runtime.getValue
77
import androidx.compose.runtime.rememberCoroutineScope
88
import androidx.compose.ui.graphics.vector.ImageVector
9-
import de.schildbach.pte.dto.Location
109
import kotlinx.coroutines.launch
1110
import net.youapps.transport.components.generic.SearchBarWithSuggestions
1211
import net.youapps.transport.components.generic.Suggestion
13-
import net.youapps.transport.extensions.displayName
12+
import net.youapps.transport.data.transport.model.Location
1413
import net.youapps.transport.models.LocationsModel
1514

1615
@Composable
@@ -34,15 +33,14 @@ fun LocationSearchBar(
3433
},
3534
searchSuggestions = suggestions.map { location ->
3635
Suggestion(
37-
key = location.id.toString(),
38-
displayName = location.displayName()
36+
key = location.id!!,
37+
displayName = location.name
3938
)
4039
},
4140
onSuggestionClicked = { suggestion ->
4241
val location = suggestions.find { it.id == suggestion.key }
4342
scope.launch {
44-
val locationName = location?.displayName()
45-
locationsModel.query.emit(locationName)
43+
locationsModel.query.emit(location?.name)
4644
}
4745
onLocation(location ?: return@SearchBarWithSuggestions)
4846
},

app/src/main/java/net/youapps/transport/components/directions/DepartureItem.kt

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,22 @@ import androidx.compose.runtime.Composable
1313
import androidx.compose.ui.Modifier
1414
import androidx.compose.ui.tooling.preview.Preview
1515
import androidx.compose.ui.unit.dp
16-
import de.schildbach.pte.NetworkId
17-
import de.schildbach.pte.dto.Departure
18-
import de.schildbach.pte.dto.Line
19-
import de.schildbach.pte.dto.Location
20-
import de.schildbach.pte.dto.LocationType
21-
import de.schildbach.pte.dto.Position
22-
import de.schildbach.pte.dto.Product
2316
import net.youapps.transport.TextUtils
2417
import net.youapps.transport.components.generic.AutoRefreshingText
25-
import net.youapps.transport.extensions.displayName
26-
import java.util.Date
18+
import net.youapps.transport.data.transport.model.Departure
19+
import net.youapps.transport.data.transport.model.EstimatedDateTime
20+
import net.youapps.transport.data.transport.model.Location
21+
import net.youapps.transport.data.transport.model.LocationType
22+
import net.youapps.transport.data.transport.model.Product
23+
import net.youapps.transport.data.transport.model.TransportLine
24+
import java.time.ZonedDateTime
2725

2826
@Composable
2927
fun DepartureItem(departure: Departure, onDestinationClicked: (Location) -> Unit) {
3028
Column(
3129
modifier = Modifier
3230
.clickable {
33-
departure.destination?.let { onDestinationClicked(it) }
31+
onDestinationClicked(departure.destination)
3432
}
3533
.padding(horizontal = 10.dp, vertical = 4.dp)
3634
) {
@@ -40,15 +38,16 @@ fun DepartureItem(departure: Departure, onDestinationClicked: (Location) -> Unit
4038
Column {
4139
Text(
4240
TextUtils.displayDepartureTimeWithDelay(
43-
departure.plannedTime,
44-
departure.predictedTime
41+
departure.departure.planned,
42+
departure.departure.predicted
4543
)
4644
)
4745

4846
AutoRefreshingText(
4947
style = MaterialTheme.typography.bodySmall
5048
) {
51-
DateUtils.getRelativeTimeSpanString(departure.time.time)
49+
departure.departure.predictedOrPlanned?.toInstant()?.toEpochMilli()
50+
?.let { DateUtils.getRelativeTimeSpanString(it) }
5251
.toString()
5352
}
5453
}
@@ -58,35 +57,36 @@ fun DepartureItem(departure: Departure, onDestinationClicked: (Location) -> Unit
5857
) {
5958
TransportLineCard(departure.line)
6059

61-
Text(departure.destination?.displayName().orEmpty())
60+
Text(departure.destination.name)
6261
}
6362

64-
if (departure.position != null) {
63+
if (departure.platform != null) {
6564
Card {
6665
Text(
6766
modifier = Modifier.padding(horizontal = 6.dp, vertical = 4.dp),
68-
text = departure.position?.name.orEmpty()
67+
text = departure.platform
6968
)
7069
}
7170
}
7271
}
7372

7473
if (departure.message != null) {
7574
Text(
76-
text = departure.message!!,
75+
text = departure.message,
7776
color = MaterialTheme.colorScheme.error
7877
)
7978
}
8079
}
8180
}
8281

8382
val DEMO_DEPARTURE = Departure(
84-
Date(),
85-
Date(),
86-
Line("12345", NetworkId.DB.name, Product.REGIONAL_TRAIN, "RB68"),
87-
Position("Pos. 3"),
88-
Location(LocationType.STATION, "endid", "Berlin", "Main station"),
89-
intArrayOf(),
83+
TransportLine("12345", "", "RB68", Product.REGIONAL_TRAIN, null),
84+
departure = EstimatedDateTime(
85+
ZonedDateTime.now(),
86+
ZonedDateTime.now().plusMinutes(5)
87+
),
88+
Location( "endid", "Berlin", LocationType.STATION,null),
89+
"Pos. 3",
9090
"No message."
9191
)
9292

app/src/main/java/net/youapps/transport/components/directions/EditLocationsSheet.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,10 @@ import androidx.compose.ui.Alignment
2727
import androidx.compose.ui.Modifier
2828
import androidx.compose.ui.res.stringResource
2929
import androidx.compose.ui.unit.dp
30-
import de.schildbach.pte.dto.Location
3130
import kotlinx.coroutines.launch
3231
import net.youapps.transport.R
3332
import net.youapps.transport.components.generic.DismissBackground
34-
import net.youapps.transport.extensions.displayName
33+
import net.youapps.transport.data.transport.model.Location
3534
import sh.calvin.reorderable.ReorderableItem
3635
import sh.calvin.reorderable.rememberReorderableLazyListState
3736

@@ -89,7 +88,7 @@ fun EditLocationsSheet(
8988
) {
9089
Text(
9190
modifier = Modifier.padding(horizontal = 8.dp),
92-
text = location.displayName()
91+
text = location.name
9392
)
9493

9594
IconButton(

app/src/main/java/net/youapps/transport/components/directions/IndividualTripCard.kt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,19 @@ import androidx.compose.material.icons.automirrored.filled.DirectionsWalk
66
import androidx.compose.material.icons.filled.DirectionsCar
77
import androidx.compose.material.icons.filled.NoTransfer
88
import androidx.compose.runtime.Composable
9-
import de.schildbach.pte.dto.Trip
109
import net.youapps.transport.TextUtils
1110
import net.youapps.transport.components.generic.CardWithIcon
11+
import net.youapps.transport.data.transport.model.IndividualType
12+
import net.youapps.transport.data.transport.model.TripLeg
1213

1314
val individualIcons = mapOf(
14-
Trip.Individual.Type.TRANSFER to Icons.Default.NoTransfer,
15-
Trip.Individual.Type.WALK to Icons.AutoMirrored.Filled.DirectionsWalk,
16-
Trip.Individual.Type.BIKE to Icons.AutoMirrored.Filled.DirectionsBike,
17-
Trip.Individual.Type.CAR to Icons.Filled.DirectionsCar
15+
IndividualType.TRANSFER to Icons.Default.NoTransfer,
16+
IndividualType.WALK to Icons.AutoMirrored.Filled.DirectionsWalk,
17+
IndividualType.BIKE to Icons.AutoMirrored.Filled.DirectionsBike,
18+
IndividualType.CAR to Icons.Filled.DirectionsCar
1819
)
1920

2021
@Composable
21-
fun IndividualTripCard(leg: Trip.Individual) {
22+
fun IndividualTripCard(leg: TripLeg.Individual) {
2223
CardWithIcon(individualIcons[leg.type], TextUtils.formatDistance(leg.distance))
2324
}

app/src/main/java/net/youapps/transport/components/directions/RouteRow.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@ import androidx.compose.ui.Alignment
1616
import androidx.compose.ui.Modifier
1717
import androidx.compose.ui.res.stringResource
1818
import androidx.compose.ui.unit.dp
19-
import de.schildbach.pte.dto.Location
2019
import net.youapps.transport.R
21-
import net.youapps.transport.extensions.displayName
20+
import net.youapps.transport.data.transport.model.Location
2221

2322
@Composable
2423
fun RouteRow(origin: Location, destination: Location, onRouteClicked: () -> Unit) {
@@ -34,7 +33,7 @@ fun RouteRow(origin: Location, destination: Location, onRouteClicked: () -> Unit
3433
) {
3534
Icon(imageVector = Icons.Default.LocationOn, contentDescription = stringResource(R.string.origin))
3635

37-
Text(text = origin.displayName())
36+
Text(text = origin.name)
3837
}
3938

4039
Row(
@@ -43,7 +42,7 @@ fun RouteRow(origin: Location, destination: Location, onRouteClicked: () -> Unit
4342
) {
4443
Icon(imageVector = Icons.Default.Flag, contentDescription = stringResource(R.string.destination))
4544

46-
Text(text = destination.displayName())
45+
Text(text = destination.name)
4746
}
4847
}
4948
}

app/src/main/java/net/youapps/transport/components/directions/TransportLineCard.kt

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package net.youapps.transport.components.directions
22

33
import androidx.compose.material.icons.Icons
44
import androidx.compose.material.icons.filled.Cable
5-
import androidx.compose.material.icons.filled.CarRental
65
import androidx.compose.material.icons.filled.DirectionsBoat
76
import androidx.compose.material.icons.filled.DirectionsBus
87
import androidx.compose.material.icons.filled.DirectionsCar
@@ -12,10 +11,9 @@ import androidx.compose.material.icons.filled.Train
1211
import androidx.compose.material.icons.filled.Tram
1312
import androidx.compose.material.icons.outlined.DirectionsRailway
1413
import androidx.compose.runtime.Composable
15-
import de.schildbach.pte.dto.Line
16-
import de.schildbach.pte.dto.Product
1714
import net.youapps.transport.components.generic.CardWithIcon
18-
import kotlin.collections.get
15+
import net.youapps.transport.data.transport.model.Product
16+
import net.youapps.transport.data.transport.model.TransportLine
1917

2018
val transportIcons = mapOf(
2119
Product.HIGH_SPEED_TRAIN to Icons.Default.DirectionsRailway,
@@ -26,11 +24,10 @@ val transportIcons = mapOf(
2624
Product.BUS to Icons.Default.DirectionsBus,
2725
Product.CABLECAR to Icons.Default.Cable,
2826
Product.FERRY to Icons.Default.DirectionsBoat,
29-
Product.CABLECAR to Icons.Default.CarRental,
3027
Product.ON_DEMAND to Icons.Default.DirectionsCar
3128
)
3229

3330
@Composable
34-
fun TransportLineCard(line: Line) {
35-
CardWithIcon(transportIcons[line.product], line.label)
31+
fun TransportLineCard(line: TransportLine) {
32+
CardWithIcon(transportIcons[line.type], line.label)
3633
}

0 commit comments

Comments
 (0)