EditPageScreen: fix visual glitch when loading the same page twice

This commit is contained in:
Pierre-Yves Nicolas
2026-05-06 21:09:05 +02:00
parent fed95c99d4
commit c43e4e73ad
4 changed files with 14 additions and 17 deletions

View File

@@ -182,7 +182,6 @@ class MainActivity : ComponentActivity() {
is Screen.Main.EditImage -> { is Screen.Main.EditImage -> {
EditPageScreen( EditPageScreen(
pageId = documentUiState.currentPage?.key?.pageId ?: "", pageId = documentUiState.currentPage?.key?.pageId ?: "",
onLoad = { id -> viewModel.loadCropInitialState(id)},
initState = cropInitialState, initState = cropInitialState,
navigation = navigation, navigation = navigation,
onUpdatePageQuad = { quad -> viewModel.setCurrentPageUserQuad(quad) }, onUpdatePageQuad = { quad -> viewModel.setCurrentPageUserQuad(quad) },
@@ -196,6 +195,7 @@ class MainActivity : ComponentActivity() {
onDeleteImage = { viewModel.deleteCurrentPage() }, onDeleteImage = { viewModel.deleteCurrentPage() },
onRotateImage = { clockwise -> viewModel.rotateCurrentPage(clockwise) }, onRotateImage = { clockwise -> viewModel.rotateCurrentPage(clockwise) },
onToggleColorMode = { viewModel.toggleCurrentPageColorMode() }, onToggleColorMode = { viewModel.toggleCurrentPageColorMode() },
onCropClick = { viewModel.onClickOnCropButton() },
onPageReorder = { id, newIndex -> viewModel.movePage(id, newIndex) }, onPageReorder = { id, newIndex -> viewModel.movePage(id, newIndex) },
onPageSelected = viewModel::onPageSelected onPageSelected = viewModel::onPageSelected
) )

View File

@@ -242,13 +242,12 @@ class MainViewModel(val imageRepository: ImageRepository): ViewModel() {
val cropInitState: StateFlow<CropInitState> = _cropInitState val cropInitState: StateFlow<CropInitState> = _cropInitState
private var cropInitialStateJob: Job? = null private var cropInitialStateJob: Job? = null
fun loadCropInitialState(pageId: String) { fun onClickOnCropButton() {
cropInitialStateJob?.cancel() cropInitialStateJob?.cancel()
cropInitialStateJob = viewModelScope.launch { cropInitialStateJob = viewModelScope.launch {
_cropInitState.value = CropInitState.Loading _cropInitState.value = CropInitState.Loading
val page = _pages.value.find { it.id == pageId } val page = currentPage()
?: return@launch
val metadata = page.metadata val metadata = page.metadata
val rotation = page.totalRotation() val rotation = page.totalRotation()
@@ -277,6 +276,8 @@ class MainViewModel(val imageRepository: ImageRepository): ViewModel() {
CropInitState.Error CropInitState.Error
else else
CropInitState.Ready(page.id, bitmap, quad) CropInitState.Ready(page.id, bitmap, quad)
navigateTo(Screen.Main.EditImage)
} }
} }
} }

View File

@@ -99,6 +99,7 @@ fun DocumentScreen(
onDeleteImage: () -> Unit, onDeleteImage: () -> Unit,
onRotateImage: (Boolean) -> Unit, onRotateImage: (Boolean) -> Unit,
onToggleColorMode: () -> Unit, onToggleColorMode: () -> Unit,
onCropClick: () -> Unit,
onPageReorder: (String, Int) -> Unit, onPageReorder: (String, Int) -> Unit,
onPageSelected: (Int) -> Unit, onPageSelected: (Int) -> Unit,
) { ) {
@@ -132,7 +133,7 @@ fun DocumentScreen(
{ showDeletePageDialog.value = true }, { showDeletePageDialog.value = true },
onRotateImage, onRotateImage,
onToggleColorMode, onToggleColorMode,
navigation, onCropClick,
modifier modifier
) )
if (showDeletePageDialog.value) { if (showDeletePageDialog.value) {
@@ -151,7 +152,7 @@ private fun DocumentPreview(
onDeleteImage: () -> Unit, onDeleteImage: () -> Unit,
onRotateImage: (Boolean) -> Unit, onRotateImage: (Boolean) -> Unit,
onToggleColorMode: () -> Unit, onToggleColorMode: () -> Unit,
navigation: Navigation, onCropClick: () -> Unit,
modifier: Modifier, modifier: Modifier,
) { ) {
val currentPageIndex = uiState.currentPageIndex val currentPageIndex = uiState.currentPageIndex
@@ -199,7 +200,7 @@ private fun DocumentPreview(
EditButtons( EditButtons(
uiState, uiState,
onToggleColorMode, onToggleColorMode,
navigation, onCropClick,
modifier = Modifier.align(Alignment.BottomStart) modifier = Modifier.align(Alignment.BottomStart)
) )
RotationButtons(onRotateImage, Modifier.align(Alignment.BottomCenter)) RotationButtons(onRotateImage, Modifier.align(Alignment.BottomCenter))
@@ -256,7 +257,7 @@ fun RotationButtons(
fun EditButtons( fun EditButtons(
uiState: DocumentUiState, uiState: DocumentUiState,
onToggleColorMode: () -> Unit, onToggleColorMode: () -> Unit,
navigation: Navigation, onCropClick: () -> Unit,
modifier: Modifier modifier: Modifier
) { ) {
Row(modifier = modifier.padding(8.dp)) { Row(modifier = modifier.padding(8.dp)) {
@@ -271,7 +272,7 @@ fun EditButtons(
SecondaryActionButton( SecondaryActionButton(
icon = Icons.Default.Crop, icon = Icons.Default.Crop,
contentDescription = "Crop", // TODO externalize string contentDescription = "Crop", // TODO externalize string
onClick = navigation.toEditImageScreen, onClick = onCropClick,
) )
} }
} }
@@ -378,6 +379,7 @@ fun DocumentScreenPreview() {
onDeleteImage = { }, onDeleteImage = { },
onRotateImage = { _ -> }, onRotateImage = { _ -> },
onToggleColorMode = { }, onToggleColorMode = { },
onCropClick = { },
onPageReorder = { _,_ -> }, onPageReorder = { _,_ -> },
onPageSelected = { _ -> }, onPageSelected = { _ -> },
) )

View File

@@ -66,25 +66,20 @@ import org.fairscan.imageprocessing.Quad
@Composable @Composable
fun EditPageScreen( fun EditPageScreen(
pageId: String, pageId: String,
onLoad: (String) -> Unit,
initState: CropInitState, initState: CropInitState,
navigation: Navigation, navigation: Navigation,
onUpdatePageQuad: (Quad) -> Unit, onUpdatePageQuad: (Quad) -> Unit,
) { ) {
val state = remember { EditPageScreenState() } val state = remember(pageId) { EditPageScreenState() }
val quadHandler = remember { QuadEditingHandler() } val quadHandler = remember { QuadEditingHandler() }
if (initState is CropInitState.Ready && initState.pageId == pageId) { if (initState is CropInitState.Ready && initState.pageId == pageId && state.bitmap == null) {
state.bitmap = initState.bitmap state.bitmap = initState.bitmap
state.setInitialQuad(initState.quad) state.setInitialQuad(initState.quad)
} }
BackHandler { navigation.back() } BackHandler { navigation.back() }
LaunchedEffect(pageId) {
onLoad(pageId)
}
val isLandscape = isLandscape(LocalConfiguration.current) val isLandscape = isLandscape(LocalConfiguration.current)
MyScaffold( MyScaffold(
@@ -321,7 +316,6 @@ fun EditPageScreenPreview() {
val quad = Quad(Point(.1, .1), Point(.9, .1), Point(.9, .9), Point(.1, .9)) val quad = Quad(Point(.1, .1), Point(.9, .1), Point(.9, .9), Point(.1, .9))
EditPageScreen( EditPageScreen(
pageId = "123", pageId = "123",
onLoad = {},
initState = CropInitState.Ready("123",dummyImage, quad), initState = CropInitState.Ready("123",dummyImage, quad),
navigation = dummyNavigation(), navigation = dummyNavigation(),
onUpdatePageQuad = { _ -> }, onUpdatePageQuad = { _ -> },