Skip to content

Commit 1c83dfd

Browse files
authored
Merge pull request #87 from joreilly/year_selection
allow selection of year
2 parents fd0f3a0 + 6e83f60 commit 1c83dfd

File tree

7 files changed

+73
-40
lines changed

7 files changed

+73
-40
lines changed

.github/workflows/build-and-publish-web.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@ jobs:
2525
- name: Build
2626
run: ./gradlew :composeApp:wasmJsBrowserDistribution
2727

28-
# - name: Copy "uninstantiated" file over (workaround for now)
29-
# run: cp compose-web/build/compileSync/wasmJs/main/productionExecutable/kotlin/chip8.uninstantiated.mjs compose-web/build/dist/wasmJs/productionExecutable
30-
3128
# If main branch update, deploy to gh-pages
3229
- name: Deploy
3330
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main'

composeApp/src/commonMain/kotlin/dev/johnoreilly/climatetrace/ui/ClimateTraceScreen.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,15 @@ class ClimateTraceScreen: Screen {
9696
selectedCountry = selectedCountry,
9797
isLoading = isLoadingCountries
9898
) { country ->
99-
viewModel.fetchCountryDetails(country)
99+
viewModel.setCountry(country)
100100
}
101101
}
102102

103103
Spacer(modifier = Modifier.width(1.dp).fillMaxWidth())
104104
CountryInfoDetailedView(
105105
country = selectedCountry,
106-
year = viewModel.year,
106+
year = viewModel.selectedYear.value,
107+
onYearSelected = { viewModel.setYear(it) },
107108
countryEmissionInfo = countryEmissionInfo,
108109
countryAssetEmissionsList = countryAssetEmissions,
109110
isLoading = isLoadingCountryDetails
@@ -121,15 +122,16 @@ class ClimateTraceScreen: Screen {
121122
selectedCountry = selectedCountry,
122123
isLoading = isLoadingCountries
123124
) { country ->
124-
viewModel.fetchCountryDetails(country)
125+
viewModel.setCountry(country)
125126
}
126127
}
127128

