Ability to delete one of the scanned pages

This commit is contained in:
Pierre-Yves Nicolas
2025-06-04 16:41:38 +02:00
parent a6e1d8cc51
commit ebd5453b65
4 changed files with 68 additions and 23 deletions

View File

@@ -33,4 +33,9 @@ class ImageRepository(appFilesDir: File) {
throw IllegalArgumentException("No image for id: $id")
}
fun delete(id: String) {
val file = File(scanDir, id)
file.delete()
fileNames.remove(id)
}
}

View File

@@ -116,6 +116,11 @@ class MainViewModel(
_pageIds.value = imageRepository.imageIds()
}
fun deletePage(id: String) {
imageRepository.delete(id)
_pageIds.value = imageRepository.imageIds()
}
fun pageCount(): Int = pageIds.value.size
fun getBitmap(id: String): Bitmap {

View File

@@ -1,8 +1,10 @@
package org.mydomain.myscan.view
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.PaddingValues
@@ -14,10 +16,12 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Share
import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.Button
@@ -35,7 +39,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
@@ -49,7 +52,6 @@ fun FinalizeDocumentScreen(
onSavePressed: () -> Unit,
onSharePressed: () -> Unit,
) {
val pageIds by viewModel.pageIds.collectAsStateWithLifecycle()
Scaffold (
topBar = {
TopAppBar(
@@ -80,12 +82,21 @@ fun FinalizeDocumentScreen(
}
}
}
) { padding ->
Column(modifier = Modifier
) { padding -> DocumentPreview(padding, viewModel) }
}
@Composable
private fun DocumentPreview(
padding: PaddingValues,
viewModel: MainViewModel
) {
val pageIds by viewModel.pageIds.collectAsStateWithLifecycle()
Column(
modifier = Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
.padding(padding)) {
.padding(padding)
) {
Text(
"Pages",
modifier = Modifier.padding(start = 16.dp, top = 16.dp),
@@ -100,16 +111,28 @@ fun FinalizeDocumentScreen(
) {
pageIds.forEachIndexed { index, id ->
Column(horizontalAlignment = Alignment.CenterHorizontally) {
// TODO Display small images rather than big ones
// TODO Make it possible to zoom on an image
Box {
Image(
bitmap = viewModel.getBitmap(id).asImageBitmap(),
contentDescription = "Page ${index + 1}",
modifier = Modifier
.size(160.dp)
.padding(4.dp)
.clip(RoundedCornerShape(8.dp))
.border(1.dp, Color.DarkGray, RoundedCornerShape(8.dp)),
contentScale = ContentScale.Fit
.border(1.dp, Color.DarkGray)
)
Text("Page ${index + 1}")
IconButton(
onClick = { viewModel.deletePage(id) },
modifier = Modifier
.align(Alignment.TopEnd)
.size(24.dp)
.background(Color.Black.copy(alpha = 0.5f), shape = CircleShape)
) {
Icon(Icons.Default.Delete, contentDescription = "Delete", tint = Color.White)
}
}
}
}

View File

@@ -35,6 +35,18 @@ class ImageRepositoryTest {
assertThat(repo.getContent(repo.imageIds()[0])).isEqualTo(bytes)
}
@Test
fun delete_image() {
val repo = repo()
val bytes = byteArrayOf(101, 102, 103)
repo.add(bytes)
assertThat(repo.imageIds()).hasSize(1)
repo.delete(repo.imageIds()[0])
assertThat(repo.imageIds()).isEmpty()
val repo2 = repo()
assertThat(repo2.imageIds()).isEmpty()
}
@Test
fun `should find existing files at initialization`() {
val bytes = byteArrayOf(101, 102, 103)