mirror of
https://github.com/element-hq/element-android
synced 2024-11-28 13:38:49 +03:00
handling creating the summary when notification events are filtered to empty due to only containing removals
This commit is contained in:
parent
3d567d0dcd
commit
0d316e69de
6 changed files with 94 additions and 65 deletions
|
@ -46,7 +46,12 @@ class NotificationFactory @Inject constructor(
|
|||
null -> OneShotNotification.Removed(key = roomId)
|
||||
else -> OneShotNotification.Append(
|
||||
notificationUtils.buildRoomInvitationNotification(event, myUserId),
|
||||
OneShotNotification.Append.Meta(key = roomId, summaryLine = event.description, isNoisy = event.noisy)
|
||||
OneShotNotification.Append.Meta(
|
||||
key = roomId,
|
||||
summaryLine = event.description,
|
||||
isNoisy = event.noisy,
|
||||
timestamp = event.timestamp
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +64,12 @@ class NotificationFactory @Inject constructor(
|
|||
null -> OneShotNotification.Removed(key = eventId)
|
||||
else -> OneShotNotification.Append(
|
||||
notificationUtils.buildSimpleEventNotification(event, myUserId),
|
||||
OneShotNotification.Append.Meta(key = eventId, summaryLine = event.description, isNoisy = event.noisy)
|
||||
OneShotNotification.Append.Meta(
|
||||
key = eventId,
|
||||
summaryLine = event.description,
|
||||
isNoisy = event.noisy,
|
||||
timestamp = event.timestamp
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -68,13 +78,19 @@ class NotificationFactory @Inject constructor(
|
|||
fun createSummaryNotification(roomNotifications: List<RoomNotification>,
|
||||
invitationNotifications: List<OneShotNotification>,
|
||||
simpleNotifications: List<OneShotNotification>,
|
||||
useCompleteNotificationFormat: Boolean): Notification {
|
||||
return summaryGroupMessageCreator.createSummaryNotification(
|
||||
roomNotifications = roomNotifications.mapToMeta(),
|
||||
invitationNotifications = invitationNotifications.mapToMeta(),
|
||||
simpleNotifications = simpleNotifications.mapToMeta(),
|
||||
useCompleteNotificationFormat = useCompleteNotificationFormat
|
||||
)
|
||||
useCompleteNotificationFormat: Boolean): SummaryNotification {
|
||||
val roomMeta = roomNotifications.mapToMeta()
|
||||
val invitationMeta = invitationNotifications.mapToMeta()
|
||||
val simpleMeta = simpleNotifications.mapToMeta()
|
||||
return when {
|
||||
roomMeta.isEmpty() && invitationMeta.isEmpty() && simpleMeta.isEmpty() -> SummaryNotification.Removed
|
||||
else -> SummaryNotification.Update(summaryGroupMessageCreator.createSummaryNotification(
|
||||
roomNotifications = roomMeta,
|
||||
invitationNotifications = invitationMeta,
|
||||
simpleNotifications = simpleMeta,
|
||||
useCompleteNotificationFormat = useCompleteNotificationFormat
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,7 +118,13 @@ sealed interface OneShotNotification {
|
|||
data class Meta(
|
||||
val key: String,
|
||||
val summaryLine: CharSequence,
|
||||
val isNoisy: Boolean
|
||||
val isNoisy: Boolean,
|
||||
val timestamp: Long,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
sealed interface SummaryNotification {
|
||||
object Removed : SummaryNotification
|
||||
data class Update(val notification: Notification) : SummaryNotification
|
||||
}
|
||||
|
|
|
@ -16,12 +16,8 @@
|
|||
package im.vector.app.features.notifications
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import androidx.annotation.WorkerThread
|
||||
import androidx.core.content.pm.ShortcutInfoCompat
|
||||
import androidx.core.content.pm.ShortcutManagerCompat
|
||||
import androidx.core.graphics.drawable.IconCompat
|
||||
import im.vector.app.features.home.room.detail.RoomDetailActivity
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
@ -41,7 +37,7 @@ class NotificationRenderer @Inject constructor(private val notifiableEventProces
|
|||
myUserAvatarUrl: String?,
|
||||
useCompleteNotificationFormat: Boolean,
|
||||
eventList: MutableList<NotifiableEvent>) {
|
||||
Timber.v("refreshNotificationDrawerBg()")
|
||||
Timber.v("Render notification events - count: ${eventList.size}")
|
||||
val notificationEvents = notifiableEventProcessor.modifyAndProcess(eventList, currentRoomId)
|
||||
if (lastKnownEventList == notificationEvents.hashCode()) {
|
||||
Timber.d("Skipping notification update due to event list not changing")
|
||||
|
@ -57,49 +53,55 @@ class NotificationRenderer @Inject constructor(private val notifiableEventProces
|
|||
val roomNotifications = roomEvents.toNotifications(myUserDisplayName, myUserAvatarUrl)
|
||||
val invitationNotifications = invitationEvents.toNotifications(myUserId)
|
||||
val simpleNotifications = simpleEvents.toNotifications(myUserId)
|
||||
val summaryNotification = createSummaryNotification(
|
||||
roomNotifications = roomNotifications,
|
||||
invitationNotifications = invitationNotifications,
|
||||
simpleNotifications = simpleNotifications,
|
||||
useCompleteNotificationFormat = useCompleteNotificationFormat
|
||||
)
|
||||
|
||||
if (roomNotifications.isEmpty() && invitationNotifications.isEmpty() && simpleNotifications.isEmpty()) {
|
||||
notificationDisplayer.cancelNotificationMessage(null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID)
|
||||
} else {
|
||||
val summaryNotification = createSummaryNotification(
|
||||
roomNotifications = roomNotifications,
|
||||
invitationNotifications = invitationNotifications,
|
||||
simpleNotifications = simpleNotifications,
|
||||
useCompleteNotificationFormat = useCompleteNotificationFormat
|
||||
)
|
||||
roomNotifications.forEach { wrapper ->
|
||||
when (wrapper) {
|
||||
is RoomNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.roomId, NotificationDrawerManager.ROOM_MESSAGES_NOTIFICATION_ID)
|
||||
is RoomNotification.Message -> if (useCompleteNotificationFormat) {
|
||||
Timber.d("Updating room messages notification ${wrapper.meta.roomId}")
|
||||
wrapper.shortcutInfo?.let {
|
||||
ShortcutManagerCompat.pushDynamicShortcut(appContext, it)
|
||||
}
|
||||
notificationDisplayer.showNotificationMessage(wrapper.meta.roomId, NotificationDrawerManager.ROOM_MESSAGES_NOTIFICATION_ID, wrapper.notification)
|
||||
roomNotifications.forEach { wrapper ->
|
||||
when (wrapper) {
|
||||
is RoomNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.roomId, NotificationDrawerManager.ROOM_MESSAGES_NOTIFICATION_ID)
|
||||
is RoomNotification.Message -> if (useCompleteNotificationFormat) {
|
||||
Timber.d("Updating room messages notification ${wrapper.meta.roomId}")
|
||||
wrapper.shortcutInfo?.let {
|
||||
ShortcutManagerCompat.pushDynamicShortcut(appContext, it)
|
||||
}
|
||||
notificationDisplayer.showNotificationMessage(wrapper.meta.roomId, NotificationDrawerManager.ROOM_MESSAGES_NOTIFICATION_ID, wrapper.notification)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
invitationNotifications.forEach { wrapper ->
|
||||
when (wrapper) {
|
||||
is OneShotNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.key, NotificationDrawerManager.ROOM_INVITATION_NOTIFICATION_ID)
|
||||
is OneShotNotification.Append -> if (useCompleteNotificationFormat) {
|
||||
Timber.d("Updating invitation notification ${wrapper.meta.key}")
|
||||
notificationDisplayer.showNotificationMessage(wrapper.meta.key, NotificationDrawerManager.ROOM_INVITATION_NOTIFICATION_ID, wrapper.notification)
|
||||
}
|
||||
invitationNotifications.forEach { wrapper ->
|
||||
when (wrapper) {
|
||||
is OneShotNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.key, NotificationDrawerManager.ROOM_INVITATION_NOTIFICATION_ID)
|
||||
is OneShotNotification.Append -> if (useCompleteNotificationFormat) {
|
||||
Timber.d("Updating invitation notification ${wrapper.meta.key}")
|
||||
notificationDisplayer.showNotificationMessage(wrapper.meta.key, NotificationDrawerManager.ROOM_INVITATION_NOTIFICATION_ID, wrapper.notification)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simpleNotifications.forEach { wrapper ->
|
||||
when (wrapper) {
|
||||
is OneShotNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.key, NotificationDrawerManager.ROOM_EVENT_NOTIFICATION_ID)
|
||||
is OneShotNotification.Append -> if (useCompleteNotificationFormat) {
|
||||
Timber.d("Updating simple notification ${wrapper.meta.key}")
|
||||
notificationDisplayer.showNotificationMessage(wrapper.meta.key, NotificationDrawerManager.ROOM_EVENT_NOTIFICATION_ID, wrapper.notification)
|
||||
}
|
||||
simpleNotifications.forEach { wrapper ->
|
||||
when (wrapper) {
|
||||
is OneShotNotification.Removed -> notificationDisplayer.cancelNotificationMessage(wrapper.key, NotificationDrawerManager.ROOM_EVENT_NOTIFICATION_ID)
|
||||
is OneShotNotification.Append -> if (useCompleteNotificationFormat) {
|
||||
Timber.d("Updating simple notification ${wrapper.meta.key}")
|
||||
notificationDisplayer.showNotificationMessage(wrapper.meta.key, NotificationDrawerManager.ROOM_EVENT_NOTIFICATION_ID, wrapper.notification)
|
||||
}
|
||||
}
|
||||
notificationDisplayer.showNotificationMessage(null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, summaryNotification)
|
||||
}
|
||||
|
||||
when (summaryNotification) {
|
||||
SummaryNotification.Removed -> {
|
||||
Timber.d("Removing summary notification")
|
||||
notificationDisplayer.cancelNotificationMessage(null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID)
|
||||
}
|
||||
is SummaryNotification.Update -> {
|
||||
Timber.d("Updating summary notification")
|
||||
notificationDisplayer.showNotificationMessage(null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, summaryNotification.notification)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,9 @@ class SummaryGroupMessageCreator @Inject constructor(
|
|||
|
||||
val messageCount = roomNotifications.fold(initial = 0) { acc, current -> acc + current.messageCount }
|
||||
|
||||
val lastMessageTimestamp1 = roomNotifications.last().latestTimestamp
|
||||
val lastMessageTimestamp = roomNotifications.lastOrNull()?.latestTimestamp
|
||||
?: invitationNotifications.lastOrNull()?.timestamp
|
||||
?: simpleNotifications.last().timestamp
|
||||
|
||||
// FIXME roomIdToEventMap.size is not correct, this is the number of rooms
|
||||
val nbEvents = roomNotifications.size + simpleNotifications.size
|
||||
|
@ -71,12 +73,12 @@ class SummaryGroupMessageCreator @Inject constructor(
|
|||
summaryInboxStyle,
|
||||
sumTitle,
|
||||
noisy = summaryIsNoisy,
|
||||
lastMessageTimestamp = lastMessageTimestamp1
|
||||
lastMessageTimestamp = lastMessageTimestamp
|
||||
)
|
||||
} else {
|
||||
processSimpleGroupSummary(summaryIsNoisy, messageCount,
|
||||
simpleNotifications.size, invitationNotifications.size,
|
||||
roomNotifications.size, lastMessageTimestamp1)
|
||||
roomNotifications.size, lastMessageTimestamp)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,8 @@ class NotificationFactoryTest {
|
|||
meta = OneShotNotification.Append.Meta(
|
||||
key = A_ROOM_ID,
|
||||
summaryLine = AN_INVITATION_EVENT.description,
|
||||
isNoisy = AN_INVITATION_EVENT.noisy
|
||||
isNoisy = AN_INVITATION_EVENT.noisy,
|
||||
timestamp = AN_INVITATION_EVENT.timestamp
|
||||
))
|
||||
)
|
||||
}
|
||||
|
@ -83,7 +84,8 @@ class NotificationFactoryTest {
|
|||
meta = OneShotNotification.Append.Meta(
|
||||
key = AN_EVENT_ID,
|
||||
summaryLine = A_SIMPLE_EVENT.description,
|
||||
isNoisy = A_SIMPLE_EVENT.noisy
|
||||
isNoisy = A_SIMPLE_EVENT.noisy,
|
||||
timestamp = AN_INVITATION_EVENT.timestamp
|
||||
))
|
||||
)
|
||||
}
|
||||
|
|
|
@ -34,12 +34,13 @@ private const val USE_COMPLETE_NOTIFICATION_FORMAT = true
|
|||
|
||||
private val AN_EVENT_LIST = mutableListOf<NotifiableEvent>()
|
||||
private val A_PROCESSED_EVENTS = ProcessedNotificationEvents(emptyMap(), emptyMap(), emptyMap())
|
||||
private val A_SUMMARY_NOTIFICATION = mockk<Notification>()
|
||||
private val A_SUMMARY_NOTIFICATION = SummaryNotification.Update(mockk())
|
||||
private val A_REMOVE_SUMMARY_NOTIFICATION = SummaryNotification.Removed
|
||||
private val A_NOTIFICATION = mockk<Notification>()
|
||||
private val MESSAGE_META = RoomNotification.Message.Meta(
|
||||
summaryLine = "ignored", messageCount = 1, latestTimestamp = -1, roomId = A_ROOM_ID, shouldBing = false
|
||||
)
|
||||
private val ONE_SHOT_META = OneShotNotification.Append.Meta(key = "ignored", summaryLine = "ignored", isNoisy = false)
|
||||
private val ONE_SHOT_META = OneShotNotification.Append.Meta(key = "ignored", summaryLine = "ignored", isNoisy = false, timestamp = -1)
|
||||
|
||||
class NotificationRendererTest {
|
||||
|
||||
|
@ -71,7 +72,7 @@ class NotificationRendererTest {
|
|||
|
||||
notificationDisplayer.verifyInOrder {
|
||||
cancelNotificationMessage(tag = A_ROOM_ID, NotificationDrawerManager.ROOM_MESSAGES_NOTIFICATION_ID)
|
||||
showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION)
|
||||
showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION.notification)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,7 +87,7 @@ class NotificationRendererTest {
|
|||
|
||||
notificationDisplayer.verifyInOrder {
|
||||
showNotificationMessage(tag = A_ROOM_ID, NotificationDrawerManager.ROOM_MESSAGES_NOTIFICATION_ID, A_NOTIFICATION)
|
||||
showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION)
|
||||
showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION.notification)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,7 +99,7 @@ class NotificationRendererTest {
|
|||
|
||||
notificationDisplayer.verifyInOrder {
|
||||
cancelNotificationMessage(tag = AN_EVENT_ID, NotificationDrawerManager.ROOM_EVENT_NOTIFICATION_ID)
|
||||
showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION)
|
||||
showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION.notification)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -113,7 +114,7 @@ class NotificationRendererTest {
|
|||
|
||||
notificationDisplayer.verifyInOrder {
|
||||
showNotificationMessage(tag = AN_EVENT_ID, NotificationDrawerManager.ROOM_EVENT_NOTIFICATION_ID, A_NOTIFICATION)
|
||||
showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION)
|
||||
showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION.notification)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,7 +126,7 @@ class NotificationRendererTest {
|
|||
|
||||
notificationDisplayer.verifyInOrder {
|
||||
cancelNotificationMessage(tag = A_ROOM_ID, NotificationDrawerManager.ROOM_INVITATION_NOTIFICATION_ID)
|
||||
showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION)
|
||||
showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION.notification)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,7 +141,7 @@ class NotificationRendererTest {
|
|||
|
||||
notificationDisplayer.verifyInOrder {
|
||||
showNotificationMessage(tag = A_ROOM_ID, NotificationDrawerManager.ROOM_EVENT_NOTIFICATION_ID, A_NOTIFICATION)
|
||||
showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION)
|
||||
showNotificationMessage(tag = null, NotificationDrawerManager.SUMMARY_NOTIFICATION_ID, A_SUMMARY_NOTIFICATION.notification)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,14 +157,14 @@ class NotificationRendererTest {
|
|||
}
|
||||
|
||||
private fun givenNoNotifications() {
|
||||
givenNotifications(emptyList(), emptyList(), emptyList(), USE_COMPLETE_NOTIFICATION_FORMAT, A_SUMMARY_NOTIFICATION)
|
||||
givenNotifications(emptyList(), emptyList(), emptyList(), USE_COMPLETE_NOTIFICATION_FORMAT, A_REMOVE_SUMMARY_NOTIFICATION)
|
||||
}
|
||||
|
||||
private fun givenNotifications(roomNotifications: List<RoomNotification> = emptyList(),
|
||||
invitationNotifications: List<OneShotNotification> = emptyList(),
|
||||
simpleNotifications: List<OneShotNotification> = emptyList(),
|
||||
useCompleteNotificationFormat: Boolean = USE_COMPLETE_NOTIFICATION_FORMAT,
|
||||
summaryNotification: Notification = A_SUMMARY_NOTIFICATION) {
|
||||
summaryNotification: SummaryNotification = A_SUMMARY_NOTIFICATION) {
|
||||
notifiableEventProcessor.givenProcessedEventsFor(AN_EVENT_LIST, A_CURRENT_ROOM_ID, A_PROCESSED_EVENTS)
|
||||
notificationFactory.givenNotificationsFor(
|
||||
processedEvents = A_PROCESSED_EVENTS,
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
|
||||
package im.vector.app.test.fakes
|
||||
|
||||
import android.app.Notification
|
||||
import im.vector.app.features.notifications.NotificationFactory
|
||||
import im.vector.app.features.notifications.OneShotNotification
|
||||
import im.vector.app.features.notifications.ProcessedNotificationEvents
|
||||
import im.vector.app.features.notifications.RoomNotification
|
||||
import im.vector.app.features.notifications.SummaryNotification
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
|
||||
|
@ -36,7 +36,7 @@ class FakeNotificationFactory {
|
|||
roomNotifications: List<RoomNotification>,
|
||||
invitationNotifications: List<OneShotNotification>,
|
||||
simpleNotifications: List<OneShotNotification>,
|
||||
summaryNotification: Notification) {
|
||||
summaryNotification: SummaryNotification) {
|
||||
with(instance) {
|
||||
every { processedEvents.roomEvents.toNotifications(myUserDisplayName, myUserAvatarUrl) } returns roomNotifications
|
||||
every { processedEvents.invitationEvents.toNotifications(myUserId) } returns invitationNotifications
|
||||
|
|
Loading…
Reference in a new issue