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 ff3e09ed056..fdffad30499 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 @@ -36,6 +36,7 @@ import io.element.android.libraries.matrix.api.media.isPreviewEnabled import io.element.android.libraries.matrix.api.notification.NotificationContent import io.element.android.libraries.matrix.api.notification.NotificationData import io.element.android.libraries.matrix.api.permalink.PermalinkParser +import io.element.android.libraries.matrix.api.room.RoomMembershipState import io.element.android.libraries.matrix.api.room.join.JoinRule import io.element.android.libraries.matrix.api.timeline.item.event.AudioMessageType import io.element.android.libraries.matrix.api.timeline.item.event.EmoteMessageType @@ -319,6 +320,29 @@ class DefaultNotifiableEventResolver( Timber.tag(loggerTag.value).d("Ignoring notification for sticker") throw NotificationResolverException.EventFilteredOut } + is NotificationContent.StateEvent.RoomMemberContent -> { + // MSC4506: the homeserver pushes knocks to users who can act on them. + if (content.membershipState == RoomMembershipState.KNOCK) { + val notifiableMessageEvent = buildNotifiableMessageEvent( + sessionId = userId, + senderId = content.userId, + roomId = roomId, + eventId = eventId, + noisy = isNoisy, + timestamp = this.timestamp, + senderDisambiguatedDisplayName = getDisambiguatedDisplayName(content.userId), + body = stringProvider.getString(R.string.notification_knock_request_body), + roomName = roomDisplayName, + roomIsDm = isDm, + roomAvatarPath = roomAvatarUrl, + senderAvatarPath = senderAvatarUrl, + ) + ResolvedPushEvent.Event(notifiableMessageEvent) + } else { + Timber.tag(loggerTag.value).d("Ignoring notification for membership ${content.membershipState}") + throw NotificationResolverException.EventFilteredOut + } + } NotificationContent.MessageLike.Beacon -> { Timber.tag(loggerTag.value).d("Ignoring notification for beacon") throw NotificationResolverException.EventFilteredOut @@ -341,7 +365,6 @@ class DefaultNotifiableEventResolver( ) ResolvedPushEvent.Event(notifiableEventMessage) } - is NotificationContent.StateEvent.RoomMemberContent, NotificationContent.StateEvent.PolicyRuleRoom, NotificationContent.StateEvent.PolicyRuleServer, NotificationContent.StateEvent.PolicyRuleUser, diff --git a/libraries/push/impl/src/main/res/values/temporary.xml b/libraries/push/impl/src/main/res/values/temporary.xml new file mode 100644 index 00000000000..494f2ee441d --- /dev/null +++ b/libraries/push/impl/src/main/res/values/temporary.xml @@ -0,0 +1,11 @@ + + + + + "Requested to join" + 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 4617c190a51..24e88e72d22 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 @@ -652,6 +652,28 @@ class DefaultNotifiableEventResolverTest : RobolectricTest() { assertThat(result.getEvent(request)).isEqualTo(Result.success(expectedResult)) } + @Test + fun `resolve RoomMemberContent knock`() = runTest { + val sut = createDefaultNotifiableEventResolver( + notificationResult = Result.success( + mapOf( + AN_EVENT_ID to Result.success(aNotificationData( + content = NotificationContent.StateEvent.RoomMemberContent( + userId = A_USER_ID_2, + membershipState = RoomMembershipState.KNOCK + ) + )) + ) + ) + ) + val request = aPushRequest(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID, "firebase") + val result = sut.resolveEvents(A_SESSION_ID, listOf(request)) + val expectedResult = ResolvedPushEvent.Event( + aNotifiableMessageEvent(body = "Requested to join") + ) + assertThat(result.getEvent(request)).isEqualTo(Result.success(expectedResult)) + } + @Test fun `resolve RoomMemberContent other`() = runTest { val sut = createDefaultNotifiableEventResolver(