Refactor app UI to satisfy gocyclo
This commit is contained in:
@@ -1,8 +1,19 @@
|
|||||||
linters:
|
linters:
|
||||||
enable:
|
enable:
|
||||||
- errcheck
|
- errcheck
|
||||||
|
- gocyclo
|
||||||
- gosimple
|
- gosimple
|
||||||
- govet
|
- govet
|
||||||
- ineffassign
|
- ineffassign
|
||||||
- staticcheck
|
- staticcheck
|
||||||
- unused
|
- unused
|
||||||
|
|
||||||
|
linters-settings:
|
||||||
|
gocyclo:
|
||||||
|
min-complexity: 15
|
||||||
|
|
||||||
|
issues:
|
||||||
|
exclude-rules:
|
||||||
|
- path: _test\.go
|
||||||
|
linters:
|
||||||
|
- gocyclo
|
||||||
|
|||||||
+657
-467
File diff suppressed because it is too large
Load Diff
+147
-233
@@ -22,18 +22,155 @@ func (u *ui) lifecycleControls(gtx layout.Context) layout.Dimensions {
|
|||||||
busy := u.lifecycleBusy()
|
busy := u.lifecycleBusy()
|
||||||
showLocalChooser := u.showLocalVaultChooser()
|
showLocalChooser := u.showLocalVaultChooser()
|
||||||
selectedLocalPath := strings.TrimSpace(u.vaultPath.Text())
|
selectedLocalPath := strings.TrimSpace(u.vaultPath.Text())
|
||||||
advancedSection := func(gtx layout.Context) layout.Dimensions {
|
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
lbl := material.Label(u.theme, unit.Sp(12), "OPEN A VAULT")
|
||||||
|
lbl.Color = mutedColor
|
||||||
|
return lbl.Layout(gtx)
|
||||||
|
}),
|
||||||
|
layout.Rigid(layout.Spacer{Height: unit.Dp(4)}.Layout),
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
message := "Choose a recent vault or enter a .kdbx path, then unlock it. Remote sync attaches to that local vault after it opens."
|
||||||
|
lbl := material.Label(u.theme, unit.Sp(14), message)
|
||||||
|
lbl.Color = accentColor
|
||||||
|
return lbl.Layout(gtx)
|
||||||
|
}),
|
||||||
|
layout.Rigid(layout.Spacer{Height: unit.Dp(8)}.Layout),
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return u.lifecycleVaultChooserSection(gtx, busy, showLocalChooser, selectedLocalPath)
|
||||||
|
}),
|
||||||
|
layout.Rigid(layout.Spacer{Height: unit.Dp(10)}.Layout),
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
lbl := material.Label(u.theme, unit.Sp(12), "UNLOCK")
|
||||||
|
lbl.Color = mutedColor
|
||||||
|
return lbl.Layout(gtx)
|
||||||
|
}),
|
||||||
|
layout.Rigid(layout.Spacer{Height: unit.Dp(4)}.Layout),
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return u.masterPasswordField(gtx, "Leave blank if this vault is protected by key file only.")
|
||||||
|
}),
|
||||||
|
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
if busy {
|
||||||
|
return labeledEditorHelp(u.theme, "Key File", keyFileHelp(), &u.keyFilePath, false)(gtx)
|
||||||
|
}
|
||||||
|
return keyFileSelector(u.theme, &u.keyFilePath, &u.pickKeyFile)(gtx)
|
||||||
|
}),
|
||||||
|
layout.Rigid(layout.Spacer{Height: unit.Dp(8)}.Layout),
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return u.lifecycleControlsFooter(gtx, busy, selectedLocalPath)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *ui) lifecycleVaultChooserSection(gtx layout.Context, busy, showLocalChooser bool, selectedLocalPath string) layout.Dimensions {
|
||||||
|
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
if !showLocalChooser {
|
||||||
|
return layout.Dimensions{}
|
||||||
|
}
|
||||||
|
lbl := material.Label(u.theme, unit.Sp(12), "RECENT VAULTS")
|
||||||
|
lbl.Color = mutedColor
|
||||||
|
return lbl.Layout(gtx)
|
||||||
|
}),
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
if !showLocalChooser {
|
||||||
|
return layout.Dimensions{}
|
||||||
|
}
|
||||||
|
return layout.Spacer{Height: unit.Dp(4)}.Layout(gtx)
|
||||||
|
}),
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
if !showLocalChooser || busy {
|
||||||
|
return layout.Dimensions{}
|
||||||
|
}
|
||||||
|
return u.recentVaultList(gtx)
|
||||||
|
}),
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return u.lifecycleImportSharedVaultButton(gtx, busy, showLocalChooser)
|
||||||
|
}),
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
if !showLocalChooser {
|
||||||
|
return layout.Dimensions{}
|
||||||
|
}
|
||||||
|
return layout.Spacer{Height: unit.Dp(8)}.Layout(gtx)
|
||||||
|
}),
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
if !showLocalChooser {
|
||||||
|
return layout.Dimensions{}
|
||||||
|
}
|
||||||
|
lbl := material.Label(u.theme, unit.Sp(12), "VAULT FILE")
|
||||||
|
lbl.Color = mutedColor
|
||||||
|
return lbl.Layout(gtx)
|
||||||
|
}),
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
if !showLocalChooser {
|
||||||
|
return layout.Dimensions{}
|
||||||
|
}
|
||||||
|
return layout.Spacer{Height: unit.Dp(4)}.Layout(gtx)
|
||||||
|
}),
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return u.lifecycleVaultPathSelector(gtx, busy, selectedLocalPath)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *ui) lifecycleImportSharedVaultButton(gtx layout.Context, busy, showLocalChooser bool) layout.Dimensions {
|
||||||
|
if !showLocalChooser || busy || !supportsSharedVaultImport(runtime.GOOS) {
|
||||||
|
return layout.Dimensions{}
|
||||||
|
}
|
||||||
|
return layout.Flex{Axis: layout.Vertical}.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.importSharedVault, "Import Shared Vault")
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *ui) lifecycleVaultPathSelector(gtx layout.Context, busy bool, selectedLocalPath string) layout.Dimensions {
|
||||||
|
switch {
|
||||||
|
case busy:
|
||||||
|
return labeledEditorHelp(u.theme, "Vault Path", localVaultPathHelp(), &u.vaultPath, false)(gtx)
|
||||||
|
case selectedLocalPath == "":
|
||||||
|
return localPathSelector(u.theme, &u.vaultPath, &u.pickVaultPath)(gtx)
|
||||||
|
default:
|
||||||
|
return layout.Dimensions{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *ui) lifecycleControlsFooter(gtx layout.Context, busy bool, selectedLocalPath string) layout.Dimensions {
|
||||||
|
if u.shouldPrioritizeLifecyclePrimaryActions() {
|
||||||
|
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions { return u.lifecyclePrimaryActionsSection(gtx, busy) }),
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return u.lifecycleSelectedVaultSection(gtx, busy, selectedLocalPath)
|
||||||
|
}),
|
||||||
|
layout.Rigid(layout.Spacer{Height: unit.Dp(8)}.Layout),
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions { return u.lifecycleAdvancedSection(gtx, busy) }),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions { return u.lifecycleAdvancedSection(gtx, busy) }),
|
||||||
|
layout.Rigid(layout.Spacer{Height: unit.Dp(8)}.Layout),
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions { return u.lifecyclePrimaryActionsSection(gtx, busy) }),
|
||||||
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return u.lifecycleSelectedVaultSection(gtx, busy, selectedLocalPath)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *ui) lifecycleAdvancedSection(gtx layout.Context, busy bool) layout.Dimensions {
|
||||||
if busy {
|
if busy {
|
||||||
return layout.Dimensions{}
|
return layout.Dimensions{}
|
||||||
}
|
}
|
||||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||||
layout.Rigid(u.lifecycleAdvancedDisclosure),
|
layout.Rigid(u.lifecycleAdvancedDisclosure),
|
||||||
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(u.lifecycleAdvancedCard),
|
||||||
if u.lifecycleAdvancedHidden {
|
)
|
||||||
return layout.Dimensions{}
|
|
||||||
}
|
}
|
||||||
if u.lifecycleMode == "remote" {
|
|
||||||
|
func (u *ui) lifecycleAdvancedCard(gtx layout.Context) layout.Dimensions {
|
||||||
|
if u.lifecycleAdvancedHidden || u.lifecycleMode == "remote" {
|
||||||
return layout.Dimensions{}
|
return layout.Dimensions{}
|
||||||
}
|
}
|
||||||
return compactCard(gtx, func(gtx layout.Context) layout.Dimensions {
|
return compactCard(gtx, func(gtx layout.Context) layout.Dimensions {
|
||||||
@@ -55,18 +192,14 @@ func (u *ui) lifecycleControls(gtx layout.Context) layout.Dimensions {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
primaryActionsSection := func(gtx layout.Context) layout.Dimensions {
|
|
||||||
|
func (u *ui) lifecyclePrimaryActionsSection(gtx layout.Context, busy bool) 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 {
|
||||||
label := "Open Vault"
|
label := "Open Vault"
|
||||||
if busy {
|
if busy {
|
||||||
label = "Opening Vault..."
|
return passiveTonedButton(gtx, u.theme, "Opening Vault...")
|
||||||
}
|
|
||||||
if busy {
|
|
||||||
return passiveTonedButton(gtx, u.theme, label)
|
|
||||||
}
|
}
|
||||||
return tonedButton(gtx, u.theme, &u.openVault, label)
|
return tonedButton(gtx, u.theme, &u.openVault, label)
|
||||||
}),
|
}),
|
||||||
@@ -97,7 +230,8 @@ func (u *ui) lifecycleControls(gtx layout.Context) layout.Dimensions {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
selectedVaultSection := func(gtx layout.Context) layout.Dimensions {
|
|
||||||
|
func (u *ui) lifecycleSelectedVaultSection(gtx layout.Context, busy bool, selectedLocalPath string) layout.Dimensions {
|
||||||
if busy || selectedLocalPath == "" {
|
if busy || selectedLocalPath == "" {
|
||||||
return layout.Dimensions{}
|
return layout.Dimensions{}
|
||||||
}
|
}
|
||||||
@@ -108,166 +242,11 @@ func (u *ui) lifecycleControls(gtx layout.Context) layout.Dimensions {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
lbl := material.Label(u.theme, unit.Sp(12), "OPEN A VAULT")
|
|
||||||
lbl.Color = mutedColor
|
|
||||||
return lbl.Layout(gtx)
|
|
||||||
}),
|
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(4)}.Layout),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
message := "Choose a recent vault or enter a .kdbx path, then unlock it. Remote sync attaches to that local vault after it opens."
|
|
||||||
lbl := material.Label(u.theme, unit.Sp(14), message)
|
|
||||||
lbl.Color = accentColor
|
|
||||||
return lbl.Layout(gtx)
|
|
||||||
}),
|
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(8)}.Layout),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
if !showLocalChooser {
|
|
||||||
return layout.Dimensions{}
|
|
||||||
}
|
|
||||||
lbl := material.Label(u.theme, unit.Sp(12), "RECENT VAULTS")
|
|
||||||
lbl.Color = mutedColor
|
|
||||||
return lbl.Layout(gtx)
|
|
||||||
}),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
if !showLocalChooser {
|
|
||||||
return layout.Dimensions{}
|
|
||||||
}
|
|
||||||
return layout.Spacer{Height: unit.Dp(4)}.Layout(gtx)
|
|
||||||
}),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
if !showLocalChooser || busy {
|
|
||||||
return layout.Dimensions{}
|
|
||||||
}
|
|
||||||
return u.recentVaultList(gtx)
|
|
||||||
}),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
if !showLocalChooser || busy || !supportsSharedVaultImport(runtime.GOOS) {
|
|
||||||
return layout.Dimensions{}
|
|
||||||
}
|
|
||||||
return layout.Spacer{Height: unit.Dp(6)}.Layout(gtx)
|
|
||||||
}),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
if !showLocalChooser || busy || !supportsSharedVaultImport(runtime.GOOS) {
|
|
||||||
return layout.Dimensions{}
|
|
||||||
}
|
|
||||||
return tonedButton(gtx, u.theme, &u.importSharedVault, "Import Shared Vault")
|
|
||||||
}),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
if !showLocalChooser {
|
|
||||||
return layout.Dimensions{}
|
|
||||||
}
|
|
||||||
return layout.Spacer{Height: unit.Dp(8)}.Layout(gtx)
|
|
||||||
}),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
if !showLocalChooser {
|
|
||||||
return layout.Dimensions{}
|
|
||||||
}
|
|
||||||
lbl := material.Label(u.theme, unit.Sp(12), "VAULT FILE")
|
|
||||||
lbl.Color = mutedColor
|
|
||||||
return lbl.Layout(gtx)
|
|
||||||
}),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
if !showLocalChooser {
|
|
||||||
return layout.Dimensions{}
|
|
||||||
}
|
|
||||||
return layout.Spacer{Height: unit.Dp(4)}.Layout(gtx)
|
|
||||||
}),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
switch {
|
|
||||||
case busy:
|
|
||||||
return labeledEditorHelp(u.theme, "Vault Path", localVaultPathHelp(), &u.vaultPath, false)(gtx)
|
|
||||||
case selectedLocalPath == "":
|
|
||||||
return localPathSelector(u.theme, &u.vaultPath, &u.pickVaultPath)(gtx)
|
|
||||||
default:
|
|
||||||
return layout.Dimensions{}
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}),
|
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(10)}.Layout),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
lbl := material.Label(u.theme, unit.Sp(12), "UNLOCK")
|
|
||||||
lbl.Color = mutedColor
|
|
||||||
return lbl.Layout(gtx)
|
|
||||||
}),
|
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(4)}.Layout),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return u.masterPasswordField(gtx, "Leave blank if this vault is protected by key file only.")
|
|
||||||
}),
|
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
if busy {
|
|
||||||
return labeledEditorHelp(u.theme, "Key File", keyFileHelp(), &u.keyFilePath, false)(gtx)
|
|
||||||
}
|
|
||||||
return keyFileSelector(u.theme, &u.keyFilePath, &u.pickKeyFile)(gtx)
|
|
||||||
}),
|
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(8)}.Layout),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
if u.shouldPrioritizeLifecyclePrimaryActions() {
|
|
||||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
|
||||||
layout.Rigid(primaryActionsSection),
|
|
||||||
layout.Rigid(selectedVaultSection),
|
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(8)}.Layout),
|
|
||||||
layout.Rigid(advancedSection),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
|
||||||
layout.Rigid(advancedSection),
|
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(8)}.Layout),
|
|
||||||
layout.Rigid(primaryActionsSection),
|
|
||||||
layout.Rigid(selectedVaultSection),
|
|
||||||
)
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *ui) shouldPrioritizeLifecyclePrimaryActions() bool {
|
func (u *ui) shouldPrioritizeLifecyclePrimaryActions() bool {
|
||||||
return u.usesCompactViewport()
|
return u.usesCompactViewport()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ui) selectedRemoteConnectionCard(gtx layout.Context) layout.Dimensions {
|
|
||||||
heading := u.selectedRemoteCardHeading()
|
|
||||||
primary := u.selectedRemoteCardPrimaryText()
|
|
||||||
details := u.selectedRemoteCardDetailLines()
|
|
||||||
return compactCard(gtx, func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return layout.UniformInset(unit.Dp(10)).Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
|
||||||
children := []layout.FlexChild{
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
lbl := material.Label(u.theme, unit.Sp(12), heading)
|
|
||||||
lbl.Color = mutedColor
|
|
||||||
return lbl.Layout(gtx)
|
|
||||||
}),
|
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(2)}.Layout),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
lbl := material.Label(u.theme, unit.Sp(14), primary)
|
|
||||||
lbl.Color = accentColor
|
|
||||||
return lbl.Layout(gtx)
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
for _, line := range details {
|
|
||||||
line := line
|
|
||||||
children = append(children, layout.Rigid(layout.Spacer{Height: unit.Dp(2)}.Layout))
|
|
||||||
children = append(children, layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
lbl := material.Label(u.theme, unit.Sp(11), line)
|
|
||||||
lbl.Color = mutedColor
|
|
||||||
return lbl.Layout(gtx)
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
children = append(children,
|
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return tonedButton(gtx, u.theme, &u.clearRemoteSelection, "Open Different Connection")
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx, children...)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *ui) selectedRemoteCardHeading() string {
|
func (u *ui) selectedRemoteCardHeading() string {
|
||||||
if u.selectedRemoteUsesLocalCache() {
|
if u.selectedRemoteUsesLocalCache() {
|
||||||
return "CACHED VAULT"
|
return "CACHED VAULT"
|
||||||
@@ -478,71 +457,6 @@ func (u *ui) recentVaultList(gtx layout.Context) layout.Dimensions {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ui) recentRemoteList(gtx layout.Context) layout.Dimensions {
|
|
||||||
if len(u.recentRemotes) == 0 {
|
|
||||||
return layout.Dimensions{}
|
|
||||||
}
|
|
||||||
if len(u.recentRemoteClicks) < len(u.recentRemotes) {
|
|
||||||
u.recentRemoteClicks = make([]widget.Clickable, len(u.recentRemotes))
|
|
||||||
}
|
|
||||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
lbl := material.Label(u.theme, unit.Sp(12), "RECENT CONNECTIONS")
|
|
||||||
lbl.Color = mutedColor
|
|
||||||
return lbl.Layout(gtx)
|
|
||||||
}),
|
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
maxY := gtx.Dp(unit.Dp(180))
|
|
||||||
if gtx.Constraints.Max.Y > maxY {
|
|
||||||
gtx.Constraints.Max.Y = maxY
|
|
||||||
}
|
|
||||||
if gtx.Constraints.Min.Y > gtx.Constraints.Max.Y {
|
|
||||||
gtx.Constraints.Min.Y = gtx.Constraints.Max.Y
|
|
||||||
}
|
|
||||||
return material.List(u.theme, &u.recentRemoteListState).Layout(gtx, len(u.recentRemotes), func(gtx layout.Context, i int) layout.Dimensions {
|
|
||||||
record := u.recentRemotes[i]
|
|
||||||
label := friendlyRecentRemoteLabel(record)
|
|
||||||
selected := strings.TrimSpace(u.remoteBaseURL.Text()) == record.BaseURL && strings.TrimSpace(u.remotePath.Text()) == record.Path
|
|
||||||
return layout.Inset{Bottom: unit.Dp(6)}.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return recentSelectionCard(gtx, selected, func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return u.recentRemoteClicks[i].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,
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
lbl := material.Label(u.theme, unit.Sp(14), label)
|
|
||||||
lbl.Color = accentColor
|
|
||||||
return lbl.Layout(gtx)
|
|
||||||
}),
|
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(2)}.Layout),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
lbl := material.Label(u.theme, unit.Sp(11), "Path: "+strings.TrimSpace(record.Path))
|
|
||||||
lbl.Color = mutedColor
|
|
||||||
return lbl.Layout(gtx)
|
|
||||||
}),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
lbl := material.Label(u.theme, unit.Sp(11), "Server: "+normalizedRemoteHost(record.BaseURL))
|
|
||||||
lbl.Color = mutedColor
|
|
||||||
return lbl.Layout(gtx)
|
|
||||||
}),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
if len(record.LastGroup) == 0 {
|
|
||||||
return layout.Dimensions{}
|
|
||||||
}
|
|
||||||
lbl := material.Label(u.theme, unit.Sp(11), "Last group: "+strings.Join(u.displayEntryPath(record.LastGroup), " / "))
|
|
||||||
lbl.Color = mutedColor
|
|
||||||
return lbl.Layout(gtx)
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func recentSelectionCard(gtx layout.Context, selected bool, w layout.Widget) layout.Dimensions {
|
func recentSelectionCard(gtx layout.Context, selected bool, w layout.Widget) layout.Dimensions {
|
||||||
if !selected {
|
if !selected {
|
||||||
return compactCard(gtx, w)
|
return compactCard(gtx, w)
|
||||||
|
|||||||
+120
-111
@@ -3,14 +3,15 @@ package appui
|
|||||||
import (
|
import (
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"gioui.org/layout"
|
"gioui.org/layout"
|
||||||
"gioui.org/op"
|
"gioui.org/op"
|
||||||
"gioui.org/unit"
|
"gioui.org/unit"
|
||||||
"gioui.org/widget"
|
"gioui.org/widget"
|
||||||
"gioui.org/widget/material"
|
"gioui.org/widget/material"
|
||||||
|
"git.julianfamily.org/keepassgo/internal/appui/actions"
|
||||||
appuilayout "git.julianfamily.org/keepassgo/internal/appui/layout"
|
appuilayout "git.julianfamily.org/keepassgo/internal/appui/layout"
|
||||||
|
"git.julianfamily.org/keepassgo/internal/vault"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (u *ui) header(gtx layout.Context) layout.Dimensions {
|
func (u *ui) header(gtx layout.Context) layout.Dimensions {
|
||||||
@@ -201,38 +202,58 @@ func (u *ui) syncMenu(gtx layout.Context) layout.Dimensions {
|
|||||||
if len(u.vaultRemoteCredentialClicks) < len(credentials) {
|
if len(u.vaultRemoteCredentialClicks) < len(credentials) {
|
||||||
u.vaultRemoteCredentialClicks = make([]widget.Clickable, len(credentials))
|
u.vaultRemoteCredentialClicks = make([]widget.Clickable, len(credentials))
|
||||||
}
|
}
|
||||||
actionRows := []layout.Widget{
|
actionRows := u.syncMenuActionRows(model)
|
||||||
|
actionWidth := menuActionWidth(gtx, actionRows)
|
||||||
|
return intrinsicCompactCard(gtx, func(gtx layout.Context) layout.Dimensions {
|
||||||
|
rows := u.syncMenuRows(model, profiles, credentials, actionWidth)
|
||||||
|
return layout.Flex{Axis: layout.Vertical}.Layout(gtx, rows...)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *ui) syncMenuActionRows(model actions.SyncMenuModel) []layout.Widget {
|
||||||
|
rows := []layout.Widget{
|
||||||
func(gtx layout.Context) layout.Dimensions {
|
func(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 model.ShowShare {
|
if model.ShowShare {
|
||||||
actionRows = append(actionRows, func(gtx layout.Context) layout.Dimensions {
|
rows = append(rows, 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 model.ShowRemoteSyncSetupShortcut() {
|
if model.ShowRemoteSyncSetupShortcut() {
|
||||||
actionRows = append(actionRows, func(gtx layout.Context) layout.Dimensions {
|
rows = append(rows, func(gtx layout.Context) layout.Dimensions {
|
||||||
return tonedButton(gtx, u.theme, &u.useSavedAdvancedSyncRemote, model.RemoteSyncSetupShortcutLabel())
|
return tonedButton(gtx, u.theme, &u.useSavedAdvancedSyncRemote, model.RemoteSyncSetupShortcutLabel())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if model.ShowDirectRemoteSyncShortcut() {
|
if model.ShowDirectRemoteSyncShortcut() {
|
||||||
actionRows = append(actionRows, func(gtx layout.Context) layout.Dimensions {
|
rows = append(rows, func(gtx layout.Context) layout.Dimensions {
|
||||||
return tonedButton(gtx, u.theme, &u.openSelectedVaultRemote, model.DirectRemoteSyncShortcutLabel())
|
return tonedButton(gtx, u.theme, &u.openSelectedVaultRemote, model.DirectRemoteSyncShortcutLabel())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if model.ShowRemoteSyncSettingsShortcut() {
|
if model.ShowRemoteSyncSettingsShortcut() {
|
||||||
actionRows = append(actionRows, func(gtx layout.Context) layout.Dimensions {
|
rows = append(rows, func(gtx layout.Context) layout.Dimensions {
|
||||||
return tonedButton(gtx, u.theme, &u.useSavedAdvancedSyncRemote, model.RemoteSyncSettingsShortcutLabel())
|
return tonedButton(gtx, u.theme, &u.useSavedAdvancedSyncRemote, model.RemoteSyncSettingsShortcutLabel())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if model.ShowRemoveRemoteSyncShortcut() {
|
if model.ShowRemoveRemoteSyncShortcut() {
|
||||||
actionRows = append(actionRows, func(gtx layout.Context) layout.Dimensions {
|
rows = append(rows, func(gtx layout.Context) layout.Dimensions {
|
||||||
return tonedButton(gtx, u.theme, &u.removeSelectedRemoteBinding, model.RemoveRemoteSyncShortcutLabel())
|
return tonedButton(gtx, u.theme, &u.removeSelectedRemoteBinding, model.RemoveRemoteSyncShortcutLabel())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
actionWidth := menuActionWidth(gtx, actionRows)
|
return rows
|
||||||
return intrinsicCompactCard(gtx, func(gtx layout.Context) layout.Dimensions {
|
}
|
||||||
|
|
||||||
|
func (u *ui) syncMenuRows(model actions.SyncMenuModel, profiles []vault.RemoteProfile, credentials []vault.Entry, actionWidth int) []layout.FlexChild {
|
||||||
|
rows := u.syncMenuPrimaryRows(model, actionWidth)
|
||||||
|
rows = append(rows, u.syncMenuSavedBindingRows(model, profiles, credentials)...)
|
||||||
|
if model.ShowSaveCurrentBinding {
|
||||||
|
rows = append(rows, u.syncMenuSaveBindingRows(model)...)
|
||||||
|
}
|
||||||
|
return rows
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *ui) syncMenuPrimaryRows(model actions.SyncMenuModel, actionWidth int) []layout.FlexChild {
|
||||||
rows := []layout.FlexChild{
|
rows := []layout.FlexChild{
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
lbl := material.Label(u.theme, unit.Sp(11), "Need another source or direction?")
|
lbl := material.Label(u.theme, unit.Sp(11), "Need another source or direction?")
|
||||||
@@ -240,10 +261,9 @@ func (u *ui) syncMenu(gtx layout.Context) layout.Dimensions {
|
|||||||
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),
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
if !model.ShowShare {
|
|
||||||
return layout.Dimensions{}
|
|
||||||
}
|
}
|
||||||
|
if model.ShowShare {
|
||||||
|
rows = append(rows, layout.Rigid(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 {
|
||||||
return rightAlignedMenuAction(gtx, actionWidth, func(gtx layout.Context) layout.Dimensions {
|
return rightAlignedMenuAction(gtx, actionWidth, func(gtx layout.Context) layout.Dimensions {
|
||||||
@@ -252,55 +272,41 @@ 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 {
|
|
||||||
return rightAlignedMenuAction(gtx, actionWidth, func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return tonedButton(gtx, u.theme, &u.openAdvancedSync, "Open Advanced Sync")
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
}
|
}
|
||||||
|
rows = append(rows, u.syncMenuActionRow(actionWidth, &u.openAdvancedSync, "Open Advanced Sync"))
|
||||||
if model.ShowRemoteSyncSetupShortcut() {
|
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),
|
rows = append(rows, u.syncMenuActionRow(actionWidth, &u.useSavedAdvancedSyncRemote, model.RemoteSyncSetupShortcutLabel()))
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return rightAlignedMenuAction(gtx, actionWidth, func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return tonedButton(gtx, u.theme, &u.useSavedAdvancedSyncRemote, model.RemoteSyncSetupShortcutLabel())
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
if model.ShowDirectRemoteSyncShortcut() {
|
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),
|
rows = append(rows, u.syncMenuActionRow(actionWidth, &u.openSelectedVaultRemote, model.DirectRemoteSyncShortcutLabel()))
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return rightAlignedMenuAction(gtx, actionWidth, func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return tonedButton(gtx, u.theme, &u.openSelectedVaultRemote, model.DirectRemoteSyncShortcutLabel())
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
if model.ShowRemoteSyncSettingsShortcut() {
|
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),
|
rows = append(rows, u.syncMenuActionRow(actionWidth, &u.useSavedAdvancedSyncRemote, model.RemoteSyncSettingsShortcutLabel()))
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return rightAlignedMenuAction(gtx, actionWidth, func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return tonedButton(gtx, u.theme, &u.useSavedAdvancedSyncRemote, model.RemoteSyncSettingsShortcutLabel())
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
if model.ShowRemoveRemoteSyncShortcut() {
|
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),
|
rows = append(rows, u.syncMenuActionRow(actionWidth, &u.removeSelectedRemoteBinding, model.RemoveRemoteSyncShortcutLabel()))
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return rightAlignedMenuAction(gtx, actionWidth, func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return tonedButton(gtx, u.theme, &u.removeSelectedRemoteBinding, model.RemoveRemoteSyncShortcutLabel())
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
if u.hasOpenVault() && len(profiles) > 0 && len(credentials) > 0 {
|
return rows
|
||||||
rows = append(rows,
|
}
|
||||||
|
|
||||||
|
func (u *ui) syncMenuActionRow(actionWidth int, click *widget.Clickable, label string) layout.FlexChild {
|
||||||
|
return layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return rightAlignedMenuAction(gtx, actionWidth, func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return tonedButton(gtx, u.theme, click, label)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *ui) syncMenuSavedBindingRows(model actions.SyncMenuModel, profiles []vault.RemoteProfile, credentials []vault.Entry) []layout.FlexChild {
|
||||||
|
if !u.hasOpenVault() || len(profiles) == 0 || len(credentials) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
rows := []layout.FlexChild{
|
||||||
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), model.SavedBindingHeading())
|
lbl := material.Label(u.theme, unit.Sp(11), model.SavedBindingHeading())
|
||||||
@@ -308,10 +314,27 @@ func (u *ui) syncMenu(gtx layout.Context) layout.Dimensions {
|
|||||||
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 !model.ShowSelectors {
|
if !model.ShowSelectors {
|
||||||
|
rows = append(rows, layout.Rigid(u.syncMenuSavedBindingSummary(model)))
|
||||||
|
} else {
|
||||||
|
rows = append(rows, u.syncMenuSelectorRows(model, profiles, credentials)...)
|
||||||
|
}
|
||||||
|
if _, ok := u.selectedVaultRemoteProfile(); ok {
|
||||||
|
if _, ok := u.selectedVaultRemoteCredentialEntry(); ok {
|
||||||
rows = append(rows,
|
rows = append(rows,
|
||||||
|
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 tonedButton(gtx, u.theme, &u.openSelectedVaultRemote, u.openSelectedVaultRemoteButtonLabel())
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rows
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *ui) syncMenuSavedBindingSummary(model actions.SyncMenuModel) layout.Widget {
|
||||||
|
return func(gtx layout.Context) layout.Dimensions {
|
||||||
summary := model.SavedBindingSummary
|
summary := model.SavedBindingSummary
|
||||||
if !summary.OK {
|
if !summary.OK {
|
||||||
return layout.Dimensions{}
|
return layout.Dimensions{}
|
||||||
@@ -339,64 +362,11 @@ func (u *ui) syncMenu(gtx layout.Context) layout.Dimensions {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
for i, profile := range profiles {
|
|
||||||
i := i
|
|
||||||
profile := profile
|
|
||||||
rows = append(rows,
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
selected := strings.TrimSpace(u.selectedVaultRemoteProfileID) == profile.ID
|
|
||||||
return layout.Inset{Bottom: unit.Dp(4)}.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return recentSelectionCard(gtx, selected, func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return u.vaultRemoteProfileClicks[i].Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
|
||||||
lbl := material.Label(u.theme, unit.Sp(13), profile.Name)
|
|
||||||
lbl.Color = accentColor
|
|
||||||
return lbl.Layout(gtx)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
rows = append(rows, layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout))
|
|
||||||
for i, entry := range credentials {
|
|
||||||
i := i
|
|
||||||
entry := entry
|
|
||||||
rows = append(rows,
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
selected := strings.TrimSpace(u.selectedVaultRemoteCredentialEntryID) == entry.ID
|
|
||||||
label := entry.Title
|
|
||||||
if strings.TrimSpace(entry.Username) != "" {
|
|
||||||
label += " · " + strings.TrimSpace(entry.Username)
|
|
||||||
}
|
|
||||||
return layout.Inset{Bottom: unit.Dp(4)}.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return recentSelectionCard(gtx, selected, func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return u.vaultRemoteCredentialClicks[i].Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
|
||||||
lbl := material.Label(u.theme, unit.Sp(13), label)
|
|
||||||
lbl.Color = accentColor
|
|
||||||
return lbl.Layout(gtx)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if _, ok := u.selectedVaultRemoteProfile(); ok {
|
|
||||||
if _, ok := u.selectedVaultRemoteCredentialEntry(); ok {
|
func (u *ui) syncMenuSaveBindingRows(model actions.SyncMenuModel) []layout.FlexChild {
|
||||||
rows = append(rows,
|
return []layout.FlexChild{
|
||||||
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
|
|
||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
|
||||||
return tonedButton(gtx, u.theme, &u.openSelectedVaultRemote, u.openSelectedVaultRemoteButtonLabel())
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if model.ShowSaveCurrentBinding {
|
|
||||||
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), model.SaveCurrentRemoteBindingHeading())
|
lbl := material.Label(u.theme, unit.Sp(11), model.SaveCurrentRemoteBindingHeading())
|
||||||
@@ -407,10 +377,49 @@ func (u *ui) syncMenu(gtx layout.Context) layout.Dimensions {
|
|||||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
return tonedButton(gtx, u.theme, &u.saveCurrentRemoteBinding, model.SaveCurrentRemoteBindingButtonLabel())
|
return tonedButton(gtx, u.theme, &u.saveCurrentRemoteBinding, model.SaveCurrentRemoteBindingButtonLabel())
|
||||||
}),
|
}),
|
||||||
)
|
|
||||||
}
|
}
|
||||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx, rows...)
|
}
|
||||||
|
|
||||||
|
func (u *ui) syncMenuSelectorRows(_ actions.SyncMenuModel, profiles []vault.RemoteProfile, credentials []vault.Entry) []layout.FlexChild {
|
||||||
|
rows := make([]layout.FlexChild, 0, len(profiles)+len(credentials)+4)
|
||||||
|
for i, profile := range profiles {
|
||||||
|
i := i
|
||||||
|
profile := profile
|
||||||
|
rows = append(rows, layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
selected := u.selectedVaultRemoteProfileID == profile.ID
|
||||||
|
return layout.Inset{Bottom: unit.Dp(4)}.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return recentSelectionCard(gtx, selected, func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return u.vaultRemoteProfileClicks[i].Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
||||||
|
lbl := material.Label(u.theme, unit.Sp(13), profile.Name)
|
||||||
|
lbl.Color = accentColor
|
||||||
|
return lbl.Layout(gtx)
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
rows = append(rows, layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout))
|
||||||
|
for i, entry := range credentials {
|
||||||
|
i := i
|
||||||
|
entry := entry
|
||||||
|
rows = append(rows, layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||||
|
selected := u.selectedVaultRemoteCredentialEntryID == entry.ID
|
||||||
|
label := entry.Title
|
||||||
|
if entry.Username != "" {
|
||||||
|
label += " · " + entry.Username
|
||||||
|
}
|
||||||
|
return layout.Inset{Bottom: unit.Dp(4)}.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return recentSelectionCard(gtx, selected, func(gtx layout.Context) layout.Dimensions {
|
||||||
|
return u.vaultRemoteCredentialClicks[i].Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
||||||
|
lbl := material.Label(u.theme, unit.Sp(13), label)
|
||||||
|
lbl.Color = accentColor
|
||||||
|
return lbl.Layout(gtx)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
return rows
|
||||||
}
|
}
|
||||||
|
|
||||||
func intrinsicCompactCard(gtx layout.Context, w layout.Widget) layout.Dimensions {
|
func intrinsicCompactCard(gtx layout.Context, w layout.Widget) layout.Dimensions {
|
||||||
|
|||||||
Reference in New Issue
Block a user