Skip to content

Commit

Permalink
finished app, with caching
Browse files Browse the repository at this point in the history
  • Loading branch information
hasan7 committed Oct 28, 2022
1 parent 328c460 commit ccca57b
Show file tree
Hide file tree
Showing 15 changed files with 397 additions and 19 deletions.
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,5 @@ dependencies {
// Room
implementation "androidx.room:room-runtime:2.4.3"
kapt "androidx.room:room-compiler:2.4.3"
implementation "androidx.room:room-ktx:2.4.3"
}
65 changes: 65 additions & 0 deletions app/src/main/java/com/hasan/weatherapp/data/database/Converters.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.hasan.weatherapp.data.database

import androidx.room.ProvidedTypeConverter
import androidx.room.TypeConverter
import com.hasan.weatherapp.data.util.JsonParser
import com.hasan.weatherapp.domain.weather.WeatherData
import com.hasan.weatherapp.domain.weather.WeatherType

import com.squareup.moshi.Types
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

@ProvidedTypeConverter
class Converters(
private val jsonParser: JsonParser
) {
// @TypeConverter
// fun fromWeatherDataJson(json: String): Map<Int, List<WeatherEntity>>? {
// return jsonParser.fromJson(
// json,
// Types.newParameterizedType(MutableMap::class.java,Int::class.java,
// Types.newParameterizedType(ArrayList::class.java, WeatherEntity::class.javaObjectType)))?: emptyMap()
// }
//
// // TODO: maybe just fuckin remove the map since the list works so we loop and insert all of the map interies and each will be diffrant using time
// @TypeConverter
// fun fromWeatherDataJson(map: Map<Int, List<WeatherEntity>>): String {
// return jsonParser.toJson(
// map,
// Types.newParameterizedType(MutableMap::class.java,Int::class.java,
// Types.newParameterizedType(ArrayList::class.java, WeatherEntity::class.javaObjectType))) ?: "[]"
// }


//
// @TypeConverter
// fun toMWeatherDataJson(weatherData: List<WeatherEntity>): String {
// return jsonParser.toJson(
// weatherData,
// Types.newParameterizedType(List::class.java, WeatherEntity::class.javaObjectType)
// ) ?: "[]"
// }

@TypeConverter
fun fromWeatherTypeNumber(num: Int): WeatherType {
return WeatherType.fromWMO(num)
}

@TypeConverter
fun toMWeatherDataNumber(weathertype: WeatherType): Int {
return weathertype.code
}

@TypeConverter
fun fromLocalDateTimeString(str: String): LocalDateTime {
return LocalDateTime.parse(str, DateTimeFormatter.ISO_DATE_TIME)
}

@TypeConverter
fun toLocalDateTimeString(localDateTime: LocalDateTime): String {
return localDateTime.toString()
}


}
29 changes: 29 additions & 0 deletions app/src/main/java/com/hasan/weatherapp/data/database/WeatherDao.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.hasan.weatherapp.data.database

import androidx.room.Dao
import androidx.room.Insert
import androidx.room.MapInfo
import androidx.room.OnConflictStrategy
import androidx.room.Query

import com.hasan.weatherapp.domain.weather.WeatherData
import kotlinx.coroutines.flow.Flow
import java.time.LocalDateTime

@Dao
interface WeatherDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertWeatherInfos(infos: WeatherData)

// @Query("DELETE FROM WeatherData WHERE time IN(:time)")
// suspend fun deletetWeatherInfos(time: LocalDateTime)

@Query("DELETE FROM WeatherData")
suspend fun deletetWeatherInfo()

// @Query("SELECT * FROM WeatherData WHERE time LIKE '%' || :time || '%'")
// suspend fun gettWeatherInfos(time: LocalDateTime): List<WeatherData>
@Query("SELECT * FROM WeatherData ")
fun gettWeatherInfos(): Flow<List<WeatherData>>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.hasan.weatherapp.data.database

import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import com.hasan.weatherapp.domain.weather.WeatherData

