mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-10-31 16:22:49 +00:00
Offer conversations in the system share sheet
Sharing from another app listed Element X once, with no way to pick a conversation: the Direct Share row never showed any. The app already publishes a long-lived, conversation-categorised shortcut per room, which is most of what the sharing shortcuts API needs. The part that was missing is the declaration that ties those shortcuts to the share intent: the launcher activity had no `android.app.shortcuts` meta-data, so there was no `<share-target>` for the system to match them against. It now ships one, matching the activity that already receives ACTION_SEND, and the shortcuts carry the category it names. The system offers these from Android 10 onwards, where sharing shortcuts are handled natively. Reaching further back would additionally need the androidx.sharetarget library, which is not added here. Part of #3835
This commit is contained in:
+8
-1
@@ -42,6 +42,12 @@ import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Category shared with the `<share-target>` in `app/src/main/res/xml/shortcuts.xml`. The system only offers a shortcut
|
||||
* in the Direct Share row of the share sheet when the two match, so the literal has to be kept in step with that file.
|
||||
*/
|
||||
private const val SHARE_TARGET_CATEGORY = "io.element.android.category.SHARE_TARGET"
|
||||
|
||||
@SingleIn(AppScope::class)
|
||||
@ContributesBinding(AppScope::class)
|
||||
class DefaultNotificationConversationService(
|
||||
@@ -86,7 +92,8 @@ class DefaultNotificationConversationService(
|
||||
}
|
||||
|
||||
val categories = setOfNotNull(
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION else null
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION else null,
|
||||
SHARE_TARGET_CATEGORY,
|
||||
)
|
||||
|
||||
val client = matrixClientProvider.getOrRestore(sessionId).getOrNull() ?: return
|
||||
|
||||
+22
@@ -10,6 +10,7 @@ package io.element.android.libraries.push.impl.notifications.conversations
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.ShortcutInfo
|
||||
import android.os.Build
|
||||
import androidx.core.content.pm.ShortcutInfoCompat
|
||||
import androidx.core.content.pm.ShortcutManagerCompat
|
||||
@@ -52,6 +53,27 @@ class DefaultNotificationConversationServiceTest : RobolectricTest() {
|
||||
assertThat(shortcuts).isNotEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `the shortcut is offered to the share sheet as a conversation`() = runTest {
|
||||
val context = InstrumentationRegistry.getInstrumentation().context
|
||||
val service = createService(context)
|
||||
|
||||
service.onSendMessage(
|
||||
sessionId = A_SESSION_ID,
|
||||
roomId = A_ROOM_ID,
|
||||
roomName = "Room title",
|
||||
roomIsDirect = false,
|
||||
roomAvatarUrl = null,
|
||||
)
|
||||
|
||||
val shortcut = ShortcutManagerCompat.getDynamicShortcuts(context).single()
|
||||
assertThat(shortcut.categories).containsAtLeast(
|
||||
ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION,
|
||||
// Matches the <share-target> category in app/src/main/res/xml/shortcuts.xml
|
||||
"io.element.android.category.SHARE_TARGET",
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `onLeftRoom removes a shortcut`() = runTest {
|
||||
val context = InstrumentationRegistry.getInstrumentation().context
|
||||
|
||||
Reference in New Issue
Block a user