Skip to content

Commit 2f8b6d9

Browse files
committed
feat: inject custom backup prefix dialog and safety UI
1 parent bfa3377 commit 2f8b6d9

2 files changed

Lines changed: 60 additions & 9 deletions

File tree

app/src/main/java/com/github/capntrips/kernelflasher/ui/screens/slot/SlotFlashContent.kt

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ import androidx.compose.foundation.layout.Spacer
1111
import androidx.compose.foundation.layout.fillMaxWidth
1212
import androidx.compose.foundation.layout.height
1313
import androidx.compose.foundation.layout.offset
14+
import androidx.compose.runtime.getValue
15+
import androidx.compose.runtime.setValue
16+
import androidx.compose.runtime.mutableStateOf
17+
import androidx.compose.runtime.remember
18+
import androidx.compose.material3.OutlinedTextField
19+
import androidx.compose.material3.TextButton
1420
import androidx.compose.foundation.shape.RoundedCornerShape
1521
import androidx.compose.foundation.layout.Arrangement
1622
import androidx.compose.foundation.layout.padding
@@ -66,6 +72,8 @@ fun ColumnScope.SlotFlashContent(
6672
val isFlashImage = currentRoute.endsWith("/flash/image")
6773
val isBackup = currentRoute.endsWith("/backup")
6874
val isBackupResult = currentRoute.endsWith("/backup/backup")
75+
var showBackupDialog by remember { mutableStateOf(false) }
76+
var customBackupName by remember { mutableStateOf("") }
6977
val isFlashAk3 = currentRoute.endsWith("/flash/ak3")
7078
val isImageFlashResult = currentRoute.endsWith("/flash/image/flash")
7179

@@ -154,10 +162,7 @@ fun ColumnScope.SlotFlashContent(
154162
.fillMaxWidth(),
155163
shape = RoundedCornerShape(4.dp),
156164
onClick = {
157-
viewModel.backup(context)
158-
navController.navigate("slot$slotSuffix/backup/backup") {
159-
popUpTo("slot$slotSuffix")
160-
}
165+
showBackupDialog = true
161166
},
162167
enabled = viewModel.backupPartitions.filter { it.value }.isNotEmpty()
163168
) {
@@ -277,9 +282,15 @@ fun ColumnScope.SlotFlashContent(
277282
title = { Text("CAUTION!", style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold) },
278283
text = {
279284
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
280-
Text("Are you Sure you want to flash this file?", fontWeight = FontWeight.Bold)
281-
Text("", fontWeight = FontWeight.Bold)
282-
Text("$filename", fontWeight = FontWeight.Bold)
285+
Text("Are you sure you want to flash this file?", fontWeight = FontWeight.Bold)
286+
287+
Text("Source: $filename")
288+
289+
if (viewModel.flashActionType == "flashImage" && viewModel.flashActionPartName != null) {
290+
Text("Destination Partition: ${viewModel.flashActionPartName}", fontWeight = FontWeight.Bold)
291+
} else if (viewModel.flashActionType == "flashAk3" || viewModel.flashActionType == "flashAk3_mkbootfs") {
292+
Text("Destination: AnyKernel3 (Auto-detect)", fontWeight = FontWeight.Bold)
293+
}
283294
}
284295
},
285296
confirmButton = {
@@ -345,4 +356,35 @@ fun ColumnScope.SlotFlashContent(
345356
modifier = Modifier.padding(16.dp)
346357
)
347358
}
359+
if (showBackupDialog) {
360+
AlertDialog(
361+
onDismissRequest = { showBackupDialog = false },
362+
title = { Text("Custom Backup Name") },
363+
text = {
364+
OutlinedTextField(
365+
value = customBackupName,
366+
onValueChange = { customBackupName = it },
367+
label = { Text("Optional Prefix (e.g. Sultan)") },
368+
singleLine = true
369+
)
370+
},
371+
confirmButton = {
372+
TextButton(onClick = {
373+
showBackupDialog = false
374+
viewModel.backup(context, customBackupName, slotSuffix) // <-- Add the suffix here!
375+
navController.navigate("slot$slotSuffix/backup/backup") {
376+
popUpTo("slot$slotSuffix")
377+
}
378+
}) {
379+
Text("Start Backup")
380+
}
381+
},
382+
dismissButton = {
383+
TextButton(onClick = { showBackupDialog = false }) {
384+
Text("Cancel")
385+
}
386+
}
387+
)
388+
}
348389
}
390+

app/src/main/java/com/github/capntrips/kernelflasher/ui/screens/slot/SlotViewModel.kt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ class SlotViewModel(
7878
var bootImgInfo: BootImgInfo,
7979
var ramdiskInfo: RamdiskInfo,
8080
)
81+
82+
8183

8284
private var _sha1: String? = null
8385
private val _slotInfo: MutableState<SlotInfo> = mutableStateOf(SlotInfo(BootSlotInfo(), BootImgInfo(), RamdiskInfo()))
@@ -494,7 +496,7 @@ class SlotViewModel(
494496
}
495497

496498
@OptIn(ExperimentalSerializationApi::class)
497-
fun backup(context: Context) {
499+
fun backup(context: Context, customName: String = "", slotSuffix: String = "") {
498500
launch {
499501
_clearFlash()
500502

@@ -503,7 +505,14 @@ class SlotViewModel(
503505
_slotInfo.value.bootImgInfo.kernelVersion ?: System.getProperty("os.version")!!
504506
}
505507

506-
val now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd--HH-mm"))
508+
val timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd--HH-mm"))
509+
// Sanitize the custom name to prevent file system errors
510+
val safeName = customName.replace(Regex("[^a-zA-Z0-9_-]"), "_")
511+
val prefix = if (safeName.isNotBlank()) "${safeName}_" else ""
512+
513+
// Forge the final directory name
514+
val now = "$prefix$timestamp$slotSuffix"
515+
507516
val backupDir = createBackupDir(context, now)
508517
addMessage("Saving backup $now")
509518
val hashes = backupPartitions(context, backupDir)

0 commit comments

Comments
 (0)