Browse Source

Fix navigation issues

Carles Sentis 1 year ago
parent
commit
a4c77a26c9

+ 4 - 0
.idea/gradle.xml

@@ -12,6 +12,10 @@
           <set>
             <option value="$PROJECT_DIR$" />
             <option value="$PROJECT_DIR$/app" />
+            <option value="$PROJECT_DIR$/feature" />
+            <option value="$PROJECT_DIR$/feature/common" />
+            <option value="$PROJECT_DIR$/feature/geocoding" />
+            <option value="$PROJECT_DIR$/feature/weather" />
           </set>
         </option>
       </GradleProjectSettings>

+ 41 - 0
.idea/inspectionProfiles/Project_Default.xml

@@ -0,0 +1,41 @@
+<component name="InspectionProjectProfileManager">
+  <profile version="1.0">
+    <option name="myName" value="Project Default" />
+    <inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true">
+      <option name="composableFile" value="true" />
+      <option name="previewFile" value="true" />
+    </inspection_tool>
+    <inspection_tool class="PreviewApiLevelMustBeValid" enabled="true" level="ERROR" enabled_by_default="true">
+      <option name="composableFile" value="true" />
+      <option name="previewFile" value="true" />
+    </inspection_tool>
+    <inspection_tool class="PreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
+      <option name="composableFile" value="true" />
+      <option name="previewFile" value="true" />
+    </inspection_tool>
+    <inspection_tool class="PreviewFontScaleMustBeGreaterThanZero" enabled="true" level="ERROR" enabled_by_default="true">
+      <option name="composableFile" value="true" />
+      <option name="previewFile" value="true" />
+    </inspection_tool>
+    <inspection_tool class="PreviewMultipleParameterProviders" enabled="true" level="ERROR" enabled_by_default="true">
+      <option name="composableFile" value="true" />
+      <option name="previewFile" value="true" />
+    </inspection_tool>
+    <inspection_tool class="PreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
+      <option name="composableFile" value="true" />
+      <option name="previewFile" value="true" />
+    </inspection_tool>
+    <inspection_tool class="PreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
+      <option name="composableFile" value="true" />
+      <option name="previewFile" value="true" />
+    </inspection_tool>
+    <inspection_tool class="PreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
+      <option name="composableFile" value="true" />
+      <option name="previewFile" value="true" />
+    </inspection_tool>
+    <inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
+      <option name="composableFile" value="true" />
+      <option name="previewFile" value="true" />
+    </inspection_tool>
+  </profile>
+</component>

+ 0 - 1
app/src/main/AndroidManifest.xml

@@ -20,7 +20,6 @@
         <activity
             android:name=".app.ui.MainActivity"
             android:exported="true"
-            android:label="@string/app_name"
             android:theme="@style/Theme.Weather">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />

+ 25 - 14
app/src/main/java/com/example/weather/app/ui/MainActivity.kt

@@ -16,6 +16,8 @@ import com.trifork.feature.geocoding.presentation.components.GeocodingScreen
 import com.trifork.feature.weather.domain.model.WeatherLocation
 import com.trifork.feature.weather.presentation.WeatherViewModel
 import com.trifork.feature.weather.presentation.components.WeatherScreen
+import com.trifork.feature.weather.presentation.mvi.WeatherEvent
+import com.trifork.feature.weather.presentation.mvi.WeatherState
 import dagger.hilt.android.AndroidEntryPoint
 
 @AndroidEntryPoint
