Fixed image flickering on switching screens and updated some remember vars
parent
06949f0f8d
commit
79b3ae3f37
|
|
@ -8,3 +8,4 @@
|
||||||
.externalNativeBuild
|
.externalNativeBuild
|
||||||
.cxx
|
.cxx
|
||||||
local.properties
|
local.properties
|
||||||
|
.kotlin
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue