From 0ca8fb0eeeac0b752f528952afdee38687872f22 Mon Sep 17 00:00:00 2001 From: johan12345 Date: Sun, 12 Jun 2022 17:22:50 +0200 Subject: [PATCH] Add ability to refresh availability data fixes #175 --- app/build.gradle | 1 + .../evmap/fragment/FavoritesFragment.kt | 6 +++ .../vonforst/evmap/fragment/MapFragment.kt | 21 ++--------- .../evmap/viewmodel/FavoritesViewModel.kt | 37 +++++++++++-------- .../vonforst/evmap/viewmodel/MapViewModel.kt | 7 ++++ app/src/main/res/drawable/ic_refresh.xml | 10 +++++ app/src/main/res/layout/detail_view.xml | 17 ++++++++- .../main/res/layout/fragment_favorites.xml | 15 +++++--- app/src/main/res/layout/item_favorite.xml | 2 +- app/src/main/res/values-de/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/values/styles.xml | 11 ++++++ 12 files changed, 88 insertions(+), 41 deletions(-) create mode 100644 app/src/main/res/drawable/ic_refresh.xml diff --git a/app/build.gradle b/app/build.gradle index fa294e7a..825b6e63 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -148,6 +148,7 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.1.3' implementation 'androidx.recyclerview:recyclerview:1.2.1' implementation 'androidx.browser:browser:1.4.0' + implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation 'com.github.johan12345:CustomBottomSheetBehavior:f69f532660' implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-moshi:2.9.0' diff --git a/app/src/main/java/net/vonforst/evmap/fragment/FavoritesFragment.kt b/app/src/main/java/net/vonforst/evmap/fragment/FavoritesFragment.kt index 0d2ad67b..959095f2 100644 --- a/app/src/main/java/net/vonforst/evmap/fragment/FavoritesFragment.kt +++ b/app/src/main/java/net/vonforst/evmap/fragment/FavoritesFragment.kt @@ -110,6 +110,12 @@ class FavoritesFragment : Fragment(), LostApiClient.ConnectionCallbacks { createTouchHelper().attachToRecyclerView(binding.favsList) locationClient!!.connect() + + binding.swipeRefresh.setOnRefreshListener { + vm.reloadAvailability() { + binding.swipeRefresh.isRefreshing = false + } + } } override fun onConnected() { diff --git a/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt b/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt index 685719e6..25da6515 100644 --- a/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt +++ b/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt @@ -95,28 +95,10 @@ import net.vonforst.evmap.utils.checkFineLocationPermission import net.vonforst.evmap.utils.distanceBetween import net.vonforst.evmap.viewmodel.* import java.io.IOException -import kotlin.collections.List -import kotlin.collections.Set -import kotlin.collections.any import kotlin.collections.component1 import kotlin.collections.component2 import kotlin.collections.contains -import kotlin.collections.emptyList -import kotlin.collections.filterIsInstance -import kotlin.collections.find -import kotlin.collections.forEach -import kotlin.collections.getOrNull -import kotlin.collections.isNotEmpty -import kotlin.collections.iterator -import kotlin.collections.listOf -import kotlin.collections.map -import kotlin.collections.mapNotNull import kotlin.collections.set -import kotlin.collections.sortedBy -import kotlin.collections.sortedByDescending -import kotlin.collections.toList -import kotlin.collections.toSet -import kotlin.collections.toTypedArray class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallback, @@ -423,6 +405,9 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac else -> false } } + binding.detailView.btnRefreshLiveData.setOnClickListener { + vm.reloadAvailability() + } } var searchKeyListener: KeyListener? = null 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 471d2f14..87c8abbb 100644 --- a/app/src/main/java/net/vonforst/evmap/viewmodel/FavoritesViewModel.kt +++ b/app/src/main/java/net/vonforst/evmap/viewmodel/FavoritesViewModel.kt @@ -32,21 +32,7 @@ class FavoritesViewModel(application: Application, geApiKey: String) : MediatorLiveData>>().apply { addSource(favorites) { favorites -> if (favorites != null) { - val chargers = favorites.map { it.charger } - viewModelScope.launch { - 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() - } + reloadAvailability() } else { value = null } @@ -54,6 +40,27 @@ class FavoritesViewModel(application: Application, geApiKey: String) : } } + fun reloadAvailability(callback: (() -> Unit)? = null) { + val favorites = favorites.value ?: return + val chargers = favorites.map { it.charger } + + viewModelScope.launch { + 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() + callback?.invoke() + } + } + val listData: MediatorLiveData> by lazy { MediatorLiveData>().apply { val callback = { _: Any -> 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 af545a48..0eae57ee 100644 --- a/app/src/main/java/net/vonforst/evmap/viewmodel/MapViewModel.kt +++ b/app/src/main/java/net/vonforst/evmap/viewmodel/MapViewModel.kt @@ -381,6 +381,13 @@ class MapViewModel(application: Application, private val state: SavedStateHandle availability.value = getAvailability(charger) } + fun reloadAvailability() { + val charger = chargerSparse.value ?: return + viewModelScope.launch { + loadAvailability(charger) + } + } + private var chargerLoadingTask: Job? = null private fun loadChargerDetails(charger: ChargeLocation, referenceData: ReferenceData) { diff --git a/app/src/main/res/drawable/ic_refresh.xml b/app/src/main/res/drawable/ic_refresh.xml new file mode 100644 index 00000000..566500b8 --- /dev/null +++ b/app/src/main/res/drawable/ic_refresh.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 1275941a..1e95a6ad 100644 --- a/app/src/main/res/layout/detail_view.xml +++ b/app/src/main/res/layout/detail_view.xml @@ -137,7 +137,7 @@ android:textColor="@android:color/white" app:backgroundTintAvailability="@{BindingAdaptersKt.flatten(filteredAvailability.data.status.values())}" app:invisibleUnlessAnimated="@{filteredAvailability.data != null && !expanded}" - app:invisibleUnless="@{filteredAvailability.data != null}" + app:invisibleUnless="@{filteredAvailability.data != null && !expanded}" app:layout_constraintEnd_toStartOf="@+id/guideline2" app:layout_constraintTop_toTopOf="@+id/txtName" tools:backgroundTint="@color/available" @@ -293,10 +293,11 @@ android:id="@+id/textView13" android:layout_width="0dp" android:layout_height="wrap_content" + android:layout_marginEnd="8dp" android:gravity="right|end" android:text="@{availability.status == Status.SUCCESS ? @string/realtime_data_source(availability.data.source) : availability.status == Status.LOADING ? @string/realtime_data_loading : @string/realtime_data_unavailable}" android:textAppearance="@style/TextAppearance.Material3.BodySmall" - app:layout_constraintEnd_toStartOf="@+id/guideline2" + app:layout_constraintEnd_toStartOf="@+id/btnRefreshLiveData" app:layout_constraintStart_toStartOf="@+id/guideline" app:layout_constraintTop_toBottomOf="@+id/connectors" tools:text="Echtzeitdaten nicht verfügbar" /> @@ -376,6 +377,18 @@ app:layout_constraintBottom_toBottomOf="parent" tools:text="The data is provided under the National Oman Open Data LicensE (NOODLE), Version 3.14, and may be used for any purpose whatsoever." /> +