From 90848fde957f55475499f7fc3fb8e07a42543afc Mon Sep 17 00:00:00 2001 From: Philipp Heckel Date: Sat, 5 Feb 2022 21:02:05 -0500 Subject: [PATCH] Swipe to delete --- .../main/java/io/heckel/ntfy/db/Database.kt | 3 +++ .../main/java/io/heckel/ntfy/db/Repository.kt | 8 +++--- .../java/io/heckel/ntfy/ui/DetailActivity.kt | 25 +++++++++++++++++++ .../java/io/heckel/ntfy/ui/DetailAdapter.kt | 4 +++ app/src/main/res/values/strings.xml | 2 ++ 5 files changed, 39 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/io/heckel/ntfy/db/Database.kt b/app/src/main/java/io/heckel/ntfy/db/Database.kt index 232cd72..0212779 100644 --- a/app/src/main/java/io/heckel/ntfy/db/Database.kt +++ b/app/src/main/java/io/heckel/ntfy/db/Database.kt @@ -297,6 +297,9 @@ interface NotificationDao { @Query("UPDATE notification SET deleted = 1 WHERE subscriptionId = :subscriptionId") fun markAllAsDeleted(subscriptionId: Long) + @Query("UPDATE notification SET deleted = 0 WHERE id = :notificationId") + fun undelete(notificationId: String) + @Query("DELETE FROM notification WHERE subscriptionId = :subscriptionId") fun removeAll(subscriptionId: Long) } diff --git a/app/src/main/java/io/heckel/ntfy/db/Repository.kt b/app/src/main/java/io/heckel/ntfy/db/Repository.kt index cb1b549..50ed8dd 100644 --- a/app/src/main/java/io/heckel/ntfy/db/Repository.kt +++ b/app/src/main/java/io/heckel/ntfy/db/Repository.kt @@ -116,12 +116,14 @@ class Repository(private val sharedPrefs: SharedPreferences, private val databas notificationDao.update(notification) } - @Suppress("RedundantSuspendModifier") - @WorkerThread - suspend fun markAsDeleted(notificationId: String) { + fun markAsDeleted(notificationId: String) { notificationDao.markAsDeleted(notificationId) } + fun undeleteNotification(notificationId: String) { + notificationDao.undelete(notificationId) + } + fun markAllAsDeleted(subscriptionId: Long) { notificationDao.markAllAsDeleted(subscriptionId) } diff --git a/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt b/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt index 912b2a8..756473b 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/DetailActivity.kt @@ -17,8 +17,10 @@ import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.core.content.ContextCompat import androidx.lifecycle.lifecycleScope +import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView import androidx.swiperefreshlayout.widget.SwipeRefreshLayout +import com.google.android.material.snackbar.Snackbar import io.heckel.ntfy.BuildConfig import io.heckel.ntfy.R import io.heckel.ntfy.app.Application @@ -34,6 +36,7 @@ import kotlinx.coroutines.* import java.util.* import kotlin.random.Random + class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFragment.NotificationSettingsListener { private val viewModel by viewModels { DetailViewModelFactory((application as Application).repository) @@ -131,6 +134,28 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra } } + // Swipe to remove + val itemTouchCallback = object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) { + override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean { + return false + } + override fun onSwiped(viewHolder: RecyclerView.ViewHolder, swipeDir: Int) { + val notification = adapter.get(viewHolder.absoluteAdapterPosition) + lifecycleScope.launch(Dispatchers.IO) { + repository.markAsDeleted(notification.id) + } + val snackbar = Snackbar.make(mainList, R.string.detail_item_snack_deleted, Snackbar.LENGTH_SHORT) + snackbar.setAction(R.string.detail_item_snack_undo) { + lifecycleScope.launch(Dispatchers.IO) { + repository.undeleteNotification(notification.id) + } + } + snackbar.show() + } + } + val itemTouchHelper = ItemTouchHelper(itemTouchCallback) + itemTouchHelper.attachToRecyclerView(mainList) + // Scroll up when new notification is added adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() { override fun onItemRangeInserted(positionStart: Int, itemCount: Int) { diff --git a/app/src/main/java/io/heckel/ntfy/ui/DetailAdapter.kt b/app/src/main/java/io/heckel/ntfy/ui/DetailAdapter.kt index 16bb94f..1df33ff 100644 --- a/app/src/main/java/io/heckel/ntfy/ui/DetailAdapter.kt +++ b/app/src/main/java/io/heckel/ntfy/ui/DetailAdapter.kt @@ -44,6 +44,10 @@ class DetailAdapter(private val activity: Activity, private val repository: Repo holder.bind(getItem(position)) } + fun get(position: Int): Notification { + return getItem(position) + } + fun toggleSelection(notificationId: String) { if (selected.contains(notificationId)) { selected.remove(notificationId) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c504937..84c8605 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -135,6 +135,8 @@ Instant delivery disabled Instant delivery is enabled Tags: %1$s + Notification deleted + Undo Open file Browse file Delete file