Move sync menu state decisions out of renderers
This commit is contained in:
@@ -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
@@ -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...)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user