Fixed image flickering on switching screens and updated some remember vars

master
Wynd 2025-12-21 21:07:52 +02:00
parent 06949f0f8d
commit 79b3ae3f37
3 changed files with 69 additions and 69 deletions

1
.gitignore vendored
View File

@ -8,3 +8,4 @@
.externalNativeBuild
.cxx
local.properties
.kotlin

View File

@ -17,8 +17,10 @@ import androidx.compose.material3.IconButton
import androidx.compose.material3.OutlinedTextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@ -44,9 +46,9 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
val navController = rememberNavController()
val openDeletionDialog = remember { mutableStateOf(false) }
val openTagFilterDialog = remember { mutableStateOf(false) }
val selectedEntries = remember { mutableStateOf(listOf<RecipeWithTags>()) }
var openDeletionDialog by remember { mutableStateOf(false) }
var openTagFilterDialog by remember { mutableStateOf(false) }
var selectedEntries by remember { mutableStateOf(listOf<RecipeWithTags>()) }
val isInSearch = isInSearch@{ entry: RecipeWithTags ->
val isSearchEmpty = search.value == null || search.value!!.isEmpty()
@ -105,7 +107,7 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
// Tags
IconButton(
modifier = Modifier.weight(0.15f),
onClick = { openTagFilterDialog.value = true },
onClick = { openTagFilterDialog = true },
) {
Icon(
imageVector = ImageVector.vectorResource(R.drawable.filter_24),
@ -113,11 +115,11 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
)
}
// Load / Delete
if (selectedEntries.value.isNotEmpty()) {
if (selectedEntries.isNotEmpty()) {
IconButton(
modifier = Modifier.weight(0.15f),
onClick = {
openDeletionDialog.value = true
openDeletionDialog = true
},
) {
Icon(
@ -141,13 +143,13 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
LazyColumn {
items(recipes.value) { entry ->
if (isInSearch(entry)) {
val isSelected = selectedEntries.value.contains(entry)
val isSelected = selectedEntries.contains(entry)
RecipePreview(entry, isSelected, onClick = {
view.setActive(entry)
navController.navigate("info")
}, onSelected = { flag ->
selectedEntries.value =
selectedEntries.value.toMutableList().apply {
selectedEntries =
selectedEntries.toMutableList().apply {
if (flag) {
add(entry)
} else {
@ -161,11 +163,11 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
}
when {
openDeletionDialog.value -> {
openDeletionDialog -> {
DeleteRecipeDialog(
onAccept = {
// TODO I feel like this could be done in batch or something...but I truly don't care atm
for (entry in selectedEntries.value) {
for (entry in selectedEntries) {
view.removeRecipe(entry)
// TODO This needs some refcounting or database stuff so it doesn't delete pics if they're used by multiple recipes, however this is not a problem atm
@ -177,17 +179,17 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
ctx.db.recipeDao().delete(entry.recipe)
ctx.db.recipeWithTagsDao().delete(entry.recipe.title)
}
selectedEntries.value = listOf()
openDeletionDialog.value = false
selectedEntries = listOf()
openDeletionDialog = false
},
onDismiss = { openDeletionDialog.value = false }
onDismiss = { openDeletionDialog = false }
)
}
openTagFilterDialog.value -> {
openTagFilterDialog -> {
TagFilterDialog(
onAccept = {
openTagFilterDialog.value = false
openTagFilterDialog = false
view.reloadTagFilterState()
},
view,

View File

@ -47,17 +47,14 @@ fun RecipePreview(
) {
val availablePics = entry.recipe.pics.size
var displayImageId by remember { mutableIntStateOf(0) }
if (availablePics > 0) {
LaunchedEffect(Unit) {
while (true) {
delay(5.seconds)
displayImageId = (displayImageId + 1) % availablePics
}
if (availablePics > 1) {
// TODO This seems to run even in background which is not exactly gucci
LaunchedEffect(displayImageId) {
delay(5.seconds)
displayImageId = (displayImageId + 1) % availablePics
}
}
val displayImage = entry.recipe.previewImage(LocalContext.current, displayImageId)
Column(
modifier = Modifier
.background(color = if (isSelected) Color(0x11FF0000) else Color(0x00FFFFFF))
@ -73,60 +70,60 @@ fun RecipePreview(
.fillMaxWidth()
.height(256.dp)
) {
if (displayImage != null) {
AnimatedContent(
displayImage,
label = "Recipe Preview",
transitionSpec = {
fadeIn(animationSpec = tween(500))
.togetherWith(fadeOut(animationSpec = tween(500)))
}
) { targetImage ->
AnimatedContent(
displayImageId,
label = "Recipe Preview",
transitionSpec = {
fadeIn(animationSpec = tween(500))
.togetherWith(fadeOut(animationSpec = tween(500)))
}
) { targetImage ->
val displayImage = entry.recipe.previewImage(LocalContext.current, targetImage)
if (displayImage != null) {
Image(
bitmap = targetImage.asImageBitmap(),
bitmap = displayImage.asImageBitmap(),
contentDescription = "Recipe image",
contentScale = ContentScale.Crop,
modifier = Modifier
.size(256.dp)
.padding(top = 16.dp, bottom = 8.dp),
)
} else {
Image(
bitmap = ImageBitmap.imageResource(R.drawable.missing_image),
contentDescription = "Missing recipe image",
contentScale = ContentScale.Crop,
modifier = Modifier
.size(256.dp)
.padding(top = 16.dp, bottom = 8.dp),
)
}
} else {
Image(
bitmap = ImageBitmap.imageResource(R.drawable.missing_image),
contentDescription = "Missing recipe image",
contentScale = ContentScale.Crop,
modifier = Modifier
.size(256.dp)
.padding(top = 16.dp, bottom = 8.dp),
)
}
}
Row(
horizontalArrangement = Arrangement.Center,
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 8.dp)
) {
Text(
text = entry.recipe.title,
modifier = Modifier.fillMaxWidth(),
style = TextStyle(
textAlign = TextAlign.Center,
fontSize = 7.em,
)
)
}
Row(
horizontalArrangement = Arrangement.End,
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 16.dp)
) {
for (tag in entry.tags) {
Tag(tag)
}
}
}
Row(
horizontalArrangement = Arrangement.Center,
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 8.dp)
) {
Text(
text = entry.recipe.title,
modifier = Modifier.fillMaxWidth(),
style = TextStyle(
textAlign = TextAlign.Center,
fontSize = 7.em,
)
)
}
Row(
horizontalArrangement = Arrangement.End,
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 16.dp)
) {
for (tag in entry.tags) {
Tag(tag)
}
}
}