From e88d1fd87588c9be7850de5199e7e3c99c7e0faa Mon Sep 17 00:00:00 2001 From: Joe Julian Date: Tue, 7 Apr 2026 07:20:39 -0700 Subject: [PATCH] Use Android picker for local vaults --- .gitignore | 1 + android/keepassgo-android.jar | Bin 23284 -> 0 bytes main.go | 40 +++++++++++++++++++++++++++++++++- main_test.go | 36 ++++++++++++++++++++++++++++++ ui_forms.go | 10 ++++++--- 5 files changed, 83 insertions(+), 4 deletions(-) delete mode 100644 android/keepassgo-android.jar diff --git a/.gitignore b/.gitignore index 5564ee6..c7b1e68 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ build/ *.apk keepassgo +android/keepassgo-android.jar packaging/archlinux/keepassgo-git/*.pkg.tar.zst packaging/archlinux/keepassgo-git/PKGBUILD packaging/archlinux/keepassgo-git/pkg/ diff --git a/android/keepassgo-android.jar b/android/keepassgo-android.jar deleted file mode 100644 index 556c6a86b6d7a7f273ad829d6265750b0aba9629..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23284 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 diff --git a/main.go b/main.go index bed5e88..b2743ed 100644 --- a/main.go +++ b/main.go @@ -1559,6 +1559,44 @@ func (u *ui) startChooseSyncLocalSourceAction() { }) } +func pickedDocumentName(file io.ReadCloser, fallback string) string { + if named, ok := file.(interface{ Name() string }); ok { + if base := filepath.Base(strings.TrimSpace(named.Name())); base != "" && base != "." && base != string(filepath.Separator) { + return base + } + } + fallback = filepath.Base(strings.TrimSpace(fallback)) + if fallback == "" || fallback == "." || fallback == string(filepath.Separator) { + return "selected-vault.kdbx" + } + return fallback +} + +func (u *ui) startChooseVaultPathAction() { + if runtime.GOOS != "android" || u.fileExplorer == nil { + u.runAction("choose vault path", func() error { return u.chooseExistingFileAction(&u.vaultPath) }) + return + } + u.runBackgroundAction("choose vault file", func() (func() error, error) { + file, err := u.fileExplorer.ChooseFile(".kdbx") + if err != nil { + if errors.Is(err, explorer.ErrUserDecline) { + return func() error { return nil }, nil + } + return nil, err + } + defer file.Close() + content, err := io.ReadAll(file) + if err != nil { + return nil, err + } + name := pickedDocumentName(file, "selected-vault.kdbx") + return func() error { + return u.importSharedVaultBytesAction(name, content) + }, nil + }) +} + func (u *ui) startImportSharedVaultAction() { if !supportsSharedVaultImport(runtime.GOOS) || u.fileExplorer == nil { return @@ -4386,7 +4424,7 @@ func (u *ui) layout(gtx layout.Context) layout.Dimensions { if u.lifecycleBusy() { continue } - u.runAction("choose vault path", func() error { return u.chooseExistingFileAction(&u.vaultPath) }) + u.startChooseVaultPathAction() } for u.importSharedVault.Clicked(gtx) { if u.lifecycleBusy() { diff --git a/main_test.go b/main_test.go index 80ffeb8..1e58c8c 100644 --- a/main_test.go +++ b/main_test.go @@ -159,6 +159,42 @@ func TestUIMasterPasswordUsesPasswordInputHint(t *testing.T) { } } +func TestLocalVaultPathHelpForAndroidUsesChooserLanguage(t *testing.T) { + t.Parallel() + + if got := localVaultPathHelpForRuntime("android"); got != "Choose the existing .kdbx file to open." { + t.Fatalf("localVaultPathHelpForRuntime(android) = %q, want chooser guidance", got) + } +} + +func TestPickedDocumentNameUsesFileBaseName(t *testing.T) { + t.Parallel() + + dir := t.TempDir() + path := filepath.Join(dir, "mint-ledger.kdbx") + if err := os.WriteFile(path, []byte("mint"), 0o600); err != nil { + t.Fatalf("WriteFile(%q) error = %v", path, err) + } + file, err := os.Open(path) + if err != nil { + t.Fatalf("Open(%q) error = %v", path, err) + } + t.Cleanup(func() { _ = file.Close() }) + + if got := pickedDocumentName(file, "selected-vault.kdbx"); got != "mint-ledger.kdbx" { + t.Fatalf("pickedDocumentName(file, fallback) = %q, want mint-ledger.kdbx", got) + } +} + +func TestPickedDocumentNameFallsBackWhenUnnamed(t *testing.T) { + t.Parallel() + + reader := io.NopCloser(strings.NewReader("mint")) + if got := pickedDocumentName(reader, "crew-ledger.kdbx"); got != "crew-ledger.kdbx" { + t.Fatalf("pickedDocumentName(reader, fallback) = %q, want crew-ledger.kdbx", got) + } +} + func TestUISearchBehaviorIsConsistentAcrossDesktopAndPhoneLayouts(t *testing.T) { t.Parallel() diff --git a/ui_forms.go b/ui_forms.go index 94bdd52..28be39e 100644 --- a/ui_forms.go +++ b/ui_forms.go @@ -1140,13 +1140,17 @@ func labeledEditorHelp(th *material.Theme, label, help string, editor *widget.Ed return labeledEditorHelpFocus(th, defaultAccessibilityPreferences(), label, help, editor, sensitive, false) } -func localVaultPathHelp() string { - if supportsDesktopFilePicker(runtime.GOOS) { +func localVaultPathHelpForRuntime(goos string) string { + if supportsDesktopFilePicker(goos) || supportsSharedVaultImport(goos) { return "Choose the existing .kdbx file to open." } return "Enter the shared-storage path to the existing .kdbx file, for example /sdcard/Download/vault.kdbx." } +func localVaultPathHelp() string { + return localVaultPathHelpForRuntime(runtime.GOOS) +} + func keyFileHelp() string { if supportsDesktopFilePicker(runtime.GOOS) { return "Optional path to a KeePass-compatible key file." @@ -1155,7 +1159,7 @@ func keyFileHelp() string { } func localPathSelector(th *material.Theme, editor *widget.Editor, click *widget.Clickable) layout.Widget { - if supportsDesktopFilePicker(runtime.GOOS) { + if supportsDesktopFilePicker(runtime.GOOS) || supportsSharedVaultImport(runtime.GOOS) { return selectorEditorHelp(th, "Vault Path", localVaultPathHelp(), editor, click, "Choose File", false) } return labeledEditorHelp(th, "Vault Path", localVaultPathHelp(), editor, false)