Extract from_notification extra to a constant in IntentNavigationExtras
Allow `IntentProvider` to receive extras and `PendingIntentFactory` to send them.
This commit is contained in:
committed by
Jorge Martin Espinosa
parent
71bfffe58f
commit
884c547123
@@ -10,6 +10,7 @@ package io.element.android.x.intent
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.core.net.toUri
|
||||
import dev.zacsweers.metro.AppScope
|
||||
import dev.zacsweers.metro.ContributesBinding
|
||||
@@ -32,11 +33,12 @@ class DefaultIntentProvider(
|
||||
roomId: RoomId?,
|
||||
threadId: ThreadId?,
|
||||
eventId: EventId?,
|
||||
extras: Bundle?,
|
||||
): Intent {
|
||||
return Intent(context, MainActivity::class.java).apply {
|
||||
action = Intent.ACTION_VIEW
|
||||
data = deepLinkCreator.create(sessionId, roomId, threadId, eventId).toUri()
|
||||
putExtra("from_notification", true)
|
||||
extras?.let(::putExtras)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import dev.zacsweers.metro.Assisted
|
||||
import dev.zacsweers.metro.AssistedInject
|
||||
import im.vector.app.features.analytics.plan.JoinedRoom
|
||||
import io.element.android.annotations.ContributesNode
|
||||
import io.element.android.appnav.analytics.AnalyticsColdStartWatcher
|
||||
import io.element.android.appnav.di.MatrixSessionCache
|
||||
import io.element.android.appnav.intent.IntentResolver
|
||||
import io.element.android.appnav.intent.ResolvedIntent
|
||||
@@ -66,6 +65,7 @@ import io.element.android.libraries.ui.common.nodes.emptyNode
|
||||
import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction
|
||||
import io.element.android.services.analytics.api.AnalyticsService
|
||||
import io.element.android.services.analytics.api.watchers.AnalyticsColdStartWatcher
|
||||
import io.element.android.services.appnavstate.api.ROOM_OPENED_FROM_NOTIFICATION
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
@@ -318,7 +318,8 @@ class RootFlowNode(
|
||||
val resolvedIntent = intentResolver.resolve(intent) ?: return
|
||||
when (resolvedIntent) {
|
||||
is ResolvedIntent.Navigation -> {
|
||||
if (intent.getBooleanExtra("from_notification", false) && resolvedIntent.deeplinkData is DeeplinkData.Room) {
|
||||
val openingRoomFromNotification = intent.getBooleanExtra(ROOM_OPENED_FROM_NOTIFICATION, false)
|
||||
if (openingRoomFromNotification && resolvedIntent.deeplinkData is DeeplinkData.Room) {
|
||||
analyticsService.startLongRunningTransaction(AnalyticsLongRunningTransaction.NotificationTapOpensTimeline)
|
||||
}
|
||||
navigateTo(resolvedIntent.deeplinkData)
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
package io.element.android.libraries.push.impl.intent
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
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
|
||||
@@ -23,5 +24,6 @@ interface IntentProvider {
|
||||
roomId: RoomId?,
|
||||
threadId: ThreadId?,
|
||||
eventId: EventId?,
|
||||
extras: Bundle? = null,
|
||||
): Intent
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import androidx.annotation.ColorInt
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationCompat.MessagingStyle
|
||||
import androidx.core.app.Person
|
||||
import androidx.core.os.bundleOf
|
||||
import coil3.ImageLoader
|
||||
import dev.zacsweers.metro.AppScope
|
||||
import dev.zacsweers.metro.ContributesBinding
|
||||
@@ -44,6 +45,7 @@ import io.element.android.libraries.push.impl.notifications.model.NotifiableMess
|
||||
import io.element.android.libraries.push.impl.notifications.model.SimpleNotifiableEvent
|
||||
import io.element.android.libraries.push.impl.notifications.shortcut.createShortcutId
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import io.element.android.services.appnavstate.api.ROOM_OPENED_FROM_NOTIFICATION
|
||||
import io.element.android.services.toolbox.api.strings.StringProvider
|
||||
|
||||
interface NotificationCreator {
|
||||
@@ -138,7 +140,12 @@ class DefaultNotificationCreator(
|
||||
val eventId = events.firstOrNull()?.eventId
|
||||
val openIntent = when {
|
||||
threadId != null -> pendingIntentFactory.createOpenThreadPendingIntent(roomInfo.sessionId, roomInfo.roomId, eventId, threadId)
|
||||
else -> pendingIntentFactory.createOpenRoomPendingIntent(roomInfo.sessionId, roomInfo.roomId, eventId)
|
||||
else -> pendingIntentFactory.createOpenRoomPendingIntent(
|
||||
sessionId = roomInfo.sessionId,
|
||||
roomId = roomInfo.roomId,
|
||||
eventId = eventId,
|
||||
extras = bundleOf(ROOM_OPENED_FROM_NOTIFICATION to true),
|
||||
)
|
||||
}
|
||||
val containsMissedCall = events.any { it.type == EventType.RTC_NOTIFICATION }
|
||||
val channelId = if (containsMissedCall) {
|
||||
@@ -233,7 +240,11 @@ class DefaultNotificationCreator(
|
||||
.addAction(rejectInvitationActionFactory.create(inviteNotifiableEvent))
|
||||
.addAction(acceptInvitationActionFactory.create(inviteNotifiableEvent))
|
||||
// Build the pending intent for when the notification is clicked
|
||||
.setContentIntent(pendingIntentFactory.createOpenRoomPendingIntent(inviteNotifiableEvent.sessionId, inviteNotifiableEvent.roomId, null))
|
||||
.setContentIntent(pendingIntentFactory.createOpenRoomPendingIntent(
|
||||
sessionId = inviteNotifiableEvent.sessionId,
|
||||
roomId = inviteNotifiableEvent.roomId,
|
||||
eventId = null,
|
||||
))
|
||||
.apply {
|
||||
if (inviteNotifiableEvent.noisy) {
|
||||
// Compat
|
||||
@@ -265,7 +276,12 @@ class DefaultNotificationCreator(
|
||||
.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_ALL)
|
||||
.configureWith(notificationAccountParams)
|
||||
.setAutoCancel(true)
|
||||
.setContentIntent(pendingIntentFactory.createOpenRoomPendingIntent(simpleNotifiableEvent.sessionId, simpleNotifiableEvent.roomId, null))
|
||||
.setContentIntent(pendingIntentFactory.createOpenRoomPendingIntent(
|
||||
sessionId = simpleNotifiableEvent.sessionId,
|
||||
roomId = simpleNotifiableEvent.roomId,
|
||||
eventId = null,
|
||||
extras = bundleOf(ROOM_OPENED_FROM_NOTIFICATION to true),
|
||||
))
|
||||
.apply {
|
||||
if (simpleNotifiableEvent.noisy) {
|
||||
// Compat
|
||||
|
||||
@@ -11,6 +11,7 @@ package io.element.android.libraries.push.impl.notifications.factories
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import dev.zacsweers.metro.Inject
|
||||
import io.element.android.libraries.androidutils.uri.createIgnoredUri
|
||||
import io.element.android.libraries.di.annotations.ApplicationContext
|
||||
@@ -31,20 +32,20 @@ class PendingIntentFactory(
|
||||
private val clock: SystemClock,
|
||||
private val actionIds: NotificationActionIds,
|
||||
) {
|
||||
fun createOpenSessionPendingIntent(sessionId: SessionId): PendingIntent? {
|
||||
return createRoomPendingIntent(sessionId = sessionId, roomId = null, eventId = null, threadId = null)
|
||||
fun createOpenSessionPendingIntent(sessionId: SessionId, extras: Bundle? = null): PendingIntent? {
|
||||
return createRoomPendingIntent(sessionId = sessionId, roomId = null, eventId = null, threadId = null, extras = extras)
|
||||
}
|
||||
|
||||
fun createOpenRoomPendingIntent(sessionId: SessionId, roomId: RoomId, eventId: EventId?): PendingIntent? {
|
||||
return createRoomPendingIntent(sessionId = sessionId, roomId = roomId, eventId = eventId, threadId = null)
|
||||
fun createOpenRoomPendingIntent(sessionId: SessionId, roomId: RoomId, eventId: EventId?, extras: Bundle? = null): PendingIntent? {
|
||||
return createRoomPendingIntent(sessionId = sessionId, roomId = roomId, eventId = eventId, threadId = null, extras = extras)
|
||||
}
|
||||
|
||||
fun createOpenThreadPendingIntent(sessionId: SessionId, roomId: RoomId, eventId: EventId?, threadId: ThreadId): PendingIntent? {
|
||||
return createRoomPendingIntent(sessionId = sessionId, roomId = roomId, eventId = eventId, threadId = threadId)
|
||||
fun createOpenThreadPendingIntent(sessionId: SessionId, roomId: RoomId, eventId: EventId?, threadId: ThreadId, extras: Bundle? = null): PendingIntent? {
|
||||
return createRoomPendingIntent(sessionId = sessionId, roomId = roomId, eventId = eventId, threadId = threadId, extras = extras)
|
||||
}
|
||||
|
||||
private fun createRoomPendingIntent(sessionId: SessionId, roomId: RoomId?, eventId: EventId?, threadId: ThreadId?): PendingIntent? {
|
||||
val intent = intentProvider.getViewRoomIntent(sessionId = sessionId, roomId = roomId, eventId = eventId, threadId = threadId)
|
||||
private fun createRoomPendingIntent(sessionId: SessionId, roomId: RoomId?, eventId: EventId?, threadId: ThreadId?, extras: Bundle? = null): PendingIntent? {
|
||||
val intent = intentProvider.getViewRoomIntent(sessionId = sessionId, roomId = roomId, eventId = eventId, threadId = threadId, extras = extras)
|
||||
return PendingIntent.getActivity(
|
||||
context,
|
||||
clock.epochMillis().toInt(),
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
package io.element.android.libraries.push.impl.notifications.factories
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
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
|
||||
@@ -16,5 +17,11 @@ import io.element.android.libraries.matrix.api.core.ThreadId
|
||||
import io.element.android.libraries.push.impl.intent.IntentProvider
|
||||
|
||||
class FakeIntentProvider : IntentProvider {
|
||||
override fun getViewRoomIntent(sessionId: SessionId, roomId: RoomId?, threadId: ThreadId?, eventId: EventId?) = Intent(Intent.ACTION_VIEW)
|
||||
override fun getViewRoomIntent(
|
||||
sessionId: SessionId,
|
||||
roomId: RoomId?,
|
||||
threadId: ThreadId?,
|
||||
eventId: EventId?,
|
||||
extras: Bundle?,
|
||||
) = Intent(Intent.ACTION_VIEW)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 2025 Element Creations Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.services.appnavstate.api
|
||||
|
||||
const val ROOM_OPENED_FROM_NOTIFICATION = "opened_from_notification"
|
||||
Reference in New Issue
Block a user