thread message notification should navigate to thread timeline (#7771)

This commit is contained in:
Nikita Fedrunov 2022-12-12 22:35:09 +01:00 committed by GitHub
parent 34ee399f94
commit 4e0c3a97bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 65 additions and 9 deletions

1
changelog.d/7770.bugfix Normal file
View File

@ -0,0 +1 @@
[Push Notifications] When push notification for threaded message is clicked, thread timeline will be opened instead of room's main timeline

View File

@ -26,6 +26,7 @@ import im.vector.app.core.extensions.addFragmentToBackstack
import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.extensions.replaceFragment
import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.platform.VectorBaseActivity
import im.vector.app.databinding.ActivityThreadsBinding import im.vector.app.databinding.ActivityThreadsBinding
import im.vector.app.features.MainActivity
import im.vector.app.features.analytics.extensions.toAnalyticsInteraction import im.vector.app.features.analytics.extensions.toAnalyticsInteraction
import im.vector.app.features.analytics.plan.Interaction import im.vector.app.features.analytics.plan.Interaction
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
@ -143,13 +144,20 @@ class ThreadsActivity : VectorBaseActivity<ActivityThreadsBinding>() {
context: Context, context: Context,
threadTimelineArgs: ThreadTimelineArgs?, threadTimelineArgs: ThreadTimelineArgs?,
threadListArgs: ThreadListArgs?, threadListArgs: ThreadListArgs?,
eventIdToNavigate: String? = null eventIdToNavigate: String? = null,
firstStartMainActivity: Boolean = false
): Intent { ): Intent {
return Intent(context, ThreadsActivity::class.java).apply { val intent = Intent(context, ThreadsActivity::class.java).apply {
putExtra(THREAD_TIMELINE_ARGS, threadTimelineArgs) putExtra(THREAD_TIMELINE_ARGS, threadTimelineArgs)
putExtra(THREAD_EVENT_ID_TO_NAVIGATE, eventIdToNavigate) putExtra(THREAD_EVENT_ID_TO_NAVIGATE, eventIdToNavigate)
putExtra(THREAD_LIST_ARGS, threadListArgs) putExtra(THREAD_LIST_ARGS, threadListArgs)
} }
return if (firstStartMainActivity) {
MainActivity.getIntentWithNextIntent(context, intent)
} else {
intent
}
} }
} }

View File

