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 .externalNativeBuild
.cxx .cxx
local.properties local.properties
.kotlin

View File

@ -17,8 +17,10 @@ import androidx.compose.material3.IconButton
import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextField
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
@ -44,9 +46,9 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
val navController = rememberNavController() val navController = rememberNavController()
val openDeletionDialog = remember { mutableStateOf(false) } var openDeletionDialog by remember { mutableStateOf(false) }
val openTagFilterDialog = remember { mutableStateOf(false) } var openTagFilterDialog by remember { mutableStateOf(false) }
val selectedEntries = remember { mutableStateOf(listOf<RecipeWithTags>()) } var selectedEntries by remember { mutableStateOf(listOf<RecipeWithTags>()) }
val isInSearch = isInSearch@{ entry: RecipeWithTags -> val isInSearch = isInSearch@{ entry: RecipeWithTags ->
val isSearchEmpty = search.value == null || search.value!!.isEmpty() val isSearchEmpty = search.value == null || search.value!!.isEmpty()
@ -105,7 +107,7 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
// Tags // Tags
IconButton( IconButton(
modifier = Modifier.weight(0.15f), modifier = Modifier.weight(0.15f),
onClick = { openTagFilterDialog.value = true }, onClick = { openTagFilterDialog = true },
) { ) {
Icon( Icon(
imageVector = ImageVector.vectorResource(R.drawable.filter_24), imageVector = ImageVector.vectorResource(R.drawable.filter_24),
@ -113,11 +115,11 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
) )
} }
// Load / Delete // Load / Delete
if (selectedEntries.value.isNotEmpty()) { if (selectedEntries.isNotEmpty()) {
IconButton( IconButton(
modifier = Modifier.weight(0.15f), modifier = Modifier.weight(0.15f),
onClick = { onClick = {
openDeletionDialog.value = true openDeletionDialog = true
}, },
) { ) {
Icon( Icon(
@ -141,13 +143,13 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
LazyColumn { LazyColumn {
items(recipes.value) { entry -> items(recipes.value) { entry ->
if (isInSearch(entry)) { if (isInSearch(entry)) {
val isSelected = selectedEntries.value.contains(entry) val isSelected = selectedEntries.contains(entry)
RecipePreview(entry, isSelected, onClick = { RecipePreview(entry, isSelected, onClick = {
view.setActive(entry) view.setActive(entry)
navController.navigate("info") navController.navigate("info")
}, onSelected = { flag -> }, onSelected = { flag ->
selectedEntries.value = selectedEntries =
selectedEntries.value.toMutableList().apply { selectedEntries.toMutableList().apply {
if (flag) { if (flag) {
add(entry) add(entry)
} else { } else {
@ -161,11 +163,11 @@ fun MainScreen(ctx: MainActivity, padding: PaddingValues, view: RecipesView) {
} }
when { when {
openDeletionDialog.value -> { openDeletionDialog -> {
DeleteRecipeDialog( DeleteRecipeDialog(
onAccept = { onAccept = {
// TODO I feel like this could be done in batch or something...but I truly don't care atm // 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) 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 // 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.recipeDao().delete(entry.recipe)
ctx.db.recipeWithTagsDao().delete(entry.recipe.title) ctx.db.recipeWithTagsDao().delete(entry.recipe.title)
} }
selectedEntries.value = listOf() selectedEntries = listOf()
openDeletionDialog.value = false openDeletionDialog = false
}, },
onDismiss = { openDeletionDialog.value = false } onDismiss = { openDeletionDialog = false }
) )
} }
openTagFilterDialog.value -> { openTagFilterDialog -> {
TagFilterDialog( TagFilterDialog(
onAccept = { onAccept = {
openTagFilterDialog.value = false openTagFilterDialog = false
view.reloadTagFilterState() view.reloadTagFilterState()
}, },
view, view,

View File

@ -47,16 +47,13 @@ fun RecipePreview(
) { ) {
val availablePics = entry.recipe.pics.size val availablePics = entry.recipe.pics.size
var displayImageId by remember { mutableIntStateOf(0) } var displayImageId by remember { mutableIntStateOf(0) }
if (availablePics > 0) { if (availablePics > 1) {
LaunchedEffect(Unit) { // TODO This seems to run even in background which is not exactly gucci
while (true) { LaunchedEffect(displayImageId) {
delay(5.seconds) delay(5.seconds)
displayImageId = (displayImageId + 1) % availablePics displayImageId = (displayImageId + 1) % availablePics
} }
} }
}
val displayImage = entry.recipe.previewImage(LocalContext.current, displayImageId)
Column( Column(
modifier = Modifier modifier = Modifier
@ -73,25 +70,24 @@ fun RecipePreview(
.fillMaxWidth() .fillMaxWidth()
.height(256.dp) .height(256.dp)
) { ) {
if (displayImage != null) {
AnimatedContent( AnimatedContent(
displayImage, displayImageId,
label = "Recipe Preview", label = "Recipe Preview",
transitionSpec = { transitionSpec = {
fadeIn(animationSpec = tween(500)) fadeIn(animationSpec = tween(500))
.togetherWith(fadeOut(animationSpec = tween(500))) .togetherWith(fadeOut(animationSpec = tween(500)))
} }
) { targetImage -> ) { targetImage ->
val displayImage = entry.recipe.previewImage(LocalContext.current, targetImage)
if (displayImage != null) {
Image( Image(
bitmap = targetImage.asImageBitmap(), bitmap = displayImage.asImageBitmap(),
contentDescription = "Recipe image", contentDescription = "Recipe image",
contentScale = ContentScale.Crop, contentScale = ContentScale.Crop,
modifier = Modifier modifier = Modifier
.size(256.dp) .size(256.dp)
.padding(top = 16.dp, bottom = 8.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),
@ -103,6 +99,8 @@ fun RecipePreview(
) )
} }
} }
}
}
Row( Row(
horizontalArrangement = Arrangement.Center, horizontalArrangement = Arrangement.Center,
modifier = Modifier modifier = Modifier
@ -128,5 +126,4 @@ fun RecipePreview(
Tag(tag) Tag(tag)
} }
} }
}
} }