Skip to content

Commit f63adb6

Browse files
authored
Merge pull request #251 from hotwired/fix-navhost-reset
Fix resetting the `TurboSessionNavHostFragment`
2 parents 31569a0 + d1cc239 commit f63adb6

File tree

1 file changed

+26
-17
lines changed

1 file changed

+26
-17
lines changed

turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavGraphBuilder.kt

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package dev.hotwire.turbo.nav
22

33
import android.net.Uri
4-
import androidx.annotation.IdRes
54
import androidx.appcompat.app.AppCompatActivity
65
import androidx.core.net.toUri
76
import androidx.fragment.app.DialogFragment
@@ -13,6 +12,7 @@ import androidx.navigation.fragment.FragmentNavigator
1312
import androidx.navigation.fragment.FragmentNavigatorDestinationBuilder
1413
import dev.hotwire.turbo.config.TurboPathConfiguration
1514
import dev.hotwire.turbo.config.uri
15+
import java.util.*
1616
import kotlin.reflect.KClass
1717
import kotlin.reflect.full.findAnnotation
1818
import kotlin.reflect.full.isSubclassOf
@@ -23,13 +23,13 @@ internal class TurboNavGraphBuilder(
2323
private val pathConfiguration: TurboPathConfiguration
2424
) {
2525
private data class ActivityDestination(
26-
val id: Int,
26+
val route: String,
2727
val uri: Uri,
2828
val kClass: KClass<out AppCompatActivity>
2929
)
3030

3131
private data class FragmentDestination(
32-
val id: Int,
32+
val route: String,
3333
val uri: Uri,
3434
val kClass: KClass<out Fragment>
3535
)
@@ -38,19 +38,19 @@ internal class TurboNavGraphBuilder(
3838
registeredActivities: List<KClass<out AppCompatActivity>>,
3939
registeredFragments: List<KClass<out Fragment>>
4040
): NavGraph {
41-
var currentId = 1
41+
var currentRoute = 1
4242

4343
val activityDestinations = registeredActivities.map {
4444
ActivityDestination(
45-
id = currentId.also { currentId++ },
45+
route = currentRoute.also { currentRoute++ }.toString(),
4646
uri = it.turboAnnotation().uri.toUri(),
4747
kClass = it
4848
)
4949
}
5050

5151
val fragmentDestinations = registeredFragments.map {
5252
FragmentDestination(
53-
id = currentId.also { currentId++ },
53+
route = currentRoute.also { currentRoute++ }.toString(),
5454
uri = it.turboAnnotation().uri.toUri(),
5555
kClass = it
5656
)
@@ -59,39 +59,48 @@ internal class TurboNavGraphBuilder(
5959
return createGraph(
6060
activityDestinations,
6161
fragmentDestinations,
62-
fragmentDestinations.startDestination().id
62+
fragmentDestinations.startDestination().route
6363
)
6464
}
6565

6666
@Suppress("UNCHECKED_CAST")
6767
private fun createGraph(
6868
activityDestinations: List<ActivityDestination>,
6969
fragmentDestinations: List<FragmentDestination>,
70-
startDestinationId: Int
70+
startDestinationRoute: String
7171
): NavGraph {
72-
return navController.createGraph(startDestination = startDestinationId) {
72+
return navController.createGraph(startDestination = startDestinationRoute) {
7373
activityDestinations.forEach {
74-
activity(it.id) {
74+
activity(it.route) {
7575
activityClass = it.kClass
7676
deepLink(it.uri.toString())
7777
}
7878
}
7979

8080
fragmentDestinations.withoutDialogs().forEach {
81-
fragment(it.id, it.kClass) {
81+
fragment(it.route, it.kClass) {
8282
deepLink(it.uri.toString())
8383
}
8484
}
8585

8686
fragmentDestinations.dialogs().forEach {
87-
dialog(it.id, it.kClass as KClass<out DialogFragment>) {
87+
dialog(it.route, it.kClass as KClass<out DialogFragment>) {
8888
deepLink(it.uri.toString())
8989
}
9090
}
9191

9292
argument("location") {
9393
defaultValue = startLocation
9494
}
95+
96+
// Use a random value to represent a unique instance of the graph, so the
97+
// graph is unique every time. This lets it be reset/recreated on-demand from
98+
// `TurboSessionNavHostFragment.reset()`. Replacing an existing nav graph with
99+
// an identical one would bypass recreating the nav stack from scratch in
100+
// `NavController.setGraph()`.
101+
argument("unique_instance") {
102+
defaultValue = UUID.randomUUID().toString()
103+
}
95104
}
96105
}
97106

@@ -100,7 +109,7 @@ internal class TurboNavGraphBuilder(
100109
}
101110

102111
private fun List<FragmentDestination>.withoutDialogs(): List<FragmentDestination> {
103-
return minus(dialogs())
112+
return minus(dialogs().toSet())
104113
}
105114

106115
private fun List<FragmentDestination>.startDestination(): FragmentDestination {
@@ -118,26 +127,26 @@ internal class TurboNavGraphBuilder(
118127

119128
// Modified from AndroidX FragmentNavigatorDestinationBuilder extensions
120129
private inline fun NavGraphBuilder.fragment(
121-
@IdRes id: Int,
130+
route: String,
122131
fragmentClass: KClass<out Fragment>,
123132
builder: FragmentNavigatorDestinationBuilder.() -> Unit
124133
) = destination(
125134
FragmentNavigatorDestinationBuilder(
126135
provider[FragmentNavigator::class],
127-
id,
136+
route,
128137
fragmentClass
129138
).apply(builder)
130139
)
131140

132141
// Modified from AndroidX DialogFragmentNavigatorDestinationBuilder extensions
133142
private inline fun NavGraphBuilder.dialog(
134-
@IdRes id: Int,
143+
route: String,
135144
fragmentClass: KClass<out DialogFragment>,
136145
builder: DialogFragmentNavigatorDestinationBuilder.() -> Unit
137146
) = destination(
138147
DialogFragmentNavigatorDestinationBuilder(
139148
provider[DialogFragmentNavigator::class],
140-
id,
149+
route,
141150
fragmentClass
142151
).apply(builder)
143152
)

0 commit comments

Comments
 (0)