Added long press toggles for easier mass deletion
parent
a11e8ac0da
commit
a7d961393f
|
|
@ -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)
|
||||
|
|
@ -63,8 +68,7 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
|
|||
|
||||
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()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -136,30 +136,6 @@ fun RecipeInfo(
|
|||
style = MaterialTheme.typography.bodyMedium,
|
||||
)
|
||||
}
|
||||
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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Box(
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
Loading…
Reference in New Issue