diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b0adc69..cb7990e 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -105,7 +105,6 @@ dependencies { implementation(libs.androidx.paging.runtimeKtx) testImplementation(libs.androidx.paging.commonKtx) - implementation(libs.jetbrains.kotlinx.datetime) implementation(libs.bumptech.glide.glide) diff --git a/app/src/debug/java/gq/kirmanak/mealient/App.kt b/app/src/main/java/gq/kirmanak/mealient/App.kt similarity index 100% rename from app/src/debug/java/gq/kirmanak/mealient/App.kt rename to app/src/main/java/gq/kirmanak/mealient/App.kt diff --git a/app/src/main/java/gq/kirmanak/mealient/data/add/impl/AddRecipeDataSourceImpl.kt b/app/src/main/java/gq/kirmanak/mealient/data/add/impl/AddRecipeDataSourceImpl.kt index 7799b79..46f7f8c 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/add/impl/AddRecipeDataSourceImpl.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/add/impl/AddRecipeDataSourceImpl.kt @@ -17,8 +17,7 @@ class AddRecipeDataSourceImpl @Inject constructor( override suspend fun addRecipe(recipe: AddRecipeRequest): String { logger.v { "addRecipe() called with: recipe = $recipe" } val service = addRecipeServiceFactory.provideService() - val response = logAndMapErrors( - logger, + val response = logger.logAndMapErrors( block = { service.addRecipe(recipe) }, logProvider = { "addRecipe: can't add recipe" } ) diff --git a/app/src/main/java/gq/kirmanak/mealient/data/add/impl/AddRecipeRepoImpl.kt b/app/src/main/java/gq/kirmanak/mealient/data/add/impl/AddRecipeRepoImpl.kt index 23b7698..8a0a0a5 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/add/impl/AddRecipeRepoImpl.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/add/impl/AddRecipeRepoImpl.kt @@ -2,11 +2,7 @@ package gq.kirmanak.mealient.data.add.impl import gq.kirmanak.mealient.data.add.AddRecipeDataSource import gq.kirmanak.mealient.data.add.AddRecipeRepo -import gq.kirmanak.mealient.data.add.models.AddRecipeIngredient -import gq.kirmanak.mealient.data.add.models.AddRecipeInstruction import gq.kirmanak.mealient.data.add.models.AddRecipeRequest -import gq.kirmanak.mealient.data.add.models.AddRecipeSettings -import gq.kirmanak.mealient.datastore.recipe.AddRecipeDraft import gq.kirmanak.mealient.datastore.recipe.AddRecipeStorage import gq.kirmanak.mealient.logging.Logger import kotlinx.coroutines.flow.Flow @@ -23,32 +19,11 @@ class AddRecipeRepoImpl @Inject constructor( ) : AddRecipeRepo { override val addRecipeRequestFlow: Flow - get() = addRecipeStorage.updates.map { it -> - AddRecipeRequest( - name = it.recipeName, - description = it.recipeDescription, - recipeYield = it.recipeYield, - recipeIngredient = it.recipeIngredients.map { AddRecipeIngredient(note = it) }, - recipeInstructions = it.recipeInstructions.map { AddRecipeInstruction(text = it) }, - settings = AddRecipeSettings( - public = it.isRecipePublic, - disableComments = it.areCommentsDisabled, - ) - ) - } + get() = addRecipeStorage.updates.map { AddRecipeRequest(it) } override suspend fun preserve(recipe: AddRecipeRequest) { logger.v { "preserveRecipe() called with: recipe = $recipe" } - val input = AddRecipeDraft( - recipeName = recipe.name, - recipeDescription = recipe.description, - recipeYield = recipe.recipeYield, - recipeInstructions = recipe.recipeInstructions.map { it.text }, - recipeIngredients = recipe.recipeIngredient.map { it.note }, - isRecipePublic = recipe.settings.public, - areCommentsDisabled = recipe.settings.disableComments, - ) - addRecipeStorage.save(input) + addRecipeStorage.save(recipe.toDraft()) } override suspend fun clear() { diff --git a/app/src/main/java/gq/kirmanak/mealient/data/auth/impl/AuthDataSourceImpl.kt b/app/src/main/java/gq/kirmanak/mealient/data/auth/impl/AuthDataSourceImpl.kt index 3af42d0..30f4011 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/auth/impl/AuthDataSourceImpl.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/auth/impl/AuthDataSourceImpl.kt @@ -5,7 +5,7 @@ import gq.kirmanak.mealient.data.network.ErrorDetail import gq.kirmanak.mealient.data.network.NetworkError.NotMealie import gq.kirmanak.mealient.data.network.NetworkError.Unauthorized import gq.kirmanak.mealient.data.network.ServiceFactory -import gq.kirmanak.mealient.extensions.decodeErrorBodyOrNull +import gq.kirmanak.mealient.extensions.decodeErrorBody import gq.kirmanak.mealient.extensions.logAndMapErrors import gq.kirmanak.mealient.logging.Logger import kotlinx.serialization.json.Json @@ -34,8 +34,7 @@ class AuthDataSourceImpl @Inject constructor( authService: AuthService, username: String, password: String - ): Response = logAndMapErrors( - logger, + ): Response = logger.logAndMapErrors( block = { authService.getToken(username = username, password = password) }, logProvider = { "sendRequest: can't get token" }, ) @@ -46,7 +45,9 @@ class AuthDataSourceImpl @Inject constructor( response.body()?.accessToken ?: throw NotMealie(NullPointerException("Body is null")) } else { val cause = HttpException(response) - val errorDetail: ErrorDetail? = response.decodeErrorBodyOrNull(json, logger) + val errorDetail = json.runCatching { decodeErrorBody(response) } + .onFailure { logger.e(it) { "Can't decode error body" } } + .getOrNull() throw when (errorDetail?.detail) { "Unauthorized" -> Unauthorized(cause) else -> NotMealie(cause) diff --git a/app/src/main/java/gq/kirmanak/mealient/data/baseurl/impl/VersionDataSourceImpl.kt b/app/src/main/java/gq/kirmanak/mealient/data/baseurl/impl/VersionDataSourceImpl.kt index 6493395..62ce4cd 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/baseurl/impl/VersionDataSourceImpl.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/baseurl/impl/VersionDataSourceImpl.kt @@ -19,8 +19,7 @@ class VersionDataSourceImpl @Inject constructor( logger.v { "getVersionInfo() called with: baseUrl = $baseUrl" } val service = serviceFactory.provideService(baseUrl) - val response = logAndMapErrors( - logger, + val response = logger.logAndMapErrors( block = { service.getVersion() }, logProvider = { "getVersionInfo: can't request version" } ) diff --git a/app/src/main/java/gq/kirmanak/mealient/extensions/NetworkExtensions.kt b/app/src/main/java/gq/kirmanak/mealient/extensions/NetworkExtensions.kt index 6c636f8..1327d57 100644 --- a/app/src/main/java/gq/kirmanak/mealient/extensions/NetworkExtensions.kt +++ b/app/src/main/java/gq/kirmanak/mealient/extensions/NetworkExtensions.kt @@ -8,28 +8,23 @@ import kotlinx.serialization.json.Json import kotlinx.serialization.json.decodeFromStream import retrofit2.HttpException import retrofit2.Response -import java.io.InputStream - -inline fun Response.decodeErrorBodyOrNull(json: Json, logger: Logger): R? = - errorBody()?.byteStream()?.let { json.decodeFromStreamOrNull(it, logger) } @OptIn(ExperimentalSerializationApi::class) -inline fun Json.decodeFromStreamOrNull(stream: InputStream, logger: Logger): T? = - runCatching { decodeFromStream(stream) } - .onFailure { logger.e(it) { "decodeFromStreamOrNull: can't decode" } } - .getOrNull() +inline fun Json.decodeErrorBody(response: Response): R = + checkNotNull(response.errorBody()) { "Can't decode absent error body" } + .byteStream() + .let(::decodeFromStream) + fun Throwable.mapToNetworkError(): NetworkError = when (this) { is HttpException, is SerializationException -> NetworkError.NotMealie(this) else -> NetworkError.NoServerConnection(this) } -inline fun logAndMapErrors( - logger: Logger, +inline fun Logger.logAndMapErrors( block: () -> T, noinline logProvider: () -> String -): T = - runCatchingExceptCancel(block).getOrElse { - logger.e(it, messageSupplier = logProvider) - throw it.mapToNetworkError() - } \ No newline at end of file +): T = runCatchingExceptCancel(block).getOrElse { + e(it, messageSupplier = logProvider) + throw it.mapToNetworkError() +} \ No newline at end of file diff --git a/app/src/release/java/gq/kirmanak/mealient/App.kt b/app/src/release/java/gq/kirmanak/mealient/App.kt deleted file mode 100644 index d929ce5..0000000 --- a/app/src/release/java/gq/kirmanak/mealient/App.kt +++ /dev/null @@ -1,7 +0,0 @@ -package gq.kirmanak.mealient - -import android.app.Application -import dagger.hilt.android.HiltAndroidApp - -@HiltAndroidApp -class App : Application()