Skip to content

Commit 3b2dae5

Browse files
committed
Initial attempt to use Jetpack Navigation in shared KMP code
1 parent d3c0ac2 commit 3b2dae5

File tree

6 files changed

+105
-8
lines changed

6 files changed

+105
-8
lines changed

composeApp/build.gradle.kts

+3
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ kotlin {
7272

7373
implementation(libs.voyager)
7474

75+
implementation(libs.androidx.lifecycle.viewmodel.compose)
76+
implementation(libs.androidx.navigation.compose)
77+
7578
implementation(libs.kmmViewModel)
7679

7780
implementation(libs.koalaplot)
+87-2
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,105 @@
1+
import androidx.compose.foundation.layout.padding
2+
import androidx.compose.material3.CenterAlignedTopAppBar
3+
import androidx.compose.material3.ExperimentalMaterial3Api
14
import androidx.compose.material3.MaterialTheme
5+
import androidx.compose.material3.Scaffold
6+
import androidx.compose.material3.Text
27
import androidx.compose.runtime.Composable
8+
import androidx.compose.runtime.LaunchedEffect
9+
import androidx.compose.runtime.collectAsState
10+
import androidx.compose.runtime.getValue
11+
import androidx.compose.ui.Modifier
12+
import androidx.navigation.NavHostController
13+
import androidx.navigation.compose.NavHost
14+
import androidx.navigation.compose.composable
15+
import androidx.navigation.compose.rememberNavController
316
import cafe.adriel.voyager.navigator.Navigator
417
import dev.johnoreilly.climatetrace.di.commonModule
18+
import dev.johnoreilly.climatetrace.remote.Country
519
import dev.johnoreilly.climatetrace.ui.ClimateTraceScreen
20+
import dev.johnoreilly.climatetrace.ui.CountryInfoDetailedView
21+
import dev.johnoreilly.climatetrace.ui.CountryListView
22+
import dev.johnoreilly.climatetrace.viewmodel.ClimateTraceViewModel
623
import org.jetbrains.compose.ui.tooling.preview.Preview
724
import org.koin.compose.KoinApplication
25+
import org.koin.compose.koinInject
826

927

1028
@Preview
1129
@Composable
12-
fun App() {
30+
fun AppVoyagerNav() {
1331
KoinApplication(application = {
1432
modules(commonModule())
1533
}) {
1634
MaterialTheme {
1735
Navigator(screen = ClimateTraceScreen())
1836
}
1937
}
20-
}
38+
}
39+
40+
@OptIn(ExperimentalMaterial3Api::class)
41+
@Composable
42+
fun AppJetpackBav() {
43+
KoinApplication(application = {
44+
modules(commonModule())
45+
}) {
46+
47+
MaterialTheme {
48+
val navController: NavHostController = rememberNavController()
49+
50+
val viewModel = koinInject<ClimateTraceViewModel>()
51+
val countryList = viewModel.countryList.collectAsState()
52+
val selectedCountry = viewModel.selectedCountry.collectAsState()
53+
val isLoadingCountries by viewModel.isLoadingCountries.collectAsState()
54+
55+
Scaffold(
56+
topBar = {
57+
CenterAlignedTopAppBar(title = {
58+
Text("ClimateTraceKMP")
59+
})
60+
}
61+
) { innerPadding ->
62+
63+
NavHost(
64+
navController = navController,
65+
startDestination = "countryList",
66+
modifier = Modifier.padding(innerPadding)
67+
) {
68+
69+
composable(route = "countryList") {
70+
CountryListView(
71+
countryList.value,
72+
selectedCountry.value,
73+
isLoadingCountries
74+
) { country ->
75+
navController.navigate("details/${country.name}/${country.alpha3}")
76+
}
77+
}
78+
composable("details/{countryName}/{countryCode}",) { backStackEntry ->
79+
80+
val countryName = backStackEntry.arguments?.getString("countryName") ?: ""
81+
val countryCode = backStackEntry.arguments?.getString("countryCode") ?: ""
82+
val country = Country(countryCode, "", countryName, "")
83+
84+
val countryEmissionInfo by viewModel.countryEmissionInfo.collectAsState()
85+
val countryAssetEmissions by viewModel.countryAssetEmissions.collectAsState()
86+
val isLoadingCountryDetails by viewModel.isLoadingCountryDetails.collectAsState()
87+
88+
LaunchedEffect(country) {
89+
viewModel.fetchCountryDetails(country)
90+
}
91+
92+
CountryInfoDetailedView(
93+
country,
94+
viewModel.year,
95+
countryEmissionInfo,
96+
countryAssetEmissions,
97+
isLoadingCountryDetails
98+
)
99+
}
100+
}
101+
}
102+
}
103+
}
104+
105+
}

composeApp/src/desktopMain/kotlin/main.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ import androidx.compose.ui.window.application
66

77
fun main() = application {
88
Window(onCloseRequest = ::exitApplication, title = "ClimateTraceKMP") {
9-
App()
9+
AppJetpackBav()
1010
}
1111
}
1212

1313
@Preview
1414
@Composable
1515
fun AppDesktopPreview() {
16-
App()
16+
AppJetpackBav()
1717
}
1818

composeApp/src/wasmJsMain/kotlin/main.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ import androidx.compose.ui.window.CanvasBasedWindow
33

44
@OptIn(ExperimentalComposeUiApi::class)
55
fun main() {
6-
CanvasBasedWindow(canvasElementId = "ComposeTarget") { App() }
6+
CanvasBasedWindow(canvasElementId = "ComposeTarget") { AppJetpackBav() }
77
}

gradle/libs.versions.toml

+10-1
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,14 @@ androidx-core-ktx = "1.12.0"
1010
androidx-espresso-core = "3.5.1"
1111
androidx-material = "1.11.0"
1212
androidx-test-junit = "1.1.5"
13+
14+
androidx-navigation = "2.8.0-alpha02"
15+
androidx-lifecycle = "2.8.0-beta02"
16+
17+
1318
compose = "1.6.5"
1419
compose-compiler = "1.5.11-kt-2.0.0-RC1"
15-
compose-plugin = "1.6.2"
20+
compose-plugin = "1.6.10-beta02"
1621
composeWindowSize = "0.5.0"
1722
imageLoader = "1.7.8"
1823
junit = "4.13.2"
@@ -41,6 +46,10 @@ androidx-material = { group = "com.google.android.material", name = "material",
4146
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "androidx-constraintlayout" }
4247
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" }
4348

49+
androidx-lifecycle-viewmodel-compose = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle" }
50+
androidx-navigation-compose = { module = "org.jetbrains.androidx.navigation:navigation-compose", version.ref = "androidx-navigation" }
51+
52+
4453
compose-ui = { module = "androidx.compose.ui:ui", version.ref = "compose" }
4554
compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" }
4655
compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" }

local.properties

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
# Location of the SDK. This is only used by Gradle.
55
# For customization when using a Version Control System, please read the
66
# header note.
7-
#Sat Apr 13 09:38:39 IST 2024
8-
sdk.dir=/Users/joreilly/Library/Android/sdk
7+
#Wed Apr 17 18:40:20 CEST 2024
8+
sdk.dir=/Users/johnoreilly/Library/Android/sdk

0 commit comments

Comments
 (0)