From b0e5e6cc616a1561aa4e256821f67cc206ada6df Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Sun, 26 Oct 2025 08:49:48 +0100 Subject: [PATCH] NotificationDataFactory: improve API --- .../notifications/NotificationDataFactory.kt | 32 ++++++--------- .../notifications/NotificationRenderer.kt | 16 ++++++-- .../NotificationDataFactoryTest.kt | 41 ++++++------------- .../fake/FakeNotificationDataFactory.kt | 20 ++++----- 4 files changed, 45 insertions(+), 64 deletions(-) diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDataFactory.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDataFactory.kt index 329d34d5f5..25cac5922d 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDataFactory.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDataFactory.kt @@ -28,30 +28,26 @@ import io.element.android.libraries.push.impl.notifications.model.SimpleNotifiab import io.element.android.services.toolbox.api.strings.StringProvider interface NotificationDataFactory { - suspend fun toNotifications( - messages: List, + suspend fun List.toNotifications( imageLoader: ImageLoader, notificationAccountParams: NotificationAccountParams, ): List @JvmName("toNotificationInvites") @Suppress("INAPPLICABLE_JVM_NAME") - fun toNotifications( - invites: List, + fun List.toNotifications( notificationAccountParams: NotificationAccountParams, ): List @JvmName("toNotificationSimpleEvents") @Suppress("INAPPLICABLE_JVM_NAME") - fun toNotifications( - simpleEvents: List, + fun List.toNotifications( notificationAccountParams: NotificationAccountParams, ): List @JvmName("toNotificationFallbackEvents") @Suppress("INAPPLICABLE_JVM_NAME") - fun toNotifications( - fallback: List, + fun List.toNotifications( notificationAccountParams: NotificationAccountParams, ): List @@ -72,12 +68,11 @@ class DefaultNotificationDataFactory( private val activeNotificationsProvider: ActiveNotificationsProvider, private val stringProvider: StringProvider, ) : NotificationDataFactory { - override suspend fun toNotifications( - messages: List, + override suspend fun List.toNotifications( imageLoader: ImageLoader, notificationAccountParams: NotificationAccountParams, ): List { - val messagesToDisplay = messages.filterNot { it.canNotBeDisplayed() } + val messagesToDisplay = filterNot { it.canNotBeDisplayed() } .groupBy { it.roomId } return messagesToDisplay.flatMap { (roomId, events) -> val roomName = events.lastOrNull()?.roomName ?: roomId.value @@ -114,11 +109,10 @@ class DefaultNotificationDataFactory( @JvmName("toNotificationInvites") @Suppress("INAPPLICABLE_JVM_NAME") - override fun toNotifications( - invites: List, + override fun List.toNotifications( notificationAccountParams: NotificationAccountParams, ): List { - return invites.map { event -> + return map { event -> OneShotNotification( key = event.roomId.value, notification = notificationCreator.createRoomInvitationNotification(notificationAccountParams, event), @@ -131,11 +125,10 @@ class DefaultNotificationDataFactory( @JvmName("toNotificationSimpleEvents") @Suppress("INAPPLICABLE_JVM_NAME") - override fun toNotifications( - simpleEvents: List, + override fun List.toNotifications( notificationAccountParams: NotificationAccountParams, ): List { - return simpleEvents.map { event -> + return map { event -> OneShotNotification( key = event.eventId.value, notification = notificationCreator.createSimpleEventNotification(notificationAccountParams, event), @@ -148,11 +141,10 @@ class DefaultNotificationDataFactory( @JvmName("toNotificationFallbackEvents") @Suppress("INAPPLICABLE_JVM_NAME") - override fun toNotifications( - fallback: List, + override fun List.toNotifications( notificationAccountParams: NotificationAccountParams, ): List { - return fallback.map { event -> + return map { event -> OneShotNotification( key = event.eventId.value, notification = notificationCreator.createFallbackNotification(notificationAccountParams, event), diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationRenderer.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationRenderer.kt index 05b72b0bcd..4d6e588726 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationRenderer.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotificationRenderer.kt @@ -51,10 +51,18 @@ class NotificationRenderer( showSessionId = numberOfAccounts > 1, ) val groupedEvents = eventsToProcess.groupByType() - val roomNotifications = notificationDataFactory.toNotifications(groupedEvents.roomEvents, imageLoader, notificationAccountParams) - val invitationNotifications = notificationDataFactory.toNotifications(groupedEvents.invitationEvents, notificationAccountParams) - val simpleNotifications = notificationDataFactory.toNotifications(groupedEvents.simpleEvents, notificationAccountParams) - val fallbackNotifications = notificationDataFactory.toNotifications(groupedEvents.fallbackEvents, notificationAccountParams) + val roomNotifications = with(notificationDataFactory) { + groupedEvents.roomEvents.toNotifications(imageLoader, notificationAccountParams) + } + val invitationNotifications = with(notificationDataFactory) { + groupedEvents.invitationEvents.toNotifications(notificationAccountParams) + } + val simpleNotifications = with(notificationDataFactory) { + groupedEvents.simpleEvents.toNotifications(notificationAccountParams) + } + val fallbackNotifications = with(notificationDataFactory) { + groupedEvents.fallbackEvents.toNotifications(notificationAccountParams) + } val summaryNotification = notificationDataFactory.createSummaryNotification( roomNotifications = roomNotifications, invitationNotifications = invitationNotifications, diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDataFactoryTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDataFactoryTest.kt index 2b11ce949b..c8a7e6ba33 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDataFactoryTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/NotificationDataFactoryTest.kt @@ -55,10 +55,7 @@ class NotificationDataFactoryTest { aNotificationAccountParams(), AN_INVITATION_EVENT, ) - val roomInvitation = listOf(AN_INVITATION_EVENT) - - val result = toNotifications(roomInvitation, aNotificationAccountParams()) - + val result = listOf(AN_INVITATION_EVENT).toNotifications(aNotificationAccountParams()) assertThat(result).isEqualTo( listOf( OneShotNotification( @@ -78,19 +75,14 @@ class NotificationDataFactoryTest { aNotificationAccountParams(), AN_INVITATION_EVENT, ) - val roomInvitation = listOf(A_SIMPLE_EVENT) - - val result = toNotifications(roomInvitation, aNotificationAccountParams()) - - assertThat(result).isEqualTo( - listOf( - OneShotNotification( - notification = expectedNotification, - key = AN_EVENT_ID.value, - summaryLine = A_SIMPLE_EVENT.description, - isNoisy = A_SIMPLE_EVENT.noisy, - timestamp = AN_INVITATION_EVENT.timestamp - ) + val result = listOf(A_SIMPLE_EVENT).toNotifications(aNotificationAccountParams()) + assertThat(result).containsExactly( + OneShotNotification( + notification = expectedNotification, + key = AN_EVENT_ID.value, + summaryLine = A_SIMPLE_EVENT.description, + isNoisy = A_SIMPLE_EVENT.noisy, + timestamp = AN_INVITATION_EVENT.timestamp ) ) } @@ -116,14 +108,11 @@ class NotificationDataFactoryTest { shouldBing = events.any { it.noisy }, threadId = null, ) - val roomWithMessage = listOf(A_MESSAGE_EVENT) - val fakeImageLoader = FakeImageLoader() - val result = toNotifications( + val result = listOf(A_MESSAGE_EVENT).toNotifications( notificationAccountParams = aNotificationAccountParams( user = MatrixUser(A_SESSION_ID, A_SESSION_ID.value, MY_AVATAR_URL), ), - messages = roomWithMessage, imageLoader = fakeImageLoader.getImageLoader(), ) @@ -134,17 +123,14 @@ class NotificationDataFactoryTest { @Test fun `given a room with only redacted events when mapping to notification then is Empty`() = testWith(notificationDataFactory) { - val redactedRoom = listOf(A_MESSAGE_EVENT.copy(isRedacted = true)) - + val redactedRoom = A_MESSAGE_EVENT.copy(isRedacted = true) val fakeImageLoader = FakeImageLoader() - val result = toNotifications( + val result = listOf(redactedRoom).toNotifications( notificationAccountParams = aNotificationAccountParams( user = MatrixUser(A_SESSION_ID, A_SESSION_ID.value, MY_AVATAR_URL), ), - messages = redactedRoom, imageLoader = fakeImageLoader.getImageLoader(), ) - assertThat(result).isEmpty() assertThat(fakeImageLoader.getCoilRequests().size).isEqualTo(0) } @@ -178,11 +164,10 @@ class NotificationDataFactoryTest { ) val fakeImageLoader = FakeImageLoader() - val result = toNotifications( + val result = roomWithRedactedMessage.toNotifications( notificationAccountParams = aNotificationAccountParams( user = MatrixUser(A_SESSION_ID, A_SESSION_ID.value, MY_AVATAR_URL), ), - messages = roomWithRedactedMessage, imageLoader = fakeImageLoader.getImageLoader(), ) diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/fake/FakeNotificationDataFactory.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/fake/FakeNotificationDataFactory.kt index a897dbfc09..89326f5ad9 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/fake/FakeNotificationDataFactory.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/fake/FakeNotificationDataFactory.kt @@ -40,39 +40,35 @@ class FakeNotificationDataFactory( var fallbackEventToNotificationsResult: LambdaOneParamRecorder, List> = lambdaRecorder { _ -> emptyList() }, ) : NotificationDataFactory { - override suspend fun toNotifications( - messages: List, + override suspend fun List.toNotifications( imageLoader: ImageLoader, notificationAccountParams: NotificationAccountParams, ): List { - return messageEventToNotificationsResult(messages, imageLoader, notificationAccountParams) + return messageEventToNotificationsResult(this, imageLoader, notificationAccountParams) } @JvmName("toNotificationInvites") @Suppress("INAPPLICABLE_JVM_NAME") - override fun toNotifications( - invites: List, + override fun List.toNotifications( notificationAccountParams: NotificationAccountParams, ): List { - return inviteToNotificationsResult(invites) + return inviteToNotificationsResult(this) } @JvmName("toNotificationSimpleEvents") @Suppress("INAPPLICABLE_JVM_NAME") - override fun toNotifications( - simpleEvents: List, + override fun List.toNotifications( notificationAccountParams: NotificationAccountParams, ): List { - return simpleEventToNotificationsResult(simpleEvents) + return simpleEventToNotificationsResult(this) } @JvmName("toNotificationFallbackEvents") @Suppress("INAPPLICABLE_JVM_NAME") - override fun toNotifications( - fallback: List, + override fun List.toNotifications( notificationAccountParams: NotificationAccountParams, ): List { - return fallbackEventToNotificationsResult(fallback) + return fallbackEventToNotificationsResult(this) } override fun createSummaryNotification(