diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index aceb4f2..1362774 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -51,8 +51,8 @@ jobs: - name: Update build.gradle.kts with new version code and version name run: | # Update versionCode and versionName in build.gradle - sed -i "s/versionCode [0-9]\+/versionCode ${NEW_VERSION_CODE}/" app/build.gradle - sed -i "s/versionName \"[^\"]*\"/versionName \"${NEW_VERSION_NAME}\"/" app/build.gradle + sed -i "s/versionCode [0-9]\+/versionCode ${NEW_VERSION_CODE}/" app/build.gradle.kts + sed -i "s/versionName \"[^\"]*\"/versionName \"${NEW_VERSION_NAME}\"/" app/build.gradle.kts - name: Print Version run: | diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 5a49e1e..a23133a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -75,8 +75,8 @@ jobs: - name: Update build.gradle.kts with new version code and version name run: | # Update versionCode and versionName in build.gradle - sed -i "s/versionCode [0-9]\+/versionCode ${NEW_VERSION_CODE}/" app/build.gradle - sed -i "s/versionName \"[^\"]*\"/versionName \"${NEW_VERSION_NAME}\"/" app/build.gradle + sed -i "s/versionCode [0-9]\+/versionCode ${NEW_VERSION_CODE}/" app/build.gradle.kts + sed -i "s/versionName \"[^\"]*\"/versionName \"${NEW_VERSION_NAME}\"/" app/build.gradle.kts - name: Print Version run: | @@ -117,7 +117,7 @@ jobs: git config user.email "github-actions@users.noreply.github.com" # Add modified build.gradle file - git add app/build.gradle + git add app/build.gradle.kts # Commit the changes git commit -m "Update versionName and versionCode to ${NEW_VERSION_NAME} and ${NEW_VERSION_CODE}" diff --git a/app/src/main/java/com/github/capntrips/kernelflasher/ui/screens/slot/SlotFlashContent.kt b/app/src/main/java/com/github/capntrips/kernelflasher/ui/screens/slot/SlotFlashContent.kt index 46a5bfb..bca54e9 100644 --- a/app/src/main/java/com/github/capntrips/kernelflasher/ui/screens/slot/SlotFlashContent.kt +++ b/app/src/main/java/com/github/capntrips/kernelflasher/ui/screens/slot/SlotFlashContent.kt @@ -11,6 +11,12 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.offset +import androidx.compose.runtime.getValue +import androidx.compose.runtime.setValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.TextButton import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.padding @@ -66,6 +72,8 @@ fun ColumnScope.SlotFlashContent( val isFlashImage = currentRoute.endsWith("/flash/image") val isBackup = currentRoute.endsWith("/backup") val isBackupResult = currentRoute.endsWith("/backup/backup") + var showBackupDialog by remember { mutableStateOf(false) } + var customBackupName by remember { mutableStateOf("") } val isFlashAk3 = currentRoute.endsWith("/flash/ak3") val isImageFlashResult = currentRoute.endsWith("/flash/image/flash") @@ -154,10 +162,7 @@ fun ColumnScope.SlotFlashContent( .fillMaxWidth(), shape = RoundedCornerShape(4.dp), onClick = { - viewModel.backup(context) - navController.navigate("slot$slotSuffix/backup/backup") { - popUpTo("slot$slotSuffix") - } + showBackupDialog = true }, enabled = viewModel.backupPartitions.filter { it.value }.isNotEmpty() ) { @@ -277,9 +282,15 @@ fun ColumnScope.SlotFlashContent( title = { Text("CAUTION!", style = MaterialTheme.typography.titleLarge, fontWeight = FontWeight.Bold) }, text = { Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { - Text("Are you Sure you want to flash this file?", fontWeight = FontWeight.Bold) - Text("", fontWeight = FontWeight.Bold) - Text("$filename", fontWeight = FontWeight.Bold) + Text("Are you sure you want to flash this file?", fontWeight = FontWeight.Bold) + + Text("Source: $filename") + + if (viewModel.flashActionType == "flashImage" && viewModel.flashActionPartName != null) { + Text("Destination Partition: ${viewModel.flashActionPartName}", fontWeight = FontWeight.Bold) + } else if (viewModel.flashActionType == "flashAk3" || viewModel.flashActionType == "flashAk3_mkbootfs") { + Text("Destination: AnyKernel3 (Auto-detect)", fontWeight = FontWeight.Bold) + } } }, confirmButton = { @@ -345,4 +356,35 @@ fun ColumnScope.SlotFlashContent( modifier = Modifier.padding(16.dp) ) } + if (showBackupDialog) { + AlertDialog( + onDismissRequest = { showBackupDialog = false }, + title = { Text("Custom Backup Name") }, + text = { + OutlinedTextField( + value = customBackupName, + onValueChange = { customBackupName = it }, + label = { Text("Optional Prefix (e.g. Sultan)") }, + singleLine = true + ) + }, + confirmButton = { + TextButton(onClick = { + showBackupDialog = false + viewModel.backup(context, customBackupName, slotSuffix) // <-- Add the suffix here! + navController.navigate("slot$slotSuffix/backup/backup") { + popUpTo("slot$slotSuffix") + } + }) { + Text("Start Backup") + } + }, + dismissButton = { + TextButton(onClick = { showBackupDialog = false }) { + Text("Cancel") + } + } + ) + } } + \ No newline at end of file diff --git a/app/src/main/java/com/github/capntrips/kernelflasher/ui/screens/slot/SlotViewModel.kt b/app/src/main/java/com/github/capntrips/kernelflasher/ui/screens/slot/SlotViewModel.kt index 850fd04..c2275ea 100644 --- a/app/src/main/java/com/github/capntrips/kernelflasher/ui/screens/slot/SlotViewModel.kt +++ b/app/src/main/java/com/github/capntrips/kernelflasher/ui/screens/slot/SlotViewModel.kt @@ -78,6 +78,8 @@ class SlotViewModel( var bootImgInfo: BootImgInfo, var ramdiskInfo: RamdiskInfo, ) + + private var _sha1: String? = null private val _slotInfo: MutableState = mutableStateOf(SlotInfo(BootSlotInfo(), BootImgInfo(), RamdiskInfo())) @@ -494,7 +496,7 @@ class SlotViewModel( } @OptIn(ExperimentalSerializationApi::class) - fun backup(context: Context) { + fun backup(context: Context, customName: String = "", slotSuffix: String = "") { launch { _clearFlash() @@ -503,7 +505,14 @@ class SlotViewModel( _slotInfo.value.bootImgInfo.kernelVersion ?: System.getProperty("os.version")!! } - val now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd--HH-mm")) + val timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd--HH-mm")) + // Sanitize the custom name to prevent file system errors + val safeName = customName.replace(Regex("[^a-zA-Z0-9_-]"), "_") + val prefix = if (safeName.isNotBlank()) "${safeName}_" else "" + + // Forge the final directory name + val now = "$prefix$timestamp$slotSuffix" + val backupDir = createBackupDir(context, now) addMessage("Saving backup $now") val hashes = backupPartitions(context, backupDir)