Add "clear all notifications" detail menu item

This commit is contained in:
Philipp Heckel 2021-11-25 09:26:37 -05:00
parent e8b1ba63e8
commit 91a29c4d8e
8 changed files with 73 additions and 26 deletions

View file

@ -174,11 +174,11 @@ interface NotificationDao {
@Query("UPDATE notification SET notificationId = 0 WHERE subscriptionId = :subscriptionId") @Query("UPDATE notification SET notificationId = 0 WHERE subscriptionId = :subscriptionId")
fun clearAllNotificationIds(subscriptionId: Long) fun clearAllNotificationIds(subscriptionId: Long)
@Update
fun update(notification: Notification)
@Query("UPDATE notification SET deleted = 1 WHERE id = :notificationId") @Query("UPDATE notification SET deleted = 1 WHERE id = :notificationId")
fun remove(notificationId: String) fun markAsDeleted(notificationId: String)
@Query("UPDATE notification SET deleted = 1 WHERE subscriptionId = :subscriptionId")
fun markAllAsDeleted(subscriptionId: Long)
@Query("DELETE FROM notification WHERE subscriptionId = :subscriptionId") @Query("DELETE FROM notification WHERE subscriptionId = :subscriptionId")
fun removeAll(subscriptionId: Long) fun removeAll(subscriptionId: Long)

View file

@ -100,14 +100,14 @@ class Repository(private val sharedPrefs: SharedPreferences, private val subscri
return !detailViewOpen && !muted return !detailViewOpen && !muted
} }
fun updateNotification(notification: Notification) {
notificationDao.update(notification)
}
@Suppress("RedundantSuspendModifier") @Suppress("RedundantSuspendModifier")
@WorkerThread @WorkerThread
suspend fun removeNotification(notificationId: String) { suspend fun markAsDeleted(notificationId: String) {
notificationDao.remove(notificationId) notificationDao.markAsDeleted(notificationId)
}
fun markAllAsDeleted(subscriptionId: Long) {
notificationDao.markAllAsDeleted(subscriptionId)
} }
@Suppress("RedundantSuspendModifier") @Suppress("RedundantSuspendModifier")

View file

@ -29,7 +29,6 @@ import io.heckel.ntfy.data.topicUrl
import io.heckel.ntfy.msg.ApiService import io.heckel.ntfy.msg.ApiService
import io.heckel.ntfy.msg.NotificationService import io.heckel.ntfy.msg.NotificationService
import kotlinx.coroutines.* import kotlinx.coroutines.*
import java.text.DateFormat
import java.util.* import java.util.*
class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFragment.NotificationSettingsListener { class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFragment.NotificationSettingsListener {
@ -241,6 +240,10 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra
onCopyUrlClick() onCopyUrlClick()
true true
} }
R.id.detail_menu_clear -> {
onClearClick()
true
}
R.id.detail_menu_unsubscribe -> { R.id.detail_menu_unsubscribe -> {
onDeleteClick() onDeleteClick()
true true
@ -403,11 +406,32 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra
} }
} }
private fun onClearClick() {
Log.d(TAG, "Clearing all notifications for ${topicShortUrl(subscriptionBaseUrl, subscriptionTopic)}")
val builder = AlertDialog.Builder(this)
val dialog = builder
.setMessage(R.string.detail_clear_dialog_message)
.setPositiveButton(R.string.detail_clear_dialog_permanently_delete) { _, _ ->
lifecycleScope.launch(Dispatchers.IO) {
repository.markAllAsDeleted(subscriptionId)
}
}
.setNegativeButton(R.string.detail_clear_dialog_cancel) { _, _ -> /* Do nothing */ }
.create()
dialog.setOnShowListener {
dialog
.getButton(AlertDialog.BUTTON_POSITIVE)
.setTextColor(ContextCompat.getColor(this, R.color.primaryDangerButtonColor))
}
dialog.show()
}
private fun onDeleteClick() { private fun onDeleteClick() {
Log.d(TAG, "Deleting subscription ${topicShortUrl(subscriptionBaseUrl, subscriptionTopic)}") Log.d(TAG, "Deleting subscription ${topicShortUrl(subscriptionBaseUrl, subscriptionTopic)}")
val builder = AlertDialog.Builder(this) val builder = AlertDialog.Builder(this)
builder val dialog = builder
.setMessage(R.string.detail_delete_dialog_message) .setMessage(R.string.detail_delete_dialog_message)
.setPositiveButton(R.string.detail_delete_dialog_permanently_delete) { _, _ -> .setPositiveButton(R.string.detail_delete_dialog_permanently_delete) { _, _ ->
// Return to main activity // Return to main activity
@ -424,7 +448,12 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra
} }
.setNegativeButton(R.string.detail_delete_dialog_cancel) { _, _ -> /* Do nothing */ } .setNegativeButton(R.string.detail_delete_dialog_cancel) { _, _ -> /* Do nothing */ }
.create() .create()
.show() dialog.setOnShowListener {
dialog
.getButton(AlertDialog.BUTTON_POSITIVE)
.setTextColor(ContextCompat.getColor(this, R.color.primaryDangerButtonColor))
}
dialog.show()
} }
private fun onNotificationClick(notification: Notification) { private fun onNotificationClick(notification: Notification) {
@ -516,17 +545,22 @@ class DetailActivity : AppCompatActivity(), ActionMode.Callback, NotificationFra
Log.d(TAG, "Showing multi-delete dialog for selected items") Log.d(TAG, "Showing multi-delete dialog for selected items")
val builder = AlertDialog.Builder(this) val builder = AlertDialog.Builder(this)
builder val dialog = builder
.setMessage(R.string.detail_action_mode_delete_dialog_message) .setMessage(R.string.detail_action_mode_delete_dialog_message)
.setPositiveButton(R.string.detail_action_mode_delete_dialog_permanently_delete) { _, _ -> .setPositiveButton(R.string.detail_action_mode_delete_dialog_permanently_delete) { _, _ ->
adapter.selected.map { notificationId -> viewModel.remove(notificationId) } adapter.selected.map { notificationId -> viewModel.markAsDeleted(notificationId) }
finishActionMode() finishActionMode()
} }
.setNegativeButton(R.string.detail_action_mode_delete_dialog_cancel) { _, _ -> .setNegativeButton(R.string.detail_action_mode_delete_dialog_cancel) { _, _ ->
finishActionMode() finishActionMode()
} }
.create() .create()
.show() dialog.setOnShowListener {
dialog
.getButton(AlertDialog.BUTTON_POSITIVE)
.setTextColor(ContextCompat.getColor(this, R.color.primaryDangerButtonColor))
}
dialog.show()
} }
override fun onDestroyActionMode(mode: ActionMode?) { override fun onDestroyActionMode(mode: ActionMode?) {

View file

@ -14,8 +14,8 @@ class DetailViewModel(private val repository: Repository) : ViewModel() {
return repository.getNotificationsLiveData(subscriptionId) return repository.getNotificationsLiveData(subscriptionId)
} }
fun remove(notificationId: String) = viewModelScope.launch(Dispatchers.IO) { fun markAsDeleted(notificationId: String) = viewModelScope.launch(Dispatchers.IO) {
repository.removeNotification(notificationId) repository.markAsDeleted(notificationId)
} }
} }

