From 78dc79f196b6815d306f80a4d0e174bff826152c Mon Sep 17 00:00:00 2001 From: Jan Skrasek Date: Thu, 26 Oct 2023 13:38:05 +0200 Subject: [PATCH 1/2] Revert "fix key mismatch with polymorphic result sharing (BC break)" This reverts commit cf23ce47e1f7405429e21a0aa074ec0cc45c6376. --- core/api/core.api | 4 ++-- .../navigationcompose/typed/ResultSharing.kt | 23 +++++++------------ .../typed/demo/Destinations.kt | 8 +------ .../typed/demo/screens/NameEditScreen.kt | 2 +- .../typed/demo/screens/Profile.kt | 6 ++--- 5 files changed, 14 insertions(+), 29 deletions(-) diff --git a/core/api/core.api b/core/api/core.api index 62a8183..95532a0 100644 --- a/core/api/core.api +++ b/core/api/core.api @@ -26,8 +26,8 @@ public abstract interface class com/kiwi/navigationcompose/typed/ResultDestinati } public final class com/kiwi/navigationcompose/typed/ResultSharingKt { - public static final fun ResultEffectImpl (Landroidx/navigation/NavController;Ljava/lang/String;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;I)V - public static final fun setResultImpl (Landroidx/navigation/NavController;Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;Ljava/lang/Object;)V + public static final fun ResultEffectImpl (Landroidx/navigation/NavController;Ljava/lang/String;Lkotlinx/serialization/KSerializer;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;I)V + public static final fun setResultImpl (Landroidx/navigation/NavController;Lkotlinx/serialization/KSerializer;Ljava/lang/Object;)V } public final class com/kiwi/navigationcompose/typed/RoutingKt { diff --git a/core/src/main/kotlin/com/kiwi/navigationcompose/typed/ResultSharing.kt b/core/src/main/kotlin/com/kiwi/navigationcompose/typed/ResultSharing.kt index 35e7c51..32d451c 100644 --- a/core/src/main/kotlin/com/kiwi/navigationcompose/typed/ResultSharing.kt +++ b/core/src/main/kotlin/com/kiwi/navigationcompose/typed/ResultSharing.kt @@ -32,7 +32,7 @@ import kotlinx.serialization.serializer @Suppress("unused") // T generic parameter is a typecheck for R being the type from ResultDestination @ExperimentalSerializationApi @Composable -public inline fun , reified R : Any> ComposableResultEffect( +public inline fun , reified R : Any> ComposableResultEffect( navController: NavController, noinline block: (R) -> Unit, ) { @@ -53,7 +53,6 @@ public inline fun , reified R : Any> Composable ResultEffectImpl( navController = navController, currentRoute = currentDestination.route!!, // routes are always not null in Nav Compose - destinationSerializer = serializer(), resultSerializer = serializer(), block = block, ) @@ -76,7 +75,7 @@ public inline fun , reified R : Any> Composable @Suppress("unused") // T generic parameter is a typecheck for R being the type from ResultDestination @ExperimentalSerializationApi @Composable -public inline fun , reified R : Any> DialogResultEffect( +public inline fun , reified R : Any> DialogResultEffect( currentRoutePattern: String, navController: NavController, noinline block: (R) -> Unit, @@ -84,7 +83,6 @@ public inline fun , reified R : Any> DialogResu ResultEffectImpl( navController = navController, currentRoute = currentRoutePattern, - destinationSerializer = serializer(), resultSerializer = serializer(), block = block, ) @@ -96,10 +94,9 @@ public inline fun , reified R : Any> DialogResu @ExperimentalSerializationApi @PublishedApi @Composable -internal fun , R : Any> ResultEffectImpl( +internal fun ResultEffectImpl( navController: NavController, currentRoute: String, - destinationSerializer: KSerializer, resultSerializer: KSerializer, block: (R) -> Unit, ) { @@ -107,7 +104,7 @@ internal fun , R : Any> ResultEffectImpl( // The implementation is based on the official documentation of the Result sharing. // It takes into consideration the possibility of a dialog usage (see the docs). // https://developer.android.com/guide/navigation/navigation-programmatic#additional_considerations - val resultKey = destinationSerializer.descriptor.serialName + "_result" + val resultKey = resultSerializer.descriptor.serialName + "_result" val backStackEntry = navController.getBackStackEntry(currentRoute) val observer = LifecycleEventObserver { _, event -> if (event == Lifecycle.Event.ON_RESUME && backStackEntry.savedStateHandle.contains(resultKey)) { @@ -130,23 +127,19 @@ internal fun , R : Any> ResultEffectImpl( */ @ExperimentalSerializationApi @Suppress("unused") // generic parameter T is a type-check for R being a ResultDestination's type -public inline fun , reified R : Any> NavController.setResult( +public inline fun , reified R : Any> NavController.setResult( data: R, ) { - setResultImpl(serializer(), serializer(), data) + setResultImpl(serializer(), data) } @ExperimentalSerializationApi @PublishedApi -internal fun , R : Any> NavController.setResultImpl( - destinationSerializer: KSerializer, +internal fun NavController.setResultImpl( serializer: KSerializer, data: R, ) { - // ResultDestination's serializer is used to identify the "key" in the map instead of Result's serializer. - // This is to avoid issues with polymorphic result types -> setting a result with Result.Success would - // generate a different key in comparison to just Result type used on the observation side. - val resultKey = destinationSerializer.descriptor.serialName + "_result" val result = Json.encodeToString(serializer, data) + val resultKey = serializer.descriptor.serialName + "_result" previousBackStackEntry?.savedStateHandle?.set(resultKey, result) } diff --git a/demo/src/main/kotlin/com/kiwi/navigationcompose/typed/demo/Destinations.kt b/demo/src/main/kotlin/com/kiwi/navigationcompose/typed/demo/Destinations.kt index 850fad4..ccb5041 100644 --- a/demo/src/main/kotlin/com/kiwi/navigationcompose/typed/demo/Destinations.kt +++ b/demo/src/main/kotlin/com/kiwi/navigationcompose/typed/demo/Destinations.kt @@ -45,12 +45,6 @@ internal sealed interface ProfileDestinations : Destination { @Serializable data object NameEditScreen : ProfileDestinations, ResultDestination { @Serializable - sealed interface Result { - @Serializable - data class Success(val name: String) : Result - - @Serializable - data object Cancelled : Result - } + data class Result(val name: String) } } diff --git a/demo/src/main/kotlin/com/kiwi/navigationcompose/typed/demo/screens/NameEditScreen.kt b/demo/src/main/kotlin/com/kiwi/navigationcompose/typed/demo/screens/NameEditScreen.kt index 5ebcda6..ef4810c 100644 --- a/demo/src/main/kotlin/com/kiwi/navigationcompose/typed/demo/screens/NameEditScreen.kt +++ b/demo/src/main/kotlin/com/kiwi/navigationcompose/typed/demo/screens/NameEditScreen.kt @@ -19,7 +19,7 @@ import kotlinx.serialization.ExperimentalSerializationApi internal fun NameEditScreen(navController: NavController) { NameEdit( onNameSave = { name -> - navController.setResult(ProfileDestinations.NameEditScreen.Result.Success(name)) + navController.setResult(ProfileDestinations.NameEditScreen.Result(name)) navController.navigateUp() }, ) diff --git a/demo/src/main/kotlin/com/kiwi/navigationcompose/typed/demo/screens/Profile.kt b/demo/src/main/kotlin/com/kiwi/navigationcompose/typed/demo/screens/Profile.kt index 6835127..cb011f6 100644 --- a/demo/src/main/kotlin/com/kiwi/navigationcompose/typed/demo/screens/Profile.kt +++ b/demo/src/main/kotlin/com/kiwi/navigationcompose/typed/demo/screens/Profile.kt @@ -36,10 +36,8 @@ internal fun Profile(navController: NavController) { times += 1 } ComposableResultEffect(navController) { result: ProfileDestinations.NameEditScreen.Result -> - if (result is ProfileDestinations.NameEditScreen.Result.Success) { - name = "Screen: ${result.name}" - times += 1 - } + name = "Screen: ${result.name}" + times += 1 } Profile(name, times, navController::navigate) From 4bfbafb97eec19d461d1ac7737372254aed8ca27 Mon Sep 17 00:00:00 2001 From: Jan Skrasek Date: Fri, 27 Oct 2023 16:35:22 +0200 Subject: [PATCH 2/2] remove unused generic that is not auto-resolved to the destination holder or reifed R --- .../com/kiwi/navigationcompose/typed/ResultSharing.kt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/core/src/main/kotlin/com/kiwi/navigationcompose/typed/ResultSharing.kt b/core/src/main/kotlin/com/kiwi/navigationcompose/typed/ResultSharing.kt index 32d451c..db41dcc 100644 --- a/core/src/main/kotlin/com/kiwi/navigationcompose/typed/ResultSharing.kt +++ b/core/src/main/kotlin/com/kiwi/navigationcompose/typed/ResultSharing.kt @@ -29,10 +29,9 @@ import kotlinx.serialization.serializer * } * ``` */ -@Suppress("unused") // T generic parameter is a typecheck for R being the type from ResultDestination @ExperimentalSerializationApi @Composable -public inline fun , reified R : Any> ComposableResultEffect( +public inline fun ComposableResultEffect( navController: NavController, noinline block: (R) -> Unit, ) { @@ -72,10 +71,9 @@ public inline fun , reified R : Any> ComposableResultEf * ) { result: Destinations.Dialog.Result -> * ``` */ -@Suppress("unused") // T generic parameter is a typecheck for R being the type from ResultDestination @ExperimentalSerializationApi @Composable -public inline fun , reified R : Any> DialogResultEffect( +public inline fun DialogResultEffect( currentRoutePattern: String, navController: NavController, noinline block: (R) -> Unit, @@ -126,8 +124,7 @@ internal fun ResultEffectImpl( * The result type has to be KotlinX Serializable. */ @ExperimentalSerializationApi -@Suppress("unused") // generic parameter T is a type-check for R being a ResultDestination's type -public inline fun , reified R : Any> NavController.setResult( +public inline fun NavController.setResult( data: R, ) { setResultImpl(serializer(), data)