mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-02-19 05:20:01 +03:00
using a process state of keep/removed rather than mapping to an ignored event id
- this state will be used to diff the currently rendered events against the new ones
This commit is contained in:
parent
b7b4c01bde
commit
b27fb264fc
5 changed files with 56 additions and 43 deletions
vector/src
main/java/im/vector/app/features/notifications
NotifiableEventProcessor.ktNotificationDrawerManager.ktNotificationFactory.ktNotificationRenderer.kt
test/java/im/vector/app/features/notifications
|
@ -17,6 +17,8 @@
|
||||||
package im.vector.app.features.notifications
|
package im.vector.app.features.notifications
|
||||||
|
|
||||||
import im.vector.app.features.invite.AutoAcceptInvites
|
import im.vector.app.features.invite.AutoAcceptInvites
|
||||||
|
import im.vector.app.features.notifications.Processed.KEEP
|
||||||
|
import im.vector.app.features.notifications.Processed.REMOVE
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class NotifiableEventProcessor @Inject constructor(
|
class NotifiableEventProcessor @Inject constructor(
|
||||||
|
@ -24,20 +26,26 @@ class NotifiableEventProcessor @Inject constructor(
|
||||||
private val autoAcceptInvites: AutoAcceptInvites
|
private val autoAcceptInvites: AutoAcceptInvites
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun process(eventList: List<NotifiableEvent>, currentRoomId: String?): Map<String, NotifiableEvent?> {
|
fun process(eventList: List<NotifiableEvent>, currentRoomId: String?): List<Pair<Processed, NotifiableEvent>> {
|
||||||
return eventList.associateBy { it.eventId }
|
return eventList.map {
|
||||||
.mapValues { (_, value) ->
|
when (it) {
|
||||||
when (value) {
|
is InviteNotifiableEvent -> if (autoAcceptInvites.hideInvites) REMOVE else KEEP
|
||||||
is InviteNotifiableEvent -> if (autoAcceptInvites.hideInvites) null else value
|
is NotifiableMessageEvent -> if (shouldIgnoreMessageEventInRoom(currentRoomId, it.roomId) || outdatedDetector.isMessageOutdated(it)) {
|
||||||
is NotifiableMessageEvent -> if (shouldIgnoreMessageEventInRoom(currentRoomId, value.roomId) || outdatedDetector.isMessageOutdated(value)) {
|
REMOVE
|
||||||
null
|
} else KEEP
|
||||||
} else value
|
is SimpleNotifiableEvent -> KEEP
|
||||||
is SimpleNotifiableEvent -> value
|
} to it
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun shouldIgnoreMessageEventInRoom(currentRoomId: String?, roomId: String?): Boolean {
|
private fun shouldIgnoreMessageEventInRoom(currentRoomId: String?, roomId: String?): Boolean {
|
||||||
return currentRoomId != null && roomId == currentRoomId
|
return currentRoomId != null && roomId == currentRoomId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class Processed {
|
||||||
|
KEEP,
|
||||||
|
REMOVE
|
||||||
|
}
|
||||||
|
|
||||||
|
fun List<Pair<Processed, NotifiableEvent>>.onlyKeptEvents() = filter { it.first == KEEP }.map { it.second }
|
||||||
|
|
|
@ -56,7 +56,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
||||||
}
|
}
|
||||||
|
|
||||||
private val eventList = loadEventInfo()
|
private val eventList = loadEventInfo()
|
||||||
private var renderedEventsList = emptyMap<String, NotifiableEvent?>()
|
private var renderedEventsList = emptyList<Pair<Processed, NotifiableEvent>>()
|
||||||
private val avatarSize = context.resources.getDimensionPixelSize(R.dimen.profile_avatar_size)
|
private val avatarSize = context.resources.getDimensionPixelSize(R.dimen.profile_avatar_size)
|
||||||
private var currentRoomId: String? = null
|
private var currentRoomId: String? = null
|
||||||
|
|
||||||
|
@ -236,10 +236,12 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
||||||
val eventsToRender = synchronized(eventList) {
|
val eventsToRender = synchronized(eventList) {
|
||||||
notifiableEventProcessor.process(eventList, currentRoomId).also {
|
notifiableEventProcessor.process(eventList, currentRoomId).also {
|
||||||
eventList.clear()
|
eventList.clear()
|
||||||
eventList.addAll(it.values.filterNotNull())
|
eventList.addAll(it.onlyKeptEvents())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (renderedEventsList == eventsToRender) {
|
if (renderedEventsList == eventsToRender) {
|
||||||
Timber.d("Skipping notification update due to event list not changing")
|
Timber.d("Skipping notification update due to event list not changing")
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -40,14 +40,14 @@ class NotificationFactory @Inject constructor(
|
||||||
|
|
||||||
private fun NotifiableMessageEvent.canNotBeDisplayed() = isRedacted
|
private fun NotifiableMessageEvent.canNotBeDisplayed() = isRedacted
|
||||||
|
|
||||||
fun Map<String, InviteNotifiableEvent?>.toNotifications(myUserId: String): List<OneShotNotification> {
|
fun List<Pair<Processed, InviteNotifiableEvent>>.toNotifications(myUserId: String): List<OneShotNotification> {
|
||||||
return map { (roomId, event) ->
|
return map { (processed, event) ->
|
||||||
when (event) {
|
when (processed) {
|
||||||
null -> OneShotNotification.Removed(key = roomId)
|
Processed.REMOVE -> OneShotNotification.Removed(key = event.roomId)
|
||||||
else -> OneShotNotification.Append(
|
Processed.KEEP -> OneShotNotification.Append(
|
||||||
notificationUtils.buildRoomInvitationNotification(event, myUserId),
|
notificationUtils.buildRoomInvitationNotification(event, myUserId),
|
||||||
OneShotNotification.Append.Meta(
|
OneShotNotification.Append.Meta(
|
||||||
key = roomId,
|
key = event.roomId,
|
||||||
summaryLine = event.description,
|
summaryLine = event.description,
|
||||||
isNoisy = event.noisy,
|
isNoisy = event.noisy,
|
||||||
timestamp = event.timestamp
|
timestamp = event.timestamp
|
||||||
|
@ -58,14 +58,14 @@ class NotificationFactory @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmName("toNotificationsSimpleNotifiableEvent")
|
@JvmName("toNotificationsSimpleNotifiableEvent")
|
||||||
fun Map<String, SimpleNotifiableEvent?>.toNotifications(myUserId: String): List<OneShotNotification> {
|
fun List<Pair<Processed, SimpleNotifiableEvent>>.toNotifications(myUserId: String): List<OneShotNotification> {
|
||||||
return map { (eventId, event) ->
|
return map { (processed, event) ->
|
||||||
when (event) {
|
when (processed) {
|
||||||
null -> OneShotNotification.Removed(key = eventId)
|
Processed.REMOVE -> OneShotNotification.Removed(key = event.eventId)
|
||||||
else -> OneShotNotification.Append(
|
Processed.KEEP -> OneShotNotification.Append(
|
||||||
notificationUtils.buildSimpleEventNotification(event, myUserId),
|
notificationUtils.buildSimpleEventNotification(event, myUserId),
|
||||||
OneShotNotification.Append.Meta(
|
OneShotNotification.Append.Meta(
|
||||||
key = eventId,
|
key = event.eventId,
|
||||||
summaryLine = event.description,
|
summaryLine = event.description,
|
||||||
isNoisy = event.noisy,
|
isNoisy = event.noisy,
|
||||||
timestamp = event.timestamp
|
timestamp = event.timestamp
|
||||||
|
|
|
@ -34,7 +34,7 @@ class NotificationRenderer @Inject constructor(private val notificationDisplayer
|
||||||
myUserDisplayName: String,
|
myUserDisplayName: String,
|
||||||
myUserAvatarUrl: String?,
|
myUserAvatarUrl: String?,
|
||||||
useCompleteNotificationFormat: Boolean,
|
useCompleteNotificationFormat: Boolean,
|
||||||
eventsToProcess: Map<String, NotifiableEvent?>) {
|
eventsToProcess: List<Pair<Processed, NotifiableEvent>>) {
|
||||||
val (roomEvents, simpleEvents, invitationEvents) = eventsToProcess.groupByType()
|
val (roomEvents, simpleEvents, invitationEvents) = eventsToProcess.groupByType()
|
||||||
with(notificationFactory) {
|
with(notificationFactory) {
|
||||||
val roomNotifications = roomEvents.toNotifications(myUserDisplayName, myUserAvatarUrl)
|
val roomNotifications = roomEvents.toNotifications(myUserDisplayName, myUserAvatarUrl)
|
||||||
|
@ -108,25 +108,28 @@ class NotificationRenderer @Inject constructor(private val notificationDisplayer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Map<String, NotifiableEvent?>.groupByType(): GroupedNotificationEvents {
|
private fun List<Pair<Processed, NotifiableEvent>>.groupByType(): GroupedNotificationEvents {
|
||||||
val roomIdToEventMap: MutableMap<String, MutableList<NotifiableMessageEvent>> = LinkedHashMap()
|
val roomIdToEventMap: MutableMap<String, MutableList<NotifiableMessageEvent>> = LinkedHashMap()
|
||||||
val simpleEvents: MutableMap<String, SimpleNotifiableEvent?> = LinkedHashMap()
|
val simpleEvents: MutableList<Pair<Processed, SimpleNotifiableEvent>> = ArrayList()
|
||||||
val invitationEvents: MutableMap<String, InviteNotifiableEvent?> = LinkedHashMap()
|
val invitationEvents: MutableList<Pair<Processed, InviteNotifiableEvent>> = ArrayList()
|
||||||
forEach { (_, value) ->
|
forEach {
|
||||||
when (value) {
|
when (val event = it.second) {
|
||||||
is InviteNotifiableEvent -> invitationEvents[value.roomId]
|
is InviteNotifiableEvent -> invitationEvents.add(it.asPair())
|
||||||
is NotifiableMessageEvent -> {
|
is NotifiableMessageEvent -> {
|
||||||
val roomEvents = roomIdToEventMap.getOrPut(value.roomId) { ArrayList() }
|
val roomEvents = roomIdToEventMap.getOrPut(event.roomId) { ArrayList() }
|
||||||
roomEvents.add(value)
|
roomEvents.add(event)
|
||||||
}
|
}
|
||||||
is SimpleNotifiableEvent -> simpleEvents[value.eventId] = value
|
is SimpleNotifiableEvent -> simpleEvents.add(it.asPair())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return GroupedNotificationEvents(roomIdToEventMap, simpleEvents, invitationEvents)
|
return GroupedNotificationEvents(roomIdToEventMap, simpleEvents, invitationEvents)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
private fun <T: NotifiableEvent> Pair<Processed, *>.asPair(): Pair<Processed, T> = this as Pair<Processed, T>
|
||||||
|
|
||||||
data class GroupedNotificationEvents(
|
data class GroupedNotificationEvents(
|
||||||
val roomEvents: Map<String, List<NotifiableMessageEvent>>,
|
val roomEvents: Map<String, List<NotifiableMessageEvent>>,
|
||||||
val simpleEvents: Map<String, SimpleNotifiableEvent?>,
|
val simpleEvents: List<Pair<Processed, SimpleNotifiableEvent>>,
|
||||||
val invitationEvents: Map<String, InviteNotifiableEvent?>
|
val invitationEvents: List<Pair<Processed, InviteNotifiableEvent>>
|
||||||
)
|
)
|
||||||
|
|
|
@ -37,7 +37,7 @@ class NotifiableEventProcessorTest {
|
||||||
aSimpleNotifiableEvent(eventId = "event-2")
|
aSimpleNotifiableEvent(eventId = "event-2")
|
||||||
)
|
)
|
||||||
|
|
||||||
val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM)
|
val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = renderedEventsList)
|
||||||
|
|
||||||
result shouldBeEqualTo aProcessedNotificationEvents(
|
result shouldBeEqualTo aProcessedNotificationEvents(
|
||||||
simpleEvents = mapOf(
|
simpleEvents = mapOf(
|
||||||
|
@ -56,7 +56,7 @@ class NotifiableEventProcessorTest {
|
||||||
anInviteNotifiableEvent(roomId = "room-2")
|
anInviteNotifiableEvent(roomId = "room-2")
|
||||||
)
|
)
|
||||||
|
|
||||||
val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM)
|
val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = renderedEventsList)
|
||||||
|
|
||||||
result shouldBeEqualTo aProcessedNotificationEvents(
|
result shouldBeEqualTo aProcessedNotificationEvents(
|
||||||
invitationEvents = mapOf(
|
invitationEvents = mapOf(
|
||||||
|
@ -75,7 +75,7 @@ class NotifiableEventProcessorTest {
|
||||||
anInviteNotifiableEvent(roomId = "room-2")
|
anInviteNotifiableEvent(roomId = "room-2")
|
||||||
)
|
)
|
||||||
|
|
||||||
val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM)
|
val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = renderedEventsList)
|
||||||
|
|
||||||
result shouldBeEqualTo aProcessedNotificationEvents(
|
result shouldBeEqualTo aProcessedNotificationEvents(
|
||||||
invitationEvents = mapOf(
|
invitationEvents = mapOf(
|
||||||
|
@ -91,7 +91,7 @@ class NotifiableEventProcessorTest {
|
||||||
val (events) = createEventsList(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1"))
|
val (events) = createEventsList(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1"))
|
||||||
outdatedDetector.givenEventIsOutOfDate(events[0])
|
outdatedDetector.givenEventIsOutOfDate(events[0])
|
||||||
|
|
||||||
val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM)
|
val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = renderedEventsList)
|
||||||
|
|
||||||
result shouldBeEqualTo aProcessedNotificationEvents(
|
result shouldBeEqualTo aProcessedNotificationEvents(
|
||||||
roomEvents = mapOf(
|
roomEvents = mapOf(
|
||||||
|
@ -106,7 +106,7 @@ class NotifiableEventProcessorTest {
|
||||||
val (events, originalEvents) = createEventsList(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1"))
|
val (events, originalEvents) = createEventsList(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1"))
|
||||||
outdatedDetector.givenEventIsInDate(events[0])
|
outdatedDetector.givenEventIsInDate(events[0])
|
||||||
|
|
||||||
val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM)
|
val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = renderedEventsList)
|
||||||
|
|
||||||
result shouldBeEqualTo aProcessedNotificationEvents(
|
result shouldBeEqualTo aProcessedNotificationEvents(
|
||||||
roomEvents = mapOf(
|
roomEvents = mapOf(
|
||||||
|
@ -120,7 +120,7 @@ class NotifiableEventProcessorTest {
|
||||||
fun `given viewing the same room as message event when processing then removes message`() {
|
fun `given viewing the same room as message event when processing then removes message`() {
|
||||||
val (events) = createEventsList(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1"))
|
val (events) = createEventsList(aNotifiableMessageEvent(eventId = "event-1", roomId = "room-1"))
|
||||||
|
|
||||||
val result = eventProcessor.process(events, currentRoomId = "room-1")
|
val result = eventProcessor.process(events, currentRoomId = "room-1", renderedEventsList = renderedEventsList)
|
||||||
|
|
||||||
result shouldBeEqualTo aProcessedNotificationEvents(
|
result shouldBeEqualTo aProcessedNotificationEvents(
|
||||||
roomEvents = mapOf(
|
roomEvents = mapOf(
|
||||||
|
|
Loading…
Add table
Reference in a new issue