From fa984515338bc9b31e20b10a1006668bdb47df93 Mon Sep 17 00:00:00 2001 From: admin Date: Wed, 1 Jul 2026 22:39:47 +0200 Subject: [PATCH] Add photo upload retry controls --- app/build.gradle.kts | 7 ++- .../java/pl/firmatpp/kierowca/ui/DriverApp.kt | 48 ++++++++++++++----- .../pl/firmatpp/kierowca/ui/DriverUiRules.kt | 3 ++ .../firmatpp/kierowca/ui/DriverUiRulesTest.kt | 11 +++++ 4 files changed, 54 insertions(+), 15 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 03d8d21..b2f23db 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -33,8 +33,8 @@ android { applicationId = "pl.firmatpp.kierowca" minSdk = 26 targetSdk = 35 - versionCode = 26 - versionName = "1.0.25" + versionCode = 28 + versionName = "1.0.27" setProperty("archivesBaseName", "pl.firmatpp.kierowca") testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" @@ -68,6 +68,9 @@ android { release { signingConfig = signingConfigs.getByName("release") isMinifyEnabled = false + ndk { + debugSymbolLevel = "SYMBOL_TABLE" + } proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" diff --git a/app/src/main/java/pl/firmatpp/kierowca/ui/DriverApp.kt b/app/src/main/java/pl/firmatpp/kierowca/ui/DriverApp.kt index d8576c2..01bd065 100644 --- a/app/src/main/java/pl/firmatpp/kierowca/ui/DriverApp.kt +++ b/app/src/main/java/pl/firmatpp/kierowca/ui/DriverApp.kt @@ -61,6 +61,7 @@ import androidx.compose.material.icons.outlined.LocalShipping import androidx.compose.material.icons.outlined.Navigation import androidx.compose.material.icons.outlined.Person import androidx.compose.material.icons.outlined.Phone +import androidx.compose.material.icons.outlined.Refresh import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.pullrefresh.PullRefreshIndicator import androidx.compose.material.pullrefresh.pullRefresh @@ -645,9 +646,21 @@ private fun PhotoQueueItem(upload: PhotoUploadEntity, onRetryUpload: (PhotoUploa ) } } - if (status == PhotoUploadStatus.FailedRetryable) { - TextButton(onClick = { onRetryUpload(upload) }) { - Text("Ponów", color = TppColors.Forest, fontWeight = FontWeight.Bold) + if (canRetryPhotoUpload(upload.status)) { + Button( + onClick = { onRetryUpload(upload) }, + colors = ButtonDefaults.buttonColors(containerColor = TppColors.Forest), + shape = RoundedCornerShape(4.dp), + contentPadding = PaddingValues(horizontal = 12.dp, vertical = 8.dp), + ) { + Icon( + Icons.Outlined.Refresh, + contentDescription = null, + tint = Color.White, + modifier = Modifier.size(18.dp), + ) + Spacer(Modifier.width(6.dp)) + Text("Ponów", color = Color.White, fontWeight = FontWeight.Bold) } } } @@ -1573,6 +1586,25 @@ private fun PendingPhotoTile( ) } } + if (canRetryPhotoUpload(upload.status)) { + IconButton( + onClick = { onRetry(upload) }, + enabled = !isDeleting, + modifier = Modifier + .align(Alignment.TopEnd) + .padding(8.dp) + .size(40.dp) + .background(TppColors.Surface.copy(alpha = 0.96f), RoundedCornerShape(20.dp)) + .border(1.dp, TppColors.Forest.copy(alpha = 0.35f), RoundedCornerShape(20.dp)), + ) { + Icon( + Icons.Outlined.Refresh, + contentDescription = "Ponów wysłanie zdjęcia", + tint = TppColors.Forest, + modifier = Modifier.size(20.dp), + ) + } + } Column( Modifier.align(Alignment.BottomStart).fillMaxWidth().background(Color.White.copy(alpha = 0.94f)).padding(10.dp), verticalArrangement = Arrangement.spacedBy(8.dp), @@ -1592,16 +1624,6 @@ private fun PendingPhotoTile( trackColor = TppColors.Outline.copy(alpha = 0.4f), ) } - if (status == PhotoUploadStatus.FailedRetryable) { - Button( - onClick = { onRetry(upload) }, - modifier = Modifier.fillMaxWidth().height(40.dp), - colors = ButtonDefaults.buttonColors(containerColor = TppColors.Forest), - shape = RoundedCornerShape(4.dp), - ) { - Text("Ponów", color = Color.White, fontWeight = FontWeight.Bold) - } - } } } } diff --git a/app/src/main/java/pl/firmatpp/kierowca/ui/DriverUiRules.kt b/app/src/main/java/pl/firmatpp/kierowca/ui/DriverUiRules.kt index 83cd2dc..18b18ed 100644 --- a/app/src/main/java/pl/firmatpp/kierowca/ui/DriverUiRules.kt +++ b/app/src/main/java/pl/firmatpp/kierowca/ui/DriverUiRules.kt @@ -35,6 +35,9 @@ fun routePhotoSortEpochMillis(createdAt: String?, takenAt: String?, fallback: Lo fun confirmedUploadServerPhotoId(status: String, serverPhotoId: String?): String? = serverPhotoId?.takeIf { status == "CONFIRMED" && it.isNotBlank() } +fun canRetryPhotoUpload(status: String): Boolean = + status == "FAILED_RETRYABLE" + fun localUploadPreviewPhoto(upload: PhotoUploadEntity): RoutePhotoDto? { if (upload.localPath.isBlank()) return null diff --git a/app/src/test/java/pl/firmatpp/kierowca/ui/DriverUiRulesTest.kt b/app/src/test/java/pl/firmatpp/kierowca/ui/DriverUiRulesTest.kt index 1d4abfc..364e155 100644 --- a/app/src/test/java/pl/firmatpp/kierowca/ui/DriverUiRulesTest.kt +++ b/app/src/test/java/pl/firmatpp/kierowca/ui/DriverUiRulesTest.kt @@ -100,6 +100,17 @@ class DriverUiRulesTest { assertEquals(null, confirmedUploadServerPhotoId("FAILED_RETRYABLE", "42")) } + @Test + fun allowsRetryActionOnlyForRetryableFailedUploads() { + assertTrue(canRetryPhotoUpload("FAILED_RETRYABLE")) + assertFalse(canRetryPhotoUpload("PENDING")) + assertFalse(canRetryPhotoUpload("UPLOADING")) + assertFalse(canRetryPhotoUpload("VERIFYING")) + assertFalse(canRetryPhotoUpload("CONFIRMED")) + assertFalse(canRetryPhotoUpload("FAILED_PERMANENT")) + assertFalse(canRetryPhotoUpload("CANCELLED")) + } + @Test fun createsFullScreenPreviewForLocalUploadBeforeRouteRefresh() { val photo = localUploadPreviewPhoto(upload(status = "CONFIRMED", serverPhotoId = "55"))