@Database(
entities = [WeatherData::class],
version = 1
)
@TypeConverters(Converters::class)
abstract class WeatherDatabase: RoomDatabase() {

abstract val dao: WeatherDao
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.hasan.weatherapp.data.database.entity
//
//
//import androidx.room.Entity
//import androidx.room.PrimaryKey
//import com.hasan.weatherapp.domain.weather.WeatherData
//import com.hasan.weatherapp.domain.weather.WeatherType
//import java.time.LocalDateTime
//
//@Entity
//data class WeatherEntity(
// val time: LocalDateTime,
// val temperatureCelsius: Double,
// val pressure: Double,
// val windSpeed: Double,
// val humidity: Double,
// val weatherType: WeatherType,
// @PrimaryKey val id: Int? = null
//) {
// fun toWordInfo(): WeatherData {
// return WeatherData(
// time = time,
// temperatureCelsius = temperatureCelsius,
// pressure = pressure,
// windSpeed = windSpeed,
// humidity = humidity,
// weatherType = weatherType
//
// )
// }
//}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class LocationTrackerImpl @Inject constructor(
// return@coroutineScope x
// }


return suspendCancellableCoroutine { continuation ->
locationClient.getCurrentLocation(Priority.PRIORITY_HIGH_ACCURACY,
object : CancellationToken() {
Expand All @@ -68,8 +68,8 @@ class LocationTrackerImpl @Inject constructor(
override fun isCancellationRequested(): Boolean {
return false
}

}).addOnSuccessListener { location -> continuation.resume(location) }
}
).addOnSuccessListener { location -> continuation.resume(location) }
.addOnFailureListener { continuation.resume(null) }
.addOnCanceledListener { continuation.cancel() }
// locationClient.lastLocation.addOnSuccessListener { location ->
Expand All @@ -82,7 +82,7 @@ class LocationTrackerImpl @Inject constructor(
// .addOnCanceledListener {
// continuation.cancel()
// }
}
}

}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.hasan.weatherapp.data.mapper

import com.hasan.weatherapp.data.database.WeatherDao
import com.hasan.weatherapp.data.remote.WeatherDataDto
import com.hasan.weatherapp.data.remote.WeatherDto
import com.hasan.weatherapp.domain.weather.WeatherData
Expand Down Expand Up @@ -42,6 +43,54 @@ fun WeatherDto.toWeatherInfo(): WeatherInfo {
}
return WeatherInfo(
weatherDataPerDay = weatherDataMap,
currentWeatherData = currentWeatherData
currentWeatherData = currentWeatherData,
)
}
}

//suspend fun WeatherDao.toWeatherInfo(): WeatherInfo {
//
//
//// return gettWeatherInfos().mapIndexed { index, weatherData ->
//// val temperature = gettWeatherInfos()[index].temperatureCelsius
//// val weatherCode = gettWeatherInfos()[index].weatherType
//// val windSpeed = gettWeatherInfos()[index].windSpeed
//// val pressure = gettWeatherInfos()[index].pressure
//// val humidity = gettWeatherInfos()[index].humidity
//// val time = gettWeatherInfos()[index].time
//// WeatherData(
//// time = LocalDateTime.parse(time, DateTimeFormatter.ISO_DATE_TIME),
//// temperatureCelsius = temperature,
//// pressure = pressure,
//// windSpeed = windSpeed,
//// humidity = humidity,
//// weatherType = WeatherType.fromWMO(weatherCode)
//// )
//// }.groupBy { }
//// return time.mapIndexed { index, time ->
//// val temperature = temperatures[index]
//// val weatherCode = weatherCodes[index]
//// val windSpeed = windSpeeds[index]
//// val pressure = pressures[index]
//// val humidity = humidities[index]
//// WeatherData(
//// time = LocalDateTime.parse(time, DateTimeFormatter.ISO_DATE_TIME),
//// temperatureCelsius = temperature,
//// pressure = pressure,
//// windSpeed = windSpeed,
//// humidity = humidity,
//// weatherType = WeatherType.fromWMO(weatherCode)
//// )
////
//// }.groupBy {
//// it.time.dayOfMonth
//// }
////
//
// val data = mapOf(Pair(LocalDateTime.now().dayOfMonth, gettWeatherInfos()))
//
// return WeatherInfo(
// currentWeatherDataListDB = data,
// currentWeatherData = null,
// weatherDataPerDay = null
// )
//}
Original file line number Diff line number Diff line change
@@ -1,25 +1,118 @@
package com.hasan.weatherapp.data.repository