@@ -37,24 +39,33 @@ class MainActivity : ComponentActivity() {
                             navArgument("long") { type = NavType.FloatType }
                         )
                     ) { backStackEntry ->
-                        val name = backStackEntry.arguments?.getString("name")
-                        val lat = backStackEntry.arguments?.getFloat("lat")
-                        val long = backStackEntry.arguments?.getFloat("long")
 
-                        val geoLocation = if (name.isNullOrBlank()) {
-                            WeatherLocation()
-                        } else {
-                            WeatherLocation(
-                                name = name,
-                                lat = lat!!.toDouble(),
-                                long = long!!.toDouble()
-                            )
-                        }
+
+                        val geoLocation = backStackEntry.arguments?.let {
+                            val name = it.getString("name") ?: ""
+                            val lat = it.getFloat("lat").toDouble()
+                            val long = it.getFloat("long").toDouble()
+
+                            it.remove("name")
+                            it.remove("lat")
+                            it.remove("long")
+
+                            if (name.isNotBlank() && lat != .0 && long != .0) {
+                                WeatherLocation(
+                                    name = name,
+                                    lat = lat,
+                                    long = long
+                                )
+                            } else WeatherLocation()
+                        } ?: WeatherLocation()
+
                         val viewModel by viewModels<WeatherViewModel>()
+
+                        viewModel.state.handleEvent(WeatherEvent.LoadWeatherInfo(geoLocation))
+
                         WeatherScreen(
                             navController,
-                            viewModel,
-                            geoLocation
+                            viewModel
                         )
                     }
                     composable(Screen.Geocoding.route) {

+ 1 - 1
app/src/main/res/values/strings.xml

@@ -1,3 +1,3 @@
 <resources>
-    <string name="app_name">Weather</string>
+    <string name="app_name">Weekly Weather</string>
 </resources>

+ 7 - 8
feature/geocoding/src/main/java/com/trifork/feature/geocoding/presentation/GeocodingViewModel.kt

@@ -2,7 +2,6 @@ package com.trifork.feature.geocoding.presentation
 
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
-
 import com.trifork.feature.common.dispatcher.DispatcherProvider
 import com.trifork.feature.common.mvi.StateReducerFlow
 import com.trifork.feature.common.util.Resource
@@ -12,8 +11,8 @@ import com.trifork.feature.geocoding.presentation.mvi.GeoAction
 import com.trifork.feature.geocoding.presentation.mvi.GeoEvent
 import com.trifork.feature.geocoding.presentation.mvi.GeoState
 import dagger.hilt.android.lifecycle.HiltViewModel
-import kotlinx.coroutines.flow.MutableSharedFlow
-import kotlinx.coroutines.flow.asSharedFlow
+import kotlinx.coroutines.channels.Channel
+import kotlinx.coroutines.flow.receiveAsFlow
 import kotlinx.coroutines.launch
 import javax.inject.Inject
 
@@ -27,8 +26,8 @@ class GeocodingViewModel @Inject constructor(
         initialState = GeoState.initial,
         reduceState = ::reduceState,
     )
-    private val _action = MutableSharedFlow<GeoAction>()
-    val action = _action.asSharedFlow()
+    private val _action = Channel<GeoAction>()
+    val action = _action.receiveAsFlow()
 
     private fun reduceState(
         currentState: GeoState,
@@ -59,7 +58,7 @@ class GeocodingViewModel @Inject constructor(
 
                 is Resource.Error -> {
                     state.handleEvent(GeoEvent.Error("No results"))
-                    _action.emit(GeoAction.ShowToast("Issue loading cache!!!"))
+                    _action.send(GeoAction.ShowToast("Issue loading cache!!!"))
                 }
             }
         }
@@ -137,7 +136,7 @@ class GeocodingViewModel @Inject constructor(
                 }
 
                 is Resource.Error -> {
-                    _action.emit(GeoAction.ShowToast("Issue saving!!!"))
+                    _action.send(GeoAction.ShowToast("Issue saving!!!"))
                 }
             }
         }
@@ -153,7 +152,7 @@ class GeocodingViewModel @Inject constructor(
                 }
 
                 is Resource.Error -> {
-                    _action.emit(GeoAction.ShowToast("Issue deleting!!!"))
+                    _action.send(GeoAction.ShowToast("Issue deleting!!!"))
                 }
             }
         }

+ 1 - 1
feature/weather/src/main/java/com/trifork/feature/weather/data/mappers/WeatherMappers.kt

@@ -78,6 +78,6 @@ fun WeatherDto.toWeatherInfo(): WeatherInfo {
     return WeatherInfo(
         geoLocation = "",
         weatherDataPerDay = weatherDataMap,
-        currentWeatherData = currentWeatherData
+        currentWeatherData = currentWeatherData,
     )
 }

+ 2 - 0
feature/weather/src/main/java/com/trifork/feature/weather/domain/model/WeatherInfo.kt

@@ -5,6 +5,8 @@ import kotlinx.collections.immutable.ImmutableMap
 
 data class WeatherInfo(
     val geoLocation: String = "",
+    val latitude: Double = .0,
+    val longitude: Double = .0,
     val weatherDataPerDay: ImmutableMap<Int, ImmutableList<WeatherData>>,
     val currentWeatherData: WeatherData?,
 )

+ 36 - 1
feature/weather/src/main/java/com/trifork/feature/weather/presentation/WeatherViewModel.kt

@@ -34,6 +34,7 @@ class WeatherViewModel @Inject constructor(
         return when (event) {
             is WeatherEvent.LoadWeatherInfo -> loadWeatherInfo(currentState, event.geoLocation)
             is WeatherEvent.UpdateHourlyInfo -> updateHourlyInfo(currentState, event.weatherInfo)
+            is WeatherEvent.Refresh -> onRefresh(currentState)
             is WeatherEvent.Error -> handleError(currentState, event.message)
         }
     }