@ -60,6 +60,8 @@ import im.vector.app.features.displayname.getBestName
import im.vector.app.features.home.HomeActivity import im.vector.app.features.home.HomeActivity
import im.vector.app.features.home.room.detail.RoomDetailActivity import im.vector.app.features.home.room.detail.RoomDetailActivity
import im.vector.app.features.home.room.detail.arguments.TimelineArgs import im.vector.app.features.home.room.detail.arguments.TimelineArgs
import im.vector.app.features.home.room.threads.ThreadsActivity
import im.vector.app.features.home.room.threads.arguments.ThreadTimelineArgs
import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorPreferences
import im.vector.app.features.settings.troubleshoot.TestNotificationReceiver import im.vector.app.features.settings.troubleshoot.TestNotificationReceiver
import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.themes.ThemeUtils
@ -574,6 +576,7 @@ class NotificationUtils @Inject constructor(
fun buildMessagesListNotification( fun buildMessagesListNotification(
messageStyle: NotificationCompat.MessagingStyle, messageStyle: NotificationCompat.MessagingStyle,
roomInfo: RoomEventGroupInfo, roomInfo: RoomEventGroupInfo,
threadId: String?,
largeIcon: Bitmap?, largeIcon: Bitmap?,
lastMessageTimestamp: Long, lastMessageTimestamp: Long,
senderDisplayNameForReplyCompat: String?, senderDisplayNameForReplyCompat: String?,
@ -581,7 +584,11 @@ class NotificationUtils @Inject constructor(
): Notification { ): Notification {
val accentColor = ContextCompat.getColor(context, R.color.notification_accent_color) val accentColor = ContextCompat.getColor(context, R.color.notification_accent_color)
// Build the pending intent for when the notification is clicked // Build the pending intent for when the notification is clicked
val openRoomIntent = buildOpenRoomIntent(roomInfo.roomId) val openIntent = when {
threadId != null && vectorPreferences.areThreadMessagesEnabled() -> buildOpenThreadIntent(roomInfo, threadId)
else -> buildOpenRoomIntent(roomInfo.roomId)
}
val smallIcon = R.drawable.ic_notification val smallIcon = R.drawable.ic_notification
val channelID = if (roomInfo.shouldBing) NOISY_NOTIFICATION_CHANNEL_ID else SILENT_NOTIFICATION_CHANNEL_ID val channelID = if (roomInfo.shouldBing) NOISY_NOTIFICATION_CHANNEL_ID else SILENT_NOTIFICATION_CHANNEL_ID
@ -666,8 +673,8 @@ class NotificationUtils @Inject constructor(
} }
} }
if (openRoomIntent != null) { if (openIntent != null) {
setContentIntent(openRoomIntent) setContentIntent(openIntent)
} }
if (largeIcon != null) { if (largeIcon != null) {
@ -826,6 +833,45 @@ class NotificationUtils @Inject constructor(
) )
} }
private fun buildOpenThreadIntent(roomInfo: RoomEventGroupInfo, threadId: String?): PendingIntent? {
val threadTimelineArgs = ThreadTimelineArgs(
startsThread = false,
roomId = roomInfo.roomId,
rootThreadEventId = threadId,
showKeyboard = false,
displayName = roomInfo.roomDisplayName,
avatarUrl = null,
roomEncryptionTrustLevel = null,
)
val threadIntentTap = ThreadsActivity.newIntent(
context = context,
threadTimelineArgs = threadTimelineArgs,
threadListArgs = null,
firstStartMainActivity = true,
)
threadIntentTap.action = actionIds.tapToView
// pending intent get reused by system, this will mess up the extra params, so put unique info to avoid that
threadIntentTap.data = createIgnoredUri("openThread?$threadId")
val roomIntent = RoomDetailActivity.newIntent(
context = context,
timelineArgs = TimelineArgs(
roomId = roomInfo.roomId,
switchToParentSpace = true
),
firstStartMainActivity = false
)
// Recreate the back stack
return TaskStackBuilder.create(context)
.addNextIntentWithParentStack(HomeActivity.newIntent(context, firstStartMainActivity = false))
.addNextIntentWithParentStack(roomIntent)
.addNextIntent(threadIntentTap)
.getPendingIntent(
clock.epochMillis().toInt(),
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE
)
}
private fun buildOpenHomePendingIntentForSummary(): PendingIntent { private fun buildOpenHomePendingIntentForSummary(): PendingIntent {
val intent = HomeActivity.newIntent(context, firstStartMainActivity = false, clearNotification = true) val intent = HomeActivity.newIntent(context, firstStartMainActivity = false, clearNotification = true)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP

View File

@ -33,14 +33,14 @@ class RoomGroupMessageCreator @Inject constructor(
) { ) {
fun createRoomMessage(events: List<NotifiableMessageEvent>, roomId: String, userDisplayName: String, userAvatarUrl: String?): RoomNotification.Message { fun createRoomMessage(events: List<NotifiableMessageEvent>, roomId: String, userDisplayName: String, userAvatarUrl: String?): RoomNotification.Message {
val firstKnownRoomEvent = events[0] val lastKnownRoomEvent = events.last()
val roomName = firstKnownRoomEvent.roomName ?: firstKnownRoomEvent.senderName ?: "" val roomName = lastKnownRoomEvent.roomName ?: lastKnownRoomEvent.senderName ?: ""
val roomIsGroup = !firstKnownRoomEvent.roomIsDirect val roomIsGroup = !lastKnownRoomEvent.roomIsDirect
val style = NotificationCompat.MessagingStyle( val style = NotificationCompat.MessagingStyle(
Person.Builder() Person.Builder()
.setName(userDisplayName) .setName(userDisplayName)
.setIcon(bitmapLoader.getUserIcon(userAvatarUrl)) .setIcon(bitmapLoader.getUserIcon(userAvatarUrl))
.setKey(firstKnownRoomEvent.matrixID) .setKey(lastKnownRoomEvent.matrixID)
.build() .build()
).also { ).also {
it.conversationTitle = roomName.takeIf { roomIsGroup } it.conversationTitle = roomName.takeIf { roomIsGroup }
@ -75,6 +75,7 @@ class RoomGroupMessageCreator @Inject constructor(
it.customSound = events.last().soundName it.customSound = events.last().soundName
it.isUpdated = events.last().isUpdated it.isUpdated = events.last().isUpdated
}, },
threadId = lastKnownRoomEvent.threadId,
largeIcon = largeBitmap, largeIcon = largeBitmap,
lastMessageTimestamp, lastMessageTimestamp,
userDisplayName, userDisplayName,