codeskraps vor 1 Jahr
Ursprung
Commit
bcbc9651d5

+ 2 - 2
app/build.gradle.kts

@@ -13,8 +13,8 @@ android {
         applicationId = "com.arklan.weather"
         minSdk = 26
         targetSdk = 34
-        versionCode = 2
-        versionName = "1.1"
+        versionCode = 3
+        versionName = "1.2"
 
         testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
         vectorDrawables {

BIN
app/release/app-release.aab


+ 2 - 2
feature/common/src/main/java/com/trifork/feature/common/data/local/GeocodingDao.kt

@@ -14,8 +14,8 @@ interface GeocodingDao {
     @Upsert
     fun insert(geoLocationEntity: GeoLocationEntity)
 
-    @Query("DELETE FROM GeoLocationEntity WHERE name = :name")
-    fun delete(name: String)
+    @Query("DELETE FROM GeoLocationEntity WHERE latitude = :latitude AND longitude = :longitude")
+    fun delete(latitude: Double, longitude: Double)
 
     @Query("SELECT * FROM GeoLocationEntity WHERE latitude=:latitude AND longitude=:longitude")
     fun getByLocation(latitude: Double, longitude: Double): List<GeoLocationEntity>

+ 1 - 1
feature/common/src/main/java/com/trifork/feature/common/data/repository/LocalGeocodingRepositoryImpl.kt

@@ -36,7 +36,7 @@ class LocalGeocodingRepositoryImpl @Inject constructor(
 
     override suspend fun deleteCacheGeoLocation(geoLocation: GeoLocation): Resource<Unit> {
         return try {
-            geocodingDB.geocodingDao().delete(geoLocation.name)
+            geocodingDB.geocodingDao().delete(geoLocation.latitude, geoLocation.longitude)
             Resource.Success(Unit)
         } catch (e: Exception) {
             e.printStackTrace()

+ 9 - 1
feature/common/src/main/java/com/trifork/feature/common/domain/model/GeoLocation.kt

@@ -7,4 +7,12 @@ data class GeoLocation(
     val country: String,
     val admin1: String?,
     val cached: Boolean = false
-)
+) {
+    fun displayName(): String {
+        return if (country.isBlank()) {
+            name
+        } else {
+            "$name, $country"
+        }
+    }
+}

+ 4 - 5
feature/geocoding/src/main/java/com/trifork/feature/geocoding/presentation/components/GeocodingScreen.kt

@@ -70,8 +70,8 @@ fun GeocodingScreen(
         onPauseOrDispose { }
     }
 
-    ObserveAsEvents(flow = action){onAction->
-        when(onAction){
+    ObserveAsEvents(flow = action) { onAction ->
+        when (onAction) {
             is GeoAction.ShowToast -> {
                 Toast.makeText(
                     context,
@@ -154,7 +154,6 @@ fun GeocodingScreen(
                         )
                     } else {
                         LazyColumn {
-
                             itemsIndexed(state.geoLocations) { index, geoLocation ->
                                 Row(
                                     modifier = Modifier
@@ -162,7 +161,7 @@ fun GeocodingScreen(
                                         .clickable {
                                             navController.navigate(
                                                 Screen.Weather.createRoute(
-                                                    "${geoLocation.name}, ${geoLocation.country}",
+                                                    geoLocation.displayName(),
                                                     geoLocation.latitude,
                                                     geoLocation.longitude
                                                 )
@@ -175,7 +174,7 @@ fun GeocodingScreen(
                                     horizontalArrangement = Arrangement.SpaceBetween
                                 ) {
                                     Text(
-                                        text = "${geoLocation.name}, ${geoLocation.country}",
+                                        text = geoLocation.displayName(),
                                         modifier = Modifier
                                             .align(CenterVertically)
                                             .padding(start = 16.dp, top = 15.dp, bottom = 15.dp)

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

@@ -7,6 +7,7 @@ import com.trifork.feature.weather.data.remote.WeatherDto
 import com.trifork.feature.weather.domain.model.SunData
 import com.trifork.feature.weather.domain.model.WeatherData
 import com.trifork.feature.weather.domain.model.WeatherInfo
+import com.trifork.feature.weather.domain.model.WeatherLocation
 import com.trifork.feature.weather.domain.model.WeatherType
 import kotlinx.collections.immutable.ImmutableList
 import kotlinx.collections.immutable.ImmutableMap
@@ -83,12 +84,20 @@ fun WeatherDto.toWeatherInfo(): WeatherInfo {
     )
 }
 
-fun WeatherInfo.toGeoLocation(): GeoLocation {
-    return GeoLocation(
+fun WeatherInfo.toWeatherLocation(): WeatherLocation {
+    return WeatherLocation(
         name = geoLocation,
-        latitude = latitude,
-        longitude = longitude,
+        lat = latitude,
+        long = longitude
+    )
+}
+
+fun WeatherLocation.toGeoLocation(): GeoLocation {
+    return GeoLocation(
+        name = name,
+        latitude = lat,
+        longitude = long,
         country = "",
-        admin1 = ""
+        admin1 = null
     )
 }

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

@@ -2,6 +2,6 @@ package com.trifork.feature.weather.domain.model
 
 data class WeatherLocation(
     val name: String = "Current Location",
-    val lat: Double = 0.0,
-    val long: Double = 0.0
+    val lat: Double = .0,
+    val long: Double = .0
 )

+ 33 - 14
feature/weather/src/main/java/com/trifork/feature/weather/presentation/WeatherViewModel.kt

@@ -8,6 +8,7 @@ import com.trifork.feature.common.domain.repository.LocalGeocodingRepository
 import com.trifork.feature.common.mvi.StateReducerViewModel
 import com.trifork.feature.common.util.Resource
 import com.trifork.feature.weather.data.mappers.toGeoLocation
+import com.trifork.feature.weather.data.mappers.toWeatherLocation
 import com.trifork.feature.weather.domain.location.LocationTracker
 import com.trifork.feature.weather.domain.model.WeatherInfo
 import com.trifork.feature.weather.domain.model.WeatherLocation
@@ -41,11 +42,11 @@ class WeatherViewModel @Inject constructor(
             is WeatherEvent.Refresh -> onRefresh(currentState)
             is WeatherEvent.Error -> handleError(currentState, event.message)
             is WeatherEvent.About -> currentState
-            is WeatherEvent.CheckCache -> onCheckCached(currentState, event.weatherInfo)
+            is WeatherEvent.CheckCache -> onCheckCached(currentState, event.weatherLocation)
             is WeatherEvent.IsCache -> onIsCached(currentState, event.isCached)
             is WeatherEvent.Resume -> onResume(currentState)
-            is WeatherEvent.Save -> onSave(currentState, event.weatherInfo)
-            is WeatherEvent.Delete -> onDelete(currentState, event.weatherInfo)
+            is WeatherEvent.Save -> onSave(currentState, event.weatherLocation)
+            is WeatherEvent.Delete -> onDelete(currentState, event.weatherLocation)
         }
     }
 
@@ -77,7 +78,7 @@ class WeatherViewModel @Inject constructor(
                         )
 
                         state.handleEvent(WeatherEvent.UpdateHourlyInfo(weatherInfo))
-                        state.handleEvent(WeatherEvent.CheckCache(weatherInfo))
+                        state.handleEvent(WeatherEvent.CheckCache(weatherInfo.toWeatherLocation()))
                     }
 
                     is Resource.Error -> {
@@ -119,7 +120,7 @@ class WeatherViewModel @Inject constructor(
                         )
 
                         state.handleEvent(WeatherEvent.UpdateHourlyInfo(weatherInfo))
-                        state.handleEvent(WeatherEvent.CheckCache(weatherInfo))
+                        state.handleEvent(WeatherEvent.CheckCache(weatherInfo.toWeatherLocation()))
                     }
 
                     is Resource.Error -> {
@@ -135,10 +136,13 @@ class WeatherViewModel @Inject constructor(
         )
     }
 
-    private fun onCheckCached(currentState: WeatherState, weatherInfo: WeatherInfo): WeatherState {
+    private fun onCheckCached(
+        currentState: WeatherState,
+        weatherLocation: WeatherLocation
+    ): WeatherState {
         viewModelScope.launch(dispatcherProvider.io) {
             val result =
-                localGeocodingRepository.isCached(weatherInfo.latitude, weatherInfo.longitude)
+                localGeocodingRepository.isCached(weatherLocation.lat, weatherLocation.long)
             when (result) {
                 is Resource.Error -> state.handleEvent(WeatherEvent.IsCache(false))
                 is Resource.Success -> state.handleEvent(WeatherEvent.IsCache(result.data))
@@ -170,14 +174,26 @@ class WeatherViewModel @Inject constructor(
         return currentState
     }
 
-    private fun onSave(currentState: WeatherState, weatherInfo: WeatherInfo): WeatherState {
+    private fun onSave(currentState: WeatherState, weatherLocation: WeatherLocation): WeatherState {
         viewModelScope.launch(dispatcherProvider.io) {
-            if (weatherInfo.geoLocation.isBlank()) {
+            if (weatherLocation.name.isBlank()) {
                 actionChannel.send(WeatherAction.Toast("Location can't be blank !!!"))
             } else {
+                var name = weatherLocation.name.trim()
+
+                if (name.endsWith(",")) {
+                    name = name.substring(0, name.lastIndexOf(","))
+                }
+
                 when (val result =
-                    localGeocodingRepository.saveCacheGeoLocation(weatherInfo.toGeoLocation())) {
-                    is Resource.Success -> state.handleEvent(WeatherEvent.CheckCache(weatherInfo))
+                    localGeocodingRepository.saveCacheGeoLocation(
+                        weatherLocation.copy(name = name).toGeoLocation()
+                    )) {
+                    is Resource.Success -> {
+                        state.handleEvent(WeatherEvent.LoadWeatherInfo(weatherLocation))
+                        state.handleEvent(WeatherEvent.CheckCache(weatherLocation))
+                    }
+
                     is Resource.Error -> actionChannel.send(WeatherAction.Toast(result.message))
                 }
             }
@@ -185,11 +201,14 @@ class WeatherViewModel @Inject constructor(
         return currentState
     }
 
-    private fun onDelete(currentState: WeatherState, weatherInfo: WeatherInfo): WeatherState {
+    private fun onDelete(
+        currentState: WeatherState,
+        weatherLocation: WeatherLocation
+    ): WeatherState {
         viewModelScope.launch(dispatcherProvider.io) {
             when (val result =
-                localGeocodingRepository.deleteCacheGeoLocation(weatherInfo.toGeoLocation())) {
-                is Resource.Success -> state.handleEvent(WeatherEvent.CheckCache(weatherInfo))
+                localGeocodingRepository.deleteCacheGeoLocation(weatherLocation.toGeoLocation())) {
+                is Resource.Success -> state.handleEvent(WeatherEvent.CheckCache(weatherLocation))
                 is Resource.Error -> actionChannel.send(WeatherAction.Toast(result.message))
             }
         }

+ 5 - 3
feature/weather/src/main/java/com/trifork/feature/weather/presentation/components/SaveLocationDialog.kt

@@ -18,6 +18,7 @@ import androidx.compose.runtime.saveable.rememberSaveable
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
+import com.trifork.feature.weather.data.mappers.toWeatherLocation
 import com.trifork.feature.weather.domain.model.WeatherInfo
 import com.trifork.feature.weather.presentation.mvi.WeatherEvent
 
@@ -46,7 +47,7 @@ fun SaveLocationDialog(
                         Spacer(modifier = Modifier.height(10.dp))
                         OutlinedTextField(
                             value = nameLocation,
-                            onValueChange = { nameLocation = it.trim() })
+                            onValueChange = { nameLocation = it })
                     }
                 },
                 confirmButton = {
@@ -55,7 +56,7 @@ fun SaveLocationDialog(
                             containerColor = MaterialTheme.colorScheme.primary
                         ),
                         onClick = {
-                            handleEvent(WeatherEvent.Save(weatherInfo.copy(geoLocation = nameLocation)))
+                            handleEvent(WeatherEvent.Save(weatherInfo.copy(geoLocation = nameLocation).toWeatherLocation()))
                             onDismissRequest()
                         }
                     ) {
@@ -75,7 +76,8 @@ fun SaveLocationDialog(
                 }
             )
         } else {
-            handleEvent(WeatherEvent.Save(weatherInfo))
+            handleEvent(WeatherEvent.Save(weatherInfo.toWeatherLocation()))
+            onDismissRequest()
         }
     }
 }

+ 2 - 6
feature/weather/src/main/java/com/trifork/feature/weather/presentation/components/WeatherScreen.kt

@@ -5,7 +5,6 @@ import android.widget.Toast
 import androidx.activity.compose.rememberLauncherForActivityResult
 import androidx.activity.result.contract.ActivityResultContracts
 import androidx.compose.foundation.background
-import androidx.compose.foundation.clickable
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Spacer
@@ -19,14 +18,11 @@ import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.filled.Favorite
 import androidx.compose.material.icons.filled.FavoriteBorder
 import androidx.compose.material.icons.filled.LocationOn
-import androidx.compose.material.icons.filled.MoreVert
 import androidx.compose.material.icons.filled.Search
 import androidx.compose.material.pullrefresh.PullRefreshIndicator
 import androidx.compose.material.pullrefresh.pullRefresh
 import androidx.compose.material.pullrefresh.rememberPullRefreshState
 import androidx.compose.material3.CircularProgressIndicator
-import androidx.compose.material3.DropdownMenu
-import androidx.compose.material3.DropdownMenuItem
 import androidx.compose.material3.ExperimentalMaterial3Api
 import androidx.compose.material3.FloatingActionButton
 import androidx.compose.material3.Icon
@@ -47,11 +43,11 @@ import androidx.compose.ui.Modifier
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.unit.dp
-import androidx.lifecycle.compose.LifecycleEventEffect
 import androidx.lifecycle.compose.LifecycleResumeEffect
 import androidx.navigation.NavController
 import com.trifork.feature.common.components.ObserveAsEvents
 import com.trifork.feature.common.navigation.Screen
+import com.trifork.feature.weather.data.mappers.toWeatherLocation
 import com.trifork.feature.weather.domain.model.WeatherLocation
 import com.trifork.feature.weather.presentation.mvi.WeatherAction
 import com.trifork.feature.weather.presentation.mvi.WeatherEvent
@@ -131,7 +127,7 @@ fun WeatherScreen(
                 actions = {
                     IconButton(onClick = {
                         if (state.cached && state.weatherInfo != null) {
-                            handleEvent(WeatherEvent.Delete(state.weatherInfo))
+                            handleEvent(WeatherEvent.Delete(state.weatherInfo.toWeatherLocation()))
                         } else {
                             showDialog = true
                         }

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

@@ -12,9 +12,9 @@ sealed interface WeatherEvent {
 
     data class Error(val message: String) : WeatherEvent
     data object About : WeatherEvent
-    data class CheckCache(val weatherInfo: WeatherInfo) : WeatherEvent
+    data class CheckCache(val weatherLocation: WeatherLocation) : WeatherEvent
     data class IsCache(val isCached: Boolean) : WeatherEvent
     data object Resume : WeatherEvent
-    data class Save(val weatherInfo: WeatherInfo) : WeatherEvent
-    data class Delete(val weatherInfo: WeatherInfo) : WeatherEvent
+    data class Save(val weatherLocation: WeatherLocation) : WeatherEvent
+    data class Delete(val weatherLocation: WeatherLocation) : WeatherEvent
 }