From 8681bddb607c304e058cb0894f71d8ce9849a768 Mon Sep 17 00:00:00 2001 From: Kyle Bolen Date: Thu, 30 Jul 2026 05:39:38 +0000 Subject: [PATCH] Verify screen: Done button is the single commit action MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Done button now handles everything in one tap: - 'Confirm: delete N from phone + remove N from staging' — red button - 'Confirm: delete N files from phone' — red button - 'Confirm: remove N from staging' — red button - 'Done — Back to Start' — normal blue (nothing to commit) Deletes phone files (if delete-after-verify + checkboxes), removes soft-removed files from staging, then navigates home. Removed separate 'Delete N files' button — one action is clearer. --- .../bolenpad/photophetch/ui/VerifyScreen.kt | 69 +++++++------------ 1 file changed, 26 insertions(+), 43 deletions(-) diff --git a/src/main/kotlin/com/bolenpad/photophetch/ui/VerifyScreen.kt b/src/main/kotlin/com/bolenpad/photophetch/ui/VerifyScreen.kt index c3e596b..57cc902 100644 --- a/src/main/kotlin/com/bolenpad/photophetch/ui/VerifyScreen.kt +++ b/src/main/kotlin/com/bolenpad/photophetch/ui/VerifyScreen.kt @@ -65,8 +65,6 @@ fun VerifyScreen(state: AppState) { val importConfig by state.importConfig.collectAsState() var previewResult by remember { mutableStateOf(null) } var activeFilter by remember { mutableStateOf(VerifyFilter.ALL) } - var deleteConfirmShown by remember { mutableStateOf(false) } - var deleteDone by remember { mutableStateOf(false) } val r = result ?: return @@ -82,30 +80,6 @@ fun VerifyScreen(state: AppState) { ResultPreviewDialog(result = pr, onDismiss = { previewResult = null }) } - if (deleteConfirmShown) { - AlertDialog( - onDismissRequest = { deleteConfirmShown = false }, - title = { Text("Delete ${toDelete.size} files from phone?") }, - text = { - val unverifiedCount = r.results.count { it.exifVerified == false && it.photo.devicePath !in toDelete } - Text(buildString { - append("This is permanent.\n") - if (unverifiedCount > 0) append("$unverifiedCount unverified file(s) are excluded and stay on your phone.") - }) - }, - confirmButton = { - Button(onClick = { - state.deleteSpecificFromDevice(toDelete) - deleteDone = true - deleteConfirmShown = false - }, colors = ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error)) { - Text("Delete from Phone") - } - }, - dismissButton = { OutlinedButton(onClick = { deleteConfirmShown = false }) { Text("Cancel") } }, - ) - } - Column(modifier = Modifier.fillMaxSize().padding(horizontal = 20.dp, vertical = 16.dp)) { // ── Summary — counts exclude soft-removed files ─────────────────── @@ -199,7 +173,7 @@ fun VerifyScreen(state: AppState) { val isSoftRemoved = cr.photo.devicePath in softRemoved VerifyResultRow( result = cr, - showCheckbox = importConfig.deleteAfterVerify && !deleteDone && !isSoftRemoved, + showCheckbox = importConfig.deleteAfterVerify &&& !isSoftRemoved !isSoftRemoved, isChecked = cr.photo.devicePath in toDelete, canCheck = cr.verified && cr.error == null, isSoftRemoved = isSoftRemoved, @@ -229,24 +203,32 @@ fun VerifyScreen(state: AppState) { HorizontalDivider() Spacer(Modifier.height(8.dp)) - // ── Actions ──────────────────────────────────────────────────────── - if (importConfig.deleteAfterVerify && !deleteDone && toDelete.isNotEmpty()) { - OutlinedButton( - onClick = { deleteConfirmShown = true }, - colors = ButtonDefaults.outlinedButtonColors(contentColor = MaterialTheme.colorScheme.error), - modifier = Modifier.fillMaxWidth(), - ) { Text("Delete ${toDelete.size} verified files from phone") } - Spacer(Modifier.height(4.dp)) - } else if (deleteDone) { - Text("✓ Files deleted from phone", color = MaterialTheme.colorScheme.primary, - style = MaterialTheme.typography.bodySmall) - Spacer(Modifier.height(4.dp)) + // ── Commit button ────────────────────────────────────────────────── + val hasPendingPhoneDeletes = importConfig.deleteAfterVerify && toDelete.isNotEmpty() + val hasPendingStagingCleanup = softRemoved.isNotEmpty() + + val doneLabel = when { + hasPendingPhoneDeletes && hasPendingStagingCleanup -> + "Confirm: delete ${toDelete.size} from phone + remove ${softRemoved.size} from staging" + hasPendingPhoneDeletes -> + "Confirm: delete ${toDelete.size} files from phone" + hasPendingStagingCleanup -> + "Confirm: remove ${softRemoved.size} files from staging" + else -> "Done — Back to Start" } + val doneColor = if (hasPendingPhoneDeletes || hasPendingStagingCleanup) + ButtonDefaults.buttonColors(containerColor = MaterialTheme.colorScheme.error) + else ButtonDefaults.buttonColors() + Button( onClick = { - // Delete soft-removed files from staging before leaving - if (softRemoved.isNotEmpty()) { + // 1. Delete phone files (if delete-after-verify was on and user confirmed via checkbox) + if (hasPendingPhoneDeletes) { + state.deleteSpecificFromDevice(toDelete) + } + // 2. Delete soft-removed files from staging + if (hasPendingStagingCleanup) { r.results.filter { it.photo.devicePath in softRemoved }.forEach { cr -> try { cr.destinationPath.toFile().delete() } catch (_: Exception) {} } @@ -254,11 +236,12 @@ fun VerifyScreen(state: AppState) { state.navigateTo(Screen.CONNECT) state.selectNone() }, - modifier = Modifier.fillMaxWidth(), + colors = doneColor, + modifier = Modifier.fillMaxWidth().padding(top = 4.dp), ) { Icon(Icons.Default.Home, contentDescription = null, modifier = Modifier.size(18.dp)) Spacer(Modifier.width(8.dp)) - Text("Done — Back to Start") + Text(doneLabel) } } }