From b5a6ceb5f94dbabbe75d0409e34a2f41fa2422db Mon Sep 17 00:00:00 2001 From: johan12345 Date: Sun, 5 Nov 2023 20:53:33 +0100 Subject: [PATCH] rework favorites deletion undo logic to fix #304 --- .../net/vonforst/evmap/auto/FilterScreen.kt | 4 +- .../evmap/fragment/FavoritesFragment.kt | 64 ++++++++----------- .../evmap/fragment/FilterProfilesFragment.kt | 2 +- .../evmap/viewmodel/FavoritesViewModel.kt | 32 ++++++++-- app/src/main/res/values-de/strings.xml | 2 +- app/src/main/res/values-fr/strings.xml | 2 +- app/src/main/res/values-nb-rNO/strings.xml | 2 +- app/src/main/res/values-nl/strings.xml | 2 +- app/src/main/res/values-pt/strings.xml | 2 +- app/src/main/res/values-ro/strings.xml | 2 +- app/src/main/res/values/strings.xml | 2 +- 11 files changed, 65 insertions(+), 51 deletions(-) diff --git a/app/src/main/java/net/vonforst/evmap/auto/FilterScreen.kt b/app/src/main/java/net/vonforst/evmap/auto/FilterScreen.kt index 91d0b05b..cd25d390 100644 --- a/app/src/main/java/net/vonforst/evmap/auto/FilterScreen.kt +++ b/app/src/main/java/net/vonforst/evmap/auto/FilterScreen.kt @@ -227,7 +227,7 @@ class FilterScreen(ctx: CarContext, val session: EVMapSession) : Screen(ctx) { CarToast.makeText( carContext, carContext.getString( - R.string.deleted_filterprofile, + R.string.deleted_item, it.name ), CarToast.LENGTH_SHORT @@ -344,7 +344,7 @@ class EditFiltersScreen(ctx: CarContext) : Screen(ctx) { CarToast.makeText( carContext, carContext.getString( - R.string.deleted_filterprofile, + R.string.deleted_item, currentProfile.name ), CarToast.LENGTH_SHORT 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 5a839237..ae2cb331 100644 --- a/app/src/main/java/net/vonforst/evmap/fragment/FavoritesFragment.kt +++ b/app/src/main/java/net/vonforst/evmap/fragment/FavoritesFragment.kt @@ -28,7 +28,6 @@ import net.vonforst.evmap.databinding.FragmentFavoritesBinding import net.vonforst.evmap.databinding.ItemFavoriteBinding import net.vonforst.evmap.location.FusionEngine import net.vonforst.evmap.location.LocationEngine -import net.vonforst.evmap.model.Favorite import net.vonforst.evmap.model.FavoriteWithDetail import net.vonforst.evmap.utils.checkAnyLocationPermission import net.vonforst.evmap.viewmodel.FavoritesViewModel @@ -37,7 +36,6 @@ import net.vonforst.evmap.viewmodel.viewModelFactory class FavoritesFragment : Fragment() { private lateinit var binding: FragmentFavoritesBinding private lateinit var locationEngine: LocationEngine - private var toDelete: Favorite? = null private var deleteSnackbar: Snackbar? = null private lateinit var adapter: FavoritesAdapter @@ -113,6 +111,32 @@ class FavoritesFragment : Fragment() { binding.swipeRefresh.isRefreshing = false } } + + vm.deletedFavorite.observe(viewLifecycleOwner) { fav -> + if (fav == null) { + deleteSnackbar?.dismiss() + return@observe + } + val snackbar = Snackbar.make( + requireView(), + getString( + R.string.deleted_item, + fav.charger.name + ), + Snackbar.LENGTH_LONG + ).setAction(R.string.undo) { + vm.undoDeletion() + }.addCallback(object : Snackbar.Callback() { + override fun onDismissed(transientBottomBar: Snackbar?, event: Int) { + // if undo was not clicked, actually delete + if (event == DISMISS_EVENT_TIMEOUT || event == DISMISS_EVENT_SWIPE) { + vm.deletedFavorite.value = null + } + } + }) + deleteSnackbar = snackbar + snackbar.show() + } } override fun onStart() { @@ -127,41 +151,7 @@ class FavoritesFragment : Fragment() { } fun delete(fav: FavoriteWithDetail) { - val position = - vm.listData.value?.indexOfFirst { it.fav.favorite.favoriteId == fav.favorite.favoriteId } - ?: return - // if there is already a profile to delete, delete it now - actuallyDelete() - deleteSnackbar?.dismiss() - - toDelete = fav.favorite - - view?.let { - val snackbar = Snackbar.make( - it, - getString(R.string.deleted_filterprofile, fav.charger.name), - Snackbar.LENGTH_LONG - ).setAction(R.string.undo) { - toDelete = null - adapter.notifyItemChanged(position) - }.addCallback(object : Snackbar.Callback() { - override fun onDismissed(transientBottomBar: Snackbar?, event: Int) { - // if undo was not clicked, actually delete - if (event == DISMISS_EVENT_TIMEOUT || event == DISMISS_EVENT_SWIPE) { - actuallyDelete() - } - } - }) - deleteSnackbar = snackbar - snackbar.show() - } ?: run { - actuallyDelete() - } - } - - private fun actuallyDelete() { - toDelete?.let { vm.deleteFavorite(it) } - toDelete = null + vm.deleteFavoriteWithUndo(fav) } private fun createTouchHelper(): ItemTouchHelper { diff --git a/app/src/main/java/net/vonforst/evmap/fragment/FilterProfilesFragment.kt b/app/src/main/java/net/vonforst/evmap/fragment/FilterProfilesFragment.kt index 684637c2..6e1faf73 100644 --- a/app/src/main/java/net/vonforst/evmap/fragment/FilterProfilesFragment.kt +++ b/app/src/main/java/net/vonforst/evmap/fragment/FilterProfilesFragment.kt @@ -230,7 +230,7 @@ class FilterProfilesFragment : Fragment() { view?.let { val snackbar = Snackbar.make( it, - getString(R.string.deleted_filterprofile, fp.name), + getString(R.string.deleted_item, fp.name), Snackbar.LENGTH_LONG ).setAction(R.string.undo) { toDelete = 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 09f00f08..7c6153e3 100644 --- a/app/src/main/java/net/vonforst/evmap/viewmodel/FavoritesViewModel.kt +++ b/app/src/main/java/net/vonforst/evmap/viewmodel/FavoritesViewModel.kt @@ -33,7 +33,7 @@ class FavoritesViewModel(application: Application) : MediatorLiveData>>().apply { addSource(favorites) { favorites -> if (favorites != null) { - reloadAvailability() + reloadAvailability(forceReload = false) } else { value = null } @@ -41,9 +41,10 @@ class FavoritesViewModel(application: Application) : } } - fun reloadAvailability(callback: (() -> Unit)? = null) { + fun reloadAvailability(forceReload: Boolean = true, callback: (() -> Unit)? = null) { val favorites = favorites.value ?: return val chargers = favorites.map { it.charger } + val previous = availability.value viewModelScope.launch { val data = hashMapOf>() @@ -54,8 +55,13 @@ class FavoritesViewModel(application: Application) : chargers.map { charger -> async { - data[charger.id] = availabilityRepo.getAvailability(charger) - availability.value = data + if (!forceReload && previous?.get(charger.id)?.status == Status.SUCCESS) { + data[charger.id] = previous[charger.id]!! + availability.value = data + } else { + data[charger.id] = availabilityRepo.getAvailability(charger) + availability.value = data + } } }.awaitAll() callback?.invoke() @@ -117,6 +123,24 @@ class FavoritesViewModel(application: Application) : } } + val deletedFavorite: MutableLiveData by lazy { + MutableLiveData() + } + + fun deleteFavoriteWithUndo(fav: FavoriteWithDetail) { + deletedFavorite.value = fav + deleteFavorite(fav.favorite) + } + + fun undoDeletion() { + deletedFavorite.value?.let { + viewModelScope.launch { + insertFavorite(it.charger) + } + deletedFavorite.value = null + } + } + fun deleteFavorite(fav: Favorite) { viewModelScope.launch { db.favoritesDao().delete(fav) diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 2227cb66..4b5d9387 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -161,7 +161,7 @@ EVMap ist kostenlos und Open Source. Über GitHub kann jeder zur Weiterentwicklung der App beitragen. Um die laufenden Kosten für die Datenquellen zu decken, freut sich der Entwickler über Spenden mit einem Betrag deiner Wahl. Du bist ein richtiger Sparfuchs! Anscheinend nutzt du den Preisvergleich sehr gern. Mit einer Spende für EVMap kannst du helfen, die Kosten für den Datenzugriff zu decken. - „%s” gelöscht + „%s” gelöscht Rückgängig Umbenennen Ohne Vertrag / Registrierung nutzbar diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index f9feb6ed..c09e3fbd 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -75,7 +75,7 @@ Cela peut également être vu dans \"À propos\" → \"Foire aux questions\" Merci d\'utiliser EVMap Vous êtes un vrai chasseur de bonnes affaires ! - \"%s\" supprimé + \"%s\" supprimé Annuler Renommer vérifié diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index f93cdbf7..41b062fb 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -144,7 +144,7 @@ Skriv inn navnet på filterprofilen: Du har ikke noen lagrede filterprofiler Du er en sann gjerrigknark. - Slettet «%s» + Slettet «%s» Kan brukes uten registrering Finn kjøretøyladere der du er Hver laders farge samsvarer med dens høyeste ladeeffekt diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 05cf96cf..3888acec 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -145,7 +145,7 @@ Bedankt om EVMap te gebruiken Jij bent een echte koopjeszoeker! Blijkbaar maak je dankbaar gebruik van de prijsvergelijkingen. Met een donatie kan je de kosten voor deze data helpen dragen. - “%s” verwijderd + “%s” verwijderd Ongedaan maken Hernoem diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index ea363185..a953ee11 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -8,7 +8,7 @@ Também pode encontrar esta informação em \"Sobre\" → \"Perguntas frequentes\" Você é um verdadeiro caçador de pechinchas! Obrigado por usar o EVMap - “%s” removido + “%s” removido Refazer Renomear Você faz grande uso da comparação de preços. Ajude a cobrir os custos de acesso à informação apoiando o EVMap com uma doação. diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 5d7db708..0b7e82f3 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -160,7 +160,7 @@ EVMap este libera si gratuita. Contributiile pe GitHub sunt apreciate. Pentru a acoperi costurile pentru acces la date, va rugam sa donati orice suma pentru dezvoltator. Stii sa cauti ofertele cele mai bune! Stii sa folosesti optiunea de comparare preturi. Puteti ajuta pentru a acoperi costurile pentru accesul la aceste date donand pentru EVMap. - “%s” a fost sters + “%s” a fost sters Anuleaza Redenumeste Utilizabile fara inregistrare diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 628e0c56..01a58596 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -161,7 +161,7 @@ EVMap is open source and free of charge. Code contributions on GitHub are much appreciated. To help cover the running costs for data access, please consider donating an amount of your choice to the developer. You\'re a real bargain hunter! You make great use of the price comparison feature. Please help cover the costs for this data by supporting EVMap with a donation. - Deleted “%s” + Deleted “%s” Undo Rename Usable without registration