Split module deeplink to api and impl.
This commit is contained in:
parent
ef230e3bda
commit
2b42271615
25 changed files with 150 additions and 85 deletions
|
|
@ -301,6 +301,7 @@ dependencies {
|
||||||
testImplementation(libs.test.turbine)
|
testImplementation(libs.test.turbine)
|
||||||
testImplementation(projects.libraries.matrix.test)
|
testImplementation(projects.libraries.matrix.test)
|
||||||
testImplementation(projects.services.toolbox.test)
|
testImplementation(projects.services.toolbox.test)
|
||||||
|
testImplementation(projects.tests.testutils)
|
||||||
|
|
||||||
koverDependencies()
|
koverDependencies()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import com.squareup.anvil.annotations.ContributesBinding
|
import com.squareup.anvil.annotations.ContributesBinding
|
||||||
import io.element.android.libraries.deeplink.DeepLinkCreator
|
import io.element.android.libraries.deeplink.api.DeepLinkCreator
|
||||||
import io.element.android.libraries.di.AppScope
|
import io.element.android.libraries.di.AppScope
|
||||||
import io.element.android.libraries.di.ApplicationContext
|
import io.element.android.libraries.di.ApplicationContext
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,22 @@
|
||||||
* Please see LICENSE files in the repository root for full details.
|
* Please see LICENSE files in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("SameParameterValue")
|
||||||
|
|
||||||
package io.element.android.x.intent
|
package io.element.android.x.intent
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import io.element.android.libraries.deeplink.DeepLinkCreator
|
import io.element.android.libraries.deeplink.api.DeepLinkCreator
|
||||||
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
|
import io.element.android.libraries.matrix.api.core.ThreadId
|
||||||
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||||
import io.element.android.libraries.matrix.test.A_SESSION_ID
|
import io.element.android.libraries.matrix.test.A_SESSION_ID
|
||||||
import io.element.android.libraries.matrix.test.A_THREAD_ID
|
import io.element.android.libraries.matrix.test.A_THREAD_ID
|
||||||
|
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
||||||
|
import io.element.android.tests.testutils.lambda.value
|
||||||
import io.element.android.x.MainActivity
|
import io.element.android.x.MainActivity
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
|
|
@ -23,45 +30,31 @@ import org.robolectric.RuntimeEnvironment
|
||||||
@RunWith(RobolectricTestRunner::class)
|
@RunWith(RobolectricTestRunner::class)
|
||||||
class DefaultIntentProviderTest {
|
class DefaultIntentProviderTest {
|
||||||
@Test
|
@Test
|
||||||
fun `test getViewRoomIntent with Session`() {
|
fun `test getViewRoomIntent with data`() {
|
||||||
val sut = createDefaultIntentProvider()
|
val deepLinkCreator = lambdaRecorder<SessionId, RoomId?, ThreadId?, String> { _, _, _ -> "deepLinkCreatorResult" }
|
||||||
val result = sut.getViewRoomIntent(
|
val sut = createDefaultIntentProvider(
|
||||||
sessionId = A_SESSION_ID,
|
deepLinkCreator = { sessionId, roomId, threadId -> deepLinkCreator.invoke(sessionId, roomId, threadId) },
|
||||||
roomId = null,
|
|
||||||
threadId = null,
|
|
||||||
)
|
)
|
||||||
result.commonAssertions()
|
|
||||||
assertThat(result.data.toString()).isEqualTo("elementx://open/@alice:server.org")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test getViewRoomIntent with Session and Room`() {
|
|
||||||
val sut = createDefaultIntentProvider()
|
|
||||||
val result = sut.getViewRoomIntent(
|
|
||||||
sessionId = A_SESSION_ID,
|
|
||||||
roomId = A_ROOM_ID,
|
|
||||||
threadId = null,
|
|
||||||
)
|
|
||||||
result.commonAssertions()
|
|
||||||
assertThat(result.data.toString()).isEqualTo("elementx://open/@alice:server.org/!aRoomId:domain")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `test getViewRoomIntent with Session, Room and Thread`() {
|
|
||||||
val sut = createDefaultIntentProvider()
|
|
||||||
val result = sut.getViewRoomIntent(
|
val result = sut.getViewRoomIntent(
|
||||||
sessionId = A_SESSION_ID,
|
sessionId = A_SESSION_ID,
|
||||||
roomId = A_ROOM_ID,
|
roomId = A_ROOM_ID,
|
||||||
threadId = A_THREAD_ID,
|
threadId = A_THREAD_ID,
|
||||||
)
|
)
|
||||||
result.commonAssertions()
|
result.commonAssertions()
|
||||||
assertThat(result.data.toString()).isEqualTo("elementx://open/@alice:server.org/!aRoomId:domain/\$aThreadId")
|
assertThat(result.data.toString()).isEqualTo("deepLinkCreatorResult")
|
||||||
|
deepLinkCreator.assertions().isCalledOnce().with(
|
||||||
|
value(A_SESSION_ID),
|
||||||
|
value(A_ROOM_ID),
|
||||||
|
value(A_THREAD_ID),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createDefaultIntentProvider(): DefaultIntentProvider {
|
private fun createDefaultIntentProvider(
|
||||||
|
deepLinkCreator: DeepLinkCreator = DeepLinkCreator { _, _, _ -> "" },
|
||||||
|
): DefaultIntentProvider {
|
||||||
return DefaultIntentProvider(
|
return DefaultIntentProvider(
|
||||||
context = RuntimeEnvironment.getApplication() as Context,
|
context = RuntimeEnvironment.getApplication() as Context,
|
||||||
deepLinkCreator = DeepLinkCreator(),
|
deepLinkCreator = deepLinkCreator,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ dependencies {
|
||||||
implementation(projects.libraries.core)
|
implementation(projects.libraries.core)
|
||||||
implementation(projects.libraries.androidutils)
|
implementation(projects.libraries.androidutils)
|
||||||
implementation(projects.libraries.architecture)
|
implementation(projects.libraries.architecture)
|
||||||
implementation(projects.libraries.deeplink)
|
implementation(projects.libraries.deeplink.api)
|
||||||
implementation(projects.libraries.matrix.api)
|
implementation(projects.libraries.matrix.api)
|
||||||
implementation(projects.libraries.oidc.api)
|
implementation(projects.libraries.oidc.api)
|
||||||
implementation(projects.libraries.preferences.api)
|
implementation(projects.libraries.preferences.api)
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ import io.element.android.libraries.architecture.BaseFlowNode
|
||||||
import io.element.android.libraries.architecture.createNode
|
import io.element.android.libraries.architecture.createNode
|
||||||
import io.element.android.libraries.architecture.waitForChildAttached
|
import io.element.android.libraries.architecture.waitForChildAttached
|
||||||
import io.element.android.libraries.core.uri.ensureProtocol
|
import io.element.android.libraries.core.uri.ensureProtocol
|
||||||
import io.element.android.libraries.deeplink.DeeplinkData
|
import io.element.android.libraries.deeplink.api.DeeplinkData
|
||||||
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
|
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
|
||||||
import io.element.android.libraries.di.AppScope
|
import io.element.android.libraries.di.AppScope
|
||||||
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
|
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ package io.element.android.appnav.intent
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import io.element.android.features.login.api.LoginIntentResolver
|
import io.element.android.features.login.api.LoginIntentResolver
|
||||||
import io.element.android.features.login.api.LoginParams
|
import io.element.android.features.login.api.LoginParams
|
||||||
import io.element.android.libraries.deeplink.DeeplinkData
|
import io.element.android.libraries.deeplink.api.DeeplinkData
|
||||||
import io.element.android.libraries.deeplink.DeeplinkParser
|
import io.element.android.libraries.deeplink.api.DeeplinkParser
|
||||||
import io.element.android.libraries.matrix.api.permalink.PermalinkData
|
import io.element.android.libraries.matrix.api.permalink.PermalinkData
|
||||||
import io.element.android.libraries.matrix.api.permalink.PermalinkParser
|
import io.element.android.libraries.matrix.api.permalink.PermalinkParser
|
||||||
import io.element.android.libraries.oidc.api.OidcAction
|
import io.element.android.libraries.oidc.api.OidcAction
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,7 @@ import androidx.core.net.toUri
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import io.element.android.features.login.api.LoginParams
|
import io.element.android.features.login.api.LoginParams
|
||||||
import io.element.android.features.login.test.FakeLoginIntentResolver
|
import io.element.android.features.login.test.FakeLoginIntentResolver
|
||||||
import io.element.android.libraries.deeplink.DeepLinkCreator
|
import io.element.android.libraries.deeplink.api.DeeplinkData
|
||||||
import io.element.android.libraries.deeplink.DeeplinkData
|
|
||||||
import io.element.android.libraries.deeplink.DeeplinkParser
|
|
||||||
import io.element.android.libraries.matrix.api.core.UserId
|
import io.element.android.libraries.matrix.api.core.UserId
|
||||||
import io.element.android.libraries.matrix.api.permalink.PermalinkData
|
import io.element.android.libraries.matrix.api.permalink.PermalinkData
|
||||||
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||||
|
|
@ -46,15 +44,11 @@ class IntentResolverTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test resolve navigation intent root`() {
|
fun `test resolve navigation intent root`() {
|
||||||
val sut = createIntentResolver()
|
val sut = createIntentResolver(
|
||||||
|
deeplinkParserResult = DeeplinkData.Root(A_SESSION_ID)
|
||||||
|
)
|
||||||
val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply {
|
val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply {
|
||||||
action = Intent.ACTION_VIEW
|
action = Intent.ACTION_VIEW
|
||||||
data = DeepLinkCreator().room(
|
|
||||||
sessionId = A_SESSION_ID,
|
|
||||||
roomId = null,
|
|
||||||
threadId = null,
|
|
||||||
)
|
|
||||||
.toUri()
|
|
||||||
}
|
}
|
||||||
val result = sut.resolve(intent)
|
val result = sut.resolve(intent)
|
||||||
assertThat(result).isEqualTo(
|
assertThat(result).isEqualTo(
|
||||||
|
|
@ -68,15 +62,15 @@ class IntentResolverTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test resolve navigation intent room`() {
|
fun `test resolve navigation intent room`() {
|
||||||
val sut = createIntentResolver()
|
val sut = createIntentResolver(
|
||||||
val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply {
|
deeplinkParserResult = DeeplinkData.Room(
|
||||||
action = Intent.ACTION_VIEW
|
|
||||||
data = DeepLinkCreator().room(
|
|
||||||
sessionId = A_SESSION_ID,
|
sessionId = A_SESSION_ID,
|
||||||
roomId = A_ROOM_ID,
|
roomId = A_ROOM_ID,
|
||||||
threadId = null,
|
threadId = null,
|
||||||
)
|
)
|
||||||
.toUri()
|
)
|
||||||
|
val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply {
|
||||||
|
action = Intent.ACTION_VIEW
|
||||||
}
|
}
|
||||||
val result = sut.resolve(intent)
|
val result = sut.resolve(intent)
|
||||||
assertThat(result).isEqualTo(
|
assertThat(result).isEqualTo(
|
||||||
|
|
@ -92,15 +86,15 @@ class IntentResolverTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `test resolve navigation intent thread`() {
|
fun `test resolve navigation intent thread`() {
|
||||||
val sut = createIntentResolver()
|
val sut = createIntentResolver(
|
||||||
val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply {
|
deeplinkParserResult = DeeplinkData.Room(
|
||||||
action = Intent.ACTION_VIEW
|
|
||||||
data = DeepLinkCreator().room(
|
|
||||||
sessionId = A_SESSION_ID,
|
sessionId = A_SESSION_ID,
|
||||||
roomId = A_ROOM_ID,
|
roomId = A_ROOM_ID,
|
||||||
threadId = A_THREAD_ID,
|
threadId = A_THREAD_ID,
|
||||||
)
|
)
|
||||||
.toUri()
|
)
|
||||||
|
val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply {
|
||||||
|
action = Intent.ACTION_VIEW
|
||||||
}
|
}
|
||||||
val result = sut.resolve(intent)
|
val result = sut.resolve(intent)
|
||||||
assertThat(result).isEqualTo(
|
assertThat(result).isEqualTo(
|
||||||
|
|
@ -240,12 +234,13 @@ class IntentResolverTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createIntentResolver(
|
private fun createIntentResolver(
|
||||||
|
deeplinkParserResult: DeeplinkData? = null,
|
||||||
permalinkParserResult: (String) -> PermalinkData = { lambdaError() },
|
permalinkParserResult: (String) -> PermalinkData = { lambdaError() },
|
||||||
loginIntentResolverResult: (String) -> LoginParams? = { lambdaError() },
|
loginIntentResolverResult: (String) -> LoginParams? = { lambdaError() },
|
||||||
oidcIntentResolverResult: (Intent) -> OidcAction? = { lambdaError() },
|
oidcIntentResolverResult: (Intent) -> OidcAction? = { lambdaError() },
|
||||||
): IntentResolver {
|
): IntentResolver {
|
||||||
return IntentResolver(
|
return IntentResolver(
|
||||||
deeplinkParser = DeeplinkParser(),
|
deeplinkParser = { deeplinkParserResult },
|
||||||
loginIntentResolver = FakeLoginIntentResolver(
|
loginIntentResolver = FakeLoginIntentResolver(
|
||||||
parseResult = loginIntentResolverResult,
|
parseResult = loginIntentResolverResult,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ dependencies {
|
||||||
implementation(projects.libraries.designsystem)
|
implementation(projects.libraries.designsystem)
|
||||||
implementation(projects.libraries.uiStrings)
|
implementation(projects.libraries.uiStrings)
|
||||||
implementation(projects.libraries.androidutils)
|
implementation(projects.libraries.androidutils)
|
||||||
implementation(projects.libraries.deeplink)
|
implementation(projects.libraries.deeplink.api)
|
||||||
implementation(projects.libraries.mediapickers.api)
|
implementation(projects.libraries.mediapickers.api)
|
||||||
implementation(projects.libraries.mediaupload.api)
|
implementation(projects.libraries.mediaupload.api)
|
||||||
implementation(projects.libraries.permissions.api)
|
implementation(projects.libraries.permissions.api)
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ dependencies {
|
||||||
implementation(projects.libraries.dateformatter.api)
|
implementation(projects.libraries.dateformatter.api)
|
||||||
implementation(projects.libraries.eventformatter.api)
|
implementation(projects.libraries.eventformatter.api)
|
||||||
implementation(projects.libraries.indicator.api)
|
implementation(projects.libraries.indicator.api)
|
||||||
implementation(projects.libraries.deeplink)
|
implementation(projects.libraries.deeplink.api)
|
||||||
implementation(projects.libraries.fullscreenintent.api)
|
implementation(projects.libraries.fullscreenintent.api)
|
||||||
implementation(projects.libraries.permissions.api)
|
implementation(projects.libraries.permissions.api)
|
||||||
implementation(projects.libraries.permissions.noop)
|
implementation(projects.libraries.permissions.noop)
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ import io.element.android.features.reportroom.api.ReportRoomEntryPoint
|
||||||
import io.element.android.libraries.architecture.BackstackView
|
import io.element.android.libraries.architecture.BackstackView
|
||||||
import io.element.android.libraries.architecture.BaseFlowNode
|
import io.element.android.libraries.architecture.BaseFlowNode
|
||||||
import io.element.android.libraries.architecture.appyx.launchMolecule
|
import io.element.android.libraries.architecture.appyx.launchMolecule
|
||||||
import io.element.android.libraries.deeplink.usecase.InviteFriendsUseCase
|
import io.element.android.libraries.deeplink.api.usecase.InviteFriendsUseCase
|
||||||
import io.element.android.libraries.di.SessionScope
|
import io.element.android.libraries.di.SessionScope
|
||||||
import io.element.android.libraries.matrix.api.MatrixClient
|
import io.element.android.libraries.matrix.api.MatrixClient
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ dependencies {
|
||||||
implementation(projects.libraries.designsystem)
|
implementation(projects.libraries.designsystem)
|
||||||
implementation(projects.libraries.uiStrings)
|
implementation(projects.libraries.uiStrings)
|
||||||
implementation(projects.libraries.androidutils)
|
implementation(projects.libraries.androidutils)
|
||||||
implementation(projects.libraries.deeplink)
|
implementation(projects.libraries.deeplink.api)
|
||||||
implementation(projects.libraries.mediapickers.api)
|
implementation(projects.libraries.mediapickers.api)
|
||||||
implementation(projects.libraries.mediaupload.api)
|
implementation(projects.libraries.mediaupload.api)
|
||||||
implementation(projects.libraries.permissions.api)
|
implementation(projects.libraries.permissions.api)
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import dagger.assisted.AssistedInject
|
||||||
import im.vector.app.features.analytics.plan.MobileScreen
|
import im.vector.app.features.analytics.plan.MobileScreen
|
||||||
import io.element.android.anvilannotations.ContributesNode
|
import io.element.android.anvilannotations.ContributesNode
|
||||||
import io.element.android.features.startchat.StartChatNavigator
|
import io.element.android.features.startchat.StartChatNavigator
|
||||||
import io.element.android.libraries.deeplink.usecase.InviteFriendsUseCase
|
import io.element.android.libraries.deeplink.api.usecase.InviteFriendsUseCase
|
||||||
import io.element.android.libraries.di.SessionScope
|
import io.element.android.libraries.di.SessionScope
|
||||||
import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias
|
import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias
|
||||||
import io.element.android.services.analytics.api.AnalyticsService
|
import io.element.android.services.analytics.api.AnalyticsService
|
||||||
|
|
|
||||||
17
libraries/deeplink/api/build.gradle.kts
Normal file
17
libraries/deeplink/api/build.gradle.kts
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2022-2024 New Vector Ltd.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||||
|
* Please see LICENSE files in the repository root for full details.
|
||||||
|
*/
|
||||||
|
plugins {
|
||||||
|
id("io.element.android-library")
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace = "io.element.android.libraries.deeplink.api"
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(projects.libraries.matrix.api)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023, 2024 New Vector 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.libraries.deeplink.api
|
||||||
|
|
||||||
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
|
import io.element.android.libraries.matrix.api.core.ThreadId
|
||||||
|
|
||||||
|
fun interface DeepLinkCreator {
|
||||||
|
fun room(sessionId: SessionId, roomId: RoomId?, threadId: ThreadId?): String
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
* Please see LICENSE files in the repository root for full details.
|
* Please see LICENSE files in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.deeplink
|
package io.element.android.libraries.deeplink.api
|
||||||
|
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
import io.element.android.libraries.matrix.api.core.SessionId
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023, 2024 New Vector 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.libraries.deeplink.api
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
|
||||||
|
fun interface DeeplinkParser {
|
||||||
|
fun getFromIntent(intent: Intent): DeeplinkData?
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023, 2024 New Vector 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.libraries.deeplink.api.usecase
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
|
||||||
|
interface InviteFriendsUseCase {
|
||||||
|
fun execute(activity: Activity)
|
||||||
|
}
|
||||||
|
|
@ -6,17 +6,19 @@ import extension.setupAnvil
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||||
* Please see LICENSE files in the repository root for full details.
|
* Please see LICENSE files in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("io.element.android-library")
|
id("io.element.android-library")
|
||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "io.element.android.libraries.deeplink"
|
namespace = "io.element.android.libraries.deeplink.impl"
|
||||||
}
|
}
|
||||||
|
|
||||||
setupAnvil()
|
setupAnvil()
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
api(projects.libraries.deeplink.api)
|
||||||
implementation(projects.libraries.di)
|
implementation(projects.libraries.di)
|
||||||
implementation(libs.dagger)
|
implementation(libs.dagger)
|
||||||
implementation(libs.androidx.corektx)
|
implementation(libs.androidx.corektx)
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
* Please see LICENSE files in the repository root for full details.
|
* Please see LICENSE files in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.deeplink
|
package io.element.android.libraries.deeplink.impl
|
||||||
|
|
||||||
internal const val SCHEME = "elementx"
|
internal const val SCHEME = "elementx"
|
||||||
internal const val HOST = "open"
|
internal const val HOST = "open"
|
||||||
|
|
@ -1,19 +1,23 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2023, 2024 New Vector Ltd.
|
* Copyright 2025 New Vector Ltd.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||||
* Please see LICENSE files in the repository root for full details.
|
* Please see LICENSE files in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.deeplink
|
package io.element.android.libraries.deeplink.impl
|
||||||
|
|
||||||
|
import com.squareup.anvil.annotations.ContributesBinding
|
||||||
|
import io.element.android.libraries.deeplink.api.DeepLinkCreator
|
||||||
|
import io.element.android.libraries.di.AppScope
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
import io.element.android.libraries.matrix.api.core.SessionId
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
import io.element.android.libraries.matrix.api.core.ThreadId
|
import io.element.android.libraries.matrix.api.core.ThreadId
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class DeepLinkCreator @Inject constructor() {
|
@ContributesBinding(AppScope::class)
|
||||||
fun room(sessionId: SessionId, roomId: RoomId?, threadId: ThreadId?): String {
|
class DefaultDeepLinkCreator @Inject constructor() : DeepLinkCreator {
|
||||||
|
override fun room(sessionId: SessionId, roomId: RoomId?, threadId: ThreadId?): String {
|
||||||
return buildString {
|
return buildString {
|
||||||
append("$SCHEME://$HOST/")
|
append("$SCHEME://$HOST/")
|
||||||
append(sessionId.value)
|
append(sessionId.value)
|
||||||
|
|
@ -1,21 +1,26 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2023, 2024 New Vector Ltd.
|
* Copyright 2025 New Vector Ltd.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||||
* Please see LICENSE files in the repository root for full details.
|
* Please see LICENSE files in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.deeplink
|
package io.element.android.libraries.deeplink.impl
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import com.squareup.anvil.annotations.ContributesBinding
|
||||||
|
import io.element.android.libraries.deeplink.api.DeeplinkData
|
||||||
|
import io.element.android.libraries.deeplink.api.DeeplinkParser
|
||||||
|
import io.element.android.libraries.di.AppScope
|
||||||
import io.element.android.libraries.matrix.api.core.RoomId
|
import io.element.android.libraries.matrix.api.core.RoomId
|
||||||
import io.element.android.libraries.matrix.api.core.SessionId
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
import io.element.android.libraries.matrix.api.core.ThreadId
|
import io.element.android.libraries.matrix.api.core.ThreadId
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class DeeplinkParser @Inject constructor() {
|
@ContributesBinding(AppScope::class)
|
||||||
fun getFromIntent(intent: Intent): DeeplinkData? {
|
class DefaultDeeplinkParser @Inject constructor() : DeeplinkParser {
|
||||||
|
override fun getFromIntent(intent: Intent): DeeplinkData? {
|
||||||
return intent
|
return intent
|
||||||
.takeIf { it.action == Intent.ACTION_VIEW }
|
.takeIf { it.action == Intent.ACTION_VIEW }
|
||||||
?.data
|
?.data
|
||||||
|
|
@ -1,15 +1,18 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2023, 2024 New Vector Ltd.
|
* Copyright 2025 New Vector Ltd.
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||||
* Please see LICENSE files in the repository root for full details.
|
* Please see LICENSE files in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.deeplink.usecase
|
package io.element.android.libraries.deeplink.impl.usecase
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
|
import com.squareup.anvil.annotations.ContributesBinding
|
||||||
import io.element.android.libraries.androidutils.system.startSharePlainTextIntent
|
import io.element.android.libraries.androidutils.system.startSharePlainTextIntent
|
||||||
import io.element.android.libraries.core.meta.BuildMeta
|
import io.element.android.libraries.core.meta.BuildMeta
|
||||||
|
import io.element.android.libraries.deeplink.api.usecase.InviteFriendsUseCase
|
||||||
|
import io.element.android.libraries.di.SessionScope
|
||||||
import io.element.android.libraries.matrix.api.MatrixClient
|
import io.element.android.libraries.matrix.api.MatrixClient
|
||||||
import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder
|
import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder
|
||||||
import io.element.android.libraries.ui.strings.CommonStrings
|
import io.element.android.libraries.ui.strings.CommonStrings
|
||||||
|
|
@ -18,13 +21,14 @@ import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import io.element.android.libraries.androidutils.R as AndroidUtilsR
|
import io.element.android.libraries.androidutils.R as AndroidUtilsR
|
||||||
|
|
||||||
class InviteFriendsUseCase @Inject constructor(
|
@ContributesBinding(SessionScope::class)
|
||||||
|
class DefaultInviteFriendsUseCase @Inject constructor(
|
||||||
private val stringProvider: StringProvider,
|
private val stringProvider: StringProvider,
|
||||||
private val matrixClient: MatrixClient,
|
private val matrixClient: MatrixClient,
|
||||||
private val buildMeta: BuildMeta,
|
private val buildMeta: BuildMeta,
|
||||||
private val permalinkBuilder: PermalinkBuilder,
|
private val permalinkBuilder: PermalinkBuilder,
|
||||||
) {
|
) : InviteFriendsUseCase {
|
||||||
fun execute(activity: Activity) {
|
override fun execute(activity: Activity) {
|
||||||
val permalinkResult = permalinkBuilder.permalinkForUser(matrixClient.sessionId)
|
val permalinkResult = permalinkBuilder.permalinkForUser(matrixClient.sessionId)
|
||||||
permalinkResult.fold(
|
permalinkResult.fold(
|
||||||
onSuccess = { permalink ->
|
onSuccess = { permalink ->
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
* Please see LICENSE files in the repository root for full details.
|
* Please see LICENSE files in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.deeplink
|
package io.element.android.libraries.deeplink.impl
|
||||||
|
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||||
|
|
@ -13,10 +13,10 @@ import io.element.android.libraries.matrix.test.A_SESSION_ID
|
||||||
import io.element.android.libraries.matrix.test.A_THREAD_ID
|
import io.element.android.libraries.matrix.test.A_THREAD_ID
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
class DeepLinkCreatorTest {
|
class DefaultDeepLinkCreatorTest {
|
||||||
@Test
|
@Test
|
||||||
fun room() {
|
fun room() {
|
||||||
val sut = DeepLinkCreator()
|
val sut = DefaultDeepLinkCreator()
|
||||||
assertThat(sut.room(A_SESSION_ID, null, null))
|
assertThat(sut.room(A_SESSION_ID, null, null))
|
||||||
.isEqualTo("elementx://open/@alice:server.org")
|
.isEqualTo("elementx://open/@alice:server.org")
|
||||||
assertThat(sut.room(A_SESSION_ID, A_ROOM_ID, null))
|
assertThat(sut.room(A_SESSION_ID, A_ROOM_ID, null))
|
||||||
|
|
@ -5,11 +5,12 @@
|
||||||
* Please see LICENSE files in the repository root for full details.
|
* Please see LICENSE files in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package io.element.android.libraries.deeplink
|
package io.element.android.libraries.deeplink.impl
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import io.element.android.libraries.deeplink.api.DeeplinkData
|
||||||
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
import io.element.android.libraries.matrix.test.A_ROOM_ID
|
||||||
import io.element.android.libraries.matrix.test.A_SESSION_ID
|
import io.element.android.libraries.matrix.test.A_SESSION_ID
|
||||||
import io.element.android.libraries.matrix.test.A_THREAD_ID
|
import io.element.android.libraries.matrix.test.A_THREAD_ID
|
||||||
|
|
@ -19,7 +20,7 @@ import org.junit.runner.RunWith
|
||||||
import org.robolectric.RobolectricTestRunner
|
import org.robolectric.RobolectricTestRunner
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner::class)
|
@RunWith(RobolectricTestRunner::class)
|
||||||
class DeeplinkParserTest {
|
class DefaultDeeplinkParserTest {
|
||||||
companion object {
|
companion object {
|
||||||
const val A_URI =
|
const val A_URI =
|
||||||
"elementx://open/@alice:server.org"
|
"elementx://open/@alice:server.org"
|
||||||
|
|
@ -29,10 +30,9 @@ class DeeplinkParserTest {
|
||||||
"elementx://open/@alice:server.org/!aRoomId:domain/\$aThreadId"
|
"elementx://open/@alice:server.org/!aRoomId:domain/\$aThreadId"
|
||||||
}
|
}
|
||||||
|
|
||||||
private val sut = DeeplinkParser()
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `nominal cases`() {
|
fun `nominal cases`() {
|
||||||
|
val sut = DefaultDeeplinkParser()
|
||||||
assertThat(sut.getFromIntent(createIntent(A_URI)))
|
assertThat(sut.getFromIntent(createIntent(A_URI)))
|
||||||
.isEqualTo(DeeplinkData.Root(A_SESSION_ID))
|
.isEqualTo(DeeplinkData.Root(A_SESSION_ID))
|
||||||
assertThat(sut.getFromIntent(createIntent(A_URI_WITH_ROOM)))
|
assertThat(sut.getFromIntent(createIntent(A_URI_WITH_ROOM)))
|
||||||
|
|
@ -43,7 +43,7 @@ class DeeplinkParserTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `error cases`() {
|
fun `error cases`() {
|
||||||
val sut = DeeplinkParser()
|
val sut = DefaultDeeplinkParser()
|
||||||
// Bad scheme
|
// Bad scheme
|
||||||
assertThat(sut.getFromIntent(createIntent("x://open/@alice:server.org"))).isNull()
|
assertThat(sut.getFromIntent(createIntent("x://open/@alice:server.org"))).isNull()
|
||||||
// Bad host
|
// Bad host
|
||||||
|
|
@ -59,7 +59,7 @@ fun DependencyHandlerScope.composeDependencies(libs: LibrariesForLibs) {
|
||||||
|
|
||||||
fun DependencyHandlerScope.allLibrariesImpl() {
|
fun DependencyHandlerScope.allLibrariesImpl() {
|
||||||
implementation(project(":libraries:androidutils"))
|
implementation(project(":libraries:androidutils"))
|
||||||
implementation(project(":libraries:deeplink"))
|
implementation(project(":libraries:deeplink:impl"))
|
||||||
implementation(project(":libraries:designsystem"))
|
implementation(project(":libraries:designsystem"))
|
||||||
implementation(project(":libraries:matrix:impl"))
|
implementation(project(":libraries:matrix:impl"))
|
||||||
implementation(project(":libraries:matrixui"))
|
implementation(project(":libraries:matrixui"))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue