From 45dd40faa71668917cc4c36046f0f2445a19f6bf Mon Sep 17 00:00:00 2001 From: Johan von Forstner Date: Sun, 21 Jun 2020 12:33:53 +0200 Subject: [PATCH] show compatible payment methods in details (#26) --- .../evmap/adapter/DataBindingAdapters.kt | 38 +++++++++++++++++-- .../goingelectric/GoingElectricAdapters.kt | 5 ++- .../api/goingelectric/GoingElectricModel.kt | 9 ++++- .../vonforst/evmap/storage/TypeConverters.kt | 15 ++++++++ .../vonforst/evmap/viewmodel/MapViewModel.kt | 11 ++++++ app/src/main/res/drawable/ic_payment.xml | 10 +++++ app/src/main/res/layout/detail_view.xml | 8 +++- app/src/main/res/layout/fragment_map.xml | 3 +- app/src/main/res/values-de/strings.xml | 6 +++ app/src/main/res/values/strings.xml | 6 +++ 10 files changed, 101 insertions(+), 10 deletions(-) create mode 100644 app/src/main/res/drawable/ic_payment.xml diff --git a/app/src/main/java/net/vonforst/evmap/adapter/DataBindingAdapters.kt b/app/src/main/java/net/vonforst/evmap/adapter/DataBindingAdapters.kt index 814df9aa..61e027b3 100644 --- a/app/src/main/java/net/vonforst/evmap/adapter/DataBindingAdapters.kt +++ b/app/src/main/java/net/vonforst/evmap/adapter/DataBindingAdapters.kt @@ -17,9 +17,7 @@ import com.google.android.material.chip.Chip import net.vonforst.evmap.BR import net.vonforst.evmap.R import net.vonforst.evmap.api.availability.ChargepointStatus -import net.vonforst.evmap.api.goingelectric.ChargeLocation -import net.vonforst.evmap.api.goingelectric.Chargepoint -import net.vonforst.evmap.api.goingelectric.OpeningHoursDays +import net.vonforst.evmap.api.goingelectric.* import net.vonforst.evmap.databinding.ItemFilterMultipleChoiceBinding import net.vonforst.evmap.databinding.ItemFilterMultipleChoiceLargeBinding import net.vonforst.evmap.databinding.ItemFilterSliderBinding @@ -115,7 +113,11 @@ class DetailAdapter : DataBindingAdapter() { } } -fun buildDetails(loc: ChargeLocation?, ctx: Context): List { +fun buildDetails( + loc: ChargeLocation?, + chargeCards: Map?, + ctx: Context +): List { if (loc == null) return emptyList() return listOfNotNull( @@ -165,6 +167,15 @@ fun buildDetails(loc: ChargeLocation?, ctx: Context): List loc.cost.descriptionLong ?: loc.cost.descriptionShort ) else null, + if (loc.chargecards != null && loc.chargecards.isNotEmpty()) DetailAdapter.Detail( + R.drawable.ic_payment, + R.string.charge_cards, + ctx.resources.getQuantityString( + R.plurals.charge_cards_compatible_num, + loc.chargecards.size, loc.chargecards.size + ), + formatChargeCards(loc.chargecards, chargeCards, ctx) + ) else null, DetailAdapter.Detail( R.drawable.ic_location, R.string.coordinates, @@ -176,6 +187,25 @@ fun buildDetails(loc: ChargeLocation?, ctx: Context): List ) } +fun formatChargeCards( + chargecards: List, + chargecardData: Map?, + ctx: Context +): String { + if (chargecardData == null) return "" + + val maxItems = 5 + var result = chargecards + .take(maxItems) + .mapNotNull { chargecardData[it.id]?.name } + .joinToString() + if (chargecards.size > maxItems) { + result += " " + ctx.getString(R.string.and_n_others, chargecards.size - maxItems) + } + + return result +} + class FavoritesAdapter(val vm: FavoritesViewModel) : DataBindingAdapter() { diff --git a/app/src/main/java/net/vonforst/evmap/api/goingelectric/GoingElectricAdapters.kt b/app/src/main/java/net/vonforst/evmap/api/goingelectric/GoingElectricAdapters.kt index 47e2bd0b..9dbe7d5c 100644 --- a/app/src/main/java/net/vonforst/evmap/api/goingelectric/GoingElectricAdapters.kt +++ b/app/src/main/java/net/vonforst/evmap/api/goingelectric/GoingElectricAdapters.kt @@ -75,14 +75,14 @@ internal class JsonObjectOrFalseAdapter private constructor( type: Type, annotations: Set?, moshi: Moshi - ): JsonAdapter<*>? { + ): JsonAdapter? { val clazz = Types.getRawType(type) return when (hasJsonObjectOrFalseAnnotation( annotations )) { false -> null true -> JsonObjectOrFalseAdapter( - moshi.adapter(clazz), clazz + moshi.adapter(type), clazz ) } } @@ -101,6 +101,7 @@ internal class JsonObjectOrFalseAdapter private constructor( } } JsonReader.Token.BEGIN_OBJECT -> objectDelegate.fromJson(reader) + JsonReader.Token.BEGIN_ARRAY -> objectDelegate.fromJson(reader) JsonReader.Token.STRING -> objectDelegate.fromJson(reader) JsonReader.Token.NUMBER -> objectDelegate.fromJson(reader) else -> diff --git a/app/src/main/java/net/vonforst/evmap/api/goingelectric/GoingElectricModel.kt b/app/src/main/java/net/vonforst/evmap/api/goingelectric/GoingElectricModel.kt index b03aebff..5d30d45f 100644 --- a/app/src/main/java/net/vonforst/evmap/api/goingelectric/GoingElectricModel.kt +++ b/app/src/main/java/net/vonforst/evmap/api/goingelectric/GoingElectricModel.kt @@ -52,7 +52,7 @@ data class ChargeLocation( val chargepoints: List, @JsonObjectOrFalse val network: String?, val url: String, - @Embedded(prefix="fault_report_") @JsonObjectOrFalse @Json(name = "fault_report") val faultReport: FaultReport?, + @Embedded(prefix = "fault_report_") @JsonObjectOrFalse @Json(name = "fault_report") val faultReport: FaultReport?, val verified: Boolean, // only shown in details: @JsonObjectOrFalse val operator: String?, @@ -60,7 +60,7 @@ data class ChargeLocation( @JsonObjectOrFalse @Json(name = "ladeweile") val amenities: String?, @JsonObjectOrFalse @Json(name = "location_description") val locationDescription: String?, val photos: List?, - //val chargecards: Boolean? + @JsonObjectOrFalse val chargecards: List?, @Embedded val openinghours: OpeningHours?, @Embedded val cost: Cost? ) : ChargepointListItem(), Equatable { @@ -279,3 +279,8 @@ data class ChargeCard( val name: String, val url: String ) + +@JsonClass(generateAdapter = true) +data class ChargeCardId( + val id: Long +) \ No newline at end of file diff --git a/app/src/main/java/net/vonforst/evmap/storage/TypeConverters.kt b/app/src/main/java/net/vonforst/evmap/storage/TypeConverters.kt index ed3adbd9..01b3cb12 100644 --- a/app/src/main/java/net/vonforst/evmap/storage/TypeConverters.kt +++ b/app/src/main/java/net/vonforst/evmap/storage/TypeConverters.kt @@ -3,6 +3,7 @@ package net.vonforst.evmap.storage import androidx.room.TypeConverter import com.squareup.moshi.Moshi import com.squareup.moshi.Types +import net.vonforst.evmap.api.goingelectric.ChargeCardId import net.vonforst.evmap.api.goingelectric.Chargepoint import net.vonforst.evmap.api.goingelectric.ChargerPhoto import java.time.Instant @@ -18,6 +19,10 @@ class Converters { val type = Types.newParameterizedType(List::class.java, ChargerPhoto::class.java) moshi.adapter>(type) } + private val chargeCardIdListAdapter by lazy { + val type = Types.newParameterizedType(List::class.java, ChargeCardId::class.java) + moshi.adapter>(type) + } private val stringSetAdapter by lazy { val type = Types.newParameterizedType(Set::class.java, String::class.java) moshi.adapter>(type) @@ -43,6 +48,16 @@ class Converters { return chargerPhotoListAdapter.fromJson(value) } + @TypeConverter + fun fromChargeCardIdList(value: List?): String { + return chargeCardIdListAdapter.toJson(value) + } + + @TypeConverter + fun toChargeCardIdList(value: String): List? { + return chargeCardIdListAdapter.fromJson(value) + } + @TypeConverter fun fromLocalTime(value: LocalTime?): String? { return value?.toString() diff --git a/app/src/main/java/net/vonforst/evmap/viewmodel/MapViewModel.kt b/app/src/main/java/net/vonforst/evmap/viewmodel/MapViewModel.kt index e1d6ec36..de98504b 100644 --- a/app/src/main/java/net/vonforst/evmap/viewmodel/MapViewModel.kt +++ b/app/src/main/java/net/vonforst/evmap/viewmodel/MapViewModel.kt @@ -61,6 +61,17 @@ class MapViewModel(application: Application, geApiKey: String) : AndroidViewMode filtersWithValue(filters, filterValues, filtersActive) } + val chargeCardMap: LiveData> by lazy { + MediatorLiveData>().apply { + value = null + addSource(chargeCards) { + value = chargeCards.value?.map { + it.id to it + }?.toMap() + } + } + } + val filtersCount: LiveData by lazy { MediatorLiveData().apply { value = 0 diff --git a/app/src/main/res/drawable/ic_payment.xml b/app/src/main/res/drawable/ic_payment.xml new file mode 100644 index 00000000..af7ee9e0 --- /dev/null +++ b/app/src/main/res/drawable/ic_payment.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/detail_view.xml b/app/src/main/res/layout/detail_view.xml index 7cd8d1b0..640e527a 100644 --- a/app/src/main/res/layout/detail_view.xml +++ b/app/src/main/res/layout/detail_view.xml @@ -9,6 +9,8 @@ + + @@ -25,6 +27,10 @@ name="availability" type="Resource<ChargeLocationStatus>" /> + + + app:availability="@{vm.availability}" + app:chargeCards="@{vm.chargeCardMap}" /> diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 9752de3f..161286cc 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -97,4 +97,10 @@ 24 Stunden geöffnet Ohne Vertrag / Registrierung nutzbar Ladesäulen mit Störung ausschließen + Ladetarife + und %d weitere + + %d kompatibler Ladetarif + %d kompatible Ladetarife + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4335fe62..3480706f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -96,4 +96,10 @@ Available 24/7 Usable without registration Exclude chargers with reported faults + Payment methods + and %d others + + %d compatible payment method + %d compatible payment methods +