@@ -62,7 +63,9 @@ class WeatherViewModel @Inject constructor(
                         state.handleEvent(
                             WeatherEvent.UpdateHourlyInfo(
                                 result.data!!.copy(
-                                    geoLocation = intLocation.name
+                                    geoLocation = intLocation.name,
+                                    latitude = intLocation.lat,
+                                    longitude = intLocation.long
                                 )
                             )
                         )
@@ -94,6 +97,38 @@ class WeatherViewModel @Inject constructor(
         )
     }
 
+    private fun onRefresh(currentState: WeatherState): WeatherState {
+        viewModelScope.launch(dispatcherProvider.io) {
+            currentState.weatherInfo?.let { intLocation ->
+                when (val result =
+                    weatherRepository.getWeatherData(intLocation.latitude, intLocation.longitude)) {
+                    is Resource.Success -> {
+                        state.handleEvent(
+                            WeatherEvent.UpdateHourlyInfo(
+                                result.data!!.copy(
+                                    geoLocation = intLocation.geoLocation,
+                                    latitude = intLocation.latitude,
+                                    longitude = intLocation.longitude
+                                )
+                            )
+                        )
+                    }
+
+                    is Resource.Error -> {
+                        state.handleEvent(WeatherEvent.Error("Check Internet"))
+                    }
+                }
+            } ?: kotlin.run {
+                state.handleEvent(WeatherEvent.Error("Check GPS"))
+            }
+        }
+        return currentState.copy(
+            isLoading = false,
+            error = null,
+            weatherInfo = currentState.weatherInfo
+        )
+    }
+
     private fun handleError(currentState: WeatherState, message: String): WeatherState {
         return currentState.copy(
             isLoading = false,

+ 3 - 8
feature/weather/src/main/java/com/trifork/feature/weather/presentation/components/WeatherScreen.kt

@@ -47,8 +47,7 @@ import com.trifork.feature.weather.presentation.mvi.WeatherEvent
 @Composable
 fun WeatherScreen(
     navController: NavController,
-    viewModel: WeatherViewModel,
-    geoLocation: WeatherLocation
+    viewModel: WeatherViewModel
 ) {
     val state by viewModel.state.collectAsState()
 
@@ -56,17 +55,13 @@ fun WeatherScreen(
         ActivityResultContracts.RequestMultiplePermissions()
     ) { map ->
         if (map.values.filter { it }.size > 1) {
-            viewModel.state.handleEvent(WeatherEvent.LoadWeatherInfo(geoLocation))
+            viewModel.state.handleEvent(WeatherEvent.Refresh)
         }
     }
 
     val isLoading = state.isLoading
     val pullRefreshState = rememberPullRefreshState(isLoading, {
-        viewModel.state.handleEvent(
-            WeatherEvent.LoadWeatherInfo(
-                geoLocation
-            )
-        )
+        viewModel.state.handleEvent(WeatherEvent.Refresh)
     })
 
 

+ 4 - 0
feature/weather/src/main/java/com/trifork/feature/weather/presentation/mvi/WeatherEvent.kt

@@ -6,7 +6,11 @@ import com.trifork.feature.weather.domain.model.WeatherLocation
 sealed interface WeatherEvent {
     data class LoadWeatherInfo(val geoLocation: WeatherLocation) :
         WeatherEvent
+
     data class UpdateHourlyInfo(val weatherInfo: WeatherInfo) :
         WeatherEvent
+
+    data object Refresh : WeatherEvent
+
     data class Error(val message: String) : WeatherEvent
 }

+ 6 - 6
gradle/libs.versions.toml

@@ -1,22 +1,22 @@
 [versions]
 androidGradlePlugin = "8.1.2"
 ktx = "1.12.0"
-compose = "1.8.0"
+compose = "1.8.2"
 immutable = "0.3.6"
 location = "21.0.1"
 hilt = "2.48.1"
-navigationCompose = "2.7.4"
-lyfecyleCompose = "2.7.0-alpha02"
+navigationCompose = "2.7.6"
+lyfecyleCompose = "2.7.0-rc02"
 retrofit = "2.9.0"
 junit = "4.13.2"
 junittest = "1.1.5"
 espresso = "3.5.1"
 coroutines = "1.7.3"
-room = "2.5.2"
-material = "1.5.3"
+room = "2.6.1"
+material = "1.5.4"
 org-jetbrains-kotlin-android = "1.9.10"
 appcompat = "1.6.1"
-com-google-android-material-material = "1.10.0"
+com-google-android-material-material = "1.11.0"
 ksp = "1.9.0-1.0.12"