Use the new RtcNotification instead of deprecated CallNotify

This commit is contained in:
Valere
2025-09-16 09:00:17 +02:00
parent 66bc4cad8f
commit 5221f0890c
27 changed files with 69 additions and 38 deletions

View File

@@ -29,6 +29,7 @@ interface ElementCallEntryPoint {
* @param senderName The name of the sender of the event that started the call.
* @param avatarUrl The avatar url of the room or DM.
* @param timestamp The timestamp of the event that started the call.
* @param expirationTimestamp The timestamp at which the call should stop ringing.
* @param notificationChannelId The id of the notification channel to use for the call notification.
* @param textContent The text content of the notification. If null the default content from the system will be used.
*/
@@ -40,6 +41,7 @@ interface ElementCallEntryPoint {
senderName: String?,
avatarUrl: String?,
timestamp: Long,
expirationTimestamp: Long,
notificationChannelId: String,
textContent: String?,
)

View File

@@ -43,6 +43,7 @@ class DefaultElementCallEntryPoint(
senderName: String?,
avatarUrl: String?,
timestamp: Long,
expirationTimestamp: Long,
notificationChannelId: String,
textContent: String?,
) {
@@ -55,6 +56,7 @@ class DefaultElementCallEntryPoint(
senderName = senderName,
avatarUrl = avatarUrl,
timestamp = timestamp,
expirationTimestamp = expirationTimestamp,
notificationChannelId = notificationChannelId,
textContent = textContent,
)

View File

@@ -26,4 +26,5 @@ data class CallNotificationData(
val notificationChannelId: String,
val timestamp: Long,
val textContent: String?,
val expirationTimestamp: Long,
) : Parcelable

View File

@@ -64,6 +64,7 @@ class RingingCallNotificationCreator(
roomAvatarUrl: String?,
notificationChannelId: String,
timestamp: Long,
expirationTimestamp: Long,
textContent: String?,
): Notification? {
val matrixClient = matrixClientProvider.getOrRestore(sessionId).getOrNull() ?: return null
@@ -88,6 +89,7 @@ class RingingCallNotificationCreator(
notificationChannelId = notificationChannelId,
timestamp = timestamp,
textContent = textContent,
expirationTimestamp = expirationTimestamp,
)
val declineIntent = PendingIntentCompat.getBroadcast(

View File

@@ -176,6 +176,7 @@ internal fun IncomingCallScreenPreview() = ElementPreview {
notificationChannelId = "incoming_call",
timestamp = 0L,
textContent = null,
expirationTimestamp = 1000L,
),
onAnswer = {},
onCancel = {},

View File

@@ -53,7 +53,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import timber.log.Timber
import kotlin.time.Duration.Companion.seconds
import kotlin.math.min
/**
* Manages the active call state.
@@ -118,8 +118,20 @@ class DefaultActiveCallManager(
override suspend fun registerIncomingCall(notificationData: CallNotificationData) {
mutex.withLock {
val ringDuration =
min(
notificationData.expirationTimestamp - System.currentTimeMillis(),
ElementCallConfig.RINGING_CALL_DURATION_SECONDS * 1000L
)
if (ringDuration < 0) {
// Should already have stopped ringing, ignore.
Timber.tag(tag).d("Received timed-out incoming ringing call for room id: ${notificationData.roomId}, cancel ringing")
return
}
appForegroundStateService.updateHasRingingCall(true)
Timber.tag(tag).d("Received incoming call for room id: ${notificationData.roomId}")
Timber.tag(tag).d("Received incoming call for room id: ${notificationData.roomId}, ringDuration: $ringDuration")
if (activeCall.value != null) {
displayMissedCallNotification(notificationData)
Timber.tag(tag).w("Already have an active call, ignoring incoming call: $notificationData")
@@ -138,14 +150,14 @@ class DefaultActiveCallManager(
showIncomingCallNotification(notificationData)
// Wait for the ringing call to time out
delay(ElementCallConfig.RINGING_CALL_DURATION_SECONDS.seconds)
delay(timeMillis = ringDuration)
incomingCallTimedOut(displayMissedCallNotification = true)
}
// Acquire a wake lock to keep the device awake during the incoming call, so we can process the room info data
if (activeWakeLock?.isHeld == false) {
Timber.tag(tag).d("Acquiring partial wakelock")
activeWakeLock.acquire(ElementCallConfig.RINGING_CALL_DURATION_SECONDS * 1000L)
activeWakeLock.acquire(ringDuration)
}
}
}
@@ -236,6 +248,7 @@ class DefaultActiveCallManager(
notificationChannelId = notificationData.notificationChannelId,
timestamp = notificationData.timestamp,
textContent = notificationData.textContent,
expirationTimestamp = notificationData.expirationTimestamp,
) ?: return
runCatchingExceptions {
notificationManagerCompat.notify(

View File

@@ -25,12 +25,12 @@ import io.element.android.features.messages.impl.actionlist.model.TimelineItemAc
import io.element.android.features.messages.impl.crypto.sendfailure.VerifiedUserSendFailure
import io.element.android.features.messages.impl.crypto.sendfailure.VerifiedUserSendFailureFactory
import io.element.android.features.messages.impl.timeline.model.TimelineItem
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemCallNotifyContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContentWithAttachment
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemLegacyCallInviteContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemPollContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRedactedContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRtcNotificationContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateContent
import io.element.android.features.messages.impl.timeline.model.event.canBeCopied
import io.element.android.features.messages.impl.timeline.model.event.canBeForwarded
@@ -242,7 +242,7 @@ class DefaultActionListPresenter(
private fun Iterable<TimelineItemAction>.postFilter(content: TimelineItemEventContent): Iterable<TimelineItemAction> {
return filter { action ->
when (content) {
is TimelineItemCallNotifyContent,
is TimelineItemRtcNotificationContent,
is TimelineItemLegacyCallInviteContent,
is TimelineItemStateContent -> action == TimelineItemAction.ViewSource
is TimelineItemRedactedContent -> {

View File

@@ -56,7 +56,6 @@ import io.element.android.features.messages.impl.timeline.a11y.a11yReactionActio
import io.element.android.features.messages.impl.timeline.components.MessageShieldView
import io.element.android.features.messages.impl.timeline.model.TimelineItem
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemAudioContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemCallNotifyContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEncryptedContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemImageContent
@@ -64,6 +63,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemLocationContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemPollContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRedactedContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRtcNotificationContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStickerContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextBasedContent
@@ -306,7 +306,7 @@ private fun MessageSummary(
is TimelineItemLegacyCallInviteContent -> {
content = { ContentForBody(textContent) }
}
is TimelineItemCallNotifyContent -> {
is TimelineItemRtcNotificationContent -> {
content = { ContentForBody(stringResource(CommonStrings.common_call_started)) }
}
}

View File

@@ -29,7 +29,7 @@ import io.element.android.compound.theme.ElementTheme
import io.element.android.compound.tokens.generated.CompoundIcons
import io.element.android.features.messages.impl.timeline.aTimelineItemEvent
import io.element.android.features.messages.impl.timeline.model.TimelineItem
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemCallNotifyContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRtcNotificationContent
import io.element.android.features.roomcall.api.RoomCallState
import io.element.android.features.roomcall.api.RoomCallStateProvider
import io.element.android.libraries.designsystem.components.avatar.Avatar
@@ -119,7 +119,7 @@ internal fun TimelineItemCallNotifyViewPreview() = ElementPreview {
.filter { it !is RoomCallState.Unavailable }
.forEach { roomCallState ->
TimelineItemCallNotifyView(
event = aTimelineItemEvent(content = TimelineItemCallNotifyContent()),
event = aTimelineItemEvent(content = TimelineItemRtcNotificationContent()),
roomCallState = roomCallState,
onLongClick = {},
onJoinCallClick = {},

View File

@@ -30,9 +30,9 @@ import io.element.android.features.messages.impl.timeline.TimelineRoomInfo
import io.element.android.features.messages.impl.timeline.components.event.TimelineItemEventContentView
import io.element.android.features.messages.impl.timeline.components.layout.ContentAvoidingLayoutData
import io.element.android.features.messages.impl.timeline.model.TimelineItem
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemCallNotifyContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemLegacyCallInviteContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemPollContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRtcNotificationContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVoiceContent
import io.element.android.features.messages.impl.timeline.protection.TimelineProtectionEvent
@@ -123,7 +123,7 @@ internal fun TimelineItemRow(
eventSink = eventSink,
)
}
is TimelineItemCallNotifyContent -> {
is TimelineItemRtcNotificationContent -> {
TimelineItemCallNotifyView(
modifier = Modifier.padding(start = 16.dp, end = 16.dp, top = 16.dp),
event = timelineItem,

View File

@@ -14,7 +14,6 @@ import io.element.android.features.messages.impl.timeline.components.layout.Cont
import io.element.android.features.messages.impl.timeline.di.LocalTimelineItemPresenterFactories
import io.element.android.features.messages.impl.timeline.di.rememberPresenter
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemAudioContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemCallNotifyContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEncryptedContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContent
@@ -23,6 +22,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemLocationContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemPollContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRedactedContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRtcNotificationContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStickerContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextBasedContent
@@ -133,6 +133,6 @@ fun TimelineItemEventContentView(
modifier = modifier
)
}
is TimelineItemCallNotifyContent -> error("This shouldn't be rendered as the content of a bubble")
is TimelineItemRtcNotificationContent -> error("This shouldn't be rendered as the content of a bubble")
}
}

View File

@@ -8,9 +8,9 @@
package io.element.android.features.messages.impl.timeline.factories.event
import dev.zacsweers.metro.Inject
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemCallNotifyContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEventContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemLegacyCallInviteContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRtcNotificationContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemUnknownContent
import io.element.android.libraries.matrix.api.timeline.item.event.CallNotifyContent
import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem
@@ -61,7 +61,7 @@ class TimelineItemContentFactory(
is StickerContent -> stickerFactory.create(itemContent)
is PollContent -> pollFactory.create(eventTimelineItem, itemContent)
is UnableToDecryptContent -> utdFactory.create(itemContent)
is CallNotifyContent -> TimelineItemCallNotifyContent()
is CallNotifyContent -> TimelineItemRtcNotificationContent()
is UnknownContent -> TimelineItemUnknownContent
}
}

View File

@@ -9,7 +9,6 @@ package io.element.android.features.messages.impl.timeline.groups
import io.element.android.features.messages.impl.timeline.model.TimelineItem
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemAudioContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemCallNotifyContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEncryptedContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemImageContent
@@ -19,6 +18,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemProfileChangeContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRedactedContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRoomMembershipContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRtcNotificationContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateEventContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStickerContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextBasedContent
@@ -60,7 +60,7 @@ internal fun TimelineItem.Event.canBeGrouped(): Boolean {
TimelineItemRedactedContent,
TimelineItemUnknownContent,
is TimelineItemLegacyCallInviteContent,
is TimelineItemCallNotifyContent -> false
is TimelineItemRtcNotificationContent -> false
is TimelineItemProfileChangeContent,
is TimelineItemRoomMembershipContent,
is TimelineItemStateEventContent -> true

View File

@@ -81,7 +81,7 @@ fun TimelineItemEventContent.canReact(): Boolean =
is TimelineItemStateContent,
is TimelineItemRedactedContent,
is TimelineItemLegacyCallInviteContent,
is TimelineItemCallNotifyContent,
is TimelineItemRtcNotificationContent,
TimelineItemUnknownContent -> false
}

View File

@@ -7,6 +7,6 @@
package io.element.android.features.messages.impl.timeline.model.event
class TimelineItemCallNotifyContent : TimelineItemEventContent {
override val type: String = "m.call.notify"
class TimelineItemRtcNotificationContent : TimelineItemEventContent {
override val type: String = "org.matrix.msc4075.rtc.notification"
}

View File

@@ -9,7 +9,6 @@ package io.element.android.features.messages.impl.timeline.protection
import io.element.android.features.messages.impl.timeline.model.TimelineItem
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemAudioContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemCallNotifyContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEmoteContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEncryptedContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContent
@@ -21,6 +20,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemProfileChangeContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRedactedContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRoomMembershipContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRtcNotificationContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateEventContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStickerContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextContent
@@ -38,7 +38,7 @@ fun TimelineItem.mustBeProtected(): Boolean {
is TimelineItemVideoContent,
is TimelineItemStickerContent -> true
is TimelineItemAudioContent,
is TimelineItemCallNotifyContent,
is TimelineItemRtcNotificationContent,
is TimelineItemEncryptedContent,
is TimelineItemFileContent,
TimelineItemLegacyCallInviteContent,

View File

@@ -12,7 +12,6 @@ import dev.zacsweers.metro.ContributesBinding
import dev.zacsweers.metro.Inject
import io.element.android.features.messages.impl.timeline.model.TimelineItem
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemAudioContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemCallNotifyContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemEncryptedContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemFileContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemImageContent
@@ -21,6 +20,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemPollContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemProfileChangeContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRedactedContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemRtcNotificationContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStateContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemStickerContent
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemTextBasedContent
@@ -54,7 +54,7 @@ class DefaultMessageSummaryFormatter(
is TimelineItemFileContent -> context.getString(CommonStrings.common_file)
is TimelineItemAudioContent -> context.getString(CommonStrings.common_audio)
is TimelineItemLegacyCallInviteContent -> context.getString(CommonStrings.common_unsupported_call)
is TimelineItemCallNotifyContent -> context.getString(CommonStrings.common_call_started)
is TimelineItemRtcNotificationContent -> context.getString(CommonStrings.common_call_started)
}
// Truncate the message to a safe length to avoid crashes in Compose
.toSafeLength()

View File

@@ -52,6 +52,7 @@ sealed interface NotificationContent {
data class CallNotify(
val senderId: UserId,
val type: CallNotifyType,
val expirationTimestampMillis: Long
) : MessageLike
data object CallHangup : MessageLike

View File

@@ -15,5 +15,6 @@ object EventType {
// Call Events
const val CALL_INVITE = "m.call.invite"
const val CALL_NOTIFY = "m.call.notify"
const val RTC_NOTIFICATION = "org.matrix.msc4075.rtc.notification"
}

View File

@@ -15,7 +15,7 @@ import io.element.android.libraries.matrix.api.notification.NotificationContent
import io.element.android.libraries.matrix.impl.room.member.RoomMemberMapper
import io.element.android.libraries.matrix.impl.timeline.item.event.EventMessageMapper
import org.matrix.rustcomponents.sdk.MessageLikeEventContent
import org.matrix.rustcomponents.sdk.NotifyType
import org.matrix.rustcomponents.sdk.RtcNotificationType
import org.matrix.rustcomponents.sdk.StateEventContent
import org.matrix.rustcomponents.sdk.TimelineEvent
import org.matrix.rustcomponents.sdk.TimelineEventType
@@ -78,7 +78,11 @@ private fun MessageLikeEventContent.toContent(senderId: UserId): NotificationCon
MessageLikeEventContent.CallCandidates -> NotificationContent.MessageLike.CallCandidates
MessageLikeEventContent.CallHangup -> NotificationContent.MessageLike.CallHangup
MessageLikeEventContent.CallInvite -> NotificationContent.MessageLike.CallInvite(senderId)
is MessageLikeEventContent.CallNotify -> NotificationContent.MessageLike.CallNotify(senderId, notifyType.map())
is MessageLikeEventContent.RtcNotification -> NotificationContent.MessageLike.CallNotify(
senderId = senderId,
type = notificationType.map(),
expirationTimestampMillis = expirationTs.toLong()
)
MessageLikeEventContent.KeyVerificationAccept -> NotificationContent.MessageLike.KeyVerificationAccept
MessageLikeEventContent.KeyVerificationCancel -> NotificationContent.MessageLike.KeyVerificationCancel
MessageLikeEventContent.KeyVerificationDone -> NotificationContent.MessageLike.KeyVerificationDone
@@ -101,7 +105,7 @@ private fun MessageLikeEventContent.toContent(senderId: UserId): NotificationCon
}
}
private fun NotifyType.map(): CallNotifyType = when (this) {
NotifyType.NOTIFY -> CallNotifyType.NOTIFY
NotifyType.RING -> CallNotifyType.RING
private fun RtcNotificationType.map(): CallNotifyType = when (this) {
RtcNotificationType.NOTIFY -> CallNotifyType.NOTIFY
RtcNotificationType.RING -> CallNotifyType.RING
}

View File

@@ -15,7 +15,7 @@ fun MessageEventType.map(): MessageLikeEventType = when (this) {
MessageEventType.CALL_INVITE -> MessageLikeEventType.CALL_INVITE
MessageEventType.CALL_HANGUP -> MessageLikeEventType.CALL_HANGUP
MessageEventType.CALL_CANDIDATES -> MessageLikeEventType.CALL_CANDIDATES
MessageEventType.CALL_NOTIFY -> MessageLikeEventType.CALL_NOTIFY
MessageEventType.CALL_NOTIFY -> MessageLikeEventType.RTC_NOTIFICATION
MessageEventType.KEY_VERIFICATION_READY -> MessageLikeEventType.KEY_VERIFICATION_READY
MessageEventType.KEY_VERIFICATION_START -> MessageLikeEventType.KEY_VERIFICATION_START
MessageEventType.KEY_VERIFICATION_CANCEL -> MessageLikeEventType.KEY_VERIFICATION_CANCEL
@@ -41,7 +41,7 @@ fun MessageLikeEventType.map(): MessageEventType = when (this) {
MessageLikeEventType.CALL_INVITE -> MessageEventType.CALL_INVITE
MessageLikeEventType.CALL_HANGUP -> MessageEventType.CALL_HANGUP
MessageLikeEventType.CALL_CANDIDATES -> MessageEventType.CALL_CANDIDATES
MessageLikeEventType.CALL_NOTIFY -> MessageEventType.CALL_NOTIFY
MessageLikeEventType.RTC_NOTIFICATION -> MessageEventType.CALL_NOTIFY
MessageLikeEventType.KEY_VERIFICATION_READY -> MessageEventType.KEY_VERIFICATION_READY
MessageLikeEventType.KEY_VERIFICATION_START -> MessageEventType.KEY_VERIFICATION_START
MessageLikeEventType.KEY_VERIFICATION_CANCEL -> MessageEventType.KEY_VERIFICATION_CANCEL

View File

@@ -437,6 +437,7 @@ class RustTimeline(
key = emoji,
itemId = eventOrTransactionId.toRustEventOrTransactionId(),
)
return@runCatchingExceptions Unit
}
}

View File

@@ -149,7 +149,7 @@ class TimelineEventContentMapper(
)
}
is TimelineItemContent.CallInvite -> LegacyCallInviteContent
is TimelineItemContent.CallNotify -> CallNotifyContent
is TimelineItemContent.RtcNotification -> CallNotifyContent
}
}
}

View File

@@ -107,6 +107,7 @@ class DefaultCallNotificationEventResolver(
callNotifyType = content.type,
senderId = content.senderId,
senderAvatarUrl = senderAvatarUrl,
expirationTimestamp = content.expirationTimestampMillis,
)
} else {
Timber.d("Event $eventId is call notify but should not ring: $isRoomCallActive, notify: ${content.type}")
@@ -124,7 +125,7 @@ class DefaultCallNotificationEventResolver(
roomIsDm = isDm,
roomAvatarPath = roomAvatarUrl,
senderAvatarPath = senderAvatarUrl,
type = EventType.CALL_NOTIFY,
type = EventType.RTC_NOTIFICATION,
)
}
}

View File

@@ -123,7 +123,7 @@ class DefaultNotificationCreator(
val smallIcon = CommonDrawables.ic_notification
val containsMissedCall = events.any { it.type == EventType.CALL_NOTIFY }
val containsMissedCall = events.any { it.type == EventType.RTC_NOTIFICATION }
val channelId = if (containsMissedCall) {
notificationChannels.getChannelForIncomingCall(false)
} else {
@@ -213,8 +213,8 @@ class DefaultNotificationCreator(
}
setDeleteIntent(pendingIntentFactory.createDismissRoomPendingIntent(roomInfo.sessionId, roomInfo.roomId))
// If any of the events are of call notify type it means a missed call, set the category to the right value
if (events.any { it.type == EventType.CALL_NOTIFY }) {
// If any of the events are of rtc notification type it means a missed call, set the category to the right value
if (events.any { it.type == EventType.RTC_NOTIFICATION }) {
setCategory(NotificationCompat.CATEGORY_MISSED_CALL)
}
}

View File

@@ -29,4 +29,5 @@ data class NotifiableRingingCallEvent(
val roomAvatarUrl: String? = null,
val callNotifyType: CallNotifyType,
val timestamp: Long,
val expirationTimestamp: Long,
) : NotifiableEvent

View File

@@ -296,6 +296,7 @@ class DefaultPushHandler(
senderName = notifiableEvent.senderDisambiguatedDisplayName,
avatarUrl = notifiableEvent.roomAvatarUrl,
timestamp = notifiableEvent.timestamp,
expirationTimestamp = notifiableEvent.expirationTimestamp,
notificationChannelId = notificationChannels.getChannelForIncomingCall(ring = true),
textContent = notifiableEvent.description,
)