Skip to content

Commit

Permalink
Merge pull request #93 from kiwicom/result-sharing-revert
Browse files Browse the repository at this point in the history
Revert Result sharing polymorphic changes
  • Loading branch information
hrach authored Oct 27, 2023
2 parents 5e8a495 + 4bfbafb commit 408d6f1
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 32 deletions.
4 changes: 2 additions & 2 deletions core/api/core.api
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 T : ResultDestination<R>, reified R : Any> ComposableResultEffect(
public inline fun <reified R : Any> ComposableResultEffect(
navController: NavController,
noinline block: (R) -> Unit,
) {
Expand All @@ -53,7 +52,6 @@ public inline fun <reified T : ResultDestination<R>, reified R : Any> Composable
ResultEffectImpl(
navController = navController,
currentRoute = currentDestination.route!!, // routes are always not null in Nav Compose
destinationSerializer = serializer<T>(),
resultSerializer = serializer<R>(),
block = block,
)
Expand All @@ -73,18 +71,16 @@ public inline fun <reified T : ResultDestination<R>, reified R : Any> Composable
* ) { 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 T : ResultDestination<R>, reified R : Any> DialogResultEffect(
public inline fun <reified R : Any> DialogResultEffect(
currentRoutePattern: String,
navController: NavController,
noinline block: (R) -> Unit,
) {
ResultEffectImpl(
navController = navController,
currentRoute = currentRoutePattern,
destinationSerializer = serializer<T>(),
resultSerializer = serializer<R>(),
block = block,
)
Expand All @@ -96,18 +92,17 @@ public inline fun <reified T : ResultDestination<R>, reified R : Any> DialogResu
@ExperimentalSerializationApi
@PublishedApi
@Composable
internal fun <T : ResultDestination<R>, R : Any> ResultEffectImpl(
internal fun <R : Any> ResultEffectImpl(
navController: NavController,
currentRoute: String,
destinationSerializer: KSerializer<T>,
resultSerializer: KSerializer<R>,
block: (R) -> Unit,
) {
DisposableEffect(navController) {
// 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)) {
Expand All @@ -129,24 +124,19 @@ internal fun <T : ResultDestination<R>, R : Any> 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 T : ResultDestination<R>, reified R : Any> NavController.setResult(
public inline fun <reified R : Any> NavController.setResult(
data: R,
) {
setResultImpl(serializer<T>(), serializer<R>(), data)
setResultImpl(serializer(), data)
}

@ExperimentalSerializationApi
@PublishedApi
internal fun <T : ResultDestination<R>, R : Any> NavController.setResultImpl(
destinationSerializer: KSerializer<T>,
internal fun <R : Any> NavController.setResultImpl(
serializer: KSerializer<R>,
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)
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,6 @@ internal sealed interface ProfileDestinations : Destination {
@Serializable
data object NameEditScreen : ProfileDestinations, ResultDestination<NameEditScreen.Result> {
@Serializable
sealed interface Result {
@Serializable
data class Success(val name: String) : Result

@Serializable
data object Cancelled : Result
}
data class Result(val name: String)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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()
},
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 408d6f1

Please sign in to comment.