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 d36f29a5..d2b51504 100644 --- a/app/src/main/java/net/vonforst/evmap/adapter/DataBindingAdapters.kt +++ b/app/src/main/java/net/vonforst/evmap/adapter/DataBindingAdapters.kt @@ -123,11 +123,7 @@ fun buildDetails(loc: ChargeLocation?, ctx: Context): List } -class FavoritesAdapter(val vm: FavoritesViewModel) : DataBindingAdapter() { +class FavoritesAdapter(val vm: FavoritesViewModel) : + DataBindingAdapter() { override fun getItemViewType(position: Int): Int = R.layout.item_favorite - - override fun bind(holder: ViewHolder, item: ChargeLocation) { - holder.binding.setVariable(BR.vm, vm) - super.bind(holder, item) - } } \ No newline at end of file diff --git a/app/src/main/java/net/vonforst/evmap/api/availability/AvailabilityDetector.kt b/app/src/main/java/net/vonforst/evmap/api/availability/AvailabilityDetector.kt index 484c93d7..5c214c2b 100644 --- a/app/src/main/java/net/vonforst/evmap/api/availability/AvailabilityDetector.kt +++ b/app/src/main/java/net/vonforst/evmap/api/availability/AvailabilityDetector.kt @@ -1,11 +1,15 @@ package net.vonforst.evmap.api.availability import com.facebook.stetho.okhttp3.StethoInterceptor +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext import net.vonforst.evmap.api.await import net.vonforst.evmap.api.goingelectric.ChargeLocation import net.vonforst.evmap.api.goingelectric.Chargepoint +import net.vonforst.evmap.viewmodel.Resource import okhttp3.OkHttpClient import okhttp3.Request +import retrofit2.HttpException import java.io.IOException import java.util.concurrent.TimeUnit @@ -104,4 +108,26 @@ val availabilityDetectors = listOf( okhttp, "6336fe713f2eb7fa04b97ff6651b76f8" ) // SW Kiel*/ -) \ No newline at end of file +) + +suspend fun getAvailability(charger: ChargeLocation): Resource { + var value: Resource? = null + withContext(Dispatchers.IO) { + for (ad in availabilityDetectors) { + try { + value = Resource.success(ad.getAvailability(charger)) + break + } catch (e: IOException) { + value = Resource.error(e.message, null) + e.printStackTrace() + } catch (e: HttpException) { + value = Resource.error(e.message, null) + e.printStackTrace() + } catch (e: AvailabilityDetectorException) { + value = Resource.error(e.message, null) + e.printStackTrace() + } + } + } + return value ?: Resource.error(null, null) +} \ No newline at end of file diff --git a/app/src/main/java/net/vonforst/evmap/viewmodel/FavoritesViewModel.kt b/app/src/main/java/net/vonforst/evmap/viewmodel/FavoritesViewModel.kt index 89a13c8e..5acf36b4 100644 --- a/app/src/main/java/net/vonforst/evmap/viewmodel/FavoritesViewModel.kt +++ b/app/src/main/java/net/vonforst/evmap/viewmodel/FavoritesViewModel.kt @@ -1,12 +1,16 @@ package net.vonforst.evmap.viewmodel import android.app.Application -import androidx.lifecycle.AndroidViewModel -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.viewModelScope +import androidx.lifecycle.* import com.google.android.gms.maps.model.LatLng +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll import kotlinx.coroutines.launch +import net.vonforst.evmap.adapter.Equatable +import net.vonforst.evmap.api.availability.ChargeLocationStatus +import net.vonforst.evmap.api.availability.ChargepointStatus +import net.vonforst.evmap.api.availability.getAvailability +import net.vonforst.evmap.api.distanceBetween import net.vonforst.evmap.api.goingelectric.ChargeLocation import net.vonforst.evmap.api.goingelectric.GoingElectricApi import net.vonforst.evmap.storage.AppDatabase @@ -24,21 +28,68 @@ class FavoritesViewModel(application: Application, geApiKey: String) : MutableLiveData() } - /*val availability: MediatorLiveData>> by lazy { + val availability: MediatorLiveData>> by lazy { MediatorLiveData>>().apply { addSource(favorites) { chargers -> if (chargers != null) { viewModelScope.launch { - chargers.map { - availability.value = Resource.loading(null) + val data = hashMapOf>() + chargers.forEach { charger -> + data[charger.id] = Resource.loading(null) } + availability.value = data + + chargers.map { charger -> + async { + data[charger.id] = getAvailability(charger) + availability.value = data + } + }.awaitAll() } } else { value = null } } } - }*/ + } + + val listData: MediatorLiveData> by lazy { + MediatorLiveData>().apply { + val callback = { _: Any -> + listData.value = favorites.value?.map { charger -> + FavoritesListItem( + charger, + totalAvailable(charger.id), + charger.chargepoints.sumBy { it.count }, + location.value.let { loc -> + if (loc == null) null else { + distanceBetween( + loc.latitude, + loc.longitude, + charger.coordinates.lat, + charger.coordinates.lng + ) / 1000 + } + }) + } + } + addSource(favorites, callback) + addSource(location, callback) + addSource(availability, callback) + } + } + + data class FavoritesListItem( + val charger: ChargeLocation, + val available: Int?, + val total: Int, + val distance: Double? + ) : Equatable + + private fun totalAvailable(id: Long): Int? { + val values = availability.value?.get(id)?.data?.status?.values ?: return null + return values.sumBy { it.filter { it == ChargepointStatus.AVAILABLE }.size } + } fun insertFavorite(charger: ChargeLocation) { viewModelScope.launch { 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 b8f5dd1e..c73f6926 100644 --- a/app/src/main/java/net/vonforst/evmap/viewmodel/MapViewModel.kt +++ b/app/src/main/java/net/vonforst/evmap/viewmodel/MapViewModel.kt @@ -3,12 +3,9 @@ package net.vonforst.evmap.viewmodel import android.app.Application import androidx.lifecycle.* import com.google.android.gms.maps.model.LatLngBounds -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import net.vonforst.evmap.api.availability.AvailabilityDetectorException import net.vonforst.evmap.api.availability.ChargeLocationStatus -import net.vonforst.evmap.api.availability.availabilityDetectors +import net.vonforst.evmap.api.availability.getAvailability import net.vonforst.evmap.api.goingelectric.ChargeLocation import net.vonforst.evmap.api.goingelectric.ChargepointList import net.vonforst.evmap.api.goingelectric.ChargepointListItem @@ -16,9 +13,7 @@ import net.vonforst.evmap.api.goingelectric.GoingElectricApi import net.vonforst.evmap.storage.AppDatabase import retrofit2.Call import retrofit2.Callback -import retrofit2.HttpException import retrofit2.Response -import java.io.IOException data class MapPosition(val bounds: LatLngBounds, val zoom: Float) @@ -133,25 +128,7 @@ class MapViewModel(application: Application, geApiKey: String) : AndroidViewMode private suspend fun loadAvailability(charger: ChargeLocation) { availability.value = Resource.loading(null) - var value: Resource? = null - withContext(Dispatchers.IO) { - for (ad in availabilityDetectors) { - try { - value = Resource.success(ad.getAvailability(charger)) - break - } catch (e: IOException) { - value = Resource.error(e.message, null) - e.printStackTrace() - } catch (e: HttpException) { - value = Resource.error(e.message, null) - e.printStackTrace() - } catch (e: AvailabilityDetectorException) { - value = Resource.error(e.message, null) - e.printStackTrace() - } - } - } - availability.value = value + availability.value = getAvailability(charger) } private fun loadChargerDetails(charger: ChargeLocation) { diff --git a/app/src/main/res/layout/fragment_favorites.xml b/app/src/main/res/layout/fragment_favorites.xml index cf6a0bf3..809576b4 100644 --- a/app/src/main/res/layout/fragment_favorites.xml +++ b/app/src/main/res/layout/fragment_favorites.xml @@ -33,6 +33,6 @@ android:id="@+id/favs_list" android:layout_width="match_parent" android:layout_height="match_parent" - app:data="@{vm.favorites}" /> + app:data="@{vm.listData}" /> \ No newline at end of file diff --git a/app/src/main/res/layout/item_favorite.xml b/app/src/main/res/layout/item_favorite.xml index 7660b473..2f2c8cf7 100644 --- a/app/src/main/res/layout/item_favorite.xml +++ b/app/src/main/res/layout/item_favorite.xml @@ -6,14 +6,11 @@ + - - + type="net.vonforst.evmap.viewmodel.FavoritesViewModel.FavoritesListItem" /> + app:layout_constraintTop_toTopOf="parent" + tools:text="9999,9 km" /> + + \ No newline at end of file