Use intermediate representation for AddRecipe draft

This commit is contained in:
Kirill Kamakin
2022-08-04 21:19:15 +02:00
parent 8784912cdb
commit 057651c60f
14 changed files with 154 additions and 119 deletions

View File

@@ -1,9 +1,12 @@
package gq.kirmanak.mealient.datastore
import android.content.Context
import android.content.SharedPreferences
import androidx.datastore.core.DataStore
import androidx.datastore.core.DataStoreFactory
import androidx.datastore.dataStoreFile
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKeys
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@@ -11,6 +14,7 @@ import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import gq.kirmanak.mealient.datastore.recipe.AddRecipeInput
import gq.kirmanak.mealient.datastore.recipe.AddRecipeInputSerializer
import javax.inject.Named
import javax.inject.Singleton
@Module
@@ -18,6 +22,8 @@ import javax.inject.Singleton
interface DataStoreModule {
companion object {
const val ENCRYPTED = "encrypted"
@Provides
@Singleton
fun provideAddRecipeInputStore(
@@ -25,5 +31,22 @@ interface DataStoreModule {
): DataStore<AddRecipeInput> = DataStoreFactory.create(AddRecipeInputSerializer) {
context.dataStoreFile("add_recipe_input")
}
@Provides
@Singleton
@Named(ENCRYPTED)
fun provideEncryptedSharedPreferences(
@ApplicationContext applicationContext: Context,
): SharedPreferences {
val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC
val mainKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec)
return EncryptedSharedPreferences.create(
ENCRYPTED,
mainKeyAlias,
applicationContext,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)
}
}
}

View File

@@ -0,0 +1,11 @@
package gq.kirmanak.mealient.datastore.recipe
data class AddRecipeDraft(
val recipeName: String,
val recipeDescription: String,
val recipeYield: String,
val recipeInstructions: List<String>,
val recipeIngredients: List<String>,
val isRecipePublic: Boolean,
val areCommentsDisabled: Boolean,
)

View File

@@ -0,0 +1,12 @@
package gq.kirmanak.mealient.datastore.recipe
import kotlinx.coroutines.flow.Flow
interface AddRecipeStorage {
val updates: Flow<AddRecipeDraft>
suspend fun save(addRecipeRequest: AddRecipeDraft)
suspend fun clear()
}

View File

@@ -0,0 +1,43 @@
package gq.kirmanak.mealient.datastore.recipe
import androidx.datastore.core.DataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class AddRecipeStorageImpl @Inject constructor(
private val dataStore: DataStore<AddRecipeInput>,
) : AddRecipeStorage {
override val updates: Flow<AddRecipeDraft>
get() = dataStore.data.map {
AddRecipeDraft(
recipeName = it.recipeName,
recipeDescription = it.recipeDescription,
recipeYield = it.recipeYield,
recipeInstructions = it.recipeInstructionsList,
recipeIngredients = it.recipeIngredientsList,
isRecipePublic = it.isRecipePublic,
areCommentsDisabled = it.areCommentsDisabled,
)
}
override suspend fun save(addRecipeRequest: AddRecipeDraft) {
val input = AddRecipeInput.newBuilder()
.setRecipeName(addRecipeRequest.recipeName)
.setRecipeDescription(addRecipeRequest.recipeDescription)
.setRecipeYield(addRecipeRequest.recipeYield)
.setIsRecipePublic(addRecipeRequest.isRecipePublic)
.setAreCommentsDisabled(addRecipeRequest.areCommentsDisabled)
.addAllRecipeIngredients(addRecipeRequest.recipeIngredients)
.addAllRecipeInstructions(addRecipeRequest.recipeInstructions)
.build()
dataStore.updateData { input }
}
override suspend fun clear() {
dataStore.updateData { AddRecipeInput.getDefaultInstance() }
}
}