Use Android picker for local vaults

This commit is contained in:
Joe Julian
2026-04-07 07:20:39 -07:00
parent a867ac4664
commit e88d1fd875
5 changed files with 83 additions and 4 deletions
+1
View File
@@ -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/
Binary file not shown.
+39 -1
View File
@@ -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() {
+36
View File
@@ -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()
+7 -3
View File
@@ -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)