Skip to content

Commit 4df9bbc

Browse files
committed
Add NiaBackStack and BackStack providers
Bump agp versions and add navigation 3 dependency
1 parent 74b10ea commit 4df9bbc

File tree

12 files changed

+167
-6
lines changed

12 files changed

+167
-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: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
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 androidx.compose.runtime.snapshots.SnapshotStateList
20+
import com.google.samples.apps.nowinandroid.core.navigation.BackStackFactory
21+
import com.google.samples.apps.nowinandroid.core.navigation.NiaBackStack
22+
import com.google.samples.apps.nowinandroid.feature.foryou.api.navigation.ForYouRoute
23+
import dagger.Module
24+
import dagger.Provides
25+
import dagger.hilt.InstallIn
26+
import javax.inject.Singleton
27+
import dagger.hilt.components.SingletonComponent
28+
29+
@Module
30+
@InstallIn(SingletonComponent::class)
31+
object NiaAppNavigation {
32+
@Provides
33+
@Singleton
34+
fun provideBackStack(backStackFactory: BackStackFactory) : SnapshotStateList<Any> =
35+
backStackFactory.create()
36+
37+
@Provides
38+
@Singleton
39+
fun provideNiaBackStack(backStack: SnapshotStateList<Any>): NiaBackStack =
40+
NiaBackStack(backStack, startKey = ForYouRoute)
41+
}

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: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
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.mutableStateListOf
20+
import androidx.compose.runtime.snapshots.SnapshotStateList
21+
import javax.inject.Inject
22+
23+
class BackStackFactory @Inject constructor() {
24+
fun create() : SnapshotStateList<Any> = mutableStateListOf()
25+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
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+
val backStack: SnapshotStateList<Any>,
29+
startKey: Any,
30+
) {
31+
init {
32+
backStack.add(startKey)
33+
}
34+
35+
// Maintain a stack for each top level route
36+
private var topLevelStacks : LinkedHashMap<Any, SnapshotStateList<Any>> = linkedMapOf(
37+
startKey to mutableStateListOf(startKey)
38+
)
39+
40+
// Expose the current top level route for consumers
41+
var topLevelKey by mutableStateOf(startKey)
42+
private set
43+
44+
private fun updateBackStack() =
45+
backStack.apply {
46+
clear()
47+
addAll(topLevelStacks.flatMap { it.value })
48+
}
49+
.also { println("cfok currBackStack:$backStack") }
50+
51+
fun navigateToTopLevelDestination(key: Any){
52+
// If the top level doesn't exist, add it
53+
if (topLevelStacks[key] == null){
54+
topLevelStacks.put(key, mutableStateListOf(key))
55+
} else {
56+
// Otherwise just move it to the end of the stacks
57+
topLevelStacks.apply {
58+
remove(key)?.let {
59+
put(key, it)
60+
}
61+
}
62+
}
63+
topLevelKey = key
64+
updateBackStack()
65+
}
66+
67+
fun navigate(key: Any){
68+
println("cfok navigate $key")
69+
topLevelStacks[topLevelKey]?.add(key)
70+
updateBackStack()
71+
}
72+
73+
fun removeLast(){
74+
val removedKey = topLevelStacks[topLevelKey]?.removeLastOrNull()
75+
// If the removed key was a top level key, remove the associated top level stack
76+
topLevelStacks.remove(removedKey)
77+
topLevelKey = topLevelStacks.keys.last()
78+
updateBackStack()
79+
}
80+
81+
}

0 commit comments

Comments
 (0)