import android.content.ContentValues.TAG
import android.util.Log
import com.hasan.weatherapp.data.database.WeatherDatabase
import com.hasan.weatherapp.data.mapper.toWeatherInfo
import com.hasan.weatherapp.data.remote.WeatherApi
import com.hasan.weatherapp.domain.repository.WeatherRepository
import com.hasan.weatherapp.domain.util.Resource
import com.hasan.weatherapp.domain.weather.WeatherData
import com.hasan.weatherapp.domain.weather.WeatherInfo
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.collectIndexed
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.time.LocalDate
import java.time.LocalDateTime
import javax.inject.Inject

class RepositoryImpl @Inject constructor(
val weatherApi: WeatherApi
val weatherApi: WeatherApi,
val weatherDatabase: WeatherDatabase
) : WeatherRepository {

val dao = weatherDatabase.dao
val now = LocalDateTime.now()
val dayOfMonth = LocalDate.now().dayOfMonth

private suspend fun WeatherDataFromDb(): WeatherInfo = withContext(Dispatchers.IO){

val weatherdataMap = dao.gettWeatherInfos().first().groupBy { it.time.dayOfMonth}

val currentWeatherData = weatherdataMap[dayOfMonth]?.find {
val hour = if(now.minute < 30) now.hour else now.hour + 1
it.time.hour == hour
}
return@withContext WeatherInfo(
weatherDataPerDay = weatherdataMap,
currentWeatherData= currentWeatherData
)

}

private suspend fun WeatherDataFromApi(lat: Double, long: Double): WeatherInfo = withContext(Dispatchers.IO){

return@withContext weatherApi.getWeatherData(lat = lat, long = long).toWeatherInfo()
}

override suspend fun getWeatherInfo(lat: Double, long: Double): Resource<WeatherInfo> {

return try {
Resource.Success(
data = weatherApi.getWeatherData(lat = lat, long = long).toWeatherInfo()
)
if (WeatherDataFromDb().weatherDataPerDay?.isEmpty() == true){
Log.d(TAG, "getWeatherInfo: hello")
val weatherDataApi = WeatherDataFromApi(lat = lat, long = long)
weatherDataApi.weatherDataPerDay?.forEach {
it.value.forEach {
//Log.d(TAG, "api: ${it}")
dao.insertWeatherInfos(it)
}
}
return Resource.Success(
data = weatherDataApi
)
} else{
return Resource.Success(
data = WeatherDataFromDb()
)
}
// if (dao.gettWeatherInfos().isNotEmpty()){
// val dataa = mapOf(Pair(LocalDateTime.now().dayOfMonth, dao.gettWeatherInfos()))
//
//// return Resource.Success(
//// data = WeatherInfo(
//// currentWeatherDataListDB = dataa,
//// currentWeatherData = null,
//// weatherDataPerDay = null
//// )
//// )
//// Log.d(TAG, "getWeatherInfo isNotEmpty")
// val dataDB = dao.gettWeatherInfos().size
// Log.d(TAG, "db: ${dataDB}")
// }

//val dataApi = weatherApi.getWeatherData(lat = lat, long = long).toWeatherInfo()
//Log.d(TAG, "fromListToMap: ${fromListToMap().get(27)?.get(23)}")
// fromListToMap().forEach {
// Log.d(TAG, "fromListToMap: ${it}")
// }





// dataApi.weatherDataPerDay?.forEach {
// it.value.forEach {
// //Log.d(TAG, "api: ${it}")
// dao.insertWeatherInfos(it)
// }
// }

// coroutineScope {
// launch(Dispatchers.IO) {
// val x = dao.gettWeatherInfos().first().groupBy { it.time.dayOfMonth}
// Log.d(TAG, "getWeatherInfo: ${x.size}")
// x.forEach { Log.d(TAG, "getWeatherInfo: $it") }
// }
// }



}catch (e: Exception) {
e.printStackTrace()
Resource.Error(e.message ?: "error occurred55555555555555555")
Resource.Error(e.message ?: "error occurred")

}
}
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/java/com/hasan/weatherapp/data/util/JsonParser.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.hasan.weatherapp.data.util

import java.lang.reflect.Type

interface JsonParser {

fun <T> fromJson(json: String, type: Type): T?

fun <T> toJson(obj: T, type: Type): String?
}
Loading

0 comments on commit ccca57b

Please sign in to comment.