Merge branch 'develop' into feature/fga/advanced_settings_moderation_and_safety
This commit is contained in:
commit
322dd9a945
278 changed files with 2632 additions and 1649 deletions
|
|
@ -103,6 +103,7 @@ class DefaultNotifiableEventResolver @Inject constructor(
|
|||
senderId = content.senderId,
|
||||
roomId = roomId,
|
||||
eventId = eventId,
|
||||
threadId = threadId,
|
||||
noisy = isNoisy,
|
||||
timestamp = this.timestamp,
|
||||
senderDisambiguatedDisplayName = senderDisambiguatedDisplayName,
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -38,10 +38,8 @@ class PushProvidersTest @Inject constructor(
|
|||
val result = sortedPushProvider.isNotEmpty()
|
||||
if (result) {
|
||||
delegate.updateState(
|
||||
description = stringProvider.getQuantityString(
|
||||
resId = R.plurals.troubleshoot_notifications_test_detect_push_provider_success,
|
||||
quantity = sortedPushProvider.size,
|
||||
sortedPushProvider.size,
|
||||
description = stringProvider.getString(
|
||||
resId = R.string.troubleshoot_notifications_test_detect_push_provider_success_2,
|
||||
sortedPushProvider.joinToString { it.name }
|
||||
),
|
||||
status = NotificationTroubleshootTestState.Status.Success
|
||||
|
|
|
|||
|
|
@ -58,13 +58,14 @@
|
|||
<string name="troubleshoot_notifications_test_current_push_provider_failure">"No push providers selected."</string>
|
||||
<string name="troubleshoot_notifications_test_current_push_provider_success">"Current push provider: %1$s."</string>
|
||||
<string name="troubleshoot_notifications_test_current_push_provider_title">"Current push provider"</string>
|
||||
<string name="troubleshoot_notifications_test_detect_push_provider_description">"Ensure that the application has at least one push provider."</string>
|
||||
<string name="troubleshoot_notifications_test_detect_push_provider_failure">"No push providers found."</string>
|
||||
<string name="troubleshoot_notifications_test_detect_push_provider_description">"Ensure that the application supports at least one push provider."</string>
|
||||
<string name="troubleshoot_notifications_test_detect_push_provider_failure">"No push provider support found."</string>
|
||||
<plurals name="troubleshoot_notifications_test_detect_push_provider_success">
|
||||
<item quantity="one">"Found %1$d push provider: %2$s"</item>
|
||||
<item quantity="other">"Found %1$d push providers: %2$s"</item>
|
||||
</plurals>
|
||||
<string name="troubleshoot_notifications_test_detect_push_provider_title">"Detect push providers"</string>
|
||||
<string name="troubleshoot_notifications_test_detect_push_provider_success_2">"The application was built with support for: %1$s"</string>
|
||||
<string name="troubleshoot_notifications_test_detect_push_provider_title">"Push provider support"</string>
|
||||
<string name="troubleshoot_notifications_test_display_notification_description">"Check that the application can display notification."</string>
|
||||
<string name="troubleshoot_notifications_test_display_notification_failure">"The notification has not been clicked."</string>
|
||||
<string name="troubleshoot_notifications_test_display_notification_permission_failure">"Cannot display the notification."</string>
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ class PushProvidersTestTest {
|
|||
assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.InProgress)
|
||||
val lastItem = awaitItem()
|
||||
assertThat(lastItem.status).isEqualTo(NotificationTroubleshootTestState.Status.Success)
|
||||
assertThat(lastItem.description).contains("2")
|
||||
assertThat(lastItem.description).contains("foo")
|
||||
assertThat(lastItem.description).contains("bar")
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue