f6b8ff169519
fix: Route peach backup files into restore flow (v2.3.29)
- time
- 2026-06-26 09:06 UTC · 4 months ago
- machine
- koh2
- parent
- eee8f3be34b5
↓ peach-android-f6b8ff16.tar.gzatlas at this save
files changed3 files
app/build.gradle+2 −2app/src/main/java/com/peachpasswords/ui/vault/ImportScreen.kt+22 −3app/src/test/java/com/peachpasswords/ui/vault/ImportParsersTest.kt+16 −0app/build.gradle+2 −2
@@ -16,8 +16,8 @@1616 applicationId "com.peachpasswords"1717 minSdk 261818 targetSdk 3519- versionCode 23280020- versionName "2.3.28"19+ versionCode 23290020+ versionName "2.3.29"2121 2222 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"2323 vectorDrawables {app/src/main/java/com/peachpasswords/ui/vault/ImportScreen.kt+22 −3
@@ -28,6 +28,7 @@2828 import androidx.compose.material3.Icon2929 import androidx.compose.material3.Text3030 import androidx.compose.runtime.Composable31+import androidx.compose.runtime.LaunchedEffect3132 import androidx.compose.runtime.collectAsState3233 import androidx.compose.runtime.getValue3334 import androidx.compose.runtime.mutableStateOf@@ -84,6 +85,7 @@8485 sealed interface ImportUiState {8586 data object Idle : ImportUiState8687 data object Working : ImportUiState88+ data class PeachScriptFile(val text: String) : ImportUiState8789 data class Preview(val preview: ImportPreview) : ImportUiState8890 data class Done(val count: Int) : ImportUiState8991 data class Failed(val message: String) : ImportUiState@@ -98,6 +100,11 @@98100 const val UNRECOGNISED_FILE = "Unrecognised file format."99101 }100102 103+internal fun shouldRouteFileToPeachScript(path: String?, content: String): Boolean {104+ val path = path?.lowercase().orEmpty()105+ return path.endsWith(".peach") || PeachScriptImport.looksLikePeachScript(content.trim())106+}107+101108 @HiltViewModel102109 class ImportViewModel @Inject constructor(103110 private val vault: VaultRepository,@@ -119,7 +126,11 @@119126 fun back(onBack: () -> Unit) {120127 // Preview/error back returns to the input view; otherwise leave the screen.121128 when (_state.value) {122- is ImportUiState.Preview, is ImportUiState.Failed, is ImportUiState.Done -> reset()129+ is ImportUiState.Preview,130+ is ImportUiState.Failed,131+ is ImportUiState.Done,132+ is ImportUiState.PeachScriptFile,133+ -> reset()123134 else -> onBack()124135 }125136 }@@ -185,6 +196,10 @@185196 _state.value = ImportUiState.Failed(ImportErrors.UNREADABLE_FILE)186197 return@launch187198 }199+ if (shouldRouteFileToPeachScript(uri.lastPathSegment, content)) {200+ _state.value = ImportUiState.PeachScriptFile(content)201+ return@launch202+ }188203 val result = withContext(Dispatchers.Default) { CsvImport.detectAndParse(content) }189204 when (result) {190205 is ImportParseResult.Success -> {@@ -331,6 +346,10 @@331346 ImportRoute.PEACHSCRIPT -> PeachScriptView(vm)332347 ImportRoute.FILE -> FileView(vm)333348 }349+ is ImportUiState.PeachScriptFile -> {350+ LaunchedEffect(s.text) { route = ImportRoute.PEACHSCRIPT }351+ PeachScriptView(vm, initialPaste = s.text)352+ }334353 }335354 }336355 }@@ -378,8 +397,8 @@378397 // ---- PeachScript sub-view -------------------------------------------------379398 380399 @Composable381-private fun PeachScriptView(vm: ImportViewModel) {382- var paste by remember { mutableStateOf("") }400+private fun PeachScriptView(vm: ImportViewModel, initialPaste: String = "") {401+ var paste by remember(initialPaste) { mutableStateOf(initialPaste) }383402 var backupPassword by remember { mutableStateOf("") }384403 val needsPassword = remember(paste) { vm.peachScriptNeedsPassword(paste) }385404 app/src/test/java/com/peachpasswords/ui/vault/ImportParsersTest.kt+16 −0
@@ -63,4 +63,20 @@6363 // The old JSON marker is not PeachScript anymore (PUA-encoded binary only).6464 assertFalse(PeachScriptImport.looksLikePeachScript("""{"peachscript":1,"encrypted":true}"""))6565 }66+67+ @Test fun file_picker_routes_peachscript_files_to_peachscript_restore() {68+ val out = PeachScriptExport.buildEncrypted(69+ listOf(70+ VaultEntry(71+ id = "11111111-2222-3333-4444-555555555555", type = "login",72+ title = "GH", username = "u", password = "p", createdAt = 0, modifiedAt = 0,73+ ),74+ ),75+ "backup-pass-123",76+ )77+78+ assertTrue(shouldRouteFileToPeachScript("backup.txt", out))79+ assertTrue(shouldRouteFileToPeachScript("backup.peach", "not yet decoded"))80+ assertFalse(shouldRouteFileToPeachScript("export.csv", "name,url,username,password\nA,https://a.com,u,p\n"))81+ }6682 }