mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-04 10:32:34 +00:00
Merge pull request #7574 from hayaksi1/fix/3835-direct-share-targets
Offer conversations in the system share sheet
This commit is contained in:
@@ -139,6 +139,12 @@
|
|||||||
<data android:host="user" />
|
<data android:host="user" />
|
||||||
<data android:host="room" />
|
<data android:host="room" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
<!--
|
||||||
|
Conversation shortcuts offered in the Direct Share row of the system share sheet.
|
||||||
|
-->
|
||||||
|
<meta-data
|
||||||
|
android:name="android.app.shortcuts"
|
||||||
|
android:resource="@xml/shortcuts" />
|
||||||
<!-- Incoming share simple -->
|
<!-- Incoming share simple -->
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.SEND" />
|
<action android:name="android.intent.action.SEND" />
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (c) 2026 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.
|
||||||
|
-->
|
||||||
|
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<!--
|
||||||
|
Lets the system offer the conversation shortcuts published by
|
||||||
|
DefaultNotificationConversationService in the Direct Share row of the share sheet.
|
||||||
|
The category must match SHARE_TARGET_CATEGORY in that class.
|
||||||
|
-->
|
||||||
|
<share-target android:targetClass="io.element.android.x.MainActivity">
|
||||||
|
<data android:mimeType="*/*" />
|
||||||
|
<category android:name="io.element.android.category.SHARE_TARGET" />
|
||||||
|
</share-target>
|
||||||
|
</shortcuts>
|
||||||
+8
-1
@@ -42,6 +42,12 @@ import kotlinx.coroutines.flow.launchIn
|
|||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import timber.log.Timber
|
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)
|
@SingleIn(AppScope::class)
|
||||||
@ContributesBinding(AppScope::class)
|
@ContributesBinding(AppScope::class)
|
||||||
class DefaultNotificationConversationService(
|
class DefaultNotificationConversationService(
|
||||||
@@ -86,7 +92,8 @@ class DefaultNotificationConversationService(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val categories = setOfNotNull(
|
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
|
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.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.pm.ShortcutInfo
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.core.content.pm.ShortcutInfoCompat
|
import androidx.core.content.pm.ShortcutInfoCompat
|
||||||
import androidx.core.content.pm.ShortcutManagerCompat
|
import androidx.core.content.pm.ShortcutManagerCompat
|
||||||
@@ -52,6 +53,27 @@ class DefaultNotificationConversationServiceTest : RobolectricTest() {
|
|||||||
assertThat(shortcuts).isNotEmpty()
|
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
|
@Test
|
||||||
fun `onLeftRoom removes a shortcut`() = runTest {
|
fun `onLeftRoom removes a shortcut`() = runTest {
|
||||||
val context = InstrumentationRegistry.getInstrumentation().context
|
val context = InstrumentationRegistry.getInstrumentation().context
|
||||||
|
|||||||
Reference in New Issue
Block a user