Skip to content

Commit

Permalink
add recipe editing and start on settings
Browse files Browse the repository at this point in the history
  • Loading branch information
jan-tennert committed Apr 1, 2024
1 parent a17a130 commit 4e3c83a
Show file tree
Hide file tree
Showing 27 changed files with 567 additions and 183 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package io.github.jan.einkaufszettel
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import cafe.adriel.voyager.core.model.ScreenModel
import cafe.adriel.voyager.core.model.rememberNavigatorScreenModel
import cafe.adriel.voyager.core.model.rememberScreenModel
import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.navigator.Navigator
import io.github.jan.supabase.gotrue.Auth
import kotlinx.coroutines.flow.StateFlow
import org.koin.compose.getKoin
Expand All @@ -25,4 +27,13 @@ public inline fun <reified T : ScreenModel> Screen.getScreenModel(
): T {
val koin = getKoin()
return rememberScreenModel(tag = tag) { koin.get(null, parameters) }
}
}

@Composable
public inline fun <reified T : ScreenModel> Navigator.getNavigatorScreenModelT(
tag: String? = null,
noinline parameters: ParametersDefinition? = null
): T {
val koin = getKoin()
return rememberNavigatorScreenModel(tag = tag) { koin.get(null, parameters) }
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package io.github.jan.einkaufszettel.cards.data.local

import app.cash.sqldelight.async.coroutines.awaitAsList
import app.cash.sqldelight.async.coroutines.awaitAsOne
import app.cash.sqldelight.coroutines.asFlow
import app.cash.sqldelight.coroutines.mapToList
import einkaufszettel.GetAllCards
import einkaufszettel.GetCardById
import io.github.jan.einkaufszettel.cards.data.remote.CardDto
import io.github.jan.einkaufszettel.root.data.local.db.DatabaseProvider
import kotlinx.coroutines.Dispatchers
Expand All @@ -26,7 +24,7 @@ interface CardsDataSource {

fun getCardById(
id: Long
): Flow<GetCardById>
): Flow<GetAllCards?>

suspend fun retrieveAllCards(): List<GetAllCards>

Expand Down Expand Up @@ -69,8 +67,8 @@ internal class CardsDataSourceImpl(
return queries.getAllCards().asFlow().mapToList(Dispatchers.Default)
}

override fun getCardById(id: Long): Flow<GetCardById> {
return queries.getCardById(id).asFlow().map { it.awaitAsOne() }
override fun getCardById(id: Long): Flow<GetAllCards?> = getAllCards().map { cards ->
cards.find { it.id == id }
}

override suspend fun retrieveAllCards(): List<GetAllCards> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.github.jan.einkaufszettel.profile.data.local

import app.cash.sqldelight.async.coroutines.awaitAsList
import app.cash.sqldelight.async.coroutines.awaitAsOne
import app.cash.sqldelight.async.coroutines.awaitAsOneOrNull
import app.cash.sqldelight.coroutines.asFlow
import app.cash.sqldelight.coroutines.mapToList
Expand All @@ -16,6 +17,8 @@ interface ProfileDataSource {

fun getProfiles(): Flow<List<ProfileDto>>

fun getOwnProfile(): Flow<ProfileDto>

suspend fun retrieveAllProfiles(): List<ProfileDto>

suspend fun insertProfile(profile: ProfileDto) = insertProfiles(listOf(profile))
Expand Down Expand Up @@ -56,6 +59,10 @@ internal class ProfileDataSourceImpl(

override suspend fun retrieveProfile(uid: String): ProfileDto? = queries.getProfileById(uid).awaitAsOneOrNull()?.toProfile()

override fun getOwnProfile(): Flow<ProfileDto> {
return auth.currentUserOrNull()?.id!!.let { id -> queries.getProfileById(id).asFlow().map { it.awaitAsOne().toProfile() } }
}

override suspend fun retrieveOwnProfile(): ProfileDto? = auth.currentUserOrNull()?.id?.let { retrieveProfile(it) }

override suspend fun clear() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ import io.github.jan.einkaufszettel.recipes.data.remote.RecipeDto
import io.github.jan.einkaufszettel.root.data.local.db.DatabaseProvider
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map

interface RecipeDataSource {

fun getAllRecipes(): Flow<List<GetAllRecipes>>

fun getRecipeById(recipeId: Long): Flow<GetAllRecipes?>

suspend fun retrieveAllRecipes(): List<GetAllRecipes>

suspend fun insertRecipe(recipe: RecipeDto)
Expand Down Expand Up @@ -41,6 +44,10 @@ internal class RecipeDataSourceImpl(
return queries.getAllRecipes().asFlow().mapToList(Dispatchers.Default)
}

override fun getRecipeById(recipeId: Long): Flow<GetAllRecipes?> = getAllRecipes().map { recipes ->
recipes.find { it.id == recipeId }
}

override suspend fun retrieveAllRecipes(): List<GetAllRecipes> {
return queries.getAllRecipes().awaitAsList()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,11 @@ interface RecipeApi {

suspend fun editRecipe(
id: Long,
name: String,
name: String?,
imagePath: String?,
ingredients: List<String>,
steps: String,
private: Boolean,
)
ingredients: List<String>?,
steps: String?,
): RecipeDto

suspend fun retrieveRecipes(): List<RecipeDto>

Expand Down Expand Up @@ -106,23 +105,22 @@ internal class RecipeApiImpl(

override suspend fun editRecipe(
id: Long,
name: String,
name: String?,
imagePath: String?,
ingredients: List<String>,
steps: String,
private: Boolean
) {
table.update({
RecipeDto::name setTo name
RecipeDto::imagePath setTo imagePath
RecipeDto::ingredients setTo ingredients
RecipeDto::steps setTo steps
RecipeDto::private setTo private
ingredients: List<String>?,
steps: String?,
): RecipeDto {
return table.update({
name?.let { RecipeDto::name setTo it }
imagePath?.let { RecipeDto::imagePath setTo it }
ingredients?.let { RecipeDto::ingredients setTo it }
steps?.let { RecipeDto::steps setTo it }
}) {
select()
filter {
RecipeDto::id eq id
}
}
}.decodeSingle()
}

override suspend fun uploadImage(imagePath: String, image: ByteArray) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.jan.einkaufszettel.recipes.ui.create.components
package io.github.jan.einkaufszettel.recipes.ui.components

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
Expand All @@ -24,9 +24,8 @@ import cafe.adriel.voyager.navigator.Navigator
import io.github.jan.einkaufszettel.Res
import io.github.jan.einkaufszettel.app.ui.components.DeleteDialog
import io.github.jan.einkaufszettel.collectAsStateWithLifecycle
import io.github.jan.einkaufszettel.recipes.ui.components.RecipeCard
import io.github.jan.einkaufszettel.recipes.ui.components.RecipeCardDefaults
import io.github.jan.einkaufszettel.recipes.ui.detail.RecipeDetailScreen
import io.github.jan.einkaufszettel.recipes.ui.edit.RecipeEditScreen
import io.github.jan.einkaufszettel.recipes.ui.main.RecipeScreenModel

@OptIn(ExperimentalMaterial3Api::class)
Expand Down Expand Up @@ -68,7 +67,10 @@ fun RecipeList(
modifier = Modifier.width(RecipeCardDefaults.WIDTH).height(
RecipeCardDefaults.HEIGHT).padding(RecipeCardDefaults.PADDING),
onClick = {
navigator.push(RecipeDetailScreen(it.id))
navigator.push(RecipeDetailScreen(it.id)) //TODO: JS
},
onEdit = {
navigator.push(RecipeEditScreen(it.id))
},
onDelete = {
screenModel.onShowDeleteDialogChanged(it)
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package io.github.jan.einkaufszettel.recipes.ui.create

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowForward
import androidx.compose.material.icons.filled.Done
Expand All @@ -24,6 +25,8 @@ import io.github.jan.einkaufszettel.app.ui.AppState
import io.github.jan.einkaufszettel.app.ui.AppStateScreen
import io.github.jan.einkaufszettel.app.ui.components.ChildTopBar
import io.github.jan.einkaufszettel.recipes.ui.detail.RecipeDetailScreen
import io.github.jan.einkaufszettel.recipes.ui.steps.RecipeModifyS1Screen
import io.github.jan.einkaufszettel.recipes.ui.steps.RecipeModifyStepScreen
import io.github.jan.einkaufszettel.root.ui.dialog.LoadingDialog

object RecipeCreateScreen: AppStateScreen<RecipeCreateScreenModel> {
Expand All @@ -37,8 +40,8 @@ object RecipeCreateScreen: AppStateScreen<RecipeCreateScreenModel> {
@Composable
override fun Content(screenModel: RecipeCreateScreenModel, state: AppState) {
val pNavigator = LocalNavigator.currentOrThrow
Navigator(RecipeCreateS1Screen) { navigator ->
val currentStep = navigator.lastItem as RecipeCreateStepScreen
Navigator(RecipeModifyS1Screen(null)) { navigator ->
val currentStep = navigator.lastItem as RecipeModifyStepScreen
Scaffold(
modifier = Modifier.fillMaxSize(),
floatingActionButton = {
Expand All @@ -64,7 +67,7 @@ object RecipeCreateScreen: AppStateScreen<RecipeCreateScreenModel> {
ChildTopBar(Res.string.create_recipe, pNavigator)
}
) {
SlideTransition(navigator) {
SlideTransition(navigator, Modifier.padding(it)) {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,28 @@
package io.github.jan.einkaufszettel.recipes.ui.create

import androidx.compose.runtime.mutableStateListOf
import cafe.adriel.voyager.core.model.screenModelScope
import com.mohamedrejeb.richeditor.model.RichTextState
import io.github.jan.einkaufszettel.app.ui.AppState
import io.github.jan.einkaufszettel.app.ui.AppStateModel
import io.github.jan.einkaufszettel.recipes.data.local.RecipeDataSource
import io.github.jan.einkaufszettel.recipes.data.remote.RecipeApi
import io.github.jan.einkaufszettel.recipes.ui.steps.RecipeModifyScreenModel
import io.github.jan.einkaufszettel.root.data.local.image.LocalImageData
import io.github.jan.einkaufszettel.root.data.local.image.LocalImageReader
import io.github.jan.supabase.exceptions.RestException
import io.github.jan.supabase.gotrue.Auth
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import kotlinx.datetime.Clock

class RecipeCreateScreenModel(
private val recipeApi: RecipeApi,
private val recipeDataSource: RecipeDataSource,
private val localImageReader: LocalImageReader,
private val auth: Auth,
): AppStateModel() {
recipeApi: RecipeApi,
recipeDataSource: RecipeDataSource,
localImageReader: LocalImageReader,
auth: Auth,
): RecipeModifyScreenModel(recipeApi, recipeDataSource, localImageReader, auth) {

sealed interface State: AppState {
data class Success(val id: Long) : State
}

private val _imageData = MutableStateFlow<LocalImageData?>(null)
private val _name = MutableStateFlow("")
private val _showIngredientsDialog = MutableStateFlow(false)
val ingredients = mutableStateListOf<String>()
val name = _name.asStateFlow()
val imageData = _imageData.asStateFlow()
val instructionState = RichTextState()
val showIngredientsDialog = _showIngredientsDialog.asStateFlow()

fun createRecipe(
name: String,
imageData: LocalImageData?,
Expand Down Expand Up @@ -65,31 +52,4 @@ class RecipeCreateScreenModel(
}
}

fun importNativeFile(file: Any) {
screenModelScope.launch {
runCatching {
localImageReader.platformFileToLocalImage(file)
}.onSuccess {
_imageData.value = it
}.onFailure {
it.printStackTrace()
}
}
}

fun setName(name: String) {
_name.value = name
}

fun setShowIngredientsDialog(show: Boolean) {
_showIngredientsDialog.value = show
}

fun resetContent() {
_name.value = ""
ingredients.clear()
instructionState.clear()
_showIngredientsDialog.value = false
}

}

This file was deleted.

Loading

0 comments on commit 4e3c83a

Please sign in to comment.