Skip to content

Commit a31451f

Browse files
committed
Add NiaBackStack and BackStack providers
Bump agp versions and add navigation 3 dependency
1 parent e3fe8af commit a31451f

File tree

11 files changed

+131
-6
lines changed

11 files changed

+131
-6
lines changed

app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ dependencies {
8383
implementation(projects.core.designsystem)
8484
implementation(projects.core.data)
8585
implementation(projects.core.model)
86+
implementation(projects.core.navigation)
8687
implementation(projects.core.analytics)
8788
implementation(projects.sync.work)
8889

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2025 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.samples.apps.nowinandroid.di
18+
19+
import com.google.samples.apps.nowinandroid.core.navigation.NiaBackStack
20+
import com.google.samples.apps.nowinandroid.navigation.TopLevelDestination
21+
import dagger.Module
22+
import dagger.Provides
23+
import dagger.hilt.InstallIn
24+
import javax.inject.Singleton
25+
import dagger.hilt.components.SingletonComponent
26+
27+
@Module
28+
@InstallIn(SingletonComponent::class)
29+
object NiaAppNavigation {
30+
@Provides
31+
@Singleton
32+
fun provideNiaBackStack(): NiaBackStack =
33+
NiaBackStack(startKey = TopLevelDestination.FOR_YOU)
34+
}

build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class AndroidApplicationConventionPlugin : Plugin<Project> {
3737

3838
extensions.configure<ApplicationExtension> {
3939
configureKotlinAndroid(this)
40-
defaultConfig.targetSdk = 35
40+
defaultConfig.targetSdk = 36
4141
@Suppress("UnstableApiUsage")
4242
testOptions.animationsDisabled = true
4343
configureGradleManagedDevices(this)

build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class AndroidLibraryConventionPlugin : Plugin<Project> {
3737

3838
extensions.configure<LibraryExtension> {
3939
configureKotlinAndroid(this)
40-
defaultConfig.targetSdk = 35
40+
defaultConfig.targetSdk = 36
4141
defaultConfig.testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
4242
testOptions.animationsDisabled = true
4343
configureFlavors(this)

build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class AndroidTestConventionPlugin : Plugin<Project> {
3030

3131
extensions.configure<TestExtension> {
3232
configureKotlinAndroid(this)
33-
defaultConfig.targetSdk = 35
33+
defaultConfig.targetSdk = 36
3434
configureGradleManagedDevices(this)
3535
}
3636
}

build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ internal fun Project.configureKotlinAndroid(
3535
commonExtension: CommonExtension<*, *, *, *, *, *>,
3636
) {
3737
commonExtension.apply {
38-
compileSdk = 35
38+
compileSdk = 36
3939

4040
defaultConfig {
4141
minSdk = 21

core/navigation/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

core/navigation/build.gradle.kts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
plugins {
2+
alias(libs.plugins.nowinandroid.jvm.library)
3+
alias(libs.plugins.nowinandroid.hilt)
4+
}
5+
6+
dependencies {
7+
implementation(libs.androidx.navigation3.runtime)
8+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright 2025 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.samples.apps.nowinandroid.core.navigation
18+
19+
import androidx.compose.runtime.getValue
20+
import androidx.compose.runtime.mutableStateListOf
21+
import androidx.compose.runtime.mutableStateOf
22+
import androidx.compose.runtime.setValue
23+
import androidx.compose.runtime.snapshots.SnapshotStateList
24+
import javax.inject.Inject
25+
import kotlin.collections.remove
26+
27+
class NiaBackStack @Inject constructor(
28+
startKey: Any,
29+
) {
30+
val backStack = mutableStateListOf(startKey)
31+
32+
// Maintain a stack for each top level route
33+
private var topLevelStacks : LinkedHashMap<Any, SnapshotStateList<Any>> = linkedMapOf(
34+
startKey to mutableStateListOf(startKey)
35+
)
36+
37+
// Expose the current top level route for consumers
38+
var topLevelKey by mutableStateOf(startKey)
39+
private set
40+
41+
private fun updateBackStack() =
42+
backStack.apply {
43+
clear()
44+
addAll(topLevelStacks.flatMap { it.value })
45+
}
46+
47+
fun navigateToTopLevelDestination(key: Any){
48+
// If the top level doesn't exist, add it
49+
if (topLevelStacks[key] == null){
50+
topLevelStacks.put(key, mutableStateListOf(key))
51+
} else {
52+
// Otherwise just move it to the end of the stacks
53+
topLevelStacks.apply {
54+
remove(key)?.let {
55+
put(key, it)
56+
}
57+
}
58+
}
59+
topLevelKey = key
60+
updateBackStack()
61+
}
62+
63+
fun navigate(key: Any){
64+
println("cfok navigate $key")
65+
topLevelStacks[topLevelKey]?.add(key)
66+
updateBackStack()
67+
}
68+
69+
fun removeLast(){
70+
val removedKey = topLevelStacks[topLevelKey]?.removeLastOrNull()
71+
// If the removed key was a top level key, remove the associated top level stack
72+
topLevelStacks.remove(removedKey)
73+
topLevelKey = topLevelStacks.keys.last()
74+
updateBackStack()
75+
}
76+
77+
}

gradle/libs.versions.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
accompanist = "0.37.0"
33
androidDesugarJdkLibs = "2.1.4"
44
# AGP and tools should be updated together
5-
androidGradlePlugin = "8.9.0"
6-
androidTools = "31.9.0"
5+
androidGradlePlugin = "8.9.3"
6+
androidTools = "31.9.3"
77
androidxActivity = "1.9.3"
88
androidxAppCompat = "1.7.0"
99
androidxBrowser = "1.8.0"
@@ -21,6 +21,7 @@ androidxLintGradle = "1.0.0-alpha03"
2121
androidxMacroBenchmark = "1.3.4"
2222
androidxMetrics = "1.0.0-beta01"
2323
androidxNavigation = "2.8.5"
24+
androidxNavigation3 = "1.0.0-alpha03"
2425
androidxProfileinstaller = "1.4.1"
2526
androidxTestCore = "1.7.0-rc01"
2627
androidxTestExt = "1.3.0-rc01"
@@ -99,6 +100,8 @@ androidx-lint-gradle = { group = "androidx.lint", name = "lint-gradle", version.
99100
androidx-metrics = { group = "androidx.metrics", name = "metrics-performance", version.ref = "androidxMetrics" }
100101
androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "androidxNavigation" }
101102
androidx-navigation-testing = { group = "androidx.navigation", name = "navigation-testing", version.ref = "androidxNavigation" }
103+
androidx-navigation3-runtime = { group = "androidx.navigation3", name = "navigation3-runtime", version.ref = "androidxNavigation3" }
104+
androidx-navigation3-ui = { group = "androidx.navigation3", name = "navigation3-ui", version.ref = "androidxNavigation3" }
102105
androidx-profileinstaller = { group = "androidx.profileinstaller", name = "profileinstaller", version.ref = "androidxProfileinstaller" }
103106
androidx-test-core = { group = "androidx.test", name = "core", version.ref = "androidxTestCore" }
104107
androidx-test-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "androidxEspresso" }

0 commit comments

Comments
 (0)