Move sync menu state decisions out of renderers

This commit is contained in:
Joe Julian
2026-04-08 23:27:47 -07:00
parent 9660369851
commit 16f603ccba
3 changed files with 196 additions and 97 deletions
+15 -52
View File
@@ -2740,98 +2740,61 @@ func (u *ui) shouldShowSavedRemoteBindingSelectors() bool {
} }
func (u *ui) savedRemoteBindingSummary() (profileLabel, credentialLabel, syncLabel string, ok bool) { func (u *ui) savedRemoteBindingSummary() (profileLabel, credentialLabel, syncLabel string, ok bool) {
profile, ok := u.selectedVaultRemoteProfile() summary := u.computeSavedRemoteBindingSummary()
if !ok { return summary.profileLabel, summary.credentialLabel, summary.syncLabel, summary.ok
return "", "", "", false
}
entry, ok := u.selectedVaultRemoteCredentialEntry()
if !ok {
return "", "", "", false
}
credentialLabel = entry.Title
if strings.TrimSpace(entry.Username) != "" {
credentialLabel += " · " + strings.TrimSpace(entry.Username)
}
syncLabel = "Sync manually when you choose Use Remote Sync."
if normalizeUISyncMode(u.selectedVaultRemoteSyncMode) == appstate.SyncModeAutomaticOnOpenSave {
syncLabel = "Syncs automatically on open and save."
}
return profile.Name, credentialLabel, syncLabel, true
} }
func (u *ui) savedRemoteBindingHeading() string { func (u *ui) savedRemoteBindingHeading() string {
if !u.shouldShowSavedRemoteBindingSelectors() { return u.buildSyncMenuModel().savedBindingHeading()
return "Use this vault's saved remote sync target"
}
return "Use a saved remote profile from this vault"
} }
func (u *ui) openSelectedVaultRemoteButtonLabel() string { func (u *ui) openSelectedVaultRemoteButtonLabel() string {
if !u.shouldShowSavedRemoteBindingSelectors() { return u.buildSyncMenuModel().openSelectedButtonLabel()
return "Use Remote Sync"
}
return "Open Saved Remote"
} }
func (u *ui) shouldShowDirectRemoteSyncShortcut() bool { func (u *ui) shouldShowDirectRemoteSyncShortcut() bool {
if !u.hasOpenVault() || u.isVaultLocked() || u.state.Section != appstate.SectionEntries { if !u.hasOpenVault() || u.isVaultLocked() || u.state.Section != appstate.SectionEntries {
return false return false
} }
_, ok := u.selectedVaultRemoteBinding() return u.buildSyncMenuModel().showDirectRemoteSyncShortcut()
return ok
} }
func (u *ui) directRemoteSyncShortcutLabel() string { func (u *ui) directRemoteSyncShortcutLabel() string {
return "Use Remote Sync" return u.buildSyncMenuModel().directRemoteSyncShortcutLabel()
} }
func (u *ui) shouldShowRemoteSyncSettingsShortcut() bool { func (u *ui) shouldShowRemoteSyncSettingsShortcut() bool {
if !u.hasOpenVault() || u.isVaultLocked() || u.state.Section != appstate.SectionEntries { if !u.hasOpenVault() || u.isVaultLocked() || u.state.Section != appstate.SectionEntries {
return false return false
} }
_, ok := u.selectedVaultRemoteBinding() return u.buildSyncMenuModel().showRemoteSyncSettingsShortcut()
return ok
} }
func (u *ui) remoteSyncSettingsShortcutLabel() string { func (u *ui) remoteSyncSettingsShortcutLabel() string {
return "Remote Sync Settings" return u.buildSyncMenuModel().remoteSyncSettingsShortcutLabel()
} }
func (u *ui) shouldShowRemoveRemoteSyncShortcut() bool { func (u *ui) shouldShowRemoveRemoteSyncShortcut() bool {
return u.shouldShowRemoteSyncSettingsShortcut() return u.buildSyncMenuModel().showRemoveRemoteSyncShortcut()
} }
func (u *ui) removeRemoteSyncShortcutLabel() string { func (u *ui) removeRemoteSyncShortcutLabel() string {
return "Stop Using Remote Sync" return u.buildSyncMenuModel().removeRemoteSyncShortcutLabel()
} }
func (u *ui) shouldShowRemoteSyncSetupShortcut() bool { func (u *ui) shouldShowRemoteSyncSetupShortcut() bool {
if !u.hasOpenVault() || u.isVaultLocked() || u.state.Section != appstate.SectionEntries { if !u.hasOpenVault() || u.isVaultLocked() || u.state.Section != appstate.SectionEntries {
return false return false
} }
_, ok := u.selectedVaultRemoteBinding() return u.buildSyncMenuModel().showRemoteSyncSetupShortcut()
return !ok
} }
func (u *ui) remoteSyncSetupShortcutLabel() string { func (u *ui) remoteSyncSetupShortcutLabel() string {
return "Set Up Remote Sync" return u.buildSyncMenuModel().remoteSyncSetupShortcutLabel()
} }
func (u *ui) syncMenuActionLabels() []string { func (u *ui) syncMenuActionLabels() []string {
labels := []string{"Open Advanced Sync"} return u.buildSyncMenuModel().actionLabels()
if u.shouldShowRemoteSyncSetupShortcut() {
labels = append(labels, u.remoteSyncSetupShortcutLabel())
}
if u.shouldShowDirectRemoteSyncShortcut() {
labels = append(labels, u.directRemoteSyncShortcutLabel())
}
if u.shouldShowRemoteSyncSettingsShortcut() {
labels = append(labels, u.remoteSyncSettingsShortcutLabel())
}
if u.shouldShowRemoveRemoteSyncShortcut() {
labels = append(labels, u.removeRemoteSyncShortcutLabel())
}
return labels
} }
func remoteBindingSuffix(baseURL, path, username string) string { func remoteBindingSuffix(baseURL, path, username string) string {
@@ -2939,11 +2902,11 @@ func (u *ui) removeSelectedRemoteBindingAction() error {
} }
func (u *ui) saveCurrentRemoteBindingHeading() string { func (u *ui) saveCurrentRemoteBindingHeading() string {
return "Bind this local vault to the current remote target" return u.buildSyncMenuModel().saveCurrentRemoteBindingHeading()
} }
func (u *ui) saveCurrentRemoteBindingButtonLabel() string { func (u *ui) saveCurrentRemoteBindingButtonLabel() string {
return "Save Remote In Vault" return u.buildSyncMenuModel().saveCurrentRemoteBindingButtonLabel()
} }
func (u *ui) materializeCurrentRemoteCache() error { func (u *ui) materializeCurrentRemoteCache() error {
+39 -45
View File
@@ -3,7 +3,6 @@ package main
import ( import (
"image" "image"
"image/color" "image/color"
"runtime"
"strings" "strings"
"gioui.org/layout" "gioui.org/layout"
@@ -192,6 +191,7 @@ func (u *ui) syncMenuToggle(gtx layout.Context) layout.Dimensions {
} }
func (u *ui) syncMenu(gtx layout.Context) layout.Dimensions { func (u *ui) syncMenu(gtx layout.Context) layout.Dimensions {
model := u.buildSyncMenuModel()
profiles := u.availableRemoteProfiles() profiles := u.availableRemoteProfiles()
credentials := u.availableRemoteCredentialEntries() credentials := u.availableRemoteCredentialEntries()
if len(u.vaultRemoteProfileClicks) < len(profiles) { if len(u.vaultRemoteProfileClicks) < len(profiles) {
@@ -205,29 +205,29 @@ func (u *ui) syncMenu(gtx layout.Context) layout.Dimensions {
return tonedButton(gtx, u.theme, &u.openAdvancedSync, "Open Advanced Sync") return tonedButton(gtx, u.theme, &u.openAdvancedSync, "Open Advanced Sync")
}, },
} }
if supportsVaultShare(runtime.GOOS) && u.vaultSharer != nil && strings.TrimSpace(u.currentShareableVaultPath()) != "" { if model.showShare {
actionRows = append(actionRows, func(gtx layout.Context) layout.Dimensions { actionRows = append(actionRows, func(gtx layout.Context) layout.Dimensions {
return tonedButton(gtx, u.theme, &u.shareCurrentVault, "Share Vault") return tonedButton(gtx, u.theme, &u.shareCurrentVault, "Share Vault")
}) })
} }
if u.shouldShowRemoteSyncSetupShortcut() { if model.showRemoteSyncSetupShortcut() {
actionRows = append(actionRows, func(gtx layout.Context) layout.Dimensions { actionRows = append(actionRows, func(gtx layout.Context) layout.Dimensions {
return tonedButton(gtx, u.theme, &u.useSavedAdvancedSyncRemote, u.remoteSyncSetupShortcutLabel()) return tonedButton(gtx, u.theme, &u.useSavedAdvancedSyncRemote, model.remoteSyncSetupShortcutLabel())
}) })
} }
if u.shouldShowDirectRemoteSyncShortcut() { if model.showDirectRemoteSyncShortcut() {
actionRows = append(actionRows, func(gtx layout.Context) layout.Dimensions { actionRows = append(actionRows, func(gtx layout.Context) layout.Dimensions {
return tonedButton(gtx, u.theme, &u.openSelectedVaultRemote, u.directRemoteSyncShortcutLabel()) return tonedButton(gtx, u.theme, &u.openSelectedVaultRemote, model.directRemoteSyncShortcutLabel())
}) })
} }
if u.shouldShowRemoteSyncSettingsShortcut() { if model.showRemoteSyncSettingsShortcut() {
actionRows = append(actionRows, func(gtx layout.Context) layout.Dimensions { actionRows = append(actionRows, func(gtx layout.Context) layout.Dimensions {
return tonedButton(gtx, u.theme, &u.useSavedAdvancedSyncRemote, u.remoteSyncSettingsShortcutLabel()) return tonedButton(gtx, u.theme, &u.useSavedAdvancedSyncRemote, model.remoteSyncSettingsShortcutLabel())
}) })
} }
if u.shouldShowRemoveRemoteSyncShortcut() { if model.showRemoveRemoteSyncShortcut() {
actionRows = append(actionRows, func(gtx layout.Context) layout.Dimensions { actionRows = append(actionRows, func(gtx layout.Context) layout.Dimensions {
return tonedButton(gtx, u.theme, &u.removeSelectedRemoteBinding, u.removeRemoteSyncShortcutLabel()) return tonedButton(gtx, u.theme, &u.removeSelectedRemoteBinding, model.removeRemoteSyncShortcutLabel())
}) })
} }
actionWidth := menuActionWidth(gtx, actionRows) actionWidth := menuActionWidth(gtx, actionRows)
@@ -240,7 +240,7 @@ func (u *ui) syncMenu(gtx layout.Context) layout.Dimensions {
}), }),
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout), layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
layout.Rigid(func(gtx layout.Context) layout.Dimensions { layout.Rigid(func(gtx layout.Context) layout.Dimensions {
if !supportsVaultShare(runtime.GOOS) || u.vaultSharer == nil || strings.TrimSpace(u.currentShareableVaultPath()) == "" { if !model.showShare {
return layout.Dimensions{} return layout.Dimensions{}
} }
return layout.Flex{Axis: layout.Vertical}.Layout(gtx, return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
@@ -258,42 +258,42 @@ func (u *ui) syncMenu(gtx layout.Context) layout.Dimensions {
}) })
}), }),
} }
if u.shouldShowRemoteSyncSetupShortcut() { if model.showRemoteSyncSetupShortcut() {
rows = append(rows, rows = append(rows,
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout), layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
layout.Rigid(func(gtx layout.Context) layout.Dimensions { layout.Rigid(func(gtx layout.Context) layout.Dimensions {
return rightAlignedMenuAction(gtx, actionWidth, func(gtx layout.Context) layout.Dimensions { return rightAlignedMenuAction(gtx, actionWidth, func(gtx layout.Context) layout.Dimensions {
return tonedButton(gtx, u.theme, &u.useSavedAdvancedSyncRemote, u.remoteSyncSetupShortcutLabel()) return tonedButton(gtx, u.theme, &u.useSavedAdvancedSyncRemote, model.remoteSyncSetupShortcutLabel())
}) })
}), }),
) )
} }
if u.shouldShowDirectRemoteSyncShortcut() { if model.showDirectRemoteSyncShortcut() {
rows = append(rows, rows = append(rows,
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout), layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
layout.Rigid(func(gtx layout.Context) layout.Dimensions { layout.Rigid(func(gtx layout.Context) layout.Dimensions {
return rightAlignedMenuAction(gtx, actionWidth, func(gtx layout.Context) layout.Dimensions { return rightAlignedMenuAction(gtx, actionWidth, func(gtx layout.Context) layout.Dimensions {
return tonedButton(gtx, u.theme, &u.openSelectedVaultRemote, u.directRemoteSyncShortcutLabel()) return tonedButton(gtx, u.theme, &u.openSelectedVaultRemote, model.directRemoteSyncShortcutLabel())
}) })
}), }),
) )
} }
if u.shouldShowRemoteSyncSettingsShortcut() { if model.showRemoteSyncSettingsShortcut() {
rows = append(rows, rows = append(rows,
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout), layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
layout.Rigid(func(gtx layout.Context) layout.Dimensions { layout.Rigid(func(gtx layout.Context) layout.Dimensions {
return rightAlignedMenuAction(gtx, actionWidth, func(gtx layout.Context) layout.Dimensions { return rightAlignedMenuAction(gtx, actionWidth, func(gtx layout.Context) layout.Dimensions {
return tonedButton(gtx, u.theme, &u.useSavedAdvancedSyncRemote, u.remoteSyncSettingsShortcutLabel()) return tonedButton(gtx, u.theme, &u.useSavedAdvancedSyncRemote, model.remoteSyncSettingsShortcutLabel())
}) })
}), }),
) )
} }
if u.shouldShowRemoveRemoteSyncShortcut() { if model.showRemoveRemoteSyncShortcut() {
rows = append(rows, rows = append(rows,
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout), layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
layout.Rigid(func(gtx layout.Context) layout.Dimensions { layout.Rigid(func(gtx layout.Context) layout.Dimensions {
return rightAlignedMenuAction(gtx, actionWidth, func(gtx layout.Context) layout.Dimensions { return rightAlignedMenuAction(gtx, actionWidth, func(gtx layout.Context) layout.Dimensions {
return tonedButton(gtx, u.theme, &u.removeSelectedRemoteBinding, u.removeRemoteSyncShortcutLabel()) return tonedButton(gtx, u.theme, &u.removeSelectedRemoteBinding, model.removeRemoteSyncShortcutLabel())
}) })
}), }),
) )
@@ -302,36 +302,36 @@ func (u *ui) syncMenu(gtx layout.Context) layout.Dimensions {
rows = append(rows, rows = append(rows,
layout.Rigid(layout.Spacer{Height: unit.Dp(10)}.Layout), layout.Rigid(layout.Spacer{Height: unit.Dp(10)}.Layout),
layout.Rigid(func(gtx layout.Context) layout.Dimensions { layout.Rigid(func(gtx layout.Context) layout.Dimensions {
lbl := material.Label(u.theme, unit.Sp(11), u.savedRemoteBindingHeading()) lbl := material.Label(u.theme, unit.Sp(11), model.savedBindingHeading())
lbl.Color = mutedColor lbl.Color = mutedColor
return lbl.Layout(gtx) return lbl.Layout(gtx)
}), }),
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout), layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
) )
if !u.shouldShowSavedRemoteBindingSelectors() { if !model.showSelectors {
rows = append(rows, rows = append(rows,
layout.Rigid(func(gtx layout.Context) layout.Dimensions { layout.Rigid(func(gtx layout.Context) layout.Dimensions {
profileLabel, credentialLabel, syncLabel, ok := u.savedRemoteBindingSummary() summary := model.savedBindingSummary
if !ok { if !summary.ok {
return layout.Dimensions{} return layout.Dimensions{}
} }
return layout.Background{}.Layout(gtx, fill(color.NRGBA{R: 242, G: 245, B: 240, A: 255}), func(gtx layout.Context) layout.Dimensions { return layout.Background{}.Layout(gtx, fill(color.NRGBA{R: 242, G: 245, B: 240, A: 255}), func(gtx layout.Context) layout.Dimensions {
return layout.UniformInset(unit.Dp(10)).Layout(gtx, func(gtx layout.Context) layout.Dimensions { return layout.UniformInset(unit.Dp(10)).Layout(gtx, func(gtx layout.Context) layout.Dimensions {
return layout.Flex{Axis: layout.Vertical}.Layout(gtx, return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
layout.Rigid(func(gtx layout.Context) layout.Dimensions { layout.Rigid(func(gtx layout.Context) layout.Dimensions {
lbl := material.Label(u.theme, unit.Sp(13), profileLabel) lbl := material.Label(u.theme, unit.Sp(13), summary.profileLabel)
lbl.Color = accentColor lbl.Color = accentColor
return lbl.Layout(gtx) return lbl.Layout(gtx)
}), }),
layout.Rigid(layout.Spacer{Height: unit.Dp(2)}.Layout), layout.Rigid(layout.Spacer{Height: unit.Dp(2)}.Layout),
layout.Rigid(func(gtx layout.Context) layout.Dimensions { layout.Rigid(func(gtx layout.Context) layout.Dimensions {
lbl := material.Label(u.theme, unit.Sp(12), "Credential: "+credentialLabel) lbl := material.Label(u.theme, unit.Sp(12), "Credential: "+summary.credentialLabel)
lbl.Color = mutedColor lbl.Color = mutedColor
return lbl.Layout(gtx) return lbl.Layout(gtx)
}), }),
layout.Rigid(layout.Spacer{Height: unit.Dp(2)}.Layout), layout.Rigid(layout.Spacer{Height: unit.Dp(2)}.Layout),
layout.Rigid(func(gtx layout.Context) layout.Dimensions { layout.Rigid(func(gtx layout.Context) layout.Dimensions {
lbl := material.Label(u.theme, unit.Sp(12), syncLabel) lbl := material.Label(u.theme, unit.Sp(12), summary.syncLabel)
lbl.Color = mutedColor lbl.Color = mutedColor
return lbl.Layout(gtx) return lbl.Layout(gtx)
}), }),
@@ -394,25 +394,19 @@ func (u *ui) syncMenu(gtx layout.Context) layout.Dimensions {
} }
} }
} }
if u.hasOpenVault() { if model.showSaveCurrentBinding {
baseURL := strings.TrimSpace(u.remoteBaseURL.Text()) rows = append(rows,
remotePath := strings.TrimSpace(u.remotePath.Text()) layout.Rigid(layout.Spacer{Height: unit.Dp(10)}.Layout),
username := strings.TrimSpace(u.remoteUsername.Text()) layout.Rigid(func(gtx layout.Context) layout.Dimensions {
password := u.remotePassword.Text() lbl := material.Label(u.theme, unit.Sp(11), model.saveCurrentRemoteBindingHeading())
if baseURL != "" && remotePath != "" && username != "" && password != "" { lbl.Color = mutedColor
rows = append(rows, return lbl.Layout(gtx)
layout.Rigid(layout.Spacer{Height: unit.Dp(10)}.Layout), }),
layout.Rigid(func(gtx layout.Context) layout.Dimensions { layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
lbl := material.Label(u.theme, unit.Sp(11), u.saveCurrentRemoteBindingHeading()) layout.Rigid(func(gtx layout.Context) layout.Dimensions {
lbl.Color = mutedColor return tonedButton(gtx, u.theme, &u.saveCurrentRemoteBinding, model.saveCurrentRemoteBindingButtonLabel())
return lbl.Layout(gtx) }),
}), )
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
return tonedButton(gtx, u.theme, &u.saveCurrentRemoteBinding, u.saveCurrentRemoteBindingButtonLabel())
}),
)
}
} }
return layout.Flex{Axis: layout.Vertical}.Layout(gtx, rows...) return layout.Flex{Axis: layout.Vertical}.Layout(gtx, rows...)
}) })
+142
View File
@@ -0,0 +1,142 @@
package main
import (
"runtime"
"strings"
"git.julianfamily.org/keepassgo/appstate"
)
type syncMenuModel struct {
hasOpenVault bool
hasSelectedBinding bool
showSelectors bool
showShare bool
showSaveCurrentBinding bool
savedBindingSummary syncMenuBindingSummary
remoteBaseURL string
remotePath string
remoteUsername string
remotePassword string
selectedVaultSyncMode appstate.SyncMode
}
type syncMenuBindingSummary struct {
profileLabel string
credentialLabel string
syncLabel string
ok bool
}
func (u *ui) buildSyncMenuModel() syncMenuModel {
model := syncMenuModel{
hasOpenVault: u.hasOpenVault(),
showSelectors: u.shouldShowSavedRemoteBindingSelectors(),
showShare: supportsVaultShare(runtime.GOOS) && u.vaultSharer != nil && strings.TrimSpace(u.currentShareableVaultPath()) != "",
remoteBaseURL: strings.TrimSpace(u.remoteBaseURL.Text()),
remotePath: strings.TrimSpace(u.remotePath.Text()),
remoteUsername: strings.TrimSpace(u.remoteUsername.Text()),
remotePassword: u.remotePassword.Text(),
selectedVaultSyncMode: normalizeUISyncMode(u.selectedVaultRemoteSyncMode),
}
_, model.hasSelectedBinding = u.selectedVaultRemoteBinding()
model.savedBindingSummary = u.computeSavedRemoteBindingSummary()
model.showSaveCurrentBinding = model.hasOpenVault && model.remoteBaseURL != "" && model.remotePath != "" && model.remoteUsername != "" && model.remotePassword != ""
return model
}
func (u *ui) computeSavedRemoteBindingSummary() syncMenuBindingSummary {
profile, ok := u.selectedVaultRemoteProfile()
if !ok {
return syncMenuBindingSummary{}
}
entry, ok := u.selectedVaultRemoteCredentialEntry()
if !ok {
return syncMenuBindingSummary{}
}
credentialLabel := entry.Title
if strings.TrimSpace(entry.Username) != "" {
credentialLabel += " · " + strings.TrimSpace(entry.Username)
}
syncLabel := "Sync manually when you choose Use Remote Sync."
if normalizeUISyncMode(u.selectedVaultRemoteSyncMode) == appstate.SyncModeAutomaticOnOpenSave {
syncLabel = "Syncs automatically on open and save."
}
return syncMenuBindingSummary{
profileLabel: profile.Name,
credentialLabel: credentialLabel,
syncLabel: syncLabel,
ok: true,
}
}
func (m syncMenuModel) savedBindingHeading() string {
if !m.showSelectors {
return "Use this vault's saved remote sync target"
}
return "Use a saved remote profile from this vault"
}
func (m syncMenuModel) openSelectedButtonLabel() string {
if !m.showSelectors {
return "Use Remote Sync"
}
return "Open Saved Remote"
}
func (m syncMenuModel) showDirectRemoteSyncShortcut() bool {
return m.hasOpenVault && m.hasSelectedBinding
}
func (m syncMenuModel) directRemoteSyncShortcutLabel() string {
return "Use Remote Sync"
}
func (m syncMenuModel) showRemoteSyncSettingsShortcut() bool {
return m.hasOpenVault && m.hasSelectedBinding
}
func (m syncMenuModel) remoteSyncSettingsShortcutLabel() string {
return "Remote Sync Settings"
}
func (m syncMenuModel) showRemoveRemoteSyncShortcut() bool {
return m.showRemoteSyncSettingsShortcut()
}
func (m syncMenuModel) removeRemoteSyncShortcutLabel() string {
return "Stop Using Remote Sync"
}
func (m syncMenuModel) showRemoteSyncSetupShortcut() bool {
return m.hasOpenVault && !m.hasSelectedBinding
}
func (m syncMenuModel) remoteSyncSetupShortcutLabel() string {
return "Set Up Remote Sync"
}
func (m syncMenuModel) actionLabels() []string {
labels := []string{"Open Advanced Sync"}
if m.showRemoteSyncSetupShortcut() {
labels = append(labels, m.remoteSyncSetupShortcutLabel())
}
if m.showDirectRemoteSyncShortcut() {
labels = append(labels, m.directRemoteSyncShortcutLabel())
}
if m.showRemoteSyncSettingsShortcut() {
labels = append(labels, m.remoteSyncSettingsShortcutLabel())
}
if m.showRemoveRemoteSyncShortcut() {
labels = append(labels, m.removeRemoteSyncShortcutLabel())
}
return labels
}
func (m syncMenuModel) saveCurrentRemoteBindingHeading() string {
return "Bind this local vault to the current remote target"
}
func (m syncMenuModel) saveCurrentRemoteBindingButtonLabel() string {
return "Save Remote In Vault"
}