@@ -51,133 +51,129 @@ import cafe.adriel.voyager.core.screen.Screen
5151import dev.johnoreilly.climatetrace.remote.Country
5252import dev.johnoreilly.climatetrace.ui.utils.PanelState
5353import dev.johnoreilly.climatetrace.ui.utils.ResizablePanel
54- import dev.johnoreilly.climatetrace.viewmodel.ClimateTraceViewModel
54+ import dev.johnoreilly.climatetrace.viewmodel.CountryDetailsViewModel
55+ import dev.johnoreilly.climatetrace.viewmodel.CountryListUIState
56+ import dev.johnoreilly.climatetrace.viewmodel.CountryListViewModel
5557import org.koin.compose.koinInject
5658
5759
58- @OptIn(ExperimentalMaterial3WindowSizeClassApi ::class )
5960class ClimateTraceScreen : Screen {
6061 @Composable
6162 override fun Content () {
62- val windowSizeClass = calculateWindowSizeClass()
63- val viewModel = koinInject<ClimateTraceViewModel >()
64-
65- val countryList by viewModel.countryList.collectAsState()
66- val selectedCountry by viewModel.selectedCountry.collectAsState()
67- val countryEmissionInfo by viewModel.countryEmissionInfo.collectAsState()
68- val countryAssetEmissions by viewModel.countryAssetEmissions.collectAsState()
69-
70- val isLoadingCountries by viewModel.isLoadingCountries.collectAsState()
71- val isLoadingCountryDetails by viewModel.isLoadingCountryDetails.collectAsState()
63+ val countryListViewModel = koinInject<CountryListViewModel >()
64+ val countryListViewState by countryListViewModel.viewState.collectAsState()
7265
66+ Column (Modifier ) {
67+ when (val state = countryListViewState) {
68+ is CountryListUIState .Loading -> {
69+ Column (modifier = Modifier .fillMaxSize().fillMaxHeight()
70+ .wrapContentSize(Alignment .Center )
71+ ) {
72+ CircularProgressIndicator ()
73+ }
74+ }
75+ is CountryListUIState .Error -> {
76+ Text (" Error" )
77+ }
78+ is CountryListUIState .Success -> {
79+ CountryScreenSuccess (state.countryList)
80+ }
81+ }
82+ }
83+ }
84+ }
7385
74- val panelState = remember { PanelState () }
86+ @OptIn(ExperimentalMaterial3WindowSizeClassApi ::class )
87+ @Composable
88+ fun CountryScreenSuccess (countryList : List <Country >) {
89+ val windowSizeClass = calculateWindowSizeClass()
90+ val countryDetailsViewModel = koinInject<CountryDetailsViewModel >()
7591
76- val animatedSize = if (panelState.splitter.isResizing) {
77- if (panelState.isExpanded) panelState.expandedSize else panelState.collapsedSize
78- } else {
79- animateDpAsState(
80- if (panelState.isExpanded) panelState.expandedSize else panelState.collapsedSize,
81- SpringSpec (stiffness = Spring .StiffnessLow )
82- ).value
83- }
8492
93+ val selectedCountry by countryDetailsViewModel.selectedCountry.collectAsState()
94+ val countryDetailsViewState by countryDetailsViewModel.viewState.collectAsState()
8595
86- Row ( Modifier .fillMaxSize()) {
96+ val panelState = remember { PanelState () }
8797
88- if (windowSizeClass.widthSizeClass == WindowWidthSizeClass .Compact ) {
89- Column (Modifier .fillMaxWidth()) {
98+ val animatedSize = if (panelState.splitter.isResizing) {
99+ if (panelState.isExpanded) panelState.expandedSize else panelState.collapsedSize
100+ } else {
101+ animateDpAsState(
102+ if (panelState.isExpanded) panelState.expandedSize else panelState.collapsedSize,
103+ SpringSpec (stiffness = Spring .StiffnessLow )
104+ ).value
105+ }
90106
91- Box (
92- Modifier .height(250 .dp).fillMaxWidth().background(color = Color .LightGray )
93- ) {
94- CountryListView (
95- countryList = countryList,
96- selectedCountry = selectedCountry,
97- isLoading = isLoadingCountries
98- ) { country ->
99- viewModel.setCountry(country)
100- }
101- }
102107
103- Spacer (modifier = Modifier .width(1 .dp).fillMaxWidth())
104- CountryInfoDetailedView (
105- country = selectedCountry,
106- year = viewModel.selectedYear.value,
107- onYearSelected = { viewModel.setYear(it) },
108- countryEmissionInfo = countryEmissionInfo,
109- countryAssetEmissionsList = countryAssetEmissions,
110- isLoading = isLoadingCountryDetails
111- )
112- }
113- } else {
108+ Row (Modifier .fillMaxSize()) {
109+ if (windowSizeClass.widthSizeClass == WindowWidthSizeClass .Compact ) {
110+ Column (Modifier .fillMaxWidth()) {
114111
115- ResizablePanel (
116- Modifier .width(animatedSize).fillMaxHeight(),
117- title = " Countries" ,
118- state = panelState
112+ Box (
113+ Modifier .height(250 .dp).fillMaxWidth().background(color = Color .LightGray )
119114 ) {
120115 CountryListView (
121116 countryList = countryList,
122117 selectedCountry = selectedCountry,
123- isLoading = isLoadingCountries
124118 ) { country ->
125- viewModel .setCountry(country)
119+ countryDetailsViewModel .setCountry(country)
126120 }
127121 }
128122
129- VerticalDivider (thickness = 1 .dp, color = Color .DarkGray )
130- Box (Modifier .fillMaxHeight()) {
131- CountryInfoDetailedView (
132- country = viewModel.selectedCountry.value,
133- year = viewModel.selectedYear.value,
134- onYearSelected = { viewModel.setYear(it) },
135- countryEmissionInfo = countryEmissionInfo,
136- countryAssetEmissionsList = countryAssetEmissions,
137- isLoading = isLoadingCountryDetails
138- )
123+ Spacer (modifier = Modifier .width(1 .dp).fillMaxWidth())
124+ CountryInfoDetailedView (countryDetailsViewState) {
125+ countryDetailsViewModel.setYear(it)
126+ }
127+ }
128+ } else {
129+
130+ ResizablePanel (
131+ Modifier .width(animatedSize).fillMaxHeight(),
132+ title = " Countries" ,
133+ state = panelState
134+ ) {
135+ CountryListView (
136+ countryList = countryList,
137+ selectedCountry = selectedCountry,
138+ ) { country ->
139+ countryDetailsViewModel.setCountry(country)
140+ }
141+ }
142+
143+ VerticalDivider (thickness = 1 .dp, color = Color .DarkGray )
144+ Box (Modifier .fillMaxHeight()) {
145+ CountryInfoDetailedView (countryDetailsViewState) {
146+ countryDetailsViewModel.setYear(it)
139147 }
140148 }
141149 }
142150 }
151+
143152}
144153
154+
145155@Composable
146156fun CountryListView (
147157 countryList : List <Country >,
148158 selectedCountry : Country ? ,
149- isLoading : Boolean ,
150159 countrySelected : (country: Country ) -> Unit
151160) {
152161 val searchQuery = remember { mutableStateOf(" " ) }
153162
154- if (isLoading) {
155- Column (
156- modifier = Modifier
157- .fillMaxSize()
158- .fillMaxHeight()
159- .wrapContentSize(Alignment .Center )
160- ) {
161- CircularProgressIndicator ()
162- }
163- } else {
164- Column {
165- SearchableList (
166- isLoading = isLoading,
167- searchQuery = searchQuery,
168- onSearchQueryChange = { query -> searchQuery.value = query },
169- countryList = countryList,
170- selectedCountry = selectedCountry,
171- countrySelected = countrySelected
172- )
173- }
163+ Column {
164+ SearchableList (
165+ searchQuery = searchQuery,
166+ onSearchQueryChange = { query -> searchQuery.value = query },
167+ countryList = countryList,
168+ selectedCountry = selectedCountry,
169+ countrySelected = countrySelected
170+ )
174171 }
175172}
176173
177174@OptIn(ExperimentalMaterial3Api ::class )
178175@Composable
179176fun SearchableList (
180- isLoading : Boolean ,
181177 searchQuery : MutableState <String >,
182178 onSearchQueryChange : (String ) -> Unit ,
183179 countryList : List <Country >,
@@ -223,7 +219,7 @@ fun SearchableList(
223219 }
224220 },
225221 content = {
226- if (filteredCountryList.isEmpty() && isLoading. not () ) {
222+ if (filteredCountryList.isEmpty()) {
227223 EmptyState (message = " " )
228224 } else {
229225 LazyColumn {
0 commit comments