Swipe to delete
This commit is contained in:
parent
3b1b1a82ae
commit
90848fde95
5 changed files with 39 additions and 3 deletions
|
@ -297,6 +297,9 @@ interface NotificationDao {
|
||||||
@Query("UPDATE notification SET deleted = 1 WHERE subscriptionId = :subscriptionId")
|
@Query("UPDATE notification SET deleted = 1 WHERE subscriptionId = :subscriptionId")
|
||||||
fun markAllAsDeleted(subscriptionId: Long)
|
fun markAllAsDeleted(subscriptionId: Long)
|
||||||
|
|
||||||
|
@Query("UPDATE notification SET deleted = 0 WHERE id = :notificationId")
|
||||||
|
fun undelete(notificationId: String)
|
||||||
|
|
||||||
@Query("DELETE FROM notification WHERE subscriptionId = :subscriptionId")
|
@Query("DELETE FROM notification WHERE subscriptionId = :subscriptionId")
|
||||||
fun removeAll(subscriptionId: Long)
|
fun removeAll(subscriptionId: Long)
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,12 +116,14 @@ class Repository(private val sharedPrefs: SharedPreferences, private val databas
|
||||||
notificationDao.update(notification)
|
notificationDao.update(notification)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("RedundantSuspendModifier")
|
fun markAsDeleted(notificationId: String) {
|
||||||
@WorkerThread
|
|
||||||
suspend fun markAsDeleted(notificationId: String) {
|
|
||||||
notificationDao.markAsDeleted(notificationId)
|
notificationDao.markAsDeleted(notificationId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun undeleteNotification(notificationId: String) {
|
||||||
|
notificationDao.undelete(notificationId)
|
||||||
|
}
|
||||||
|
|
||||||
fun markAllAsDeleted(subscriptionId: Long) {
|
fun markAllAsDeleted(subscriptionId: Long) {
|
||||||
notificationDao.markAllAsDeleted(subscriptionId)
|
notificationDao.markAllAsDeleted(subscriptionId)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,10 @@ import androidx.activity.viewModels
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.recyclerview.widget.ItemTouchHelper
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import io.heckel.ntfy.BuildConfig
|
import io.heckel.ntfy.BuildConfig
|
||||||
import io.heckel.ntfy.R
|
import io.heckel.ntfy.R
|
||||||
import io.heckel.ntfy.app.Application
|
import io.heckel.ntfy.app.Application
|
||||||
|
@ -34,6 +36,7 @@ import kotlinx.coroutines.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
|
||||||
class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFragment.NotificationSettingsListener {
|
class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFragment.NotificationSettingsListener {
|
||||||
private val viewModel by viewModels<DetailViewModel> {
|
private val viewModel by viewModels<DetailViewModel> {
|
||||||
DetailViewModelFactory((application as Application).repository)
|
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
|
// Scroll up when new notification is added
|
||||||
adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
||||||
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
|
override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
|
||||||
|
|
|
@ -44,6 +44,10 @@ class DetailAdapter(private val activity: Activity, private val repository: Repo
|
||||||
holder.bind(getItem(position))
|
holder.bind(getItem(position))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun get(position: Int): Notification {
|
||||||
|
return getItem(position)
|
||||||
|
}
|
||||||
|
|
||||||
fun toggleSelection(notificationId: String) {
|
fun toggleSelection(notificationId: String) {
|
||||||
if (selected.contains(notificationId)) {
|
if (selected.contains(notificationId)) {
|
||||||
selected.remove(notificationId)
|
selected.remove(notificationId)
|
||||||
|
|
|
@ -135,6 +135,8 @@
|
||||||
<string name="detail_instant_delivery_disabled">Instant delivery disabled</string>
|
<string name="detail_instant_delivery_disabled">Instant delivery disabled</string>
|
||||||
<string name="detail_instant_info">Instant delivery is enabled</string>
|
<string name="detail_instant_info">Instant delivery is enabled</string>
|
||||||
<string name="detail_item_tags">Tags: %1$s</string>
|
<string name="detail_item_tags">Tags: %1$s</string>
|
||||||
|
<string name="detail_item_snack_deleted">Notification deleted</string>
|
||||||
|
<string name="detail_item_snack_undo">Undo</string>
|
||||||
<string name="detail_item_menu_open">Open file</string>
|
<string name="detail_item_menu_open">Open file</string>
|
||||||
<string name="detail_item_menu_browse">Browse file</string>
|
<string name="detail_item_menu_browse">Browse file</string>
|
||||||
<string name="detail_item_menu_delete">Delete file</string>
|
<string name="detail_item_menu_delete">Delete file</string>
|
||||||
|
|
Loading…
Reference in a new issue