From a27e31b01b523f6bf839af1a880841b75abc211a Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 4 Dec 2025 12:25:30 +0100 Subject: [PATCH] change(notification): handle invite notification for spaces --- .../api/notification/NotificationData.kt | 1 + .../impl/notification/NotificationMapper.kt | 1 + .../test/notification/NotificationData.kt | 2 + .../DefaultNotifiableEventResolver.kt | 23 ++++++++--- .../impl/src/main/res/values/localazy.xml | 2 + .../DefaultNotifiableEventResolverTest.kt | 40 +++++++++++++++++++ 6 files changed, 63 insertions(+), 6 deletions(-) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notification/NotificationData.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notification/NotificationData.kt index 40ec310c34..aff3092549 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notification/NotificationData.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notification/NotificationData.kt @@ -30,6 +30,7 @@ data class NotificationData( val roomDisplayName: String?, val isDirect: Boolean, val isDm: Boolean, + val isSpace: Boolean, val isEncrypted: Boolean, val isNoisy: Boolean, val timestamp: Long, diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/NotificationMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/NotificationMapper.kt index 8e33117cc7..511c899fdb 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/NotificationMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/NotificationMapper.kt @@ -53,6 +53,7 @@ class NotificationMapper( roomDisplayName = item.roomInfo.displayName, isDirect = item.roomInfo.isDirect, isDm = isDm, + isSpace = item.roomInfo.isSpace, isEncrypted = item.roomInfo.isEncrypted.orFalse(), isNoisy = item.isNoisy.orFalse(), timestamp = timestamp, diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notification/NotificationData.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notification/NotificationData.kt index 3eb0758b1b..b6b6cb66e9 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notification/NotificationData.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notification/NotificationData.kt @@ -21,6 +21,7 @@ import io.element.android.libraries.matrix.test.A_USER_NAME_2 fun aNotificationData( content: NotificationContent = NotificationContent.MessageLike.RoomEncrypted, isDirect: Boolean = false, + isSpace: Boolean = false, hasMention: Boolean = false, threadId: ThreadId? = null, timestamp: Long = A_TIMESTAMP, @@ -40,6 +41,7 @@ fun aNotificationData( roomDisplayName = roomDisplayName, isDirect = isDirect, isDm = false, + isSpace = isSpace, isEncrypted = false, isNoisy = false, timestamp = timestamp, diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt index 3b39815947..763747d7ce 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolver.kt @@ -183,7 +183,11 @@ class DefaultNotifiableEventResolver( soundName = null, isRedacted = false, isUpdated = false, - description = descriptionFromRoomMembershipInvite(senderDisambiguatedDisplayName, isDirect), + description = descriptionFromRoomMembershipInvite( + senderDisambiguatedDisplayName = senderDisambiguatedDisplayName, + isDirectRoom = isDirect, + isSpace = isSpace + ), // TODO check if type is needed anymore type = null, // TODO check if title is needed anymore @@ -332,12 +336,19 @@ class DefaultNotifiableEventResolver( private fun descriptionFromRoomMembershipInvite( senderDisambiguatedDisplayName: String, - isDirectRoom: Boolean + isDirectRoom: Boolean, + isSpace: Boolean, ): String { - return if (isDirectRoom) { - stringProvider.getString(R.string.notification_invite_body_with_sender, senderDisambiguatedDisplayName) - } else { - stringProvider.getString(R.string.notification_room_invite_body_with_sender, senderDisambiguatedDisplayName) + return when { + isDirectRoom -> { + stringProvider.getString(R.string.notification_invite_body_with_sender, senderDisambiguatedDisplayName) + } + isSpace -> { + stringProvider.getString(R.string.notification_space_invite_body_with_sender, senderDisambiguatedDisplayName) + } + else -> { + stringProvider.getString(R.string.notification_room_invite_body_with_sender, senderDisambiguatedDisplayName) + } } } diff --git a/libraries/push/impl/src/main/res/values/localazy.xml b/libraries/push/impl/src/main/res/values/localazy.xml index 0764851647..79e50a8e65 100644 --- a/libraries/push/impl/src/main/res/values/localazy.xml +++ b/libraries/push/impl/src/main/res/values/localazy.xml @@ -38,6 +38,8 @@ "%1$s invited you to join the room" "Me" "%1$s mentioned or replied" + "Invited you to join the space" + "%1$s invited you to join the space" "You are viewing the notification! Click me!" "Thread in %1$s" "%1$s: %2$s" diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt index d625c7804b..58f97e55cb 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/DefaultNotifiableEventResolverTest.kt @@ -38,6 +38,7 @@ import io.element.android.libraries.matrix.test.A_REDACTION_REASON import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_ROOM_NAME import io.element.android.libraries.matrix.test.A_SESSION_ID +import io.element.android.libraries.matrix.test.A_SPACE_NAME import io.element.android.libraries.matrix.test.A_TIMESTAMP import io.element.android.libraries.matrix.test.A_USER_ID_2 import io.element.android.libraries.matrix.test.A_USER_NAME_2 @@ -474,6 +475,45 @@ class DefaultNotifiableEventResolverTest { assertThat(result.getEvent(request)).isEqualTo(Result.success(expectedResult)) } + @Test + fun `resolve invite space`() = runTest { + val sut = createDefaultNotifiableEventResolver( + notificationResult = Result.success( + mapOf( + AN_EVENT_ID to Result.success(aNotificationData( + content = NotificationContent.Invite( + senderId = A_USER_ID_2, + ), + roomDisplayName = A_SPACE_NAME, + isDirect = false, + isSpace = true, + )) + ) + ) + ) + val request = NotificationEventRequest(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID, "firebase") + val result = sut.resolveEvents(A_SESSION_ID, listOf(request)) + val expectedResult = ResolvedPushEvent.Event( + InviteNotifiableEvent( + sessionId = A_SESSION_ID, + roomId = A_ROOM_ID, + eventId = AN_EVENT_ID, + editedEventId = null, + canBeReplaced = true, + roomName = A_SPACE_NAME, + noisy = false, + title = null, + description = "Bob invited you to join the space", + type = null, + timestamp = A_TIMESTAMP, + soundName = null, + isRedacted = false, + isUpdated = false, + ) + ) + assertThat(result.getEvent(request)).isEqualTo(Result.success(expectedResult)) + } + @Test fun `resolve invite direct`() = runTest { val sut = createDefaultNotifiableEventResolver(