mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-02-07 23:58:40 +01:00
using dedicated ProcessedEvent data class instead of type alias for passing around the process notificatiable events
- also includes @JvmName on all conflicting extensions for consistency
This commit is contained in:
parent
d3234b33d3
commit
d1f6db4236
@ -17,29 +17,32 @@
|
||||
package im.vector.app.features.notifications
|
||||
|
||||
import im.vector.app.features.invite.AutoAcceptInvites
|
||||
import im.vector.app.features.notifications.ProcessedType.KEEP
|
||||
import im.vector.app.features.notifications.ProcessedType.REMOVE
|
||||
import im.vector.app.features.notifications.ProcessedEvent.Type.KEEP
|
||||
import im.vector.app.features.notifications.ProcessedEvent.Type.REMOVE
|
||||
import javax.inject.Inject
|
||||
|
||||
private typealias ProcessedEvents = List<ProcessedEvent<NotifiableEvent>>
|
||||
|
||||
class NotifiableEventProcessor @Inject constructor(
|
||||
private val outdatedDetector: OutdatedEventDetector,
|
||||
private val autoAcceptInvites: AutoAcceptInvites
|
||||
) {
|
||||
|
||||
fun process(eventList: List<NotifiableEvent>, currentRoomId: String?, renderedEventsList: List<ProcessedEvent>): List<ProcessedEvent> {
|
||||
fun process(eventList: List<NotifiableEvent>, currentRoomId: String?, renderedEventsList: ProcessedEvents): ProcessedEvents {
|
||||
val processedEventList = eventList.map {
|
||||
when (it) {
|
||||
val type = when (it) {
|
||||
is InviteNotifiableEvent -> if (autoAcceptInvites.hideInvites) REMOVE else KEEP
|
||||
is NotifiableMessageEvent -> if (shouldIgnoreMessageEventInRoom(currentRoomId, it.roomId) || outdatedDetector.isMessageOutdated(it)) {
|
||||
REMOVE
|
||||
} else KEEP
|
||||
is SimpleNotifiableEvent -> KEEP
|
||||
} to it
|
||||
}
|
||||
ProcessedEvent(type, it)
|
||||
}
|
||||
|
||||
val removedEventsDiff = renderedEventsList.filter { renderedEvent ->
|
||||
eventList.none { it.eventId == renderedEvent.second.eventId }
|
||||
}.map { REMOVE to it.second }
|
||||
eventList.none { it.eventId == renderedEvent.event.eventId }
|
||||
}.map { ProcessedEvent(REMOVE, it.event) }
|
||||
|
||||
return removedEventsDiff + processedEventList
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ class NotificationDrawerManager @Inject constructor(private val context: Context
|
||||
* we keep track of them in order to know which events have been removed from the eventList
|
||||
* allowing us to cancel any notifications previous displayed by now removed events
|
||||
*/
|
||||
private var renderedEventsList = emptyList<Pair<ProcessedType, NotifiableEvent>>()
|
||||
private var renderedEventsList = emptyList<ProcessedEvent<NotifiableEvent>>()
|
||||
private val avatarSize = context.resources.getDimensionPixelSize(R.dimen.profile_avatar_size)
|
||||
private var currentRoomId: String? = null
|
||||
|
||||
|
@ -20,7 +20,7 @@ import android.app.Notification
|
||||
import androidx.core.content.pm.ShortcutInfoCompat
|
||||
import javax.inject.Inject
|
||||
|
||||
private typealias ProcessedMessageEvent = Pair<ProcessedType, NotifiableMessageEvent>
|
||||
private typealias ProcessedMessageEvents = List<ProcessedEvent<NotifiableMessageEvent>>
|
||||
|
||||
class NotificationFactory @Inject constructor(
|
||||
private val notificationUtils: NotificationUtils,
|
||||
@ -28,29 +28,30 @@ class NotificationFactory @Inject constructor(
|
||||
private val summaryGroupMessageCreator: SummaryGroupMessageCreator
|
||||
) {
|
||||
|
||||
fun Map<String, List<ProcessedMessageEvent>>.toNotifications(myUserDisplayName: String, myUserAvatarUrl: String?): List<RoomNotification> {
|
||||
fun Map<String, ProcessedMessageEvents>.toNotifications(myUserDisplayName: String, myUserAvatarUrl: String?): List<RoomNotification> {
|
||||
return map { (roomId, events) ->
|
||||
when {
|
||||
events.hasNoEventsToDisplay() -> RoomNotification.Removed(roomId)
|
||||
else -> {
|
||||
val messageEvents = events.filter { it.first == ProcessedType.KEEP }.map { it.second }
|
||||
val messageEvents = events.onlyKeptEvents()
|
||||
roomGroupMessageCreator.createRoomMessage(messageEvents, roomId, myUserDisplayName, myUserAvatarUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun List<Pair<ProcessedType, NotifiableMessageEvent>>.hasNoEventsToDisplay() = isEmpty() || all {
|
||||
it.first == ProcessedType.REMOVE || it.second.canNotBeDisplayed()
|
||||
private fun ProcessedMessageEvents.hasNoEventsToDisplay() = isEmpty() || all {
|
||||
it.type == ProcessedEvent.Type.REMOVE || it.event.canNotBeDisplayed()
|
||||
}
|
||||
|
||||
private fun NotifiableMessageEvent.canNotBeDisplayed() = isRedacted
|
||||
|
||||
fun List<Pair<ProcessedType, InviteNotifiableEvent>>.toNotifications(myUserId: String): List<OneShotNotification> {
|
||||
@JvmName("toNotificationsInviteNotifiableEvent")
|
||||
fun List<ProcessedEvent<InviteNotifiableEvent>>.toNotifications(myUserId: String): List<OneShotNotification> {
|
||||
return map { (processed, event) ->
|
||||
when (processed) {
|
||||
ProcessedType.REMOVE -> OneShotNotification.Removed(key = event.roomId)
|
||||
ProcessedType.KEEP -> OneShotNotification.Append(
|
||||
ProcessedEvent.Type.REMOVE -> OneShotNotification.Removed(key = event.roomId)
|
||||
ProcessedEvent.Type.KEEP -> OneShotNotification.Append(
|
||||
notificationUtils.buildRoomInvitationNotification(event, myUserId),
|
||||
OneShotNotification.Append.Meta(
|
||||
key = event.roomId,
|
||||
@ -64,11 +65,11 @@ class NotificationFactory @Inject constructor(
|
||||
}
|
||||
|
||||
@JvmName("toNotificationsSimpleNotifiableEvent")
|
||||
fun List<Pair<ProcessedType, SimpleNotifiableEvent>>.toNotifications(myUserId: String): List<OneShotNotification> {
|
||||
fun List<ProcessedEvent<SimpleNotifiableEvent>>.toNotifications(myUserId: String): List<OneShotNotification> {
|
||||
return map { (processed, event) ->
|
||||
when (processed) {
|
||||
ProcessedType.REMOVE -> OneShotNotification.Removed(key = event.eventId)
|
||||
ProcessedType.KEEP -> OneShotNotification.Append(
|
||||
ProcessedEvent.Type.REMOVE -> OneShotNotification.Removed(key = event.eventId)
|
||||
ProcessedEvent.Type.KEEP -> OneShotNotification.Append(
|
||||
notificationUtils.buildSimpleEventNotification(event, myUserId),
|
||||
OneShotNotification.Append.Meta(
|
||||
key = event.eventId,
|
||||
|
@ -34,7 +34,7 @@ class NotificationRenderer @Inject constructor(private val notificationDisplayer
|
||||
myUserDisplayName: String,
|
||||
myUserAvatarUrl: String?,
|
||||
useCompleteNotificationFormat: Boolean,
|
||||
eventsToProcess: List<ProcessedEvent>) {
|
||||
eventsToProcess: List<ProcessedEvent<NotifiableEvent>>) {
|
||||
val (roomEvents, simpleEvents, invitationEvents) = eventsToProcess.groupByType()
|
||||
with(notificationFactory) {
|
||||
val roomNotifications = roomEvents.toNotifications(myUserDisplayName, myUserAvatarUrl)
|
||||
@ -108,28 +108,28 @@ class NotificationRenderer @Inject constructor(private val notificationDisplayer
|
||||
}
|
||||
}
|
||||
|
||||
private fun List<ProcessedEvent>.groupByType(): GroupedNotificationEvents {
|
||||
val roomIdToEventMap: MutableMap<String, MutableList<Pair<ProcessedType, NotifiableMessageEvent>>> = LinkedHashMap()
|
||||
val simpleEvents: MutableList<Pair<ProcessedType, SimpleNotifiableEvent>> = ArrayList()
|
||||
val invitationEvents: MutableList<Pair<ProcessedType, InviteNotifiableEvent>> = ArrayList()
|
||||
private fun List<ProcessedEvent<NotifiableEvent>>.groupByType(): GroupedNotificationEvents {
|
||||
val roomIdToEventMap: MutableMap<String, MutableList<ProcessedEvent<NotifiableMessageEvent>>> = LinkedHashMap()
|
||||
val simpleEvents: MutableList<ProcessedEvent<SimpleNotifiableEvent>> = ArrayList()
|
||||
val invitationEvents: MutableList<ProcessedEvent<InviteNotifiableEvent>> = ArrayList()
|
||||
forEach {
|
||||
when (val event = it.second) {
|
||||
is InviteNotifiableEvent -> invitationEvents.add(it.asPair())
|
||||
when (val event = it.event) {
|
||||
is InviteNotifiableEvent -> invitationEvents.add(it.castedToEventType())
|
||||
is NotifiableMessageEvent -> {
|
||||
val roomEvents = roomIdToEventMap.getOrPut(event.roomId) { ArrayList() }
|
||||
roomEvents.add(it.asPair())
|
||||
roomEvents.add(it.castedToEventType())
|
||||
}
|
||||
is SimpleNotifiableEvent -> simpleEvents.add(it.asPair())
|
||||
is SimpleNotifiableEvent -> simpleEvents.add(it.castedToEventType())
|
||||
}
|
||||
}
|
||||
return GroupedNotificationEvents(roomIdToEventMap, simpleEvents, invitationEvents)
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun <T : NotifiableEvent> Pair<ProcessedType, *>.asPair(): Pair<ProcessedType, T> = this as Pair<ProcessedType, T>
|
||||
private fun <T : NotifiableEvent> ProcessedEvent<NotifiableEvent>.castedToEventType(): ProcessedEvent<T> = this as ProcessedEvent<T>
|
||||
|
||||
data class GroupedNotificationEvents(
|
||||
val roomEvents: Map<String, List<Pair<ProcessedType, NotifiableMessageEvent>>>,
|
||||
val simpleEvents: List<Pair<ProcessedType, SimpleNotifiableEvent>>,
|
||||
val invitationEvents: List<Pair<ProcessedType, InviteNotifiableEvent>>
|
||||
val roomEvents: Map<String, List<ProcessedEvent<NotifiableMessageEvent>>>,
|
||||
val simpleEvents: List<ProcessedEvent<SimpleNotifiableEvent>>,
|
||||
val invitationEvents: List<ProcessedEvent<InviteNotifiableEvent>>
|
||||
)
|
||||
|
@ -16,11 +16,15 @@
|
||||
|
||||
package im.vector.app.features.notifications
|
||||
|
||||
typealias ProcessedEvent = Pair<ProcessedType, NotifiableEvent>
|
||||
data class ProcessedEvent<T>(
|
||||
val type: Type,
|
||||
val event: T
|
||||
) {
|
||||
|
||||
enum class ProcessedType {
|
||||
KEEP,
|
||||
REMOVE
|
||||
enum class Type {
|
||||
KEEP,
|
||||
REMOVE
|
||||
}
|
||||
}
|
||||
|
||||
fun List<ProcessedEvent>.onlyKeptEvents() = filter { it.first == ProcessedType.KEEP }.map { it.second }
|
||||
fun <T> List<ProcessedEvent<T>>.onlyKeptEvents() = filter { it.type == ProcessedEvent.Type.KEEP }.map { it.event }
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package im.vector.app.features.notifications
|
||||
|
||||
import im.vector.app.features.notifications.ProcessedEvent.Type
|
||||
import im.vector.app.test.fakes.FakeAutoAcceptInvites
|
||||
import im.vector.app.test.fakes.FakeOutdatedEventDetector
|
||||
import org.amshove.kluent.shouldBeEqualTo
|
||||
@ -39,9 +40,9 @@ class NotifiableEventProcessorTest {
|
||||
|
||||
val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = emptyList())
|
||||
|
||||
result shouldBeEqualTo listOf(
|
||||
ProcessedType.KEEP to events[0],
|
||||
ProcessedType.KEEP to events[1]
|
||||
result shouldBeEqualTo listOfProcessedEvents(
|
||||
Type.KEEP to events[0],
|
||||
Type.KEEP to events[1]
|
||||
)
|
||||
}
|
||||
|
||||
@ -55,9 +56,9 @@ class NotifiableEventProcessorTest {
|
||||
|
||||
val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = emptyList())
|
||||
|
||||
result shouldBeEqualTo listOf(
|
||||
ProcessedType.REMOVE to events[0],
|
||||
ProcessedType.REMOVE to events[1]
|
||||
result shouldBeEqualTo listOfProcessedEvents(
|
||||
Type.REMOVE to events[0],
|
||||
Type.REMOVE to events[1]
|
||||
)
|
||||
}
|
||||
|
||||
@ -71,9 +72,9 @@ class NotifiableEventProcessorTest {
|
||||
|
||||
val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = emptyList())
|
||||
|
||||
result shouldBeEqualTo listOf(
|
||||
ProcessedType.KEEP to events[0],
|
||||
ProcessedType.KEEP to events[1]
|
||||
result shouldBeEqualTo listOfProcessedEvents(
|
||||
Type.KEEP to events[0],
|
||||
Type.KEEP to events[1]
|
||||
)
|
||||
}
|
||||
|
||||
@ -84,8 +85,8 @@ class NotifiableEventProcessorTest {
|
||||
|
||||
val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = emptyList())
|
||||
|
||||
result shouldBeEqualTo listOf(
|
||||
ProcessedType.REMOVE to events[0],
|
||||
result shouldBeEqualTo listOfProcessedEvents(
|
||||
Type.REMOVE to events[0],
|
||||
)
|
||||
}
|
||||
|
||||
@ -96,8 +97,8 @@ class NotifiableEventProcessorTest {
|
||||
|
||||
val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = emptyList())
|
||||
|
||||
result shouldBeEqualTo listOf(
|
||||
ProcessedType.KEEP to events[0],
|
||||
result shouldBeEqualTo listOfProcessedEvents(
|
||||
Type.KEEP to events[0],
|
||||
)
|
||||
}
|
||||
|
||||
@ -107,26 +108,30 @@ class NotifiableEventProcessorTest {
|
||||
|
||||
val result = eventProcessor.process(events, currentRoomId = "room-1", renderedEventsList = emptyList())
|
||||
|
||||
result shouldBeEqualTo listOf(
|
||||
ProcessedType.REMOVE to events[0],
|
||||
result shouldBeEqualTo listOfProcessedEvents(
|
||||
Type.REMOVE to events[0],
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given events are different to rendered events when processing then removes difference`() {
|
||||
val events = listOf(aSimpleNotifiableEvent(eventId = "event-1"))
|
||||
val renderedEvents = listOf(
|
||||
ProcessedType.KEEP to events[0],
|
||||
ProcessedType.KEEP to anInviteNotifiableEvent(roomId = "event-2")
|
||||
val renderedEvents = listOf<ProcessedEvent<NotifiableEvent>>(
|
||||
ProcessedEvent(Type.KEEP, events[0]),
|
||||
ProcessedEvent(Type.KEEP, anInviteNotifiableEvent(roomId = "event-2"))
|
||||
)
|
||||
|
||||
val result = eventProcessor.process(events, currentRoomId = NOT_VIEWING_A_ROOM, renderedEventsList = renderedEvents)
|
||||
|
||||
result shouldBeEqualTo listOf(
|
||||
ProcessedType.REMOVE to renderedEvents[1].second,
|
||||
ProcessedType.KEEP to renderedEvents[0].second
|
||||
result shouldBeEqualTo listOfProcessedEvents(
|
||||
Type.REMOVE to renderedEvents[1].event,
|
||||
Type.KEEP to renderedEvents[0].event
|
||||
)
|
||||
}
|
||||
|
||||
private fun listOfProcessedEvents(vararg event: Pair<Type, NotifiableEvent>) = event.map {
|
||||
ProcessedEvent(it.first, it.second)
|
||||
}
|
||||
}
|
||||
|
||||
fun aSimpleNotifiableEvent(eventId: String) = SimpleNotifiableEvent(
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package im.vector.app.features.notifications
|
||||
|
||||
import im.vector.app.features.notifications.ProcessedEvent.Type
|
||||
import im.vector.app.test.fakes.FakeNotificationUtils
|
||||
import im.vector.app.test.fakes.FakeRoomGroupMessageCreator
|
||||
import im.vector.app.test.fakes.FakeSummaryGroupMessageCreator
|
||||
@ -46,7 +47,7 @@ class NotificationFactoryTest {
|
||||
@Test
|
||||
fun `given a room invitation when mapping to notification then is Append`() = testWith(notificationFactory) {
|
||||
val expectedNotification = notificationUtils.givenBuildRoomInvitationNotificationFor(AN_INVITATION_EVENT, MY_USER_ID)
|
||||
val roomInvitation = listOf(ProcessedType.KEEP to AN_INVITATION_EVENT)
|
||||
val roomInvitation = listOf(ProcessedEvent(Type.KEEP, AN_INVITATION_EVENT))
|
||||
|
||||
val result = roomInvitation.toNotifications(MY_USER_ID)
|
||||
|
||||
@ -63,7 +64,7 @@ class NotificationFactoryTest {
|
||||
|
||||
@Test
|
||||
fun `given a missing event in room invitation when mapping to notification then is Removed`() = testWith(notificationFactory) {
|
||||
val missingEventRoomInvitation = listOf(ProcessedType.REMOVE to AN_INVITATION_EVENT)
|
||||
val missingEventRoomInvitation = listOf(ProcessedEvent(Type.REMOVE, AN_INVITATION_EVENT))
|
||||
|
||||
val result = missingEventRoomInvitation.toNotifications(MY_USER_ID)
|
||||
|
||||
@ -75,7 +76,7 @@ class NotificationFactoryTest {
|
||||
@Test
|
||||
fun `given a simple event when mapping to notification then is Append`() = testWith(notificationFactory) {
|
||||
val expectedNotification = notificationUtils.givenBuildSimpleInvitationNotificationFor(A_SIMPLE_EVENT, MY_USER_ID)
|
||||
val roomInvitation = listOf(ProcessedType.KEEP to A_SIMPLE_EVENT)
|
||||
val roomInvitation = listOf(ProcessedEvent(Type.KEEP, A_SIMPLE_EVENT))
|
||||
|
||||
val result = roomInvitation.toNotifications(MY_USER_ID)
|
||||
|
||||
@ -92,7 +93,7 @@ class NotificationFactoryTest {
|
||||
|
||||
@Test
|
||||
fun `given a missing simple event when mapping to notification then is Removed`() = testWith(notificationFactory) {
|
||||
val missingEventRoomInvitation = listOf(ProcessedType.REMOVE to A_SIMPLE_EVENT)
|
||||
val missingEventRoomInvitation = listOf(ProcessedEvent(Type.REMOVE, A_SIMPLE_EVENT))
|
||||
|
||||
val result = missingEventRoomInvitation.toNotifications(MY_USER_ID)
|
||||
|
||||
@ -105,7 +106,7 @@ class NotificationFactoryTest {
|
||||
fun `given room with message when mapping to notification then delegates to room group message creator`() = testWith(notificationFactory) {
|
||||
val events = listOf(A_MESSAGE_EVENT)
|
||||
val expectedNotification = roomGroupMessageCreator.givenCreatesRoomMessageFor(events, A_ROOM_ID, MY_USER_ID, MY_AVATAR_URL)
|
||||
val roomWithMessage = mapOf(A_ROOM_ID to listOf(ProcessedType.KEEP to A_MESSAGE_EVENT))
|
||||
val roomWithMessage = mapOf(A_ROOM_ID to listOf(ProcessedEvent(Type.KEEP, A_MESSAGE_EVENT)))
|
||||
|
||||
val result = roomWithMessage.toNotifications(MY_USER_ID, MY_AVATAR_URL)
|
||||
|
||||
@ -114,7 +115,7 @@ class NotificationFactoryTest {
|
||||
|
||||
@Test
|
||||
fun `given a room with no events to display when mapping to notification then is Empty`() = testWith(notificationFactory) {
|
||||
val events = listOf(ProcessedType.REMOVE to A_MESSAGE_EVENT)
|
||||
val events = listOf(ProcessedEvent(Type.REMOVE, A_MESSAGE_EVENT))
|
||||
val emptyRoom = mapOf(A_ROOM_ID to events)
|
||||
|
||||
val result = emptyRoom.toNotifications(MY_USER_ID, MY_AVATAR_URL)
|
||||
@ -126,7 +127,7 @@ class NotificationFactoryTest {
|
||||
|
||||
@Test
|
||||
fun `given a room with only redacted events when mapping to notification then is Empty`() = testWith(notificationFactory) {
|
||||
val redactedRoom = mapOf(A_ROOM_ID to listOf(ProcessedType.KEEP to A_MESSAGE_EVENT.copy(isRedacted = true)))
|
||||
val redactedRoom = mapOf(A_ROOM_ID to listOf(ProcessedEvent(Type.KEEP, A_MESSAGE_EVENT.copy(isRedacted = true))))
|
||||
|
||||
val result = redactedRoom.toNotifications(MY_USER_ID, MY_AVATAR_URL)
|
||||
|
||||
|
@ -30,7 +30,7 @@ private const val AN_EVENT_ID = "event-id"
|
||||
private const val A_ROOM_ID = "room-id"
|
||||
private const val USE_COMPLETE_NOTIFICATION_FORMAT = true
|
||||
|
||||
private val AN_EVENT_LIST = listOf<Pair<ProcessedType, NotifiableEvent>>()
|
||||
private val AN_EVENT_LIST = listOf<ProcessedEvent<NotifiableEvent>>()
|
||||
private val A_PROCESSED_EVENTS = GroupedNotificationEvents(emptyMap(), emptyList(), emptyList())
|
||||
private val A_SUMMARY_NOTIFICATION = SummaryNotification.Update(mockk())
|
||||
private val A_REMOVE_SUMMARY_NOTIFICATION = SummaryNotification.Removed
|
||||
|
Loading…
x
Reference in New Issue
Block a user