diff --git a/changelog.d/7770.bugfix b/changelog.d/7770.bugfix new file mode 100644 index 0000000000..598deb6073 --- /dev/null +++ b/changelog.d/7770.bugfix @@ -0,0 +1 @@ +[Push Notifications] When push notification for threaded message is clicked, thread timeline will be opened instead of room's main timeline diff --git a/vector/src/main/java/im/vector/app/features/home/room/threads/ThreadsActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/threads/ThreadsActivity.kt index b3f2ef1f75..014b9f0504 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/threads/ThreadsActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/threads/ThreadsActivity.kt @@ -26,6 +26,7 @@ import im.vector.app.core.extensions.addFragmentToBackstack import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.platform.VectorBaseActivity 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.plan.Interaction import im.vector.app.features.home.AvatarRenderer @@ -143,13 +144,20 @@ class ThreadsActivity : VectorBaseActivity() { context: Context, threadTimelineArgs: ThreadTimelineArgs?, threadListArgs: ThreadListArgs?, - eventIdToNavigate: String? = null + eventIdToNavigate: String? = null, + firstStartMainActivity: Boolean = false ): Intent { - return Intent(context, ThreadsActivity::class.java).apply { + val intent = Intent(context, ThreadsActivity::class.java).apply { putExtra(THREAD_TIMELINE_ARGS, threadTimelineArgs) putExtra(THREAD_EVENT_ID_TO_NAVIGATE, eventIdToNavigate) putExtra(THREAD_LIST_ARGS, threadListArgs) } + + return if (firstStartMainActivity) { + MainActivity.getIntentWithNextIntent(context, intent) + } else { + intent + } } } diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt index bf1b23093d..7bf78bdb95 100755 --- a/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotificationUtils.kt @@ -60,6 +60,8 @@ import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.HomeActivity 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.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.troubleshoot.TestNotificationReceiver import im.vector.app.features.themes.ThemeUtils @@ -574,6 +576,7 @@ class NotificationUtils @Inject constructor( fun buildMessagesListNotification( messageStyle: NotificationCompat.MessagingStyle, roomInfo: RoomEventGroupInfo, + threadId: String?, largeIcon: Bitmap?, lastMessageTimestamp: Long, senderDisplayNameForReplyCompat: String?, @@ -581,7 +584,11 @@ class NotificationUtils @Inject constructor( ): Notification { val accentColor = ContextCompat.getColor(context, R.color.notification_accent_color) // 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 channelID = if (roomInfo.shouldBing) NOISY_NOTIFICATION_CHANNEL_ID else SILENT_NOTIFICATION_CHANNEL_ID @@ -666,8 +673,8 @@ class NotificationUtils @Inject constructor( } } - if (openRoomIntent != null) { - setContentIntent(openRoomIntent) + if (openIntent != null) { + setContentIntent(openIntent) } 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 { val intent = HomeActivity.newIntent(context, firstStartMainActivity = false, clearNotification = true) intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP diff --git a/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt b/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt index 7fdfa3535e..767f427f39 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/RoomGroupMessageCreator.kt @@ -33,14 +33,14 @@ class RoomGroupMessageCreator @Inject constructor( ) { fun createRoomMessage(events: List, roomId: String, userDisplayName: String, userAvatarUrl: String?): RoomNotification.Message { - val firstKnownRoomEvent = events[0] - val roomName = firstKnownRoomEvent.roomName ?: firstKnownRoomEvent.senderName ?: "" - val roomIsGroup = !firstKnownRoomEvent.roomIsDirect + val lastKnownRoomEvent = events.last() + val roomName = lastKnownRoomEvent.roomName ?: lastKnownRoomEvent.senderName ?: "" + val roomIsGroup = !lastKnownRoomEvent.roomIsDirect val style = NotificationCompat.MessagingStyle( Person.Builder() .setName(userDisplayName) .setIcon(bitmapLoader.getUserIcon(userAvatarUrl)) - .setKey(firstKnownRoomEvent.matrixID) + .setKey(lastKnownRoomEvent.matrixID) .build() ).also { it.conversationTitle = roomName.takeIf { roomIsGroup } @@ -75,6 +75,7 @@ class RoomGroupMessageCreator @Inject constructor( it.customSound = events.last().soundName it.isUpdated = events.last().isUpdated }, + threadId = lastKnownRoomEvent.threadId, largeIcon = largeBitmap, lastMessageTimestamp, userDisplayName,