Compare commits

...

2 Commits

4 changed files with 109 additions and 39 deletions

View File

@ -11,6 +11,7 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.OutlinedTextField
@ -20,6 +21,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.vectorResource
@ -41,6 +43,9 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
val navController = rememberNavController()
val openTagFilterDialog = remember { mutableStateOf(false) }
val selectedEntries = remember { mutableStateOf(listOf<RecipeWithTags>()) }
val isInSearch = isInSearch@{ entry: RecipeWithTags ->
val isSearchEmpty = search.value == null || search.value!!.isEmpty()
val hasTitle = entry.recipe.title.contains(search.value.orEmpty(), ignoreCase = true)
@ -52,7 +57,7 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
return@isInSearch false
}
val totalFilters = filters.value.stream().filter{ f -> f.checked }.count()
val totalFilters = filters.value.stream().filter { f -> f.checked }.count()
var checkedFilters = 0
for (filter in filters.value) {
@ -61,10 +66,9 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
.filter { tag -> tag.name.contains(filter.tag, ignoreCase = true) }
.count() > 0
if(hasTagFilters) {
if (hasTagFilters) {
checkedFilters += 1
}
else {
} else {
checkedFilters -= 1
}
}
@ -78,8 +82,6 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
true
}
val openTagFilterDialog = remember { mutableStateOf(false) }
NavHost(
navController = navController,
startDestination = "list"
@ -108,7 +110,27 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
contentDescription = "Toggle tags filtering menu"
)
}
// Load
// Load / Delete
if (selectedEntries.value.isNotEmpty()) {
IconButton(
modifier = Modifier.weight(0.15f),
onClick = {
// TODO I feel like this could be done in batch or something...but I truly don't care atm
for (entry in selectedEntries.value) {
view.removeRecipe(entry)
ctx.db.recipeDao().delete(entry.recipe)
ctx.db.recipeWithTagsDao().delete(entry.recipe.title)
}
},
) {
Icon(
imageVector = Icons.Default.Delete,
tint = Color(0xFFFF0000),
contentDescription = "Load recipes from filesystem"
)
}
}
else {
IconButton(
modifier = Modifier.weight(0.15f),
onClick = { ctx.sourceChooser.launch(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)) },
@ -119,13 +141,24 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
)
}
}
}
LazyColumn {
items(recipes.value) { entry ->
if (isInSearch(entry)) {
val previewUri = entry.recipe.previewImage(LocalContext.current)
RecipePreview(entry, previewUri, onClick = {
val isSelected = selectedEntries.value.contains(entry)
RecipePreview(entry, previewUri, isSelected, onClick = {
view.setActive(entry)
navController.navigate("info")
}, onSelected = { flag ->
selectedEntries.value =
selectedEntries.value.toMutableList().apply {
if (flag) {
add(entry)
} else {
remove(entry)
}
}.toList()
})
}
}

View File

@ -1,5 +1,6 @@
package xyz.pixelatedw.recipe.ui.components
import android.text.format.DateFormat
import android.view.WindowManager
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
@ -36,6 +37,8 @@ import xyz.pixelatedw.recipe.MainActivity
import xyz.pixelatedw.recipe.data.RecipeWithTags
import xyz.pixelatedw.recipe.data.RecipesView
import xyz.pixelatedw.recipe.utils.parseMarkdown
import java.util.Calendar
import java.util.Locale
@Composable
fun RecipeInfo(
@ -49,6 +52,11 @@ fun RecipeInfo(
val openDeletionDialog = remember { mutableStateOf(false) }
val picsCounts = remember { active.recipe.pics.size };
val timestamp = view.activeRecipe.collectAsState().value?.recipe?.lastModified ?: 0
val calendar = Calendar.getInstance(Locale.ENGLISH)
calendar.timeInMillis = timestamp
val lastModified = DateFormat.format("yyyy-MM-dd",calendar).toString()
Column(
modifier = Modifier
.verticalScroll(rememberScrollState())
@ -113,29 +121,20 @@ fun RecipeInfo(
}
)
}
Row(
modifier = Modifier
.fillMaxWidth()
.padding(end = 16.dp),
horizontalArrangement = Arrangement.End
) {
Box(
modifier = Modifier
.fillMaxHeight()
.padding(start = 16.dp)
) {
Button(
onClick = {
openDeletionDialog.value = true
},
colors = ButtonDefaults.buttonColors(containerColor = Color.Red)
) {
Text(
text = "Delete",
style = MaterialTheme.typography.bodyMedium
text = "Last Modified",
style = MaterialTheme.typography.bodySmall,
)
Text(
text = lastModified,
modifier = Modifier.padding(start = 2.dp, top = 24.dp),
style = MaterialTheme.typography.bodyMedium,
)
}
}
}
}

View File

@ -2,7 +2,9 @@ package xyz.pixelatedw.recipe.ui.components
import android.graphics.Bitmap
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@ -12,7 +14,10 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.vector.ImageVector
@ -28,10 +33,14 @@ import xyz.pixelatedw.recipe.data.Recipe
import xyz.pixelatedw.recipe.data.RecipeWithTags
@Composable
fun RecipePreview(entry: RecipeWithTags, previewUri: Bitmap?, onClick: () -> Unit) {
fun RecipePreview(entry: RecipeWithTags, previewUri: Bitmap?, isSelected: Boolean, onClick: () -> Unit, onSelected: (Boolean) -> Unit) {
Column(modifier = Modifier
.background(color = if(isSelected) Color(0x11FF0000) else Color(0x00FFFFFF) )
.padding(8.dp)
.clickable(onClick = onClick)) {
.combinedClickable(
onLongClick = { onSelected(!isSelected) },
onClick = onClick
)) {
Row(horizontalArrangement = Arrangement.Center, modifier = Modifier.fillMaxWidth().height(256.dp)) {
if (previewUri != null) {
Image(

29
example.md 100644
View File

@ -0,0 +1,29 @@
+++
title = "Example Recipe Name" # mandatory
tags = ["test", "recipe"] # optional
pics = ["pics/test.jpg", "pics/test2.jpg"] # optional, only reads jpgs
# Everything below here is just plain markdown,
# use whatever format or layout you feel fits your needs best
+++
- **Portions:**
- **Prep Time:**
- **Cook Time:**
## Ingredients
- Ingredient 1
- Ingredient 2
- Ingredient 3
## Steps
1. Step 1
2. Step 2
3. Step 3