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 991f8dd117..60d889d046 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 @@ -20,15 +20,25 @@ import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.UserId -//TODO add content data class NotificationData( val senderId: UserId, val eventId: EventId, val roomId: RoomId, - val senderAvatarUrl: String? = null, - val senderDisplayName: String? = null, - val roomAvatarUrl: String? = null, + val senderAvatarUrl: String?, + val senderDisplayName: String?, + val roomAvatarUrl: String?, + val roomDisplayName: String?, val isDirect: Boolean, val isEncrypted: Boolean, val isNoisy: Boolean, + val event: NotificationEvent, +) + +data class NotificationEvent( + val eventId: EventId, + val senderId: UserId, + val timestamp: Long, + val content: String, + // For images for instance + val contentUrl: String? ) 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 4b121db9bf..e6125cf69b 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 @@ -23,9 +23,9 @@ import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.notification.NotificationData import org.matrix.rustcomponents.sdk.NotificationItem import org.matrix.rustcomponents.sdk.use -import javax.inject.Inject -class NotificationMapper @Inject constructor() { +class NotificationMapper { + private val timelineEventMapper = TimelineEventMapper() fun map(notificationItem: NotificationItem): NotificationData { return notificationItem.use { @@ -36,9 +36,11 @@ class NotificationMapper @Inject constructor() { senderAvatarUrl = it.senderAvatarUrl, senderDisplayName = it.senderDisplayName, roomAvatarUrl = it.roomAvatarUrl, + roomDisplayName = it.roomDisplayName, isDirect = it.isDirect, isEncrypted = it.isEncrypted.orFalse(), - isNoisy = it.isNoisy + isNoisy = it.isNoisy, + event = it.event.use { event -> timelineEventMapper.map(event) } ) } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationService.kt index bd94de21fc..8b630cd64a 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/RustNotificationService.kt @@ -16,18 +16,13 @@ package io.element.android.libraries.matrix.impl.notification -import io.element.android.libraries.core.coroutine.CoroutineDispatchers -import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.SessionId -import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.notification.NotificationData import io.element.android.libraries.matrix.api.notification.NotificationService -import kotlinx.coroutines.withContext import org.matrix.rustcomponents.sdk.Client import org.matrix.rustcomponents.sdk.use -import java.io.File class RustNotificationService( private val client: Client, diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/TimelineEventMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/TimelineEventMapper.kt new file mode 100644 index 0000000000..3d2759c6d1 --- /dev/null +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notification/TimelineEventMapper.kt @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.matrix.impl.notification + +import io.element.android.libraries.matrix.api.core.EventId +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.notification.NotificationEvent +import org.matrix.rustcomponents.sdk.MessageLikeEventContent +import org.matrix.rustcomponents.sdk.MessageType +import org.matrix.rustcomponents.sdk.StateEventContent +import org.matrix.rustcomponents.sdk.TimelineEvent +import org.matrix.rustcomponents.sdk.TimelineEventType +import org.matrix.rustcomponents.sdk.use +import javax.inject.Inject + +class TimelineEventMapper @Inject constructor() { + + fun map(timelineEvent: TimelineEvent): NotificationEvent { + return timelineEvent.use { + NotificationEvent( + eventId = EventId(it.eventId()), + senderId = UserId(it.senderId()), + timestamp = it.timestamp().toLong(), + content = it.eventType().toContent(), + contentUrl = null // TODO it.eventType().toContentUrl(), + ) + } + } +} + +private fun TimelineEventType.toContent(): String { + return when (this) { + is TimelineEventType.MessageLike -> content.toContent() + is TimelineEventType.State -> content.toContent() + } +} + +private fun StateEventContent.toContent(): String { + return when (this) { + StateEventContent.PolicyRuleRoom -> "PolicyRuleRoom" + StateEventContent.PolicyRuleServer -> "PolicyRuleServer" + StateEventContent.PolicyRuleUser -> "PolicyRuleUser" + StateEventContent.RoomAliases -> "RoomAliases" + StateEventContent.RoomAvatar -> "RoomAvatar" + StateEventContent.RoomCanonicalAlias -> "RoomCanonicalAlias" + StateEventContent.RoomCreate -> "RoomCreate" + StateEventContent.RoomEncryption -> "RoomEncryption" + StateEventContent.RoomGuestAccess -> "RoomGuestAccess" + StateEventContent.RoomHistoryVisibility -> "RoomHistoryVisibility" + StateEventContent.RoomJoinRules -> "RoomJoinRules" + is StateEventContent.RoomMemberContent -> "$userId is now $membershipState" + StateEventContent.RoomName -> "RoomName" + StateEventContent.RoomPinnedEvents -> "RoomPinnedEvents" + StateEventContent.RoomPowerLevels -> "RoomPowerLevels" + StateEventContent.RoomServerAcl -> "RoomServerAcl" + StateEventContent.RoomThirdPartyInvite -> "RoomThirdPartyInvite" + StateEventContent.RoomTombstone -> "RoomTombstone" + StateEventContent.RoomTopic -> "RoomTopic" + StateEventContent.SpaceChild -> "SpaceChild" + StateEventContent.SpaceParent -> "SpaceParent" + } +} + +private fun MessageLikeEventContent.toContent(): String { + return use { + when (it) { + MessageLikeEventContent.CallAnswer -> "CallAnswer" + MessageLikeEventContent.CallCandidates -> "CallCandidates" + MessageLikeEventContent.CallHangup -> "CallHangup" + MessageLikeEventContent.CallInvite -> "CallInvite" + MessageLikeEventContent.KeyVerificationAccept -> "KeyVerificationAccept" + MessageLikeEventContent.KeyVerificationCancel -> "KeyVerificationCancel" + MessageLikeEventContent.KeyVerificationDone -> "KeyVerificationDone" + MessageLikeEventContent.KeyVerificationKey -> "KeyVerificationKey" + MessageLikeEventContent.KeyVerificationMac -> "KeyVerificationMac" + MessageLikeEventContent.KeyVerificationReady -> "KeyVerificationReady" + MessageLikeEventContent.KeyVerificationStart -> "KeyVerificationStart" + is MessageLikeEventContent.ReactionContent -> "Reacted to ${it.relatedEventId.take(8)}…" + MessageLikeEventContent.RoomEncrypted -> "RoomEncrypted" + is MessageLikeEventContent.RoomMessage -> it.messageType.toContent() + MessageLikeEventContent.RoomRedaction -> "RoomRedaction" + MessageLikeEventContent.Sticker -> "Sticker" + } + } +} + +private fun MessageType.toContent(): String { + return when (this) { + is MessageType.Audio -> content.use { it.body } + is MessageType.Emote -> content.body + is MessageType.File -> content.use { it.body } + is MessageType.Image -> content.use { it.body } + is MessageType.Notice -> content.body + is MessageType.Text -> content.body + is MessageType.Video -> content.use { it.body } + } +} diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventResolver.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventResolver.kt index de168090f4..840a38350e 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventResolver.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/NotifiableEventResolver.kt @@ -24,11 +24,11 @@ import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.notification.NotificationData +import io.element.android.libraries.matrix.api.notification.NotificationEvent import io.element.android.libraries.push.impl.log.pushLoggerTag import io.element.android.libraries.push.impl.notifications.model.NotifiableEvent import io.element.android.libraries.push.impl.notifications.model.NotifiableMessageEvent import io.element.android.services.toolbox.api.strings.StringProvider -import io.element.android.services.toolbox.api.systemclock.SystemClock import timber.log.Timber import javax.inject.Inject @@ -44,7 +44,6 @@ class NotifiableEventResolver @Inject constructor( private val stringProvider: StringProvider, // private val noticeEventFormatter: NoticeEventFormatter, // private val displayableEventFormatter: DisplayableEventFormatter, - private val clock: SystemClock, private val matrixAuthenticationService: MatrixAuthenticationService, private val buildMeta: BuildMeta, ) { @@ -80,13 +79,13 @@ class NotifiableEventResolver @Inject constructor( editedEventId = null, canBeReplaced = true, noisy = isNoisy, - timestamp = clock.epochMillis(), + timestamp = event.timestamp, senderName = senderDisplayName, senderId = senderId.value, - body = "Message ${eventId.value.take(8)}… in room ${roomId.value.take(8)}…", - imageUriString = null, + body = event.content, + imageUriString = event.contentUrl, threadId = null, - roomName = null, + roomName = roomDisplayName, roomIsDirect = false, roomAvatarPath = roomAvatarUrl, senderAvatarPath = senderAvatarUrl, @@ -107,8 +106,19 @@ private fun NotificationData?.orDefault(roomId: RoomId, eventId: EventId): Notif eventId = eventId, senderId = UserId("@user:domain"), roomId = roomId, + senderAvatarUrl = null, + senderDisplayName = null, + roomAvatarUrl = null, + roomDisplayName = null, isNoisy = false, isEncrypted = false, - isDirect = false + isDirect = false, + event = NotificationEvent( + eventId = eventId, + senderId = UserId("@user:domain"), + timestamp = System.currentTimeMillis(), + content = "Message ${eventId.value.take(8)}… in room ${roomId.value.take(8)}…", + contentUrl = null + ) ) }