fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v25.4.7 (#4548)

* fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v25.4.8

* Fix API breaks:

- Add `ReplyParameters` class and parameters to send functions.
- Remove outdated OIDC related values.
- Stop pre-processing the timeline to add the timeline start item, this is already done by the SDK.

* Use the new function to reply to messages in a quick reply from a notification, however:

1. We don't have the thread id value at the moment since the SDK does not provide it yet.
2. The replied to event id wasn't being passed from the notification info.

* Remove also timeline start virtual item for DMs, since this wasn't present before either

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jorge Martín <jorgem@element.io>
This commit is contained in:
renovate[bot] 2025-04-08 14:21:49 +02:00 committed by GitHub
parent 7bcfb20268
commit b9385ce382
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
35 changed files with 454 additions and 296 deletions

View file

@ -102,6 +102,7 @@ class DefaultNotifiableEventResolver @Inject constructor(
senderId = content.senderId,
roomId = roomId,
eventId = eventId,
threadId = threadId,
noisy = isNoisy,
timestamp = this.timestamp,
senderDisambiguatedDisplayName = senderDisambiguatedDisplayName,

View file

@ -14,9 +14,9 @@ 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.ThreadId
import io.element.android.libraries.matrix.api.core.asEventId
import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.isDm
import io.element.android.libraries.matrix.api.room.message.replyInThread
import io.element.android.libraries.matrix.api.timeline.ReceiptType
import io.element.android.libraries.preferences.api.store.SessionPreferencesStoreFactory
import io.element.android.libraries.push.api.notifications.NotificationCleaner
@ -54,7 +54,7 @@ class NotificationBroadcastReceiverHandler @Inject constructor(
Timber.tag(loggerTag.value).d("onReceive: ${intent.action} ${intent.data} for: ${roomId?.value}/${eventId?.value}")
when (intent.action) {
actionIds.smartReply -> if (roomId != null) {
handleSmartReply(sessionId, roomId, threadId, intent)
handleSmartReply(sessionId, roomId, eventId, threadId, intent)
}
actionIds.dismissRoom -> if (roomId != null) {
notificationCleaner.clearMessagesForRoom(sessionId, roomId)
@ -106,6 +106,7 @@ class NotificationBroadcastReceiverHandler @Inject constructor(
private fun handleSmartReply(
sessionId: SessionId,
roomId: RoomId,
replyToEventId: EventId?,
threadId: ThreadId?,
intent: Intent,
) = appCoroutineScope.launch {
@ -120,6 +121,7 @@ class NotificationBroadcastReceiverHandler @Inject constructor(
sendMatrixEvent(
sessionId = sessionId,
roomId = roomId,
replyToEventId = replyToEventId,
threadId = threadId,
room = room,
message = message,
@ -131,6 +133,7 @@ class NotificationBroadcastReceiverHandler @Inject constructor(
sessionId: SessionId,
roomId: RoomId,
threadId: ThreadId?,
replyToEventId: EventId?,
room: MatrixRoom,
message: String,
) {
@ -158,13 +161,13 @@ class NotificationBroadcastReceiverHandler @Inject constructor(
)
onNotifiableEventReceived.onNotifiableEventReceived(notifiableMessageEvent)
if (threadId != null) {
if (threadId != null && replyToEventId != null) {
room.liveTimeline.replyMessage(
eventId = threadId.asEventId(),
body = message,
htmlBody = null,
intentionalMentions = emptyList(),
fromNotification = true,
replyParameters = replyInThread(replyToEventId),
)
} else {
room.liveTimeline.sendMessage(

View file

@ -197,7 +197,8 @@ class DefaultNotificationCreator @Inject constructor(
addAction(markAsReadActionFactory.create(roomInfo))
// Quick reply
if (!roomInfo.hasSmartReplyError) {
addAction(quickReplyActionFactory.create(roomInfo, threadId))
val latestEventId = events.lastOrNull()?.eventId
addAction(quickReplyActionFactory.create(roomInfo, latestEventId, threadId))
}
if (openIntent != null) {
setContentIntent(openIntent)

View file

@ -16,6 +16,7 @@ import androidx.core.app.RemoteInput
import io.element.android.appconfig.NotificationConfig
import io.element.android.libraries.androidutils.uri.createIgnoredUri
import io.element.android.libraries.di.ApplicationContext
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.ThreadId
@ -33,11 +34,11 @@ class QuickReplyActionFactory @Inject constructor(
private val stringProvider: StringProvider,
private val clock: SystemClock,
) {
fun create(roomInfo: RoomEventGroupInfo, threadId: ThreadId?): NotificationCompat.Action? {
fun create(roomInfo: RoomEventGroupInfo, eventId: EventId?, threadId: ThreadId?): NotificationCompat.Action? {
if (!NotificationConfig.SHOW_QUICK_REPLY_ACTION) return null
val sessionId = roomInfo.sessionId
val roomId = roomInfo.roomId
val replyPendingIntent = buildQuickReplyIntent(sessionId, roomId, threadId)
val replyPendingIntent = buildQuickReplyIntent(sessionId, roomId, eventId, threadId)
val remoteInput = RemoteInput.Builder(NotificationBroadcastReceiver.KEY_TEXT_REPLY)
.setLabel(stringProvider.getString(R.string.notification_room_action_quick_reply))
.build()
@ -63,6 +64,7 @@ class QuickReplyActionFactory @Inject constructor(
private fun buildQuickReplyIntent(
sessionId: SessionId,
roomId: RoomId,
eventId: EventId?,
threadId: ThreadId?,
): PendingIntent {
val intent = Intent(context, NotificationBroadcastReceiver::class.java)
@ -70,9 +72,8 @@ class QuickReplyActionFactory @Inject constructor(
intent.data = createIgnoredUri("quickReply/$sessionId/$roomId" + threadId?.let { "/$it" }.orEmpty())
intent.putExtra(NotificationBroadcastReceiver.KEY_SESSION_ID, sessionId.value)
intent.putExtra(NotificationBroadcastReceiver.KEY_ROOM_ID, roomId.value)
threadId?.let {
intent.putExtra(NotificationBroadcastReceiver.KEY_THREAD_ID, it.value)
}
eventId?.let { intent.putExtra(NotificationBroadcastReceiver.KEY_EVENT_ID, it.value) }
threadId?.let { intent.putExtra(NotificationBroadcastReceiver.KEY_THREAD_ID, it.value) }
return PendingIntent.getBroadcast(
context,

View file

@ -14,8 +14,9 @@ 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.ThreadId
import io.element.android.libraries.matrix.api.core.asEventId
import io.element.android.libraries.matrix.api.room.IntentionalMention
import io.element.android.libraries.matrix.api.room.message.ReplyParameters
import io.element.android.libraries.matrix.api.room.message.replyInThread
import io.element.android.libraries.matrix.api.roomlist.RoomSummary
import io.element.android.libraries.matrix.api.timeline.ReceiptType
import io.element.android.libraries.matrix.test.AN_EVENT_ID
@ -330,7 +331,8 @@ class NotificationBroadcastReceiverHandlerTest {
@Test
fun `Test send reply`() = runTest {
val sendMessage = lambdaRecorder<String, String?, List<IntentionalMention>, Result<Unit>> { _, _, _ -> Result.success(Unit) }
val replyMessage = lambdaRecorder<EventId, String, String?, List<IntentionalMention>, Boolean, Result<Unit>> { _, _, _, _, _ -> Result.success(Unit) }
val replyMessage =
lambdaRecorder<ReplyParameters, String, String?, List<IntentionalMention>, Boolean, Result<Unit>> { _, _, _, _, _ -> Result.success(Unit) }
val liveTimeline = FakeTimeline().apply {
sendMessageLambda = sendMessage
replyMessageLambda = replyMessage
@ -396,7 +398,8 @@ class NotificationBroadcastReceiverHandlerTest {
@Test
fun `Test send reply to thread`() = runTest {
val sendMessage = lambdaRecorder<String, String?, List<IntentionalMention>, Result<Unit>> { _, _, _ -> Result.success(Unit) }
val replyMessage = lambdaRecorder<EventId, String, String?, List<IntentionalMention>, Boolean, Result<Unit>> { _, _, _, _, _ -> Result.success(Unit) }
val replyMessage =
lambdaRecorder<ReplyParameters, String, String?, List<IntentionalMention>, Boolean, Result<Unit>> { _, _, _, _, _ -> Result.success(Unit) }
val liveTimeline = FakeTimeline().apply {
sendMessageLambda = sendMessage
replyMessageLambda = replyMessage
@ -423,6 +426,7 @@ class NotificationBroadcastReceiverHandlerTest {
createIntent(
action = actionIds.smartReply,
roomId = A_ROOM_ID,
eventId = AN_EVENT_ID,
threadId = A_THREAD_ID,
),
)
@ -433,7 +437,13 @@ class NotificationBroadcastReceiverHandlerTest {
.isCalledOnce()
replyMessage.assertions()
.isCalledOnce()
.with(value(A_THREAD_ID.asEventId()), value(A_MESSAGE), value(null), value(emptyList<IntentionalMention>()), value(true))
.with(
value(replyInThread(eventId = AN_EVENT_ID, explicitReply = false)),
value(A_MESSAGE),
value(null),
value(emptyList<IntentionalMention>()),
value(true)
)
}
private fun createIntent(