View file

@ -405,7 +405,7 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc
Log.d(DetailActivity.TAG, "Showing multi-delete dialog for selected items") Log.d(DetailActivity.TAG, "Showing multi-delete dialog for selected items")
val builder = AlertDialog.Builder(this) val builder = AlertDialog.Builder(this)
builder val dialog = builder
.setMessage(R.string.main_action_mode_delete_dialog_message) .setMessage(R.string.main_action_mode_delete_dialog_message)
.setPositiveButton(R.string.main_action_mode_delete_dialog_permanently_delete) { _, _ -> .setPositiveButton(R.string.main_action_mode_delete_dialog_permanently_delete) { _, _ ->
adapter.selected.map { viewModel.remove(it) } adapter.selected.map { viewModel.remove(it) }
@ -415,7 +415,12 @@ class MainActivity : AppCompatActivity(), ActionMode.Callback, AddFragment.Subsc
finishActionMode() finishActionMode()
} }
.create() .create()
.show() dialog.setOnShowListener {
dialog
.getButton(AlertDialog.BUTTON_POSITIVE)
.setTextColor(ContextCompat.getColor(this, R.color.primaryDangerButtonColor))
}
dialog.show()
} }
override fun onDestroyActionMode(mode: ActionMode?) { override fun onDestroyActionMode(mode: ActionMode?) {

View file

@ -13,5 +13,6 @@
android:icon="@drawable/ic_bolt_white_24dp" app:showAsAction="ifRoom"/> android:icon="@drawable/ic_bolt_white_24dp" app:showAsAction="ifRoom"/>
<item android:id="@+id/detail_menu_test" android:title="@string/detail_menu_test"/> <item android:id="@+id/detail_menu_test" android:title="@string/detail_menu_test"/>
<item android:id="@+id/detail_menu_copy_url" android:title="@string/detail_menu_copy_url"/> <item android:id="@+id/detail_menu_copy_url" android:title="@string/detail_menu_copy_url"/>
<item android:id="@+id/detail_menu_clear" android:title="@string/detail_menu_clear"/>
<item android:id="@+id/detail_menu_unsubscribe" android:title="@string/detail_menu_unsubscribe"/> <item android:id="@+id/detail_menu_unsubscribe" android:title="@string/detail_menu_unsubscribe"/>
</menu> </menu>

View file

@ -8,5 +8,6 @@
<color name="primaryLightTextColor">#FFFFFF</color> <color name="primaryLightTextColor">#FFFFFF</color>
<color name="primarySelectedRowColor">#EEEEEE</color> <color name="primarySelectedRowColor">#EEEEEE</color>
<color name="primaryDangerButtonColor">#C30000</color>
</resources> </resources>

View file

@ -31,8 +31,8 @@
<!-- Main activity: Action mode --> <!-- Main activity: Action mode -->
<string name="main_action_mode_menu_unsubscribe">Unsubscribe</string> <string name="main_action_mode_menu_unsubscribe">Unsubscribe</string>
<string name="main_action_mode_delete_dialog_message"> <string name="main_action_mode_delete_dialog_message">
Do you really want to unsubscribe from selected topic(s) and Do you really want to unsubscribe from the selected topic(s) and
permanently delete all the messages you received? permanently delete all the notifications you received?
</string> </string>
<string name="main_action_mode_delete_dialog_permanently_delete">Permanently delete</string> <string name="main_action_mode_delete_dialog_permanently_delete">Permanently delete</string>
<string name="main_action_mode_delete_dialog_cancel">Cancel</string> <string name="main_action_mode_delete_dialog_cancel">Cancel</string>
@ -76,8 +76,12 @@
<string name="detail_how_to_intro">To send notifications to this topic, simply PUT or POST to the topic URL.</string> <string name="detail_how_to_intro">To send notifications to this topic, simply PUT or POST to the topic URL.</string>
<string name="detail_how_to_example"><![CDATA[ Example (using curl):<br/><tt>$ curl -d \"Hi\" %1$s</tt> ]]></string> <string name="detail_how_to_example"><![CDATA[ Example (using curl):<br/><tt>$ curl -d \"Hi\" %1$s</tt> ]]></string>
<string name="detail_how_to_link">For more detailed instructions, check out the ntfy.sh website and documentation.</string> <string name="detail_how_to_link">For more detailed instructions, check out the ntfy.sh website and documentation.</string>
<string name="detail_delete_dialog_message">Do you really want to unsubscribe from this topic and delete all of the <string name="detail_clear_dialog_message">Do you really want to delete all of the notifications in this topic?</string>
messages you received? <string name="detail_clear_dialog_permanently_delete">Permanently delete</string>
<string name="detail_clear_dialog_cancel">Cancel</string>
<string name="detail_delete_dialog_message">
Do you really want to unsubscribe from this topic and delete all of the
notifications you received?
</string> </string>
<string name="detail_delete_dialog_permanently_delete">Permanently delete</string> <string name="detail_delete_dialog_permanently_delete">Permanently delete</string>
<string name="detail_delete_dialog_cancel">Cancel</string> <string name="detail_delete_dialog_cancel">Cancel</string>
@ -94,15 +98,17 @@
<string name="detail_menu_notifications_disabled_until">Notifications disabled until %1$s</string> <string name="detail_menu_notifications_disabled_until">Notifications disabled until %1$s</string>
<string name="detail_menu_enable_instant">Enable instant delivery</string> <string name="detail_menu_enable_instant">Enable instant delivery</string>
<string name="detail_menu_disable_instant">Disable instant delivery</string> <string name="detail_menu_disable_instant">Disable instant delivery</string>
<string name="detail_menu_instant_info">Instant delivery enabled</string>
<string name="detail_menu_test">Send test notification</string> <string name="detail_menu_test">Send test notification</string>
<string name="detail_menu_copy_url">Copy topic address</string> <string name="detail_menu_copy_url">Copy topic address</string>
<string name="detail_menu_instant_info">Instant delivery enabled</string> <string name="detail_menu_clear">Clear all notifications</string>
<string name="detail_menu_unsubscribe">Unsubscribe</string> <string name="detail_menu_unsubscribe">Unsubscribe</string>
<!-- Detail activity: Action mode --> <!-- Detail activity: Action mode -->
<string name="detail_action_mode_menu_copy">Copy</string> <string name="detail_action_mode_menu_copy">Copy</string>
<string name="detail_action_mode_menu_delete">Delete</string> <string name="detail_action_mode_menu_delete">Delete</string>
<string name="detail_action_mode_delete_dialog_message">Do you really want to permanently delete the selected message(s)? <string name="detail_action_mode_delete_dialog_message">
Do you really want to permanently delete the selected notification(s)?
</string> </string>
<string name="detail_action_mode_delete_dialog_permanently_delete">Permanently delete</string> <string name="detail_action_mode_delete_dialog_permanently_delete">Permanently delete</string>
<string name="detail_action_mode_delete_dialog_cancel">Cancel</string> <string name="detail_action_mode_delete_dialog_cancel">Cancel</string>