Skip to content

Commit

Permalink
Setup Room Database
Browse files Browse the repository at this point in the history
  • Loading branch information
Lê Chí Dũng committed Sep 5, 2024
1 parent fb68f91 commit 2f1c292
Show file tree
Hide file tree
Showing 36 changed files with 532 additions and 198 deletions.
4 changes: 4 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'io.gitlab.arturbosch.detekt' version '1.22.0-RC2'
id 'kotlin-parcelize'
id 'kotlin-kapt'
}

def localProperties = new Properties()
Expand All @@ -16,6 +18,8 @@ if (localPropertiesFile.exists()) {
}
}



android {
namespace 'com.sun.weather'
compileSdk 34
Expand Down
1 change: 0 additions & 1 deletion app/src/main/java/com/sun/weather/AndroidApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import org.koin.android.ext.koin.androidFileProperties
import org.koin.core.context.startKoin

class AndroidApplication : Application() {

override fun onCreate() {
super.onCreate()

Expand Down
7 changes: 5 additions & 2 deletions app/src/main/java/com/sun/weather/base/BaseFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,16 @@ abstract class BaseFragment<VB : ViewBinding>(private val inflate: FragmentInfla
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
savedInstanceState: Bundle?,
): View? {
_binding = inflate.invoke(inflater, container, false)
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
override fun onViewCreated(
view: View,
savedInstanceState: Bundle?,
) {
super.onViewCreated(view, savedInstanceState)
initView()
initData()
Expand Down
40 changes: 40 additions & 0 deletions app/src/main/java/com/sun/weather/data/model/CurrentWeather.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.sun.weather.data.model

import com.google.gson.annotations.SerializedName
import com.sun.weather.data.model.entity.WeatherEntity
import com.sun.weather.utils.ext.combineWithCountry

data class CurrentWeather(
@SerializedName("main")
Expand Down Expand Up @@ -62,3 +64,41 @@ data class Sys(
@SerializedName("country")
var country: String,
)

fun CurrentWeather.toWeatherEntity(): WeatherEntity {
val country: String? = sys.country
val id = nameCity.combineWithCountry(country)
val latitude = coord.lat
val longitude = coord.lon
val timeZone = dt
val city = nameCity
val weatherCurrent: WeatherBasic? = this.toWeatherBasic()
val weatherHourlyList: List<WeatherBasic>? = null
val weatherDailyList: List<WeatherBasic>? = null

return WeatherEntity(
id = id,
latitude = latitude,
longitude = longitude,
timeZone = timeZone,
city = city,
country = country,
weatherCurrent = weatherCurrent,
weatherHourlyList = weatherHourlyList,
weatherDailyList = weatherDailyList,
)
}

fun CurrentWeather.toWeatherBasic(): WeatherBasic {
return WeatherBasic(
dateTime = dt,
currentTemperature = main.currentTemperature,
maxTemperature = main.tempMax,
minTemperature = main.tempMin,
iconWeather = weathers.firstOrNull()?.iconWeather,
weatherDescription = weathers.firstOrNull()?.description,
humidity = main.humidity,
percentCloud = clouds.percentCloud,
windSpeed = wind.windSpeed,
)
}
29 changes: 29 additions & 0 deletions app/src/main/java/com/sun/weather/data/model/HourlyForecast.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.sun.weather.data.model

import com.google.gson.annotations.SerializedName
import com.sun.weather.data.model.entity.WeatherEntity
import com.sun.weather.utils.ext.combineWithCountry

data class HourlyForecast(
@SerializedName("cnt") val cnt: Int,
Expand All @@ -24,3 +26,30 @@ data class HourlyForecastItem(
@SerializedName("dt_txt") val dtTxt: String,
val iconWeather: String = "",
)

fun HourlyForecast.toWeather(): WeatherEntity {
return WeatherEntity(
id = city.name.combineWithCountry(city.country),
latitude = city.coord.lat,
longitude = city.coord.lon,
city = city.name,
country = city.country,
weatherCurrent = null,
weatherHourlyList = forecastList.map { it.toWeatherBasic() },
weatherDailyList = null,
)
}

fun HourlyForecastItem.toWeatherBasic(): WeatherBasic {
return WeatherBasic(
dateTime = dt,
currentTemperature = main.currentTemperature,
maxTemperature = main.tempMax,
minTemperature = main.tempMin,
iconWeather = weather.firstOrNull()?.iconWeather,
weatherDescription = weather.firstOrNull()?.description,
humidity = main.humidity,
percentCloud = clouds.percentCloud,
windSpeed = wind.windSpeed,
)
}
17 changes: 17 additions & 0 deletions app/src/main/java/com/sun/weather/data/model/WeatherBasic.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.sun.weather.data.model

import android.os.Parcelable
import kotlinx.parcelize.Parcelize

@Parcelize
data class WeatherBasic(
var dateTime: Long? = 0,
var currentTemperature: Double? = 0.0,
var maxTemperature: Double? = 0.0,
var minTemperature: Double? = 0.0,
var iconWeather: String? = "",
var weatherDescription: String? = "",
var humidity: Int? = 0,
var percentCloud: Int? = 0,
var windSpeed: Double? = 0.0,
) : Parcelable
29 changes: 28 additions & 1 deletion app/src/main/java/com/sun/weather/data/model/WeeklyForecast.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.sun.weather.data.model

import com.google.gson.annotations.SerializedName
import com.sun.weather.data.model.entity.WeatherEntity
import com.sun.weather.utils.ext.combineWithCountry

data class WeeklyForecast(
@SerializedName("city") val city: City,
Expand All @@ -27,3 +28,29 @@ data class Temp(
@SerializedName("eve") val eve: Double,
@SerializedName("morn") val morn: Double,
)

fun WeeklyForecast.toWeatherEntity(): WeatherEntity {
return WeatherEntity(
id = city.name.combineWithCountry(city.country),
latitude = city.coord.lat,
longitude = city.coord.lon,
city = city.name,
country = city.country,
weatherDailyList = forecastList.map { it.toWeatherBasic() },
weatherHourlyList = null,
weatherCurrent = null,
)
}

fun WeeklyForecastItem.toWeatherBasic(): WeatherBasic {
return WeatherBasic(
dateTime = dt,
currentTemperature = temp.day,
maxTemperature = temp.max,
minTemperature = temp.min,
iconWeather = weather.firstOrNull()?.iconWeather,
humidity = humidity,
percentCloud = clouds,
windSpeed = speed,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.sun.weather.data.model.entity

import android.os.Parcelable
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.sun.weather.data.model.WeatherBasic
import com.sun.weather.data.model.entity.WeatherEntry.CURRENTLY_OBJECT
import com.sun.weather.data.model.entity.WeatherEntry.DAILY_OBJECT
import com.sun.weather.data.model.entity.WeatherEntry.HOURLY_OBJECT
import com.sun.weather.data.model.entity.WeatherEntry.TBL_WEATHER_NAME
import kotlinx.parcelize.Parcelize

@Entity(tableName = TBL_WEATHER_NAME)
@Parcelize
data class WeatherEntity(
@PrimaryKey
val id: String = "",
val latitude: Double? = 0.0,
val longitude: Double? = 0.0,
val timeZone: Long? = 0,
var city: String? = "",
var country: String? = "",
@ColumnInfo(name = CURRENTLY_OBJECT)
val weatherCurrent: WeatherBasic?,
@ColumnInfo(name = HOURLY_OBJECT)
var weatherHourlyList: List<WeatherBasic>?,
@ColumnInfo(name = DAILY_OBJECT)
var weatherDailyList: List<WeatherBasic>?,
) : Parcelable {
fun getLocation(): String {
return if (!city.isNullOrEmpty() && !country.isNullOrEmpty()) {
"$city, $country"
} else {
"Unknown"
}
}
}

object WeatherEntry {
// Local database entries
const val TBL_WEATHER_NAME = "weather_forecasts"
const val CURRENTLY_OBJECT = "currently"
const val HOURLY_OBJECT = "hourly"
const val DAILY_OBJECT = "daily"
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,50 @@
package com.sun.weather.data.repository.source
package com.sun.weather.data.repository

import com.sun.weather.data.model.CurrentWeather
import com.sun.weather.data.model.HourlyForecast
import com.sun.weather.data.model.WeeklyForecast
import com.sun.weather.data.model.FavouriteLocation
import com.sun.weather.data.model.Weather
import com.sun.weather.data.model.entity.WeatherEntity
import kotlinx.coroutines.flow.Flow

interface WeatherRepository {
fun getCurrentWeather(city: String, language: String): Flow<CurrentWeather>
fun getCurrentLocationWeather(lat: Double, lon: Double, language: String): Flow<CurrentWeather>
fun getHourlyForecast(city: String, language: String): Flow<HourlyForecast>
fun getWeeklyForecast(city: String, language: String): Flow<WeeklyForecast>
fun getSelectedLocation(key: String): String

fun isFavoriteLocationExists(
cityName: String,
countryName: String,
): Boolean

fun saveCurrentWeather(currentWeather: WeatherEntity)

fun saveWeeklyForecastLocal(weeklyForecast: WeatherEntity)

fun getLocalWeather(id: String): Weather?

fun saveHourlyForecastLocal(hourlyForecast: WeatherEntity)

fun insertFavoriteWeather(favouriteLocation: FavouriteLocation)

fun getAllFavorite(): List<FavouriteLocation>

fun removeFavoriteItem(id: Long)

fun getCurrentWeather(
city: String,
language: String,
): Flow<WeatherEntity>

fun getCurrentLocationWeather(
lat: Double,
lon: Double,
language: String,
): Flow<WeatherEntity>

fun getHourlyForecast(
city: String,
language: String,
): Flow<WeatherEntity>

fun getWeeklyForecast(
city: String,
language: String,
): Flow<WeatherEntity>
}
Original file line number Diff line number Diff line change
@@ -1,40 +1,50 @@
package com.sun.weather.data.repository

import com.sun.weather.data.model.CurrentWeather
import com.sun.weather.data.model.HourlyForecast
import com.sun.weather.data.model.WeeklyForecast
import com.sun.weather.data.model.entity.WeatherEntity
import com.sun.weather.data.model.toWeatherEntity
import com.sun.weather.data.repository.source.WeatherDataSource
import com.sun.weather.data.repository.source.WeatherRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import org.koin.core.component.KoinComponent

class WeatherRepositoryImpl(
private val localDataSource: WeatherDataSource.Local,
private val remoteDataSource: WeatherDataSource.Remote
private val remoteDataSource: WeatherDataSource.Remote,
) : KoinComponent, WeatherRepository {

override fun getCurrentWeather(city: String, language: String): Flow<CurrentWeather> {
override fun getCurrentWeather(
city: String,
language: String,
): Flow<WeatherEntity> {
return flow {
emit(remoteDataSource.getCurrentWeather(city, language))
emit(remoteDataSource.getCurrentWeather(city, language).toWeatherEntity())
}
}

override fun getCurrentLocationWeather(lat: Double, lon: Double, language: String): Flow<CurrentWeather> {
override fun getCurrentLocationWeather(
lat: Double,
lon: Double,
language: String,
): Flow<WeatherEntity> {
return flow {
emit(remoteDataSource.getCurrentLocationWeather(lat, lon, language))
emit(remoteDataSource.getCurrentLocationWeather(lat, lon, language).toWeatherEntity())
}
}

override fun getHourlyForecast(city: String, language: String): Flow<HourlyForecast> {
override fun getHourlyForecast(
city: String,
language: String,
): Flow<WeatherEntity> {
return flow {
emit(remoteDataSource.getHourlyForecast(city, language))
emit(remoteDataSource.getHourlyForecast(city, language).toWeatherEntity())
}
}

override fun getWeeklyForecast(city: String, language: String): Flow<WeeklyForecast> {
override fun getWeeklyForecast(
city: String,
language: String,
): Flow<WeatherEntity> {
return flow {
emit(remoteDataSource.getWeeklyForecast(city, language))
emit(remoteDataSource.getWeeklyForecast(city, language).toWeatherEntity())
}
}
}
Loading

0 comments on commit 2f1c292

Please sign in to comment.