From 0bb310f822f0520ad2b6eefee66064d93cea50dd Mon Sep 17 00:00:00 2001 From: Johan von Forstner Date: Mon, 16 Mar 2020 20:36:16 +0100 Subject: [PATCH] load some charger details --- app/build.gradle | 1 + .../main/java/com/johan/evmap/MapsActivity.kt | 42 ++++++++++++++--- .../johan/evmap/api/GoingElectricAdapters.kt | 47 ++++++++++++++++++- .../com/johan/evmap/api/GoingElectricApi.kt | 4 ++ .../com/johan/evmap/api/GoingElectricModel.kt | 14 ++++-- .../com/johan/evmap/ui/BindingAdapters.kt | 5 ++ app/src/main/res/layout/activity_maps.xml | 3 +- app/src/main/res/layout/detail_view.xml | 14 +++++- 8 files changed, 118 insertions(+), 12 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index a3bf1134..d85fcd7e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -50,6 +50,7 @@ dependencies { implementation 'com.squareup.retrofit2:retrofit:2.7.2' implementation 'com.squareup.retrofit2:converter-moshi:2.7.2' implementation 'com.squareup.moshi:moshi-kotlin:1.9.2' + implementation 'com.squareup.picasso:picasso:2.71828' // debug tools implementation 'com.facebook.stetho:stetho:1.5.1' diff --git a/app/src/main/java/com/johan/evmap/MapsActivity.kt b/app/src/main/java/com/johan/evmap/MapsActivity.kt index 1221b92f..3055eaeb 100644 --- a/app/src/main/java/com/johan/evmap/MapsActivity.kt +++ b/app/src/main/java/com/johan/evmap/MapsActivity.kt @@ -38,17 +38,23 @@ class MapsActivity : AppCompatActivity(), OnMapReadyCallback { mapFragment.getMapAsync(this) api = GoingElectricApi.create(getString(R.string.goingelectric_key)) - val behavior = BottomSheetBehaviorGoogleMapsLike.from(binding.bottomSheet); + val behavior = BottomSheetBehaviorGoogleMapsLike.from(binding.bottomSheet) binding.addOnPropertyChangedCallback(object : Observable.OnPropertyChangedCallback() { + var previousCharger = binding.charger + override fun onPropertyChanged(sender: Observable?, propertyId: Int) { - when (propertyId) { - BR.charger -> { - if (binding.charger != null) { + if (propertyId == BR.charger) { + if (binding.charger != null) { + if (previousCharger == null || + previousCharger!!.id != binding.charger!!.id + ) { behavior.state = BottomSheetBehaviorGoogleMapsLike.STATE_COLLAPSED - } else { - behavior.state = BottomSheetBehaviorGoogleMapsLike.STATE_HIDDEN + loadChargerDetails() } + } else { + behavior.state = BottomSheetBehaviorGoogleMapsLike.STATE_HIDDEN } + previousCharger = binding.charger } } @@ -94,6 +100,7 @@ class MapsActivity : AppCompatActivity(), OnMapReadyCallback { clusterDistance = 70 ).enqueue(object : Callback { override fun onFailure(call: Call, t: Throwable) { + //TODO: show error message t.printStackTrace() } @@ -102,6 +109,7 @@ class MapsActivity : AppCompatActivity(), OnMapReadyCallback { response: Response ) { if (!response.isSuccessful || response.body()!!.status != "ok") { + //TODO: show error message return } @@ -111,6 +119,28 @@ class MapsActivity : AppCompatActivity(), OnMapReadyCallback { }) } + private fun loadChargerDetails() { + val id = binding.charger?.id ?: return + api.getChargepointDetail(id).enqueue(object : Callback { + override fun onFailure(call: Call, t: Throwable) { + //TODO: show error message + t.printStackTrace() + } + + override fun onResponse( + call: Call, + response: Response + ) { + if (!response.isSuccessful || response.body()!!.status != "ok") { + //TODO: show error message + return + } + + binding.charger = response.body()!!.chargelocations[0] as ChargeLocation + } + }) + } + private fun updateMap() { markers.keys.forEach { it.remove() } clusterMarkers.forEach { it.remove() } diff --git a/app/src/main/java/com/johan/evmap/api/GoingElectricAdapters.kt b/app/src/main/java/com/johan/evmap/api/GoingElectricAdapters.kt index f8409b13..85fb48e4 100644 --- a/app/src/main/java/com/johan/evmap/api/GoingElectricAdapters.kt +++ b/app/src/main/java/com/johan/evmap/api/GoingElectricAdapters.kt @@ -55,4 +55,49 @@ internal class ChargepointListItemJsonAdapter(val moshi: Moshi) : override fun toJson(writer: JsonWriter, value: ChargepointListItem?) { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } -} \ No newline at end of file +} + +internal class JsonObjectOrFalseAdapter private constructor( + private val objectDelegate: JsonAdapter? +) : JsonAdapter() { + + class Factory() : JsonAdapter.Factory { + override fun create( + type: Type, + annotations: Set?, + moshi: Moshi + ): JsonAdapter<*>? { + val clazz = Types.getRawType(type) + return when (hasJsonObjectOrFalseAnnotation(annotations)) { + false -> null + true -> JsonObjectOrFalseAdapter(moshi.adapter(clazz)) + } + } + } + + override fun fromJson(reader: JsonReader) = when (reader.peek()) { + JsonReader.Token.BOOLEAN -> when (reader.nextBoolean()) { + false -> null // Response was false + else -> + throw IllegalStateException("Non-false boolean for @JsonObjectOrFalse field") + } + JsonReader.Token.BEGIN_OBJECT -> objectDelegate?.fromJson(reader) + JsonReader.Token.STRING -> objectDelegate?.fromJson(reader) + JsonReader.Token.NUMBER -> objectDelegate?.fromJson(reader) + else -> + throw IllegalStateException("Non-object-non-boolean value for @JsonObjectOrFalse field") + } + + override fun toJson(writer: JsonWriter, value: T?) = + objectDelegate?.toJson(writer, value) ?: Unit +} + +private fun hasJsonObjectOrFalseAnnotation(annotations: Set?) = + annotations?.firstOrNull { it.annotationClass == JsonObjectOrFalse::class } != null + +@JsonQualifier +@Retention(AnnotationRetention.RUNTIME) +@Target(AnnotationTarget.FIELD) +annotation class JsonObjectOrFalse { + +} diff --git a/app/src/main/java/com/johan/evmap/api/GoingElectricApi.kt b/app/src/main/java/com/johan/evmap/api/GoingElectricApi.kt index d6c9b83b..ec22c2f8 100644 --- a/app/src/main/java/com/johan/evmap/api/GoingElectricApi.kt +++ b/app/src/main/java/com/johan/evmap/api/GoingElectricApi.kt @@ -19,6 +19,9 @@ interface GoingElectricApi { @Query("cluster_distance") clusterDistance: Int ): Call + @GET("/chargepoints/") + fun getChargepointDetail(@Query("ge_id") id: Long): Call + companion object { fun create(apikey: String): GoingElectricApi { val client = OkHttpClient.Builder() @@ -34,6 +37,7 @@ interface GoingElectricApi { val moshi = Moshi.Builder() .add(ChargepointListItemJsonAdapterFactory()) + .add(JsonObjectOrFalseAdapter.Factory()) .build() val retrofit = Retrofit.Builder() diff --git a/app/src/main/java/com/johan/evmap/api/GoingElectricModel.kt b/app/src/main/java/com/johan/evmap/api/GoingElectricModel.kt index 1de99665..8380eaa6 100644 --- a/app/src/main/java/com/johan/evmap/api/GoingElectricModel.kt +++ b/app/src/main/java/com/johan/evmap/api/GoingElectricModel.kt @@ -18,10 +18,15 @@ data class ChargeLocation( val coordinates: Coordinate, val address: Address, val chargepoints: List, - //val network: String, + @JsonObjectOrFalse val network: String?, val url: String, - @Json(name = "fault_report") val faultReport: Boolean, - val verified: Boolean + // @Json(name = "fault_report") val faultReport: Boolean, <- Object or false in detail, true or false in overview + val verified: Boolean, + // only shown in details: + @JsonObjectOrFalse val operator: String?, + @Json(name = "general_information") @JsonObjectOrFalse val generalInformation: String?, + val photos: List? + //val chargecards: Boolean? ) : ChargepointListItem() { val maxPower: Double get() { @@ -40,6 +45,9 @@ data class ChargeLocation( } } +@JsonClass(generateAdapter = true) +data class ChargerPhoto(val id: String) + @JsonClass(generateAdapter = true) data class ChargeLocationCluster( val clusterCount: Int, diff --git a/app/src/main/java/com/johan/evmap/ui/BindingAdapters.kt b/app/src/main/java/com/johan/evmap/ui/BindingAdapters.kt index 42c3e72b..fc4e928c 100644 --- a/app/src/main/java/com/johan/evmap/ui/BindingAdapters.kt +++ b/app/src/main/java/com/johan/evmap/ui/BindingAdapters.kt @@ -6,4 +6,9 @@ import androidx.databinding.BindingAdapter @BindingAdapter("app:goneUnless") fun goneUnless(view: View, visible: Boolean) { view.visibility = if (visible) View.VISIBLE else View.GONE +} + +@BindingAdapter("app:invisibleUnless") +fun invisibleUnless(view: View, visible: Boolean) { + view.visibility = if (visible) View.VISIBLE else View.INVISIBLE } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_maps.xml b/app/src/main/res/layout/activity_maps.xml index 4f740502..bc444698 100644 --- a/app/src/main/res/layout/activity_maps.xml +++ b/app/src/main/res/layout/activity_maps.xml @@ -29,7 +29,8 @@ android:layout_height="@dimen/anchor_point" android:background="@color/colorAccent" app:layout_behavior="@string/BackDropBottomSheetBehavior" - android:fitsSystemWindows="true" /> + android:fitsSystemWindows="true" + app:invisibleUnless="@{charger.photos != null && charger.photos.size() > 0}" /> + +