Compare commits
No commits in common. "d60cbe4678c809893cd1fe549a88b58daa015910" and "9131a028a3f5e684e7ac02cec0ca52d12e819a5f" have entirely different histories.
d60cbe4678
...
9131a028a3
|
|
@ -3,8 +3,8 @@ package xyz.pixelatedw.recipe.data
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.widget.ImageView
|
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
|
import androidx.documentfile.provider.DocumentFile
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Delete
|
import androidx.room.Delete
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
|
|
@ -17,9 +17,6 @@ import com.google.gson.Gson
|
||||||
import com.google.gson.reflect.TypeToken
|
import com.google.gson.reflect.TypeToken
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
|
||||||
private val imagesCache: HashMap<String, Bitmap> = hashMapOf()
|
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
data class Recipe(
|
data class Recipe(
|
||||||
@PrimaryKey
|
@PrimaryKey
|
||||||
|
|
@ -36,17 +33,10 @@ data class Recipe(
|
||||||
fun showImage(ctx: Context, idx: Int): Bitmap? {
|
fun showImage(ctx: Context, idx: Int): Bitmap? {
|
||||||
val img = this.pics.getOrNull(idx)
|
val img = this.pics.getOrNull(idx)
|
||||||
if (img != null) {
|
if (img != null) {
|
||||||
val cachedImage = imagesCache[img]
|
|
||||||
if (cachedImage != null) {
|
|
||||||
return cachedImage
|
|
||||||
}
|
|
||||||
|
|
||||||
val file = File(ctx.filesDir, img)
|
val file = File(ctx.filesDir, img)
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
ctx.contentResolver.openInputStream(file.toUri()).use {
|
ctx.contentResolver.openInputStream(file.toUri()).use {
|
||||||
val bitmapData = BitmapFactory.decodeStream(it)
|
return BitmapFactory.decodeStream(it)
|
||||||
imagesCache[img] = bitmapData
|
|
||||||
return bitmapData
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,14 +44,20 @@ class RecipesView : ViewModel() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val filters = filtersMap.map { TagFilter(it.key, checked = activeFilterNames.contains(it.key), count = it.value) }
|
if (activeFilterNames.isNotEmpty()) {
|
||||||
_tagFilters.update { filters.distinct().sortedBy { it.tag }.toList() }
|
_tagFilters.value = _tagFilters.value.map {
|
||||||
|
it.count = filtersMap[it.tag] ?: 0
|
||||||
|
it
|
||||||
|
}.toList()
|
||||||
|
} else {
|
||||||
|
val filters = filtersMap.map { TagFilter(it.key, count = it.value) }.toList()
|
||||||
|
_tagFilters.update { filters.distinct().sortedBy { it.tag } }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setTagFilterState(tag: String, state: Boolean) {
|
fun setTagFilterState(tag: String, state: Boolean) {
|
||||||
_tagFilters.value = _tagFilters.value.map { if (tag == it.tag) it.checked = state; it }
|
_tagFilters.value = _tagFilters.value.toMutableList()
|
||||||
|
.apply { replaceAll { it -> if (tag == it.tag) it.checked = state; it } }.toList()
|
||||||
this.reloadTagFilterState()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setKeepScreenOn(flag: Boolean) {
|
fun setKeepScreenOn(flag: Boolean) {
|
||||||
|
|
@ -61,7 +67,19 @@ class RecipesView : ViewModel() {
|
||||||
fun setRecipes(recipes: List<RecipeWithTags>) {
|
fun setRecipes(recipes: List<RecipeWithTags>) {
|
||||||
_recipes.update { recipes.sortedBy { it.recipe.title } }
|
_recipes.update { recipes.sortedBy { it.recipe.title } }
|
||||||
|
|
||||||
this.reloadTagFilterState()
|
val filtersMap = mutableMapOf<String, Int>()
|
||||||
|
|
||||||
|
_recipes.value.stream()
|
||||||
|
.filter { it.tags.isNotEmpty() }
|
||||||
|
.forEach {
|
||||||
|
it.tags.forEach { tag ->
|
||||||
|
val count = filtersMap[tag.name] ?: 0
|
||||||
|
filtersMap[tag.name] = count + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val filters = filtersMap.map { it -> TagFilter(it.key, count = it.value) }.toList()
|
||||||
|
_tagFilters.update { filters.distinct().sortedBy { it.tag } }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeRecipe(recipe: RecipeWithTags) {
|
fun removeRecipe(recipe: RecipeWithTags) {
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,10 @@ import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.grid.GridCells
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Delete
|
import androidx.compose.material.icons.filled.Delete
|
||||||
import androidx.compose.material.icons.filled.Settings
|
import androidx.compose.material.icons.filled.Settings
|
||||||
|
|
@ -44,12 +42,12 @@ import java.io.File
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
|
fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
|
||||||
val recipes by view.recipes.collectAsState()
|
val recipes = view.recipes.collectAsState()
|
||||||
val active by view.activeRecipe.collectAsState()
|
val active = view.activeRecipe.collectAsState()
|
||||||
val search by view.search.collectAsState()
|
val search = view.search.collectAsState()
|
||||||
val filters by view.tagFilters.collectAsState()
|
val filters = view.tagFilters.collectAsState()
|
||||||
|
|
||||||
var activeRecipes by remember { mutableStateOf(recipes) }
|
var activeRecipes = remember { recipes.value }
|
||||||
var activeTags = 0
|
var activeTags = 0
|
||||||
|
|
||||||
val navController = rememberNavController()
|
val navController = rememberNavController()
|
||||||
|
|
@ -58,8 +56,6 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
|
||||||
var openTagFilterDialog by remember { mutableStateOf(false) }
|
var openTagFilterDialog by remember { mutableStateOf(false) }
|
||||||
var selectedEntries by remember { mutableStateOf(listOf<RecipeWithTags>()) }
|
var selectedEntries by remember { mutableStateOf(listOf<RecipeWithTags>()) }
|
||||||
|
|
||||||
val gridState = rememberLazyGridState()
|
|
||||||
|
|
||||||
NavHost(
|
NavHost(
|
||||||
navController = navController,
|
navController = navController,
|
||||||
startDestination = "list"
|
startDestination = "list"
|
||||||
|
|
@ -77,11 +73,11 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(0.7f)
|
.weight(0.7f)
|
||||||
.padding(end = 4.dp),
|
.padding(end = 4.dp),
|
||||||
value = search.orEmpty(),
|
value = search.value.orEmpty(),
|
||||||
onValueChange = { search ->
|
onValueChange = { search ->
|
||||||
view.setSearch(search)
|
view.setSearch(search)
|
||||||
activeRecipes =
|
activeRecipes =
|
||||||
recipes.filter { filterRecipe(it, search, filters) }
|
recipes.value.filter { filterRecipe(it, search, filters.value) }
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
// Tags / Delete
|
// Tags / Delete
|
||||||
|
|
@ -133,34 +129,23 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LazyVerticalGrid(
|
LazyColumn {
|
||||||
columns = GridCells.Fixed(3),
|
items(activeRecipes) { entry ->
|
||||||
modifier = Modifier.fillMaxSize(),
|
val isSelected = selectedEntries.contains(entry)
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
RecipePreview(entry, isSelected, onClick = {
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
view.setActive(entry)
|
||||||
state = gridState,
|
navController.navigate("info")
|
||||||
) {
|
}, onSelected = { flag ->
|
||||||
items(
|
selectedEntries =
|
||||||
count = activeRecipes.size,
|
selectedEntries.toMutableList().apply {
|
||||||
key = { activeRecipes[it].recipe.title },
|
if (flag) {
|
||||||
itemContent = { entryId ->
|
add(entry)
|
||||||
val entry = activeRecipes[entryId]
|
} else {
|
||||||
val isSelected = selectedEntries.contains(entry)
|
remove(entry)
|
||||||
RecipePreview(entry, isSelected, onClick = {
|
}
|
||||||
view.setActive(entry)
|
}.toList()
|
||||||
navController.navigate("info")
|
})
|
||||||
}, onSelected = { flag ->
|
}
|
||||||
selectedEntries =
|
|
||||||
selectedEntries.toMutableList().apply {
|
|
||||||
if (flag) {
|
|
||||||
add(entry)
|
|
||||||
} else {
|
|
||||||
remove(entry)
|
|
||||||
}
|
|
||||||
}.toList()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -193,12 +178,12 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
|
||||||
onAccept = {
|
onAccept = {
|
||||||
openTagFilterDialog = false
|
openTagFilterDialog = false
|
||||||
view.reloadTagFilterState()
|
view.reloadTagFilterState()
|
||||||
activeTags = filters.count { f -> f.checked }
|
activeTags = filters.value.count { f -> f.checked }
|
||||||
activeRecipes = recipes.filter {
|
activeRecipes = recipes.value.filter {
|
||||||
filterRecipe(
|
filterRecipe(
|
||||||
it,
|
it,
|
||||||
search,
|
search.value,
|
||||||
filters
|
filters.value
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -208,7 +193,7 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
composable("info") {
|
composable("info") {
|
||||||
RecipeInfo(ctx, view, navController, padding, active!!)
|
RecipeInfo(ctx, view, navController, padding, active.value!!)
|
||||||
}
|
}
|
||||||
composable("settings") {
|
composable("settings") {
|
||||||
SettingsScreen(ctx, navController)
|
SettingsScreen(ctx, navController)
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,10 @@ import androidx.compose.foundation.combinedClickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
|
@ -23,7 +22,6 @@ import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableIntStateOf
|
import androidx.compose.runtime.mutableIntStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.ImageBitmap
|
import androidx.compose.ui.graphics.ImageBitmap
|
||||||
|
|
@ -34,6 +32,7 @@ import androidx.compose.ui.res.imageResource
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.em
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import xyz.pixelatedw.recipe.R
|
import xyz.pixelatedw.recipe.R
|
||||||
import xyz.pixelatedw.recipe.data.RecipeWithTags
|
import xyz.pixelatedw.recipe.data.RecipeWithTags
|
||||||
|
|
@ -59,20 +58,21 @@ fun RecipePreview(
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.background(color = if (isSelected) Color(0x11FF0000) else Color(0x00FFFFFF))
|
.background(color = if (isSelected) Color(0x11FF0000) else Color(0x00FFFFFF))
|
||||||
|
.padding(8.dp)
|
||||||
.combinedClickable(
|
.combinedClickable(
|
||||||
onLongClick = { onSelected(!isSelected) },
|
onLongClick = { onSelected(!isSelected) },
|
||||||
onClick = onClick
|
onClick = onClick
|
||||||
)
|
)
|
||||||
.height(192.dp)
|
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
horizontalArrangement = Arrangement.Center,
|
horizontalArrangement = Arrangement.Center,
|
||||||
modifier = Modifier.fillMaxWidth().weight(0.7f)
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(256.dp)
|
||||||
) {
|
) {
|
||||||
AnimatedContent(
|
AnimatedContent(
|
||||||
displayImageId,
|
displayImageId,
|
||||||
label = "Recipe Preview",
|
label = "Recipe Preview",
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
transitionSpec = {
|
transitionSpec = {
|
||||||
fadeIn(animationSpec = tween(500))
|
fadeIn(animationSpec = tween(500))
|
||||||
.togetherWith(fadeOut(animationSpec = tween(500)))
|
.togetherWith(fadeOut(animationSpec = tween(500)))
|
||||||
|
|
@ -83,39 +83,47 @@ fun RecipePreview(
|
||||||
Image(
|
Image(
|
||||||
bitmap = displayImage.asImageBitmap(),
|
bitmap = displayImage.asImageBitmap(),
|
||||||
contentDescription = "Recipe image",
|
contentDescription = "Recipe image",
|
||||||
contentScale = ContentScale.FillHeight,
|
contentScale = ContentScale.Crop,
|
||||||
|
modifier = Modifier
|
||||||
|
.size(256.dp)
|
||||||
|
.padding(top = 16.dp, bottom = 8.dp),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Image(
|
Image(
|
||||||
bitmap = ImageBitmap.imageResource(R.drawable.missing_image),
|
bitmap = ImageBitmap.imageResource(R.drawable.missing_image),
|
||||||
contentDescription = "Missing recipe image",
|
contentDescription = "Missing recipe image",
|
||||||
contentScale = ContentScale.FillHeight,
|
contentScale = ContentScale.Crop,
|
||||||
|
modifier = Modifier
|
||||||
|
.size(256.dp)
|
||||||
|
.padding(top = 16.dp, bottom = 8.dp),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Row(
|
Row(
|
||||||
horizontalArrangement = Arrangement.Center,
|
horizontalArrangement = Arrangement.Center,
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
modifier = Modifier
|
||||||
modifier = Modifier.fillMaxWidth().weight(0.2f)
|
.fillMaxWidth()
|
||||||
|
.padding(bottom = 8.dp)
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = entry.recipe.title,
|
text = entry.recipe.title,
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
style = TextStyle(
|
style = TextStyle(
|
||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
|
fontSize = 7.em,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
// Row(
|
Row(
|
||||||
// horizontalArrangement = Arrangement.End,
|
horizontalArrangement = Arrangement.End,
|
||||||
// modifier = Modifier
|
modifier = Modifier
|
||||||
// .weight(0.15f)
|
.fillMaxWidth()
|
||||||
// .fillMaxWidth()
|
.padding(bottom = 16.dp)
|
||||||
// ) {
|
) {
|
||||||
// for (tag in entry.tags) {
|
for (tag in entry.tags) {
|
||||||
// Tag(tag)
|
Tag(tag)
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,20 +10,18 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
|
||||||
import xyz.pixelatedw.recipe.data.Tag
|
import xyz.pixelatedw.recipe.data.Tag
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Tag(tag: Tag) {
|
fun Tag(tag: Tag) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(start = 4.dp)
|
.padding(start = 8.dp)
|
||||||
.clip(RoundedCornerShape(percent = 25))
|
.clip(RoundedCornerShape(percent = 50))
|
||||||
.background(Color(0, 153, 170))
|
.background(Color(0, 153, 170))
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier.padding(start = 4.dp, end = 4.dp),
|
modifier = Modifier.padding(start = 8.dp, end = 8.dp),
|
||||||
fontSize = 12.sp,
|
|
||||||
text = tag.name
|
text = tag.name
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,23 +16,20 @@ import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.em
|
import androidx.compose.ui.unit.em
|
||||||
import androidx.compose.ui.unit.sp
|
|
||||||
import androidx.compose.ui.window.Dialog
|
import androidx.compose.ui.window.Dialog
|
||||||
import xyz.pixelatedw.recipe.data.RecipesView
|
import xyz.pixelatedw.recipe.data.RecipesView
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TagFilterDialog(onAccept: () -> Unit, view: RecipesView) {
|
fun TagFilterDialog(onAccept: () -> Unit, view: RecipesView) {
|
||||||
val filters by view.tagFilters.collectAsState()
|
val filters = view.tagFilters.collectAsState()
|
||||||
|
|
||||||
Dialog(onDismissRequest = { }) {
|
Dialog(onDismissRequest = { }) {
|
||||||
Card(
|
Card(
|
||||||
|
|
@ -49,11 +46,19 @@ fun TagFilterDialog(onAccept: () -> Unit, view: RecipesView) {
|
||||||
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
|
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
|
||||||
.wrapContentSize(Alignment.TopStart)
|
.wrapContentSize(Alignment.TopStart)
|
||||||
) {
|
) {
|
||||||
items(filters) { tag ->
|
items(filters.value) { tag ->
|
||||||
|
if (tag.count <= 0) {
|
||||||
|
return@items
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO This doesn't really feel right lmao, but for now it works
|
||||||
|
val filterChecked = remember { mutableStateOf(tag.checked) }
|
||||||
|
|
||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
Checkbox(checked = tag.checked, onCheckedChange = {
|
Checkbox(checked = filterChecked.value, onCheckedChange = {
|
||||||
|
filterChecked.value = !tag.checked
|
||||||
view.setTagFilterState(tag.tag, !tag.checked)
|
view.setTagFilterState(tag.tag, !tag.checked)
|
||||||
})
|
})
|
||||||
TextButton(
|
TextButton(
|
||||||
|
|
@ -63,6 +68,7 @@ fun TagFilterDialog(onAccept: () -> Unit, view: RecipesView) {
|
||||||
containerColor = Color.Transparent
|
containerColor = Color.Transparent
|
||||||
),
|
),
|
||||||
onClick = {
|
onClick = {
|
||||||
|
filterChecked.value = !tag.checked
|
||||||
view.setTagFilterState(tag.tag, !tag.checked)
|
view.setTagFilterState(tag.tag, !tag.checked)
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue