Reorganize code

This commit is contained in:
Kirill Kamakin
2022-04-03 17:21:18 +05:00
parent 984415bfb2
commit 8fee0c3a3d
19 changed files with 49 additions and 41 deletions

View File

@@ -0,0 +1,18 @@
package gq.kirmanak.mealient.extensions
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
import retrofit2.Response
import timber.log.Timber
import java.io.InputStream
inline fun <T, reified R> Response<T>.decodeErrorBodyOrNull(json: Json): R? =
errorBody()?.byteStream()?.let { json.decodeFromStreamOrNull<R>(it) }
@OptIn(ExperimentalSerializationApi::class)
inline fun <reified T> Json.decodeFromStreamOrNull(stream: InputStream): T? =
runCatching { decodeFromStream<T>(stream) }
.onFailure { Timber.e(it, "decodeFromStreamOrNull: can't decode") }
.getOrNull()

View File

@@ -0,0 +1,44 @@
package gq.kirmanak.mealient.extensions
import gq.kirmanak.mealient.data.recipes.db.entity.RecipeEntity
import gq.kirmanak.mealient.data.recipes.db.entity.RecipeIngredientEntity
import gq.kirmanak.mealient.data.recipes.db.entity.RecipeInstructionEntity
import gq.kirmanak.mealient.data.recipes.db.entity.RecipeSummaryEntity
import gq.kirmanak.mealient.data.recipes.network.response.GetRecipeIngredientResponse
import gq.kirmanak.mealient.data.recipes.network.response.GetRecipeInstructionResponse
import gq.kirmanak.mealient.data.recipes.network.response.GetRecipeResponse
import gq.kirmanak.mealient.data.recipes.network.response.GetRecipeSummaryResponse
fun GetRecipeResponse.toRecipeEntity() = RecipeEntity(
remoteId = remoteId,
recipeYield = recipeYield
)
fun GetRecipeIngredientResponse.toRecipeIngredientEntity(remoteId: Long) =
RecipeIngredientEntity(
recipeId = remoteId,
title = title,
note = note,
unit = unit,
food = food,
disableAmount = disableAmount,
quantity = quantity
)
fun GetRecipeInstructionResponse.toRecipeInstructionEntity(remoteId: Long) =
RecipeInstructionEntity(
recipeId = remoteId,
title = title,
text = text
)
fun GetRecipeSummaryResponse.recipeEntity() = RecipeSummaryEntity(
remoteId = remoteId,
name = name,
slug = slug,
image = image,
description = description,
rating = rating,
dateAdded = dateAdded,
dateUpdated = dateUpdated,
)

View File

@@ -0,0 +1,22 @@
package gq.kirmanak.mealient.extensions
import androidx.room.TypeConverter
import kotlinx.datetime.*
object RoomTypeConverters {
@TypeConverter
fun localDateTimeToTimestamp(localDateTime: LocalDateTime) =
localDateTime.toInstant(TimeZone.UTC).toEpochMilliseconds()
@TypeConverter
fun timestampToLocalDateTime(timestamp: Long) =
Instant.fromEpochMilliseconds(timestamp).toLocalDateTime(TimeZone.UTC)
@TypeConverter
fun localDateToTimeStamp(date: LocalDate) =
localDateTimeToTimestamp(date.atTime(0, 0))
@TypeConverter
fun timestampToLocalDate(timestamp: Long) =
timestampToLocalDateTime(timestamp).date
}

View File

@@ -0,0 +1,36 @@
package gq.kirmanak.mealient.extensions
import android.content.SharedPreferences
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.channels.onClosed
import kotlinx.coroutines.channels.onFailure
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.withContext
import timber.log.Timber
suspend fun SharedPreferences.getStringOrNull(key: String) =
withContext(Dispatchers.IO) { getString(key, null) }
suspend fun SharedPreferences.getBooleanOrFalse(key: String) =
withContext(Dispatchers.IO) { getBoolean(key, false) }
@OptIn(ExperimentalCoroutinesApi::class)
fun SharedPreferences.changesFlow(): Flow<Pair<SharedPreferences, String?>> = callbackFlow {
val listener = SharedPreferences.OnSharedPreferenceChangeListener { prefs, key ->
Timber.v("watchChanges: listener called with key $key")
trySend(prefs to key)
.onFailure { Timber.e(it, "watchChanges: can't send preference change, key $key") }
.onClosed { Timber.e(it, "watchChanges: flow has been closed") }
}
Timber.v("watchChanges: registering listener")
registerOnSharedPreferenceChangeListener(listener)
send(this@changesFlow to null)
awaitClose {
Timber.v("watchChanges: flow has been closed")
unregisterOnSharedPreferenceChangeListener(listener)
}
}