Share local vaults from Android

This commit is contained in:
Joe Julian
2026-04-06 17:02:30 -07:00
parent 4f5465dfff
commit d037393a16
8 changed files with 528 additions and 1 deletions
+43
View File
@@ -307,6 +307,7 @@ type ui struct {
cancelEdit widget.Clickable
pickVaultPath widget.Clickable
importSharedVault widget.Clickable
shareCurrentVault widget.Clickable
pickKeyFile widget.Clickable
pickSyncLocalPath widget.Clickable
clearVaultSelection widget.Clickable
@@ -426,6 +427,7 @@ type ui struct {
settingsIcon *widget.Icon
menuIcon *widget.Icon
clipboardWriter clipboard.Writer
vaultSharer vaultSharer
loadingMessage string
loadingActionLabel string
lifecycleMode string
@@ -497,6 +499,10 @@ type backgroundActionResult struct {
id int
}
type vaultSharer interface {
ShareVault(path, title string) error
}
var (
bgColor = color.NRGBA{R: 242, G: 239, B: 233, A: 255}
panelColor = color.NRGBA{R: 250, G: 248, B: 244, A: 255}
@@ -635,6 +641,7 @@ func newUIWithState(mode string, sess appstate.CurrentSession, paths statePaths)
syncDefaultDirection: syncDirectionPull,
apiPolicyGroupScope: true,
autofillNoticePreference: autofillNoticeAll,
vaultSharer: newPlatformVaultSharer(runtime.GOOS),
backgroundResults: make(chan backgroundActionResult, 8),
phoneGroupBrowserExpanded: true,
}
@@ -772,6 +779,10 @@ func supportsSharedVaultImport(goos string) bool {
return strings.EqualFold(strings.TrimSpace(goos), "android")
}
func supportsVaultShare(goos string) bool {
return strings.EqualFold(strings.TrimSpace(goos), "android")
}
func (u *ui) selectedAttachmentItems() []attachmentItem {
item, ok := u.selectedEntry()
if !ok || len(item.Attachments) == 0 {
@@ -1551,6 +1562,24 @@ func (u *ui) importSharedVaultBytesAction(name string, content []byte) error {
return nil
}
func (u *ui) currentShareableVaultPath() string {
return strings.TrimSpace(u.vaultPath.Text())
}
func (u *ui) shareCurrentVaultAction() error {
if u.vaultSharer == nil {
return fmt.Errorf("vault sharing is not available on this platform")
}
path := u.currentShareableVaultPath()
if path == "" {
return errors.New(errVaultPathRequired)
}
if err := u.state.Save(); err != nil {
return err
}
return u.vaultSharer.ShareVault(path, friendlyRecentVaultLabel(path))
}
func (u *ui) noteRecentVault(path string) {
path = strings.TrimSpace(path)
if path == "" {
@@ -3653,6 +3682,9 @@ func (u *ui) layout(gtx layout.Context) layout.Dimensions {
for u.saveCurrentRemoteBinding.Clicked(gtx) {
u.runAction("save remote binding", u.saveCurrentRemoteBindingAction)
}
for u.shareCurrentVault.Clicked(gtx) {
u.runAction("share vault", u.shareCurrentVaultAction)
}
for u.clearVaultSelection.Clicked(gtx) {
if u.lifecycleBusy() {
continue
@@ -4777,6 +4809,17 @@ func (u *ui) syncMenu(gtx layout.Context) layout.Dimensions {
return lbl.Layout(gtx)
}),
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
if !supportsVaultShare(runtime.GOOS) || u.vaultSharer == nil || strings.TrimSpace(u.currentShareableVaultPath()) == "" {
return layout.Dimensions{}
}
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
return tonedButton(gtx, u.theme, &u.shareCurrentVault, "Share Vault")
}),
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
)
}),
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
return tonedButton(gtx, u.theme, &u.openAdvancedSync, "Open Advanced Sync")
}),