128129
VerticalDivider(thickness = 1.dp, color = Color.DarkGray)
129130
Box(Modifier.fillMaxHeight()) {
130131
CountryInfoDetailedView(
131132
country = viewModel.selectedCountry.value,
132-
year = viewModel.year,
133+
year = viewModel.selectedYear.value,
134+
onYearSelected = { viewModel.setYear(it) },
133135
countryEmissionInfo = countryEmissionInfo,
134136
countryAssetEmissionsList = countryAssetEmissions,
135137
isLoading = isLoadingCountryDetails

composeApp/src/commonMain/kotlin/dev/johnoreilly/climatetrace/ui/CountryEmissionsScreen.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ data class CountryEmissionsScreen(val country: Country) : Screen {
3030
val isLoadingCountryDetails by viewModel.isLoadingCountryDetails.collectAsState()
3131

3232
LaunchedEffect(country) {
33-
viewModel.fetchCountryDetails(country)
33+
viewModel.setCountry(country)
3434
}
3535

3636
Scaffold(
@@ -50,7 +50,8 @@ data class CountryEmissionsScreen(val country: Country) : Screen {
5050
Column(Modifier.padding(it)) {
5151
CountryInfoDetailedView(
5252
country,
53-
viewModel.year,
53+
viewModel.selectedYear.value,
54+
onYearSelected = { viewModel.setYear(it) },
5455
countryEmissionInfo,
5556
countryAssetEmissions,
5657
isLoadingCountryDetails

composeApp/src/commonMain/kotlin/dev/johnoreilly/climatetrace/ui/CountryInfoDetailedView.kt

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
11
package dev.johnoreilly.climatetrace.ui
22

3+
import androidx.compose.foundation.clickable
4+
import androidx.compose.foundation.layout.Box
35
import androidx.compose.foundation.layout.Column
46
import androidx.compose.foundation.layout.Spacer
5-
import androidx.compose.foundation.layout.fillMaxHeight
67
import androidx.compose.foundation.layout.fillMaxSize
78
import androidx.compose.foundation.layout.padding
89
import androidx.compose.foundation.layout.size
910
import androidx.compose.foundation.layout.wrapContentSize
1011
import androidx.compose.foundation.rememberScrollState
1112
import androidx.compose.foundation.verticalScroll
1213
import androidx.compose.material3.CircularProgressIndicator
14+
import androidx.compose.material3.DropdownMenu
15+
import androidx.compose.material3.DropdownMenuItem
1316
import androidx.compose.material3.MaterialTheme
1417
import androidx.compose.material3.Text
1518
import androidx.compose.runtime.Composable
19+
import androidx.compose.runtime.getValue
20+
import androidx.compose.runtime.mutableStateOf
21+
import androidx.compose.runtime.remember
22+
import androidx.compose.runtime.setValue
1623
import androidx.compose.ui.Alignment
1724
import androidx.compose.ui.Modifier
1825
import androidx.compose.ui.graphics.Color
@@ -26,35 +33,24 @@ import dev.johnoreilly.climatetrace.remote.CountryEmissionsInfo
2633
fun CountryInfoDetailedView(
2734
country: Country?,
2835
year: String,
36+
onYearSelected: (String) -> Unit,
2937
countryEmissionInfo: CountryEmissionsInfo?,
3038
countryAssetEmissionsList: List<CountryAssetEmissionsInfo>?,
3139
isLoading: Boolean
3240
) {
3341
when {
3442
country == null -> {
3543
Column(
36-
modifier = Modifier
37-
.fillMaxSize()
38-
.fillMaxHeight()
44+
modifier = Modifier.fillMaxSize()
3945
.wrapContentSize(Alignment.Center)
4046
) {
41-
Column(
42-
modifier = Modifier
43-
.fillMaxSize()
44-
.fillMaxHeight()
45-
.wrapContentSize(Alignment.Center),
46-
horizontalAlignment = Alignment.CenterHorizontally
47-
) {
48-
Text(text = "No Country Selected.", style = MaterialTheme.typography.titleMedium)
49-
}
47+
Text(text = "No Country Selected.", style = MaterialTheme.typography.titleMedium)
5048
}
5149
}
5250
else -> {
5351
if (isLoading) {
5452
Column(
55-
modifier = Modifier
56-
.fillMaxSize()
57-
.fillMaxHeight()
53+
modifier = Modifier.fillMaxSize()
5854
.wrapContentSize(Alignment.Center)
5955
) {
6056
CircularProgressIndicator()
@@ -76,6 +72,8 @@ fun CountryInfoDetailedView(
7672

7773
Spacer(modifier = Modifier.size(16.dp))
7874

75+
YearSelector(year, onYearSelected)
76+
7977
val co2 = (countryEmissionInfo.emissions.co2 / 1_000_000).toInt()
8078
val percentage = (countryEmissionInfo.emissions.co2 / countryEmissionInfo.worldEmissions.co2).toPercent(2)
8179

@@ -86,10 +84,9 @@ fun CountryInfoDetailedView(
8684

8785
val filteredCountryAssetEmissionsList = countryAssetEmissionsList.filter { it.sector != null }
8886
if (filteredCountryAssetEmissionsList.isNotEmpty()) {
89-
CountryAssetEmissionsInfoTreeMapChart(countryAssetEmissionsList)
90-
Spacer(modifier = Modifier.size(16.dp))
91-
9287
SectorEmissionsPieChart(countryAssetEmissionsList)
88+
Spacer(modifier = Modifier.size(16.dp))
89+
CountryAssetEmissionsInfoTreeMapChart(countryAssetEmissionsList)
9390
} else {
9491
Spacer(modifier = Modifier.size(16.dp))
9592
Column(horizontalAlignment = Alignment.CenterHorizontally) {
@@ -107,3 +104,26 @@ fun CountryInfoDetailedView(
107104
}
108105
}
109106

107+
@Composable
108+
fun YearSelector(selectedYear: String, onYearSelected: (String) -> Unit) {
109+
var expanded by remember { mutableStateOf(false) }
110+
val items = listOf("2021", "2022")
111+
112+
Box(modifier = Modifier.wrapContentSize(Alignment.TopStart)) {
113+
Text(selectedYear, modifier = Modifier.clickable(onClick = { expanded = true }))
114+
DropdownMenu(
115+
expanded = expanded,
116+
onDismissRequest = { expanded = false },
117+
) {
118+
items.forEach { year ->
119+
DropdownMenuItem(onClick = {
120+
onYearSelected(year)
121+
expanded = false
122+
}, text = {
123+
Text(year)
124+
})
125+
}
126+
}
127+
}
128+
}
129+

composeApp/src/commonMain/kotlin/dev/johnoreilly/climatetrace/viewmodel/ClimateTraceViewModel.kt

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@ open class ClimateTraceViewModel : ViewModel(), KoinComponent {
1818
private val climateTraceApi: ClimateTraceApi by inject()
1919
private val climateTraceRepository: ClimateTraceRepository by inject()
2020

21-
var year: String = "2022" // TODO make this configurable
22-
2321
private val _countryList = MutableStateFlow<List<Country>>(viewModelScope, emptyList())
2422
@NativeCoroutinesState
2523
val countryList = _countryList.asStateFlow()
2624

25+
@NativeCoroutinesState
26+
val selectedYear = MutableStateFlow<String>(viewModelScope, "2022")
27+
2728
@NativeCoroutinesState
2829
val selectedCountry = MutableStateFlow<Country?>(viewModelScope, null)
2930

@@ -44,13 +45,24 @@ open class ClimateTraceViewModel : ViewModel(), KoinComponent {
4445
}
4546
}
4647

47-
fun fetchCountryDetails(country: Country) {
48+
fun setYear(year: String) {
49+
selectedYear.value = year
50+
fetchCountryDetails()
51+
}
52+
53+
fun setCountry(country: Country) {
4854
selectedCountry.value = country
49-
isLoadingCountryDetails.value = true
50-
viewModelScope.coroutineScope.launch {
51-
countryEmissionInfo.value = climateTraceApi.fetchCountryEmissionsInfo(country.alpha3, year).firstOrNull()
52-
countryAssetEmissions.value = climateTraceApi.fetchCountryAssetEmissionsInfo(country.alpha3)
53-
isLoadingCountryDetails.value = false
55+
fetchCountryDetails()
56+
}
57+
58+
fun fetchCountryDetails() {
59+
selectedCountry.value?.let { country ->
60+
isLoadingCountryDetails.value = true
61+
viewModelScope.coroutineScope.launch {
62+
countryEmissionInfo.value = climateTraceApi.fetchCountryEmissionsInfo(country.alpha3, selectedYear.value).firstOrNull()
63+
countryAssetEmissions.value = climateTraceApi.fetchCountryAssetEmissionsInfo(country.alpha3)
64+
isLoadingCountryDetails.value = false
65+
}
5466
}
5567
}
5668
}

composeApp/src/iosMain/kotlin/MainViewController.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,16 @@ fun CountryListViewController(onCountryClicked: (country: Country) -> Unit) = Co
2323
}
2424

2525

26-
fun CountryInfoDetailedViewController(country: Country, year: String) = ComposeUIViewController {
26+
fun CountryInfoDetailedViewController(country: Country) = ComposeUIViewController {
2727
val viewModel = koinInject<ClimateTraceViewModel>()
2828
val countryEmissionInfo by viewModel.countryEmissionInfo.collectAsState()
2929
val countryAssetEmissions by viewModel.countryAssetEmissions.collectAsState()
3030
val isLoadingCountryDetails by viewModel.isLoadingCountryDetails.collectAsState()
3131

3232
LaunchedEffect(country) {
33-
viewModel.fetchCountryDetails(country)
33+
viewModel.setCountry(country)
3434
}
3535

36-
CountryInfoDetailedView(country, year, countryEmissionInfo, countryAssetEmissions, isLoadingCountryDetails)
36+
CountryInfoDetailedView(country, viewModel.selectedYear.value, { viewModel.setYear(it) },
37+
countryEmissionInfo, countryAssetEmissions, isLoadingCountryDetails)
3738
}

iosApp/iosApp/ContentView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ struct CountryInfoDetailedViewShared: UIViewControllerRepresentable {
110110
let country: Country
111111

112112
func makeUIViewController(context: Context) -> UIViewController {
113-
MainViewControllerKt.CountryInfoDetailedViewController(country: country, year: "2022")
113+
MainViewControllerKt.CountryInfoDetailedViewController(country: country)
114114
}
115115

116116
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}

0 commit comments

Comments
 (0)