From 3df5ca58b7b14a164a220dbd21b552b13159262a Mon Sep 17 00:00:00 2001 From: Gabriel Ittner Date: Fri, 6 Oct 2023 11:49:51 +0200 Subject: [PATCH] move as much DeepLink code as possible to common --- build.gradle.kts | 8 + .../FileGeneratorTestNavHostActivity.kt | 20 +-- .../khonshu/codegen/codegen/util/External.kt | 2 +- gradle/libs.versions.toml | 2 +- .../internal/AndroidXDeepLinkHandler.kt | 8 +- .../khonshu/navigation/compose/NavHost.kt | 2 +- .../khonshu/navigation/compose/NavHost.kt | 2 +- .../MultiStackNavigationExecutorBuilder.kt | 7 +- .../navigation/fragment/NavHostFragment.kt | 2 +- navigation/api/android/navigation.api | 119 +++++++------- navigation/api/jvm/navigation.api | 51 ++++++ navigation/navigation.gradle.kts | 3 +- .../freeletics/khonshu/navigation/DeepLink.kt | 145 ------------------ .../deeplinks/ActivityRouteDeepLink.kt | 50 ++++++ .../deeplinks/AndroidDeepLinkExtensions.kt | 58 +++++++ .../DeepLinkMatcherTest.kt | 108 ++++++++----- .../DeepLinkParserTest.kt | 29 ++-- .../test/DeepLinkHandlerPatternSubject.kt | 4 +- .../navigation/test/DeepLinkHandlerSubject.kt | 6 +- .../khonshu/navigation/test/Routes.kt | 2 +- .../navigation/test/TestDeepLinkHandler.kt | 8 +- .../khonshu/navigation/deeplinks/DeepLink.kt | 45 ++++++ .../navigation/deeplinks}/DeepLinkHandler.kt | 2 +- .../navigation/deeplinks}/DeepLinkMatcher.kt | 8 +- .../navigation/deeplinks}/DeepLinkParser.kt | 7 +- 25 files changed, 398 insertions(+), 300 deletions(-) delete mode 100644 navigation/src/androidMain/kotlin/com/freeletics/khonshu/navigation/DeepLink.kt create mode 100644 navigation/src/androidMain/kotlin/com/freeletics/khonshu/navigation/deeplinks/ActivityRouteDeepLink.kt create mode 100644 navigation/src/androidMain/kotlin/com/freeletics/khonshu/navigation/deeplinks/AndroidDeepLinkExtensions.kt rename navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/{internal => deeplinks}/DeepLinkMatcherTest.kt (59%) rename navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/{internal => deeplinks}/DeepLinkParserTest.kt (87%) create mode 100644 navigation/src/commonMain/kotlin/com/freeletics/khonshu/navigation/deeplinks/DeepLink.kt rename navigation/src/{androidMain/kotlin/com/freeletics/khonshu/navigation => commonMain/kotlin/com/freeletics/khonshu/navigation/deeplinks}/DeepLinkHandler.kt (98%) rename navigation/src/{androidMain/kotlin/com/freeletics/khonshu/navigation/internal => commonMain/kotlin/com/freeletics/khonshu/navigation/deeplinks}/DeepLinkMatcher.kt (91%) rename navigation/src/{androidMain/kotlin/com/freeletics/khonshu/navigation/internal => commonMain/kotlin/com/freeletics/khonshu/navigation/deeplinks}/DeepLinkParser.kt (91%) diff --git a/build.gradle.kts b/build.gradle.kts index 1d1d1a007..be87aa0da 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -17,6 +17,14 @@ plugins { dependencyAnalysis { issues { all { + onAny { + // issue with Kotlin multiplatform artifacts + exclude( + "com.eygraber:uri-kmp", + "com.eygraber:uri-kmp-android", + "com.eygraber:uri-kmp-android-debug", + ) + } onUsedTransitiveDependencies { exclude("dev.drewhamilton.poko:poko-annotations") } diff --git a/codegen-compiler-test/src/test/kotlin/com/freeletics/khonshu/codegen/codegen/FileGeneratorTestNavHostActivity.kt b/codegen-compiler-test/src/test/kotlin/com/freeletics/khonshu/codegen/codegen/FileGeneratorTestNavHostActivity.kt index 939fdf1ed..809293dd1 100644 --- a/codegen-compiler-test/src/test/kotlin/com/freeletics/khonshu/codegen/codegen/FileGeneratorTestNavHostActivity.kt +++ b/codegen-compiler-test/src/test/kotlin/com/freeletics/khonshu/codegen/codegen/FileGeneratorTestNavHostActivity.kt @@ -59,9 +59,9 @@ internal class FileGeneratorTestNavHostActivity { import androidx.compose.runtime.Composable import com.freeletics.khonshu.codegen.compose.NavHostActivity import com.freeletics.khonshu.navigation.BaseRoute - import com.freeletics.khonshu.navigation.DeepLinkHandler import com.freeletics.khonshu.navigation.NavRoot import com.freeletics.khonshu.navigation.compose.NavDestination + import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler import com.test.parent.TestParentScope @NavHostActivity( @@ -96,10 +96,10 @@ internal class FileGeneratorTestNavHostActivity { import com.freeletics.khonshu.codegen.`internal`.asComposeState import com.freeletics.khonshu.codegen.`internal`.component import com.freeletics.khonshu.navigation.BaseRoute - import com.freeletics.khonshu.navigation.DeepLinkHandler import com.freeletics.khonshu.navigation.NavRoot import com.freeletics.khonshu.navigation.compose.NavDestination import com.freeletics.khonshu.navigation.compose.NavHost + import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler import com.squareup.anvil.annotations.ContributesSubcomponent import com.squareup.anvil.annotations.ContributesTo import com.squareup.anvil.annotations.optional.ForScope @@ -234,7 +234,7 @@ internal class FileGeneratorTestNavHostActivity { import com.freeletics.khonshu.codegen.ActivityScope import com.freeletics.khonshu.codegen.compose.NavHostActivity import com.freeletics.khonshu.navigation.BaseRoute - import com.freeletics.khonshu.navigation.DeepLinkHandler + import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler import com.freeletics.khonshu.navigation.NavRoot @NavHostActivity( @@ -269,10 +269,10 @@ internal class FileGeneratorTestNavHostActivity { import com.freeletics.khonshu.codegen.`internal`.asComposeState import com.freeletics.khonshu.codegen.`internal`.component import com.freeletics.khonshu.navigation.BaseRoute - import com.freeletics.khonshu.navigation.DeepLinkHandler import com.freeletics.khonshu.navigation.NavRoot import com.freeletics.khonshu.navigation.compose.NavDestination import com.freeletics.khonshu.navigation.compose.NavHost + import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler import com.squareup.anvil.annotations.ContributesSubcomponent import com.squareup.anvil.annotations.ContributesTo import com.squareup.anvil.annotations.optional.ForScope @@ -422,9 +422,9 @@ internal class FileGeneratorTestNavHostActivity { import androidx.compose.runtime.Composable import com.freeletics.khonshu.codegen.compose.NavHostActivity import com.freeletics.khonshu.navigation.BaseRoute - import com.freeletics.khonshu.navigation.DeepLinkHandler import com.freeletics.khonshu.navigation.NavRoot import com.freeletics.khonshu.navigation.compose.NavDestination + import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler import com.test.other.TestClass2 import com.test.parent.TestParentScope @@ -464,10 +464,10 @@ internal class FileGeneratorTestNavHostActivity { import com.freeletics.khonshu.codegen.`internal`.asComposeState import com.freeletics.khonshu.codegen.`internal`.component import com.freeletics.khonshu.navigation.BaseRoute - import com.freeletics.khonshu.navigation.DeepLinkHandler import com.freeletics.khonshu.navigation.NavRoot import com.freeletics.khonshu.navigation.compose.NavDestination import com.freeletics.khonshu.navigation.compose.NavHost + import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler import com.squareup.anvil.annotations.ContributesSubcomponent import com.squareup.anvil.annotations.ContributesTo import com.squareup.anvil.annotations.optional.ForScope @@ -620,9 +620,9 @@ internal class FileGeneratorTestNavHostActivity { import androidx.compose.runtime.Composable import com.freeletics.khonshu.codegen.compose.NavHostActivity import com.freeletics.khonshu.navigation.BaseRoute - import com.freeletics.khonshu.navigation.DeepLinkHandler import com.freeletics.khonshu.navigation.NavRoot import com.freeletics.khonshu.navigation.compose.NavDestination + import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler import com.test.parent.TestParentScope @NavHostActivity( @@ -655,10 +655,10 @@ internal class FileGeneratorTestNavHostActivity { import com.freeletics.khonshu.codegen.`internal`.asComposeState import com.freeletics.khonshu.codegen.`internal`.component import com.freeletics.khonshu.navigation.BaseRoute - import com.freeletics.khonshu.navigation.DeepLinkHandler import com.freeletics.khonshu.navigation.NavRoot import com.freeletics.khonshu.navigation.compose.NavDestination import com.freeletics.khonshu.navigation.compose.NavHost + import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler import com.squareup.anvil.annotations.ContributesSubcomponent import com.squareup.anvil.annotations.ContributesTo import com.squareup.anvil.annotations.optional.ForScope @@ -788,9 +788,9 @@ internal class FileGeneratorTestNavHostActivity { import androidx.compose.runtime.Composable import com.freeletics.khonshu.codegen.compose.NavHostActivity import com.freeletics.khonshu.navigation.BaseRoute - import com.freeletics.khonshu.navigation.DeepLinkHandler import com.freeletics.khonshu.navigation.NavRoot import com.freeletics.khonshu.navigation.compose.NavDestination + import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler import com.test.parent.TestParentScope @NavHostActivity( @@ -824,10 +824,10 @@ internal class FileGeneratorTestNavHostActivity { import com.freeletics.khonshu.codegen.`internal`.asComposeState import com.freeletics.khonshu.codegen.`internal`.component import com.freeletics.khonshu.navigation.BaseRoute - import com.freeletics.khonshu.navigation.DeepLinkHandler import com.freeletics.khonshu.navigation.NavRoot import com.freeletics.khonshu.navigation.compose.NavDestination import com.freeletics.khonshu.navigation.compose.NavHost + import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler import com.squareup.anvil.annotations.ContributesSubcomponent import com.squareup.anvil.annotations.ContributesTo import com.squareup.anvil.annotations.optional.ForScope diff --git a/codegen-compiler/src/main/kotlin/com/freeletics/khonshu/codegen/codegen/util/External.kt b/codegen-compiler/src/main/kotlin/com/freeletics/khonshu/codegen/codegen/util/External.kt index 8329d7437..a28517845 100644 --- a/codegen-compiler/src/main/kotlin/com/freeletics/khonshu/codegen/codegen/util/External.kt +++ b/codegen-compiler/src/main/kotlin/com/freeletics/khonshu/codegen/codegen/util/External.kt @@ -41,7 +41,7 @@ internal val composeLocalNavigationExecutor = MemberName("com.freeletics.khonshu.navigation.compose", "LocalNavigationExecutor") internal val fragmentFindNavigationExecutor = MemberName("com.freeletics.khonshu.navigation.fragment", "findNavigationExecutor") -internal val deepLinkHandler = ClassName("com.freeletics.khonshu.navigation", "DeepLinkHandler") +internal val deepLinkHandler = ClassName("com.freeletics.khonshu.navigation.deeplinks", "DeepLinkHandler") internal val deepLinkPrefix = deepLinkHandler.nestedClass("Prefix") internal val fragmentNavigationHandler = MemberName("com.freeletics.khonshu.navigation.fragment", "handleNavigation") internal val fragmentDestination = ClassName("com.freeletics.khonshu.navigation.fragment", "NavDestination") diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5b1977421..a2845c1fb 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -85,7 +85,7 @@ androidx-fragment = { module = "androidx.fragment:fragment", version.ref = "andr androidx-savedstate = { module = "androidx.savedstate:savedstate", version.ref = "androidx-savedstate" } androidx-viewbinding = { module = "androidx.databinding:viewbinding", version.ref = "android-gradle" } -uri = { module = "com.eygraber:uri-kmp-android", version.ref = "uri" } +uri = { module = "com.eygraber:uri-kmp", version.ref = "uri" } inject = { module = "javax.inject:javax.inject", version.ref = "inject" } dagger = { module = "com.google.dagger:dagger", version.ref = "dagger" } diff --git a/navigation-androidx/src/main/kotlin/com/freeletics/khonshu/navigation/internal/AndroidXDeepLinkHandler.kt b/navigation-androidx/src/main/kotlin/com/freeletics/khonshu/navigation/internal/AndroidXDeepLinkHandler.kt index c8fd1e339..f4b8c0f4d 100644 --- a/navigation-androidx/src/main/kotlin/com/freeletics/khonshu/navigation/internal/AndroidXDeepLinkHandler.kt +++ b/navigation-androidx/src/main/kotlin/com/freeletics/khonshu/navigation/internal/AndroidXDeepLinkHandler.kt @@ -9,9 +9,11 @@ import androidx.navigation.NavController.Companion.KEY_DEEP_LINK_IDS import com.eygraber.uri.Uri import com.freeletics.khonshu.navigation.ActivityRoute import com.freeletics.khonshu.navigation.BaseRoute -import com.freeletics.khonshu.navigation.DeepLink -import com.freeletics.khonshu.navigation.DeepLink.Companion.EXTRA_DEEPLINK_ROUTES -import com.freeletics.khonshu.navigation.DeepLinkHandler +import com.freeletics.khonshu.navigation.deeplinks.DeepLink +import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler +import com.freeletics.khonshu.navigation.deeplinks.EXTRA_DEEPLINK_ROUTES +import com.freeletics.khonshu.navigation.deeplinks.buildIntent +import com.freeletics.khonshu.navigation.deeplinks.createDeepLinkIfMatching /** * Handles 2 different kind of deep links: diff --git a/navigation-compose/src/main/kotlin/com/freeletics/khonshu/navigation/compose/NavHost.kt b/navigation-compose/src/main/kotlin/com/freeletics/khonshu/navigation/compose/NavHost.kt index 0b72ca4a2..3667f5c91 100644 --- a/navigation-compose/src/main/kotlin/com/freeletics/khonshu/navigation/compose/NavHost.kt +++ b/navigation-compose/src/main/kotlin/com/freeletics/khonshu/navigation/compose/NavHost.kt @@ -18,11 +18,11 @@ import androidx.navigation.compose.rememberNavController import androidx.navigation.createGraph import androidx.navigation.get import com.freeletics.khonshu.navigation.BaseRoute -import com.freeletics.khonshu.navigation.DeepLinkHandler import com.freeletics.khonshu.navigation.NavRoot import com.freeletics.khonshu.navigation.NavRoute import com.freeletics.khonshu.navigation.compose.internal.OverlayHost import com.freeletics.khonshu.navigation.compose.internal.OverlayNavigator +import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler import com.freeletics.khonshu.navigation.internal.AndroidXNavigationExecutor import com.freeletics.khonshu.navigation.internal.CustomActivityNavigator import com.freeletics.khonshu.navigation.internal.InternalNavigationApi diff --git a/navigation-experimental/src/main/kotlin/com/freeletics/khonshu/navigation/compose/NavHost.kt b/navigation-experimental/src/main/kotlin/com/freeletics/khonshu/navigation/compose/NavHost.kt index fe236a527..4148f919b 100644 --- a/navigation-experimental/src/main/kotlin/com/freeletics/khonshu/navigation/compose/NavHost.kt +++ b/navigation-experimental/src/main/kotlin/com/freeletics/khonshu/navigation/compose/NavHost.kt @@ -13,11 +13,11 @@ import androidx.compose.runtime.saveable.rememberSaveableStateHolder import androidx.compose.runtime.snapshotFlow import androidx.compose.runtime.staticCompositionLocalOf import com.freeletics.khonshu.navigation.BaseRoute -import com.freeletics.khonshu.navigation.DeepLinkHandler import com.freeletics.khonshu.navigation.NavRoot import com.freeletics.khonshu.navigation.compose.internal.MultiStackNavigationExecutor import com.freeletics.khonshu.navigation.compose.internal.StackEntry import com.freeletics.khonshu.navigation.compose.internal.rememberNavigationExecutor +import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler import com.freeletics.khonshu.navigation.internal.InternalNavigationApi import com.freeletics.khonshu.navigation.internal.NavigationExecutor import java.io.Closeable diff --git a/navigation-experimental/src/main/kotlin/com/freeletics/khonshu/navigation/compose/internal/MultiStackNavigationExecutorBuilder.kt b/navigation-experimental/src/main/kotlin/com/freeletics/khonshu/navigation/compose/internal/MultiStackNavigationExecutorBuilder.kt index 8791e4c95..4ad889565 100644 --- a/navigation-experimental/src/main/kotlin/com/freeletics/khonshu/navigation/compose/internal/MultiStackNavigationExecutorBuilder.kt +++ b/navigation-experimental/src/main/kotlin/com/freeletics/khonshu/navigation/compose/internal/MultiStackNavigationExecutorBuilder.kt @@ -9,15 +9,16 @@ import androidx.compose.ui.platform.LocalContext import androidx.lifecycle.SavedStateViewModelFactory import androidx.lifecycle.viewmodel.compose.viewModel import com.eygraber.uri.Uri -import com.freeletics.khonshu.navigation.DeepLink.Companion.EXTRA_DEEPLINK_ROUTES -import com.freeletics.khonshu.navigation.DeepLinkHandler import com.freeletics.khonshu.navigation.NavRoot import com.freeletics.khonshu.navigation.compose.ActivityDestination import com.freeletics.khonshu.navigation.compose.ContentDestination import com.freeletics.khonshu.navigation.compose.NavDestination import com.freeletics.khonshu.navigation.compose.findActivity import com.freeletics.khonshu.navigation.compose.internal.MultiStackNavigationExecutor.Companion.SAVED_STATE_STACK -import com.freeletics.khonshu.navigation.internal.createDeepLinkIfMatching +import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler +import com.freeletics.khonshu.navigation.deeplinks.EXTRA_DEEPLINK_ROUTES +import com.freeletics.khonshu.navigation.deeplinks.buildIntent +import com.freeletics.khonshu.navigation.deeplinks.createDeepLinkIfMatching @Composable internal fun rememberNavigationExecutor( diff --git a/navigation-fragment/src/main/kotlin/com/freeletics/khonshu/navigation/fragment/NavHostFragment.kt b/navigation-fragment/src/main/kotlin/com/freeletics/khonshu/navigation/fragment/NavHostFragment.kt index c8e5ae5b5..e0888f59d 100644 --- a/navigation-fragment/src/main/kotlin/com/freeletics/khonshu/navigation/fragment/NavHostFragment.kt +++ b/navigation-fragment/src/main/kotlin/com/freeletics/khonshu/navigation/fragment/NavHostFragment.kt @@ -10,7 +10,7 @@ import androidx.navigation.fragment.FragmentNavigator import androidx.navigation.fragment.NavHostFragment import androidx.navigation.get import com.freeletics.khonshu.navigation.BaseRoute -import com.freeletics.khonshu.navigation.DeepLinkHandler +import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler import com.freeletics.khonshu.navigation.internal.CustomActivityNavigator import com.freeletics.khonshu.navigation.internal.destinationId import com.freeletics.khonshu.navigation.internal.getArguments diff --git a/navigation/api/android/navigation.api b/navigation/api/android/navigation.api index 9e614407b..74f8e9701 100644 --- a/navigation/api/android/navigation.api +++ b/navigation/api/android/navigation.api @@ -16,60 +16,6 @@ public abstract interface class com/freeletics/khonshu/navigation/BaseRoute : an public abstract class com/freeletics/khonshu/navigation/ContractResultOwner : com/freeletics/khonshu/navigation/ResultOwner { } -public final class com/freeletics/khonshu/navigation/DeepLink { - public static final field Companion Lcom/freeletics/khonshu/navigation/DeepLink$Companion; - public static final field EXTRA_DEEPLINK_ROUTES Ljava/lang/String; - public fun (Lcom/freeletics/khonshu/navigation/ActivityRoute;Ljava/lang/String;)V - public synthetic fun (Lcom/freeletics/khonshu/navigation/ActivityRoute;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun (Lcom/freeletics/khonshu/navigation/NavRoot;Ljava/util/List;Lcom/freeletics/khonshu/navigation/ActivityRoute;Ljava/lang/String;)V - public synthetic fun (Lcom/freeletics/khonshu/navigation/NavRoot;Ljava/util/List;Lcom/freeletics/khonshu/navigation/ActivityRoute;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun (Lcom/freeletics/khonshu/navigation/NavRoot;Ljava/util/List;Ljava/lang/String;)V - public synthetic fun (Lcom/freeletics/khonshu/navigation/NavRoot;Ljava/util/List;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun (Ljava/util/List;Lcom/freeletics/khonshu/navigation/ActivityRoute;Ljava/lang/String;)V - public synthetic fun (Ljava/util/List;Lcom/freeletics/khonshu/navigation/ActivityRoute;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun (Ljava/util/List;Ljava/lang/String;)V - public synthetic fun (Ljava/util/List;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun buildIntent (Landroid/content/Context;)Landroid/content/Intent; - public final fun buildPendingIntent (Landroid/content/Context;I)Landroid/app/PendingIntent; - public static synthetic fun buildPendingIntent$default (Lcom/freeletics/khonshu/navigation/DeepLink;Landroid/content/Context;IILjava/lang/Object;)Landroid/app/PendingIntent; - public final fun buildTaskStack (Landroid/content/Context;)Landroidx/core/app/TaskStackBuilder; - public fun equals (Ljava/lang/Object;)Z - public fun hashCode ()I - public fun toString ()Ljava/lang/String; -} - -public abstract interface class com/freeletics/khonshu/navigation/DeepLinkHandler { - public abstract fun deepLink (Ljava/util/Map;Ljava/util/Map;)Lcom/freeletics/khonshu/navigation/DeepLink; - public abstract fun getPatterns ()Ljava/util/Set; - public fun getPrefixes ()Ljava/util/Set; -} - -public final class com/freeletics/khonshu/navigation/DeepLinkHandler$Pattern { - public static final synthetic fun box-impl (Ljava/lang/String;)Lcom/freeletics/khonshu/navigation/DeepLinkHandler$Pattern; - public static fun constructor-impl (Ljava/lang/String;)Ljava/lang/String; - public fun equals (Ljava/lang/Object;)Z - public static fun equals-impl (Ljava/lang/String;Ljava/lang/Object;)Z - public static final fun equals-impl0 (Ljava/lang/String;Ljava/lang/String;)Z - public fun hashCode ()I - public static fun hashCode-impl (Ljava/lang/String;)I - public fun toString ()Ljava/lang/String; - public static fun toString-impl (Ljava/lang/String;)Ljava/lang/String; - public final synthetic fun unbox-impl ()Ljava/lang/String; -} - -public final class com/freeletics/khonshu/navigation/DeepLinkHandler$Prefix { - public static final synthetic fun box-impl (Ljava/lang/String;)Lcom/freeletics/khonshu/navigation/DeepLinkHandler$Prefix; - public static fun constructor-impl (Ljava/lang/String;)Ljava/lang/String; - public fun equals (Ljava/lang/Object;)Z - public static fun equals-impl (Ljava/lang/String;Ljava/lang/Object;)Z - public static final fun equals-impl0 (Ljava/lang/String;Ljava/lang/String;)Z - public fun hashCode ()I - public static fun hashCode-impl (Ljava/lang/String;)I - public fun toString ()Ljava/lang/String; - public static fun toString-impl (Ljava/lang/String;)Ljava/lang/String; - public final synthetic fun unbox-impl ()Ljava/lang/String; -} - public abstract interface class com/freeletics/khonshu/navigation/ExternalActivityRoute : com/freeletics/khonshu/navigation/ActivityRoute { public fun fillInIntent ()Landroid/content/Intent; } @@ -153,10 +99,71 @@ public abstract class com/freeletics/khonshu/navigation/ResultOwner { public final fun getResults ()Lkotlinx/coroutines/flow/Flow; } -public final class com/freeletics/khonshu/navigation/internal/DeepLinkMatcherKt { +public final class com/freeletics/khonshu/navigation/deeplinks/ActivityRouteDeepLinkKt { + public static final fun DeepLink (Lcom/freeletics/khonshu/navigation/ActivityRoute;Ljava/lang/String;)Lcom/freeletics/khonshu/navigation/deeplinks/DeepLink; + public static final fun DeepLink (Lcom/freeletics/khonshu/navigation/NavRoot;Ljava/util/List;Lcom/freeletics/khonshu/navigation/ActivityRoute;Ljava/lang/String;)Lcom/freeletics/khonshu/navigation/deeplinks/DeepLink; + public static final fun DeepLink (Ljava/util/List;Lcom/freeletics/khonshu/navigation/ActivityRoute;Ljava/lang/String;)Lcom/freeletics/khonshu/navigation/deeplinks/DeepLink; + public static synthetic fun DeepLink$default (Lcom/freeletics/khonshu/navigation/ActivityRoute;Ljava/lang/String;ILjava/lang/Object;)Lcom/freeletics/khonshu/navigation/deeplinks/DeepLink; + public static synthetic fun DeepLink$default (Lcom/freeletics/khonshu/navigation/NavRoot;Ljava/util/List;Lcom/freeletics/khonshu/navigation/ActivityRoute;Ljava/lang/String;ILjava/lang/Object;)Lcom/freeletics/khonshu/navigation/deeplinks/DeepLink; + public static synthetic fun DeepLink$default (Ljava/util/List;Lcom/freeletics/khonshu/navigation/ActivityRoute;Ljava/lang/String;ILjava/lang/Object;)Lcom/freeletics/khonshu/navigation/deeplinks/DeepLink; +} + +public final class com/freeletics/khonshu/navigation/deeplinks/AndroidDeepLinkExtensionsKt { + public static final fun buildIntent (Lcom/freeletics/khonshu/navigation/deeplinks/DeepLink;Landroid/content/Context;)Landroid/content/Intent; + public static final fun buildPendingIntent (Lcom/freeletics/khonshu/navigation/deeplinks/DeepLink;Landroid/content/Context;I)Landroid/app/PendingIntent; + public static synthetic fun buildPendingIntent$default (Lcom/freeletics/khonshu/navigation/deeplinks/DeepLink;Landroid/content/Context;IILjava/lang/Object;)Landroid/app/PendingIntent; + public static final fun buildTaskStack (Lcom/freeletics/khonshu/navigation/deeplinks/DeepLink;Landroid/content/Context;)Landroidx/core/app/TaskStackBuilder; +} + +public final class com/freeletics/khonshu/navigation/deeplinks/DeepLink { + public fun equals (Ljava/lang/Object;)Z + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public abstract interface class com/freeletics/khonshu/navigation/deeplinks/DeepLinkHandler { + public abstract fun deepLink (Ljava/util/Map;Ljava/util/Map;)Lcom/freeletics/khonshu/navigation/deeplinks/DeepLink; + public abstract fun getPatterns ()Ljava/util/Set; + public fun getPrefixes ()Ljava/util/Set; +} + +public final class com/freeletics/khonshu/navigation/deeplinks/DeepLinkHandler$Pattern { + public static final synthetic fun box-impl (Ljava/lang/String;)Lcom/freeletics/khonshu/navigation/deeplinks/DeepLinkHandler$Pattern; + public static fun constructor-impl (Ljava/lang/String;)Ljava/lang/String; + public fun equals (Ljava/lang/Object;)Z + public static fun equals-impl (Ljava/lang/String;Ljava/lang/Object;)Z + public static final fun equals-impl0 (Ljava/lang/String;Ljava/lang/String;)Z + public fun hashCode ()I + public static fun hashCode-impl (Ljava/lang/String;)I + public fun toString ()Ljava/lang/String; + public static fun toString-impl (Ljava/lang/String;)Ljava/lang/String; + public final synthetic fun unbox-impl ()Ljava/lang/String; +} + +public final class com/freeletics/khonshu/navigation/deeplinks/DeepLinkHandler$Prefix { + public static final synthetic fun box-impl (Ljava/lang/String;)Lcom/freeletics/khonshu/navigation/deeplinks/DeepLinkHandler$Prefix; + public static fun constructor-impl (Ljava/lang/String;)Ljava/lang/String; + public fun equals (Ljava/lang/Object;)Z + public static fun equals-impl (Ljava/lang/String;Ljava/lang/Object;)Z + public static final fun equals-impl0 (Ljava/lang/String;Ljava/lang/String;)Z + public fun hashCode ()I + public static fun hashCode-impl (Ljava/lang/String;)I + public fun toString ()Ljava/lang/String; + public static fun toString-impl (Ljava/lang/String;)Ljava/lang/String; + public final synthetic fun unbox-impl ()Ljava/lang/String; +} + +public final class com/freeletics/khonshu/navigation/deeplinks/DeepLinkKt { + public static final fun DeepLink (Lcom/freeletics/khonshu/navigation/NavRoot;Ljava/util/List;Ljava/lang/String;)Lcom/freeletics/khonshu/navigation/deeplinks/DeepLink; + public static final fun DeepLink (Ljava/util/List;Ljava/lang/String;)Lcom/freeletics/khonshu/navigation/deeplinks/DeepLink; + public static synthetic fun DeepLink$default (Lcom/freeletics/khonshu/navigation/NavRoot;Ljava/util/List;Ljava/lang/String;ILjava/lang/Object;)Lcom/freeletics/khonshu/navigation/deeplinks/DeepLink; + public static synthetic fun DeepLink$default (Ljava/util/List;Ljava/lang/String;ILjava/lang/Object;)Lcom/freeletics/khonshu/navigation/deeplinks/DeepLink; +} + +public final class com/freeletics/khonshu/navigation/deeplinks/DeepLinkMatcherKt { } -public final class com/freeletics/khonshu/navigation/internal/DeepLinkParserKt { +public final class com/freeletics/khonshu/navigation/deeplinks/DeepLinkParserKt { } public final class com/freeletics/khonshu/navigation/internal/DestinationIdKt { diff --git a/navigation/api/jvm/navigation.api b/navigation/api/jvm/navigation.api index 7cc4be792..da185ca76 100644 --- a/navigation/api/jvm/navigation.api +++ b/navigation/api/jvm/navigation.api @@ -7,6 +7,57 @@ public abstract interface class com/freeletics/khonshu/navigation/NavRoot : com/ public abstract interface class com/freeletics/khonshu/navigation/NavRoute : com/freeletics/khonshu/navigation/BaseRoute { } +public final class com/freeletics/khonshu/navigation/deeplinks/DeepLink { + public fun equals (Ljava/lang/Object;)Z + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public abstract interface class com/freeletics/khonshu/navigation/deeplinks/DeepLinkHandler { + public abstract fun deepLink (Ljava/util/Map;Ljava/util/Map;)Lcom/freeletics/khonshu/navigation/deeplinks/DeepLink; + public abstract fun getPatterns ()Ljava/util/Set; + public fun getPrefixes ()Ljava/util/Set; +} + +public final class com/freeletics/khonshu/navigation/deeplinks/DeepLinkHandler$Pattern { + public static final synthetic fun box-impl (Ljava/lang/String;)Lcom/freeletics/khonshu/navigation/deeplinks/DeepLinkHandler$Pattern; + public static fun constructor-impl (Ljava/lang/String;)Ljava/lang/String; + public fun equals (Ljava/lang/Object;)Z + public static fun equals-impl (Ljava/lang/String;Ljava/lang/Object;)Z + public static final fun equals-impl0 (Ljava/lang/String;Ljava/lang/String;)Z + public fun hashCode ()I + public static fun hashCode-impl (Ljava/lang/String;)I + public fun toString ()Ljava/lang/String; + public static fun toString-impl (Ljava/lang/String;)Ljava/lang/String; + public final synthetic fun unbox-impl ()Ljava/lang/String; +} + +public final class com/freeletics/khonshu/navigation/deeplinks/DeepLinkHandler$Prefix { + public static final synthetic fun box-impl (Ljava/lang/String;)Lcom/freeletics/khonshu/navigation/deeplinks/DeepLinkHandler$Prefix; + public static fun constructor-impl (Ljava/lang/String;)Ljava/lang/String; + public fun equals (Ljava/lang/Object;)Z + public static fun equals-impl (Ljava/lang/String;Ljava/lang/Object;)Z + public static final fun equals-impl0 (Ljava/lang/String;Ljava/lang/String;)Z + public fun hashCode ()I + public static fun hashCode-impl (Ljava/lang/String;)I + public fun toString ()Ljava/lang/String; + public static fun toString-impl (Ljava/lang/String;)Ljava/lang/String; + public final synthetic fun unbox-impl ()Ljava/lang/String; +} + +public final class com/freeletics/khonshu/navigation/deeplinks/DeepLinkKt { + public static final fun DeepLink (Lcom/freeletics/khonshu/navigation/NavRoot;Ljava/util/List;Ljava/lang/String;)Lcom/freeletics/khonshu/navigation/deeplinks/DeepLink; + public static final fun DeepLink (Ljava/util/List;Ljava/lang/String;)Lcom/freeletics/khonshu/navigation/deeplinks/DeepLink; + public static synthetic fun DeepLink$default (Lcom/freeletics/khonshu/navigation/NavRoot;Ljava/util/List;Ljava/lang/String;ILjava/lang/Object;)Lcom/freeletics/khonshu/navigation/deeplinks/DeepLink; + public static synthetic fun DeepLink$default (Ljava/util/List;Ljava/lang/String;ILjava/lang/Object;)Lcom/freeletics/khonshu/navigation/deeplinks/DeepLink; +} + +public final class com/freeletics/khonshu/navigation/deeplinks/DeepLinkMatcherKt { +} + +public final class com/freeletics/khonshu/navigation/deeplinks/DeepLinkParserKt { +} + public abstract interface annotation class com/freeletics/khonshu/navigation/internal/InternalNavigationApi : java/lang/annotation/Annotation { } diff --git a/navigation/navigation.gradle.kts b/navigation/navigation.gradle.kts index 1bad4cf7f..d3db50e1f 100644 --- a/navigation/navigation.gradle.kts +++ b/navigation/navigation.gradle.kts @@ -22,12 +22,13 @@ freeletics { } dependencies { + "commonMainApi"(libs.uri) + "androidMainApi"(libs.androidx.activity) "androidMainApi"(libs.androidx.core) "androidMainApi"(libs.androidx.lifecycle.common) "androidMainApi"(libs.androidx.viewmodel.savedstate) "androidMainApi"(libs.coroutines.core) - "androidMainApi"(libs.uri) "androidMainImplementation"(libs.androidx.lifecycle.runtime) "androidMainImplementation"(libs.kotlin.parcelize) diff --git a/navigation/src/androidMain/kotlin/com/freeletics/khonshu/navigation/DeepLink.kt b/navigation/src/androidMain/kotlin/com/freeletics/khonshu/navigation/DeepLink.kt deleted file mode 100644 index 44a5f0f1b..000000000 --- a/navigation/src/androidMain/kotlin/com/freeletics/khonshu/navigation/DeepLink.kt +++ /dev/null @@ -1,145 +0,0 @@ -package com.freeletics.khonshu.navigation - -import android.app.PendingIntent -import android.app.PendingIntent.FLAG_IMMUTABLE -import android.app.PendingIntent.FLAG_UPDATE_CURRENT -import android.content.Context -import android.content.Intent -import android.os.Build -import android.os.Parcelable -import androidx.core.app.TaskStackBuilder -import com.freeletics.khonshu.navigation.internal.InternalNavigationApi -import dev.drewhamilton.poko.Poko - -/** - * Represents a link into the app. - */ -@Poko -public class DeepLink internal constructor( - private val action: String?, - private val routes: List, -) { - - /** - * A deep link created with this will open the app with the given [routes] added to the back - * stack on top of the start destination. The last of the given routes will be the visible - * screen. - * - * If an [action] is provided the [Intent] returned by [buildIntent] and the other builders - * will use it as it's [Intent.getAction]. If no `action` is provided the app's - * [android.content.pm.PackageManager.getLaunchIntentForPackage] will be used. - */ - public constructor( - routes: List, - action: String? = null, - ) : this(action, routes) - - /** - * A deep link created with this will open the app and create a back stack with [root] on top - * of the start destination. The given [routes] will be added to that back stack. The last of - * the given routes will be the visible screen, if none is provided `root` will be visible. - * - * If an [action] is provided the [Intent] returned by [buildIntent] and the other builders - * will use it as it's [Intent.getAction]. If no `action` is provided the app's - * [android.content.pm.PackageManager.getLaunchIntentForPackage] will be used. - */ - public constructor( - root: NavRoot, - routes: List = emptyList(), - action: String? = null, - ) : this(action, listOf(root) + routes) - - /** - * A deep link created with this will open the app with it's start destination and then launch - * [ActivityRoute] on top of it. - * - * If an [action] is provided the [Intent] returned by [buildIntent] and the other builders - * will use it as it's [Intent.getAction]. If no `action` is provided the app's - * [android.content.pm.PackageManager.getLaunchIntentForPackage] will be used. - */ - public constructor( - activityRoute: ActivityRoute, - action: String? = null, - ) : this(action, listOf(activityRoute)) - - /** - * A deep link created with this will open the app with the given [routes] added to the back - * stack on top of the start destination, [activityRoute] will then be launched on top of this. - * - * If an [action] is provided the [Intent] returned by [buildIntent] and the other builders - * will use it as it's [Intent.getAction]. If no `action` is provided the app's - * [android.content.pm.PackageManager.getLaunchIntentForPackage] will be used. - */ - public constructor( - routes: List, - activityRoute: ActivityRoute, - action: String? = null, - ) : this(action, routes + activityRoute) - - /** - * A deep link created with this will open the app and create a back stack with [root] on top - * of the start destination. The given [routes] will be added to that back stack and - * [activityRoute] will then be launched on top of this. - * - * If an [action] is provided the [Intent] returned by [buildIntent] and the other builders - * will use it as it's [Intent.getAction]. If no `action` is provided the app's - * [android.content.pm.PackageManager.getLaunchIntentForPackage] will be used. - */ - public constructor( - root: NavRoot, - routes: List, - activityRoute: ActivityRoute, - action: String? = null, - ) : this(action, listOf(root) + routes + activityRoute) - - /** - * Creates an [Intent] that can be used to launch this deep link. - */ - public fun buildIntent(context: Context): Intent { - val intent = if (action != null) { - Intent(action).setPackage(context.packageName) - } else { - requireNotNull(context.packageManager.getLaunchIntentForPackage(context.packageName)) { - "Couldn't obtain launch intent for ${context.packageName}" - } - } - return intent - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) - .putParcelableArrayListExtra(EXTRA_DEEPLINK_ROUTES, ArrayList(routes)) - } - - /** - * Creates a [TaskStackBuilder] that can be used to launch this deep link. - */ - public fun buildTaskStack(context: Context): TaskStackBuilder { - return TaskStackBuilder.create(context).addNextIntent(buildIntent(context)) - } - - /** - * Creates a [PendingIntent] that can be used to launch this deep link. - */ - public fun buildPendingIntent( - context: Context, - flags: Int = defaultFlag(), - ): PendingIntent { - val requestCode: Int = routes.fold(0) { acc, navDirection -> - 31 * acc + navDirection.hashCode() - } - - return buildTaskStack(context).getPendingIntent(requestCode, flags)!! - } - - @InternalNavigationApi - public companion object { - @property:InternalNavigationApi - public const val EXTRA_DEEPLINK_ROUTES: String = "com.freeletics.khonshu.navigation.DEEPLINK_ROUTES" - - private fun defaultFlag(): Int { - return if (Build.VERSION.SDK_INT >= 23) { - FLAG_UPDATE_CURRENT or FLAG_IMMUTABLE - } else { - FLAG_UPDATE_CURRENT - } - } - } -} diff --git a/navigation/src/androidMain/kotlin/com/freeletics/khonshu/navigation/deeplinks/ActivityRouteDeepLink.kt b/navigation/src/androidMain/kotlin/com/freeletics/khonshu/navigation/deeplinks/ActivityRouteDeepLink.kt new file mode 100644 index 000000000..f98df0aa1 --- /dev/null +++ b/navigation/src/androidMain/kotlin/com/freeletics/khonshu/navigation/deeplinks/ActivityRouteDeepLink.kt @@ -0,0 +1,50 @@ +package com.freeletics.khonshu.navigation.deeplinks + +import android.content.Intent +import com.freeletics.khonshu.navigation.ActivityRoute +import com.freeletics.khonshu.navigation.BaseRoute +import com.freeletics.khonshu.navigation.NavRoot +import com.freeletics.khonshu.navigation.NavRoute + +/** + * A deep link created with this will open the app with it's start destination and then launch + * [ActivityRoute] on top of it. + * + * If an [action] is provided the [Intent] returned by [buildIntent] and the other builders + * will use it as it's [Intent.getAction]. If no `action` is provided the app's + * [android.content.pm.PackageManager.getLaunchIntentForPackage] will be used. + */ +public fun DeepLink( + activityRoute: ActivityRoute, + action: String? = null, +): DeepLink = DeepLink(action, listOf(activityRoute)) + +/** + * A deep link created with this will open the app with the given [routes] added to the back + * stack on top of the start destination, [activityRoute] will then be launched on top of this. + * + * If an [action] is provided the [Intent] returned by [buildIntent] and the other builders + * will use it as it's [Intent.getAction]. If no `action` is provided the app's + * [android.content.pm.PackageManager.getLaunchIntentForPackage] will be used. + */ +public fun DeepLink( + routes: List, + activityRoute: ActivityRoute, + action: String? = null, +): DeepLink = DeepLink(action, routes + activityRoute) + +/** + * A deep link created with this will open the app and create a back stack with [root] on top + * of the start destination. The given [routes] will be added to that back stack and + * [activityRoute] will then be launched on top of this. + * + * If an [action] is provided the [Intent] returned by [buildIntent] and the other builders + * will use it as it's [Intent.getAction]. If no `action` is provided the app's + * [android.content.pm.PackageManager.getLaunchIntentForPackage] will be used. + */ +public fun DeepLink( + root: NavRoot, + routes: List, + activityRoute: ActivityRoute, + action: String? = null, +): DeepLink = DeepLink(action, listOf(root) + routes + activityRoute) diff --git a/navigation/src/androidMain/kotlin/com/freeletics/khonshu/navigation/deeplinks/AndroidDeepLinkExtensions.kt b/navigation/src/androidMain/kotlin/com/freeletics/khonshu/navigation/deeplinks/AndroidDeepLinkExtensions.kt new file mode 100644 index 000000000..eab3087ed --- /dev/null +++ b/navigation/src/androidMain/kotlin/com/freeletics/khonshu/navigation/deeplinks/AndroidDeepLinkExtensions.kt @@ -0,0 +1,58 @@ +package com.freeletics.khonshu.navigation.deeplinks + +import android.app.PendingIntent +import android.app.PendingIntent.FLAG_IMMUTABLE +import android.app.PendingIntent.FLAG_UPDATE_CURRENT +import android.content.Context +import android.content.Intent +import android.os.Build +import androidx.core.app.TaskStackBuilder +import com.freeletics.khonshu.navigation.internal.InternalNavigationApi + +/** + * Creates an [Intent] that can be used to launch this deep link. + */ +public fun DeepLink.buildIntent(context: Context): Intent { + val intent = if (action != null) { + Intent(action).setPackage(context.packageName) + } else { + requireNotNull(context.packageManager.getLaunchIntentForPackage(context.packageName)) { + "Couldn't obtain launch intent for ${context.packageName}" + } + } + return intent + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK) + .putParcelableArrayListExtra(EXTRA_DEEPLINK_ROUTES, ArrayList(routes)) +} + +/** + * Creates a [TaskStackBuilder] that can be used to launch this deep link. + */ +public fun DeepLink.buildTaskStack(context: Context): TaskStackBuilder { + return TaskStackBuilder.create(context).addNextIntent(buildIntent(context)) +} + +/** + * Creates a [PendingIntent] that can be used to launch this deep link. + */ +public fun DeepLink.buildPendingIntent( + context: Context, + flags: Int = defaultFlag(), +): PendingIntent { + val requestCode: Int = routes.fold(0) { acc, navDirection -> + 31 * acc + navDirection.hashCode() + } + + return buildTaskStack(context).getPendingIntent(requestCode, flags)!! +} + +@property:InternalNavigationApi +public const val EXTRA_DEEPLINK_ROUTES: String = "com.freeletics.khonshu.navigation.DEEPLINK_ROUTES" + +private fun defaultFlag(): Int { + return if (Build.VERSION.SDK_INT >= 23) { + FLAG_UPDATE_CURRENT or FLAG_IMMUTABLE + } else { + FLAG_UPDATE_CURRENT + } +} diff --git a/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/internal/DeepLinkMatcherTest.kt b/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/deeplinks/DeepLinkMatcherTest.kt similarity index 59% rename from navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/internal/DeepLinkMatcherTest.kt rename to navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/deeplinks/DeepLinkMatcherTest.kt index a51db82eb..3b09e7dd8 100644 --- a/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/internal/DeepLinkMatcherTest.kt +++ b/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/deeplinks/DeepLinkMatcherTest.kt @@ -1,22 +1,19 @@ -package com.freeletics.khonshu.navigation.internal +package com.freeletics.khonshu.navigation.deeplinks import com.eygraber.uri.Uri -import com.freeletics.khonshu.navigation.DeepLink -import com.freeletics.khonshu.navigation.DeepLinkHandler.Pattern -import com.freeletics.khonshu.navigation.DeepLinkHandler.Prefix import com.freeletics.khonshu.navigation.test.DeepLinkHandlerSubject.Companion.assertThat import com.freeletics.khonshu.navigation.test.TestDeepLinkHandler import com.google.common.truth.Truth.assertThat import java.util.regex.PatternSyntaxException -import org.junit.Assert.assertThrows +import org.junit.Assert import org.junit.Test internal class DeepLinkMatcherTest { - private val prefixes: Set = setOf( - Prefix("https://a.com"), - Prefix("https://b.de"), - Prefix("app://b.de"), - Prefix("app://a.b.de"), + private val prefixes: Set = setOf( + DeepLinkHandler.Prefix("https://a.com"), + DeepLinkHandler.Prefix("https://b.de"), + DeepLinkHandler.Prefix("app://b.de"), + DeepLinkHandler.Prefix("app://a.b.de"), ) @Test @@ -26,12 +23,14 @@ internal class DeepLinkMatcherTest { assertThat(handler).matchesPattern("https://a.com/home", prefixes).isTrue() // first prefix assertThat(handler).matchesPattern("https://b.de/home", prefixes).isTrue() // second prefix assertThat(handler).matchesPattern("app://b.de/home", prefixes).isTrue() // third prefix - assertThat(handler).matchesPattern("https://a.com/home?param1=value1¶m2=value2", prefixes) + assertThat(handler) + .matchesPattern("https://a.com/home?param1=value1¶m2=value2", prefixes) .isTrue() // with query parameters assertThat(handler).matchesPattern("https://a.com", prefixes).isFalse() // just the prefix 1 assertThat(handler).matchesPattern("https://a.com/", prefixes).isFalse() // just the prefix 2 - assertThat(handler).matchesPattern("https://a.com/home/world", prefixes).isFalse() // different path + assertThat(handler) + .matchesPattern("https://a.com/home/world", prefixes).isFalse() // different path assertThat(handler).matchesPattern("https://a.com/home/", prefixes) .isFalse() // trailing slash that is not in pattern assertThat(handler).matchesPattern("https://c.com/home", prefixes).isFalse() // different domain @@ -49,9 +48,11 @@ internal class DeepLinkMatcherTest { assertThat(handler).matchesPattern("https://a.com", prefixes).isTrue() // first prefix assertThat(handler).matchesPattern("https://b.de", prefixes).isTrue() // second prefix assertThat(handler).matchesPattern("app://b.de", prefixes).isTrue() // third prefix - assertThat(handler).matchesPattern("https://a.com?param1=value1¶m2=value2", prefixes) + assertThat(handler) + .matchesPattern("https://a.com?param1=value1¶m2=value2", prefixes) .isTrue() // with query parameters - assertThat(handler).matchesPattern("https://a.com/?param1=value1¶m2=value2", prefixes) + assertThat(handler) + .matchesPattern("https://a.com/?param1=value1¶m2=value2", prefixes) .isTrue() // with query parameters assertThat(handler).matchesPattern("https://a.com/home", prefixes).isFalse() // different path @@ -61,18 +62,25 @@ internal class DeepLinkMatcherTest { fun `when the pattern is foo_bar_placeholder`() { val handler = TestDeepLinkHandler("foo/bar/{placeholder}") - assertThat(handler).matchesPattern("https://a.com/foo/bar/abc", prefixes).isTrue() // lower case chars - assertThat(handler).matchesPattern("https://a.com/foo/bar/ABC", prefixes).isTrue() // upper case chars - assertThat(handler).matchesPattern("https://a.com/foo/bar/123", prefixes).isTrue() // numbers - assertThat(handler).matchesPattern("https://a.com/foo/bar/_'!+~=,-.@\$:", prefixes) + assertThat(handler) + .matchesPattern("https://a.com/foo/bar/abc", prefixes).isTrue() // lower case chars + assertThat(handler) + .matchesPattern("https://a.com/foo/bar/ABC", prefixes).isTrue() // upper case chars + assertThat(handler) + .matchesPattern("https://a.com/foo/bar/123", prefixes).isTrue() // numbers + assertThat(handler) + .matchesPattern("https://a.com/foo/bar/_'!+~=,-.@\$:", prefixes) .isTrue() // all allowed special character - assertThat(handler).matchesPattern("https://a.com/foo/bar/aBC123_=", prefixes) + assertThat(handler) + .matchesPattern("https://a.com/foo/bar/aBC123_=", prefixes) .isTrue() // combination of the above - assertThat(handler).matchesPattern("https://a.com/foo/bar/abc?param1=value1¶m2=value2", prefixes) + assertThat(handler) + .matchesPattern("https://a.com/foo/bar/abc?param1=value1¶m2=value2", prefixes) .isTrue() // with query parameters assertThat(handler).matchesPattern("https://a.com/foo/bar/", prefixes).isFalse() // empty placeholder - assertThat(handler).matchesPattern("https://a.com/foo/bar/§&", prefixes) + assertThat(handler) + .matchesPattern("https://a.com/foo/bar/§&", prefixes) .isFalse() // not allowed special characters } @@ -80,18 +88,25 @@ internal class DeepLinkMatcherTest { fun `when the pattern is placeholder_foo_bar`() { val handler = TestDeepLinkHandler("{placeholder}/foo/bar") - assertThat(handler).matchesPattern("https://a.com/abc/foo/bar", prefixes).isTrue() // lower case chars - assertThat(handler).matchesPattern("https://a.com/ABC/foo/bar", prefixes).isTrue() // upper case chars - assertThat(handler).matchesPattern("https://a.com/123/foo/bar", prefixes).isTrue() // numbers - assertThat(handler).matchesPattern("https://a.com/_'!+~=,-.@\$:/foo/bar", prefixes) + assertThat(handler) + .matchesPattern("https://a.com/abc/foo/bar", prefixes).isTrue() // lower case chars + assertThat(handler) + .matchesPattern("https://a.com/ABC/foo/bar", prefixes).isTrue() // upper case chars + assertThat(handler) + .matchesPattern("https://a.com/123/foo/bar", prefixes).isTrue() // numbers + assertThat(handler) + .matchesPattern("https://a.com/_'!+~=,-.@\$:/foo/bar", prefixes) .isTrue() // all allowed special character - assertThat(handler).matchesPattern("https://a.com/aBC123_=/foo/bar", prefixes) + assertThat(handler) + .matchesPattern("https://a.com/aBC123_=/foo/bar", prefixes) .isTrue() // combination of the above - assertThat(handler).matchesPattern("https://a.com/abc/foo/bar?param1=value1¶m2=value2", prefixes) + assertThat(handler) + .matchesPattern("https://a.com/abc/foo/bar?param1=value1¶m2=value2", prefixes) .isTrue() // with query parameters assertThat(handler).matchesPattern("https://a.com//foo/bar", prefixes).isFalse() // empty placeholder - assertThat(handler).matchesPattern("https://a.com/§&/foo/bar", prefixes) + assertThat(handler) + .matchesPattern("https://a.com/§&/foo/bar", prefixes) .isFalse() // not allowed special characters } @@ -99,18 +114,25 @@ internal class DeepLinkMatcherTest { fun `when the pattern is foo_placeholder_bar`() { val handler = TestDeepLinkHandler("foo/{placeholder}/bar") - assertThat(handler).matchesPattern("https://a.com/foo/abc/bar", prefixes).isTrue() // lower case chars - assertThat(handler).matchesPattern("https://a.com/foo/ABC/bar", prefixes).isTrue() // upper case chars - assertThat(handler).matchesPattern("https://a.com/foo/123/bar", prefixes).isTrue() // numbers - assertThat(handler).matchesPattern("https://a.com/foo/_'!+~=,-.@\$:/bar", prefixes) + assertThat(handler) + .matchesPattern("https://a.com/foo/abc/bar", prefixes).isTrue() // lower case chars + assertThat(handler) + .matchesPattern("https://a.com/foo/ABC/bar", prefixes).isTrue() // upper case chars + assertThat(handler) + .matchesPattern("https://a.com/foo/123/bar", prefixes).isTrue() // numbers + assertThat(handler) + .matchesPattern("https://a.com/foo/_'!+~=,-.@\$:/bar", prefixes) .isTrue() // all allowed special character - assertThat(handler).matchesPattern("https://a.com/foo/aBC123_=/bar", prefixes) + assertThat(handler) + .matchesPattern("https://a.com/foo/aBC123_=/bar", prefixes) .isTrue() // combination of the above - assertThat(handler).matchesPattern("https://a.com/foo/abc/bar?param1=value1¶m2=value2", prefixes) + assertThat(handler) + .matchesPattern("https://a.com/foo/abc/bar?param1=value1¶m2=value2", prefixes) .isTrue() // with query parameters assertThat(handler).matchesPattern("https://a.com/foo//bar", prefixes).isFalse() // empty placeholder - assertThat(handler).matchesPattern("https://a.com/foo/§&/bar", prefixes) + assertThat(handler) + .matchesPattern("https://a.com/foo/§&/bar", prefixes) .isFalse() // not allowed special characters } @@ -118,14 +140,15 @@ internal class DeepLinkMatcherTest { fun `when the pattern is foo_placeholder1_bar_placeholder2`() { val handler = TestDeepLinkHandler("foo/{placeholder1}/bar/{placeholder2}") - assertThat(handler).matchesPattern("https://a.com/foo/abc/bar/aBC123_=", prefixes).isTrue() + assertThat(handler) + .matchesPattern("https://a.com/foo/abc/bar/aBC123_=", prefixes).isTrue() } @Test fun `when the pattern has an invalid placeholder`() { val handler = TestDeepLinkHandler("foo/a{placeholder}/bar") - val exception = assertThrows(PatternSyntaxException::class.java) { + val exception = Assert.assertThrows(PatternSyntaxException::class.java) { handler.matchesPattern(Uri.parse("https://a.com/foo/abc/bar"), prefixes) } assertThat(exception).hasMessageThat().startsWith("Illegal repetition near index ") @@ -134,12 +157,13 @@ internal class DeepLinkMatcherTest { @Test fun `when the prefix is https_test_com`() { val handler = TestDeepLinkHandler( - patterns = setOf(Pattern("home")), - prefixes = setOf(Prefix("https://test.com")), + patterns = setOf(DeepLinkHandler.Pattern("home")), + prefixes = setOf(DeepLinkHandler.Prefix("https://test.com")), ) assertThat(handler.matchesPattern(Uri.parse("https://test.com/home"), prefixes)).isTrue() - assertThat(handler).matchesPattern("https://test.com/home?param1=value1¶m2=value2", prefixes) + assertThat(handler) + .matchesPattern("https://test.com/home?param1=value1¶m2=value2", prefixes) .isTrue() // with query parameters assertThat(handler).matchesPattern("https://a.com/home", prefixes).isFalse() // first default prefix @@ -151,7 +175,7 @@ internal class DeepLinkMatcherTest { fun `for a set of deep links, returns true if one matches`() { val handlers = setOf( TestDeepLinkHandler( - patterns = setOf(Pattern("home")), + patterns = setOf(DeepLinkHandler.Pattern("home")), deepLinkFactory = { _, _ -> DeepLink("test", listOf()) }, ), TestDeepLinkHandler(""), @@ -165,7 +189,7 @@ internal class DeepLinkMatcherTest { fun `for a set of deep links, returns false if none matches`() { val handlers = setOf( TestDeepLinkHandler( - patterns = setOf(Pattern("home")), + patterns = setOf(DeepLinkHandler.Pattern("home")), ), TestDeepLinkHandler(""), ) diff --git a/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/internal/DeepLinkParserTest.kt b/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/deeplinks/DeepLinkParserTest.kt similarity index 87% rename from navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/internal/DeepLinkParserTest.kt rename to navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/deeplinks/DeepLinkParserTest.kt index efe740d8e..70cbcae21 100644 --- a/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/internal/DeepLinkParserTest.kt +++ b/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/deeplinks/DeepLinkParserTest.kt @@ -1,9 +1,6 @@ -package com.freeletics.khonshu.navigation.internal +package com.freeletics.khonshu.navigation.deeplinks import com.eygraber.uri.Uri -import com.freeletics.khonshu.navigation.DeepLink -import com.freeletics.khonshu.navigation.DeepLinkHandler.Pattern -import com.freeletics.khonshu.navigation.DeepLinkHandler.Prefix import com.freeletics.khonshu.navigation.test.DeepLinkHandlerPatternSubject.Companion.assertThat import com.freeletics.khonshu.navigation.test.DeepLinkRoute import com.freeletics.khonshu.navigation.test.TestDeepLinkHandler @@ -13,7 +10,7 @@ import org.junit.Test internal class DeepLinkParserTest { @Test fun `when the pattern is home`() { - val pattern = Pattern("home") + val pattern = DeepLinkHandler.Pattern("home") assertThat(pattern).extractPathParameters("https://a.com/home").isEmpty() assertThat(pattern).extractPathParameters("https://b.de/home").isEmpty() @@ -23,7 +20,7 @@ internal class DeepLinkParserTest { @Test fun `when the pattern is empty`() { - val pattern = Pattern("") + val pattern = DeepLinkHandler.Pattern("") assertThat(pattern).extractPathParameters("https://a.com/").isEmpty() assertThat(pattern).extractPathParameters("https://b.de/").isEmpty() @@ -37,7 +34,7 @@ internal class DeepLinkParserTest { @Test fun `when the pattern is foo_bar_placeholder`() { - val pattern = Pattern("foo/bar/{placeholder}") + val pattern = DeepLinkHandler.Pattern("foo/bar/{placeholder}") assertThat(pattern).extractPathParameters("https://a.com/foo/bar/abc") .containsExactly("placeholder", "abc") @@ -55,7 +52,7 @@ internal class DeepLinkParserTest { @Test fun `when the pattern is placeholder_foo_bar`() { - val pattern = Pattern("{placeholder}/foo/bar") + val pattern = DeepLinkHandler.Pattern("{placeholder}/foo/bar") assertThat(pattern).extractPathParameters("https://a.com/abc/foo/bar") .containsExactly("placeholder", "abc") @@ -73,7 +70,7 @@ internal class DeepLinkParserTest { @Test fun `when the pattern is foo_placeholder_bar`() { - val pattern = Pattern("foo/{placeholder}/bar") + val pattern = DeepLinkHandler.Pattern("foo/{placeholder}/bar") assertThat(pattern).extractPathParameters("https://a.com/foo/abc/bar") .containsExactly("placeholder", "abc") @@ -91,7 +88,7 @@ internal class DeepLinkParserTest { @Test fun `when the pattern is foo_placeholder1_bar_placeholder2`() { - val pattern = Pattern("foo/{placeholder1}/bar/{placeholder2}") + val pattern = DeepLinkHandler.Pattern("foo/{placeholder1}/bar/{placeholder2}") assertThat(pattern).extractPathParameters("https://a.com/foo/abc/bar/aBC123_=") .containsExactly("placeholder1", "abc", "placeholder2", "aBC123_=") @@ -101,8 +98,8 @@ internal class DeepLinkParserTest { fun `for a set of deep links, returns deep link if one matches`() { val handlers = setOf( TestDeepLinkHandler( - patterns = setOf(Pattern("home")), - prefixes = setOf(Prefix("https://a.com")), + patterns = setOf(DeepLinkHandler.Pattern("home")), + prefixes = setOf(DeepLinkHandler.Prefix("https://a.com")), deepLinkFactory = { _, _ -> DeepLink("test", listOf()) }, ), TestDeepLinkHandler(""), @@ -118,8 +115,8 @@ internal class DeepLinkParserTest { fun `for a set of deep links, returns deep link with parameters if one matches`() { val handlers = setOf( TestDeepLinkHandler( - patterns = setOf(Pattern("{path}")), - prefixes = setOf(Prefix("https://a.com")), + patterns = setOf(DeepLinkHandler.Pattern("{path}")), + prefixes = setOf(DeepLinkHandler.Prefix("https://a.com")), deepLinkFactory = { path, query -> DeepLink("test", listOf(DeepLinkRoute(path, query))) }, @@ -145,8 +142,8 @@ internal class DeepLinkParserTest { fun `for a set of deep links, returns null if none matches`() { val handlers = setOf( TestDeepLinkHandler( - patterns = setOf(Pattern("home")), - prefixes = setOf(Prefix("https://a.com")), + patterns = setOf(DeepLinkHandler.Pattern("home")), + prefixes = setOf(DeepLinkHandler.Prefix("https://a.com")), ), TestDeepLinkHandler(""), ) diff --git a/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/test/DeepLinkHandlerPatternSubject.kt b/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/test/DeepLinkHandlerPatternSubject.kt index e4f79fea5..8e3db4eb5 100644 --- a/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/test/DeepLinkHandlerPatternSubject.kt +++ b/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/test/DeepLinkHandlerPatternSubject.kt @@ -1,8 +1,8 @@ package com.freeletics.khonshu.navigation.test import com.eygraber.uri.Uri -import com.freeletics.khonshu.navigation.DeepLinkHandler -import com.freeletics.khonshu.navigation.internal.extractPathParameters +import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler +import com.freeletics.khonshu.navigation.deeplinks.extractPathParameters import com.google.common.truth.FailureMetadata import com.google.common.truth.MapSubject import com.google.common.truth.Subject diff --git a/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/test/DeepLinkHandlerSubject.kt b/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/test/DeepLinkHandlerSubject.kt index 8d49149e3..b256960ca 100644 --- a/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/test/DeepLinkHandlerSubject.kt +++ b/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/test/DeepLinkHandlerSubject.kt @@ -1,9 +1,9 @@ package com.freeletics.khonshu.navigation.test import com.eygraber.uri.Uri -import com.freeletics.khonshu.navigation.DeepLinkHandler -import com.freeletics.khonshu.navigation.DeepLinkHandler.Prefix -import com.freeletics.khonshu.navigation.internal.matchesPattern +import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler +import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler.Prefix +import com.freeletics.khonshu.navigation.deeplinks.matchesPattern import com.google.common.truth.BooleanSubject import com.google.common.truth.FailureMetadata import com.google.common.truth.Subject diff --git a/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/test/Routes.kt b/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/test/Routes.kt index 2c5aad0e8..679ccb180 100644 --- a/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/test/Routes.kt +++ b/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/test/Routes.kt @@ -1,9 +1,9 @@ package com.freeletics.khonshu.navigation.test -import android.os.Parcelable import com.freeletics.khonshu.navigation.InternalActivityRoute import com.freeletics.khonshu.navigation.NavRoot import com.freeletics.khonshu.navigation.NavRoute +import com.freeletics.khonshu.navigation.internal.Parcelable import dev.drewhamilton.poko.Poko import kotlinx.parcelize.Parcelize diff --git a/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/test/TestDeepLinkHandler.kt b/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/test/TestDeepLinkHandler.kt index bd5c8500c..7fe454b65 100644 --- a/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/test/TestDeepLinkHandler.kt +++ b/navigation/src/androidUnitTest/kotlin/com/freeletics/khonshu/navigation/test/TestDeepLinkHandler.kt @@ -1,9 +1,9 @@ package com.freeletics.khonshu.navigation.test -import com.freeletics.khonshu.navigation.DeepLink -import com.freeletics.khonshu.navigation.DeepLinkHandler -import com.freeletics.khonshu.navigation.DeepLinkHandler.Pattern -import com.freeletics.khonshu.navigation.DeepLinkHandler.Prefix +import com.freeletics.khonshu.navigation.deeplinks.DeepLink +import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler +import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler.Pattern +import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler.Prefix internal class TestDeepLinkHandler( override val patterns: Set, diff --git a/navigation/src/commonMain/kotlin/com/freeletics/khonshu/navigation/deeplinks/DeepLink.kt b/navigation/src/commonMain/kotlin/com/freeletics/khonshu/navigation/deeplinks/DeepLink.kt new file mode 100644 index 000000000..2a86b26a6 --- /dev/null +++ b/navigation/src/commonMain/kotlin/com/freeletics/khonshu/navigation/deeplinks/DeepLink.kt @@ -0,0 +1,45 @@ +package com.freeletics.khonshu.navigation.deeplinks + +import com.freeletics.khonshu.navigation.BaseRoute +import com.freeletics.khonshu.navigation.NavRoot +import com.freeletics.khonshu.navigation.NavRoute +import com.freeletics.khonshu.navigation.internal.Parcelable +import dev.drewhamilton.poko.Poko + +/** + * A deep link created with this will open the app with the given [routes] added to the back + * stack on top of the start destination. The last of the given routes will be the visible + * screen. + * + * If an [action] is provided the [Intent] returned by [buildIntent] and the other builders + * will use it as it's [Intent.getAction]. If no `action` is provided the app's + * [android.content.pm.PackageManager.getLaunchIntentForPackage] will be used. + */ +public fun DeepLink( + routes: List, + action: String? = null, +): DeepLink = DeepLink(action, routes) + +/** + * A deep link created with this will open the app and create a back stack with [root] on top + * of the start destination. The given [routes] will be added to that back stack. The last of + * the given routes will be the visible screen, if none is provided `root` will be visible. + * + * If an [action] is provided the [Intent] returned by [buildIntent] and the other builders + * will use it as it's [Intent.getAction]. If no `action` is provided the app's + * [android.content.pm.PackageManager.getLaunchIntentForPackage] will be used. + */ +public fun DeepLink( + root: NavRoot, + routes: List = emptyList(), + action: String? = null, +): DeepLink = DeepLink(action, listOf(root) + routes) + +/** + * Represents a link into the app. + */ +@Poko +public class DeepLink internal constructor( + internal val action: String?, + internal val routes: List, +) diff --git a/navigation/src/androidMain/kotlin/com/freeletics/khonshu/navigation/DeepLinkHandler.kt b/navigation/src/commonMain/kotlin/com/freeletics/khonshu/navigation/deeplinks/DeepLinkHandler.kt similarity index 98% rename from navigation/src/androidMain/kotlin/com/freeletics/khonshu/navigation/DeepLinkHandler.kt rename to navigation/src/commonMain/kotlin/com/freeletics/khonshu/navigation/deeplinks/DeepLinkHandler.kt index 8fd37001d..62ff12d68 100644 --- a/navigation/src/androidMain/kotlin/com/freeletics/khonshu/navigation/DeepLinkHandler.kt +++ b/navigation/src/commonMain/kotlin/com/freeletics/khonshu/navigation/deeplinks/DeepLinkHandler.kt @@ -1,4 +1,4 @@ -package com.freeletics.khonshu.navigation +package com.freeletics.khonshu.navigation.deeplinks /** * DeepLinkHandler can be used to implement Uri based deep links. diff --git a/navigation/src/androidMain/kotlin/com/freeletics/khonshu/navigation/internal/DeepLinkMatcher.kt b/navigation/src/commonMain/kotlin/com/freeletics/khonshu/navigation/deeplinks/DeepLinkMatcher.kt similarity index 91% rename from navigation/src/androidMain/kotlin/com/freeletics/khonshu/navigation/internal/DeepLinkMatcher.kt rename to navigation/src/commonMain/kotlin/com/freeletics/khonshu/navigation/deeplinks/DeepLinkMatcher.kt index 2564d2d96..4e9a614dc 100644 --- a/navigation/src/androidMain/kotlin/com/freeletics/khonshu/navigation/internal/DeepLinkMatcher.kt +++ b/navigation/src/commonMain/kotlin/com/freeletics/khonshu/navigation/deeplinks/DeepLinkMatcher.kt @@ -1,9 +1,9 @@ -package com.freeletics.khonshu.navigation.internal +package com.freeletics.khonshu.navigation.deeplinks import com.eygraber.uri.Uri -import com.freeletics.khonshu.navigation.DeepLinkHandler -import com.freeletics.khonshu.navigation.DeepLinkHandler.Pattern -import com.freeletics.khonshu.navigation.DeepLinkHandler.Prefix +import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler.Pattern +import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler.Prefix +import com.freeletics.khonshu.navigation.internal.InternalNavigationApi /** * Checks if any of the given [uri] matches one of [DeepLinkHandler.patterns] and returns `true` diff --git a/navigation/src/androidMain/kotlin/com/freeletics/khonshu/navigation/internal/DeepLinkParser.kt b/navigation/src/commonMain/kotlin/com/freeletics/khonshu/navigation/deeplinks/DeepLinkParser.kt similarity index 91% rename from navigation/src/androidMain/kotlin/com/freeletics/khonshu/navigation/internal/DeepLinkParser.kt rename to navigation/src/commonMain/kotlin/com/freeletics/khonshu/navigation/deeplinks/DeepLinkParser.kt index f33ba17e2..7dad040d9 100644 --- a/navigation/src/androidMain/kotlin/com/freeletics/khonshu/navigation/internal/DeepLinkParser.kt +++ b/navigation/src/commonMain/kotlin/com/freeletics/khonshu/navigation/deeplinks/DeepLinkParser.kt @@ -1,9 +1,8 @@ -package com.freeletics.khonshu.navigation.internal +package com.freeletics.khonshu.navigation.deeplinks import com.eygraber.uri.Uri -import com.freeletics.khonshu.navigation.DeepLink -import com.freeletics.khonshu.navigation.DeepLinkHandler -import com.freeletics.khonshu.navigation.DeepLinkHandler.Prefix +import com.freeletics.khonshu.navigation.deeplinks.DeepLinkHandler.Prefix +import com.freeletics.khonshu.navigation.internal.InternalNavigationApi /** * Checks if the given [uri] matches one of the [DeepLinkHandler] in the `Set` and if yes