From 00f232d6e544bc2254c91b1b7f05cb15913383ba Mon Sep 17 00:00:00 2001 From: Claire G Date: Wed, 20 Apr 2022 14:31:27 +0200 Subject: [PATCH 1/5] update notifications rules: make a sound for each notification --- changelog.d/46312.misc | 1 + .../im/vector/app/features/notifications/NotificationUtils.kt | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) create mode 100644 changelog.d/46312.misc diff --git a/changelog.d/46312.misc b/changelog.d/46312.misc new file mode 100644 index 00000000000..3fac7cbeba2 --- /dev/null +++ b/changelog.d/46312.misc @@ -0,0 +1 @@ +Use the same notification rules than web / iOs client diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt index 161b58d53d2..e1d1dceb6f0 100755 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt @@ -574,7 +574,6 @@ class NotificationUtils @Inject constructor(private val context: Context, val channelID = if (roomInfo.shouldBing) NOISY_NOTIFICATION_CHANNEL_ID else SILENT_NOTIFICATION_CHANNEL_ID return NotificationCompat.Builder(context, channelID) - .setOnlyAlertOnce(true) .setWhen(lastMessageTimestamp) // MESSAGING_STYLE sets title and content for API 16 and above devices. .setStyle(messageStyle) @@ -682,7 +681,6 @@ class NotificationUtils @Inject constructor(private val context: Context, val channelID = if (inviteNotifiableEvent.noisy) NOISY_NOTIFICATION_CHANNEL_ID else SILENT_NOTIFICATION_CHANNEL_ID return NotificationCompat.Builder(context, channelID) - .setOnlyAlertOnce(true) .setContentTitle(inviteNotifiableEvent.roomName ?: stringProvider.getString(R.string.app_name)) .setContentText(inviteNotifiableEvent.description) .setGroup(stringProvider.getString(R.string.app_name)) @@ -756,7 +754,6 @@ class NotificationUtils @Inject constructor(private val context: Context, val channelID = if (simpleNotifiableEvent.noisy) NOISY_NOTIFICATION_CHANNEL_ID else SILENT_NOTIFICATION_CHANNEL_ID return NotificationCompat.Builder(context, channelID) - .setOnlyAlertOnce(true) .setContentTitle(stringProvider.getString(R.string.app_name)) .setContentText(simpleNotifiableEvent.description) .setGroup(stringProvider.getString(R.string.app_name)) @@ -866,7 +863,6 @@ class NotificationUtils @Inject constructor(private val context: Context, val smallIcon = R.drawable.ic_status_bar return NotificationCompat.Builder(context, if (noisy) NOISY_NOTIFICATION_CHANNEL_ID else SILENT_NOTIFICATION_CHANNEL_ID) - .setOnlyAlertOnce(true) // used in compat < N, after summary is built based on child notifications .setWhen(lastMessageTimestamp) .setStyle(style) From 132e44f245f960ec50f6688dcdeb694e52f06af9 Mon Sep 17 00:00:00 2001 From: Claire G Date: Thu, 5 May 2022 10:40:35 +0200 Subject: [PATCH 2/5] add isUpdated in NotifiableEvent and RoomEventGroupInfo --- .../app/features/notifications/InviteNotifiableEvent.kt | 3 ++- .../im/vector/app/features/notifications/NotifiableEvent.kt | 1 + .../app/features/notifications/NotifiableMessageEvent.kt | 3 ++- .../app/features/notifications/NotificationEventQueue.kt | 2 +- .../im/vector/app/features/notifications/NotificationUtils.kt | 4 ++++ .../vector/app/features/notifications/RoomEventGroupInfo.kt | 1 + .../app/features/notifications/RoomGroupMessageCreator.kt | 1 + .../app/features/notifications/SimpleNotifiableEvent.kt | 3 ++- 8 files changed, 14 insertions(+), 4 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt index 832f97bc4e9..dceaa92f1b4 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt @@ -28,5 +28,6 @@ data class InviteNotifiableEvent( val type: String?, val timestamp: Long, val soundName: String?, - override val isRedacted: Boolean = false + override val isRedacted: Boolean = false, + override var isUpdated: Boolean = false ) : NotifiableEvent diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt index 52d8119cbbd..a76aad6aee7 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt @@ -27,4 +27,5 @@ sealed interface NotifiableEvent : Serializable { // Used to know if event should be replaced with the one coming from eventstream val canBeReplaced: Boolean val isRedacted: Boolean + var isUpdated: Boolean } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt index 35718666b0f..559504ad6f9 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt @@ -38,7 +38,8 @@ data class NotifiableMessageEvent( // This is used for >N notification, as the result of a smart reply val outGoingMessage: Boolean = false, val outGoingMessageFailed: Boolean = false, - override val isRedacted: Boolean = false + override val isRedacted: Boolean = false, + override var isUpdated: Boolean = false ) : NotifiableEvent { val type: String = EventType.MESSAGE diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationEventQueue.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationEventQueue.kt index 04506b218b1..b9651e23381 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationEventQueue.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationEventQueue.kt @@ -112,7 +112,7 @@ data class NotificationEventQueue( private fun replace(replace: NotifiableEvent, with: NotifiableEvent) { queue.remove(replace) - queue.add(with) + queue.add(with.apply { isUpdated = true }) } fun clearMemberShipNotificationForRoom(roomId: String) { diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt index e1d1dceb6f0..4308d17827f 100755 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt @@ -574,6 +574,7 @@ class NotificationUtils @Inject constructor(private val context: Context, val channelID = if (roomInfo.shouldBing) NOISY_NOTIFICATION_CHANNEL_ID else SILENT_NOTIFICATION_CHANNEL_ID return NotificationCompat.Builder(context, channelID) + .setOnlyAlertOnce(roomInfo.isUpdated) .setWhen(lastMessageTimestamp) // MESSAGING_STYLE sets title and content for API 16 and above devices. .setStyle(messageStyle) @@ -681,6 +682,7 @@ class NotificationUtils @Inject constructor(private val context: Context, val channelID = if (inviteNotifiableEvent.noisy) NOISY_NOTIFICATION_CHANNEL_ID else SILENT_NOTIFICATION_CHANNEL_ID return NotificationCompat.Builder(context, channelID) + .setOnlyAlertOnce(true) .setContentTitle(inviteNotifiableEvent.roomName ?: stringProvider.getString(R.string.app_name)) .setContentText(inviteNotifiableEvent.description) .setGroup(stringProvider.getString(R.string.app_name)) @@ -754,6 +756,7 @@ class NotificationUtils @Inject constructor(private val context: Context, val channelID = if (simpleNotifiableEvent.noisy) NOISY_NOTIFICATION_CHANNEL_ID else SILENT_NOTIFICATION_CHANNEL_ID return NotificationCompat.Builder(context, channelID) + .setOnlyAlertOnce(true) .setContentTitle(stringProvider.getString(R.string.app_name)) .setContentText(simpleNotifiableEvent.description) .setGroup(stringProvider.getString(R.string.app_name)) @@ -863,6 +866,7 @@ class NotificationUtils @Inject constructor(private val context: Context, val smallIcon = R.drawable.ic_status_bar return NotificationCompat.Builder(context, if (noisy) NOISY_NOTIFICATION_CHANNEL_ID else SILENT_NOTIFICATION_CHANNEL_ID) + .setOnlyAlertOnce(true) // used in compat < N, after summary is built based on child notifications .setWhen(lastMessageTimestamp) .setStyle(style) diff --git a/vector/src/main/java/im/vector/app/features/notifications/RoomEventGroupInfo.kt b/vector/src/main/java/im/vector/app/features/notifications/RoomEventGroupInfo.kt index 64e40ed7487..6ec46453824 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/RoomEventGroupInfo.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/RoomEventGroupInfo.kt @@ -31,4 +31,5 @@ data class RoomEventGroupInfo( var shouldBing: Boolean = false var customSound: String? = null var hasSmartReplyError: Boolean = false + var isUpdated: Boolean = false } diff --git a/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt b/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt index 8310c15daa2..535ac8b62e2 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt @@ -72,6 +72,7 @@ class RoomGroupMessageCreator @Inject constructor( it.hasSmartReplyError = smartReplyErrors.isNotEmpty() it.shouldBing = meta.shouldBing it.customSound = events.last().soundName + it.isUpdated = events.last().isUpdated }, largeIcon = largeBitmap, lastMessageTimestamp, diff --git a/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt index 8c723722041..bd2d9b369d5 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt @@ -26,5 +26,6 @@ data class SimpleNotifiableEvent( val timestamp: Long, val soundName: String?, override var canBeReplaced: Boolean, - override val isRedacted: Boolean = false + override val isRedacted: Boolean = false, + override var isUpdated: Boolean = false ) : NotifiableEvent From 96921b6040c31501f94303008bf948d358bfaf01 Mon Sep 17 00:00:00 2001 From: Claire G Date: Thu, 5 May 2022 11:12:06 +0200 Subject: [PATCH 3/5] use val instead of var --- .../app/features/notifications/InviteNotifiableEvent.kt | 2 +- .../vector/app/features/notifications/NotifiableEvent.kt | 2 +- .../app/features/notifications/NotifiableMessageEvent.kt | 2 +- .../app/features/notifications/NotificationEventQueue.kt | 8 +++++++- .../app/features/notifications/SimpleNotifiableEvent.kt | 2 +- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt index dceaa92f1b4..eb0735f2be0 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/InviteNotifiableEvent.kt @@ -29,5 +29,5 @@ data class InviteNotifiableEvent( val timestamp: Long, val soundName: String?, override val isRedacted: Boolean = false, - override var isUpdated: Boolean = false + override val isUpdated: Boolean = false ) : NotifiableEvent diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt index a76aad6aee7..a9ad79febf6 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEvent.kt @@ -27,5 +27,5 @@ sealed interface NotifiableEvent : Serializable { // Used to know if event should be replaced with the one coming from eventstream val canBeReplaced: Boolean val isRedacted: Boolean - var isUpdated: Boolean + val isUpdated: Boolean } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt index 559504ad6f9..d13e41daa82 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableMessageEvent.kt @@ -39,7 +39,7 @@ data class NotifiableMessageEvent( val outGoingMessage: Boolean = false, val outGoingMessageFailed: Boolean = false, override val isRedacted: Boolean = false, - override var isUpdated: Boolean = false + override val isUpdated: Boolean = false ) : NotifiableEvent { val type: String = EventType.MESSAGE diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationEventQueue.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationEventQueue.kt index b9651e23381..7c933c389d9 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationEventQueue.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationEventQueue.kt @@ -112,7 +112,13 @@ data class NotificationEventQueue( private fun replace(replace: NotifiableEvent, with: NotifiableEvent) { queue.remove(replace) - queue.add(with.apply { isUpdated = true }) + queue.add( + when (with) { + is InviteNotifiableEvent -> with.copy(isUpdated = true) + is NotifiableMessageEvent -> with.copy(isUpdated = true) + is SimpleNotifiableEvent -> with.copy(isUpdated = true) + } + ) } fun clearMemberShipNotificationForRoom(roomId: String) { diff --git a/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt b/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt index bd2d9b369d5..a58f22087d7 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/SimpleNotifiableEvent.kt @@ -27,5 +27,5 @@ data class SimpleNotifiableEvent( val soundName: String?, override var canBeReplaced: Boolean, override val isRedacted: Boolean = false, - override var isUpdated: Boolean = false + override val isUpdated: Boolean = false ) : NotifiableEvent From 051bee65cd4c5081a4dc2ded0e5418b0784210ec Mon Sep 17 00:00:00 2001 From: Claire G Date: Thu, 5 May 2022 11:18:56 +0200 Subject: [PATCH 4/5] update changelog file --- changelog.d/46312.misc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.d/46312.misc b/changelog.d/46312.misc index 3fac7cbeba2..5e0112372f1 100644 --- a/changelog.d/46312.misc +++ b/changelog.d/46312.misc @@ -1 +1 @@ -Use the same notification rules than web / iOs client +Notify the user for each new message From f188eb6f0d8b31e9f467edaa3029fd0909d7955c Mon Sep 17 00:00:00 2001 From: Claire G Date: Thu, 5 May 2022 11:52:07 +0200 Subject: [PATCH 5/5] Fix TUs --- .../features/notifications/NotificationEventQueueTest.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vector/src/test/java/im/vector/app/features/notifications/NotificationEventQueueTest.kt b/vector/src/test/java/im/vector/app/features/notifications/NotificationEventQueueTest.kt index 3429f882f86..e7349b61517 100644 --- a/vector/src/test/java/im/vector/app/features/notifications/NotificationEventQueueTest.kt +++ b/vector/src/test/java/im/vector/app/features/notifications/NotificationEventQueueTest.kt @@ -145,7 +145,7 @@ class NotificationEventQueueTest { @Test fun `given replaceable event when adding event with same id then updates existing event`() { val replaceableEvent = aSimpleNotifiableEvent(canBeReplaced = true) - val updatedEvent = replaceableEvent.copy(title = "updated title") + val updatedEvent = replaceableEvent.copy(title = "updated title", isUpdated = true) val queue = givenQueue(listOf(replaceableEvent)) queue.add(updatedEvent) @@ -167,7 +167,7 @@ class NotificationEventQueueTest { @Test fun `given event when adding new event with edited event id matching the existing event id then updates existing event`() { val editedEvent = aSimpleNotifiableEvent(eventId = "id-to-edit") - val updatedEvent = editedEvent.copy(eventId = "1", editedEventId = "id-to-edit", title = "updated title") + val updatedEvent = editedEvent.copy(eventId = "1", editedEventId = "id-to-edit", title = "updated title", isUpdated = true) val queue = givenQueue(listOf(editedEvent)) queue.add(updatedEvent) @@ -178,7 +178,7 @@ class NotificationEventQueueTest { @Test fun `given event when adding new event with edited event id matching the existing event edited id then updates existing event`() { val editedEvent = aSimpleNotifiableEvent(eventId = "0", editedEventId = "id-to-edit") - val updatedEvent = editedEvent.copy(eventId = "1", editedEventId = "id-to-edit", title = "updated title") + val updatedEvent = editedEvent.copy(eventId = "1", editedEventId = "id-to-edit", title = "updated title", isUpdated = true) val queue = givenQueue(listOf(editedEvent)) queue.add(updatedEvent)