Refine entry detail and edit panels
This commit is contained in:
@@ -299,6 +299,7 @@ type ui struct {
|
||||
syncedPath []string
|
||||
selectedHistoryIndex int
|
||||
showPassword bool
|
||||
generatedPasswordDraft bool
|
||||
togglePassword widget.Clickable
|
||||
copyAPITokenSecret widget.Clickable
|
||||
issueAPIToken widget.Clickable
|
||||
@@ -3719,11 +3720,11 @@ func (u *ui) detailPanelContent(gtx layout.Context) layout.Dimensions {
|
||||
password := u.detailPasswordValue()
|
||||
titleSize := unit.Sp(26)
|
||||
titlePad := unit.Dp(10)
|
||||
sectionGap := unit.Dp(8)
|
||||
sectionGap := unit.Dp(6)
|
||||
if u.mode == "phone" {
|
||||
titleSize = unit.Sp(18)
|
||||
titlePad = unit.Dp(6)
|
||||
sectionGap = unit.Dp(6)
|
||||
titlePad = unit.Dp(4)
|
||||
sectionGap = unit.Dp(4)
|
||||
}
|
||||
rows := []layout.Widget{
|
||||
func(gtx layout.Context) layout.Dimensions {
|
||||
@@ -3765,72 +3766,87 @@ func (u *ui) detailPanelContent(gtx layout.Context) layout.Dimensions {
|
||||
}
|
||||
return 0
|
||||
}()}.Layout,
|
||||
detailLine(u.theme, "Path", strings.Join(u.displayEntryPath(item.Path), " / ")),
|
||||
layout.Spacer{Height: sectionGap}.Layout,
|
||||
detailLine(u.theme, "Username", item.Username),
|
||||
layout.Spacer{Height: sectionGap}.Layout,
|
||||
u.passwordLine("Password", password),
|
||||
layout.Spacer{Height: sectionGap}.Layout,
|
||||
detailLine(u.theme, "URL", item.URL),
|
||||
layout.Spacer{Height: sectionGap}.Layout,
|
||||
detailLine(u.theme, "Tags", strings.Join(item.Tags, ", ")),
|
||||
layout.Spacer{Height: unit.Dp(10)}.Layout,
|
||||
func(gtx layout.Context) layout.Dimensions {
|
||||
lbl := material.Label(u.theme, unit.Sp(12), "Quick actions")
|
||||
lbl.Color = mutedColor
|
||||
return lbl.Layout(gtx)
|
||||
return compactCard(gtx, func(gtx layout.Context) layout.Dimensions {
|
||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||
layout.Rigid(detailLine(u.theme, "Path", strings.Join(u.displayEntryPath(item.Path), " / "))),
|
||||
layout.Rigid(layout.Spacer{Height: sectionGap}.Layout),
|
||||
layout.Rigid(detailLine(u.theme, "Username", item.Username)),
|
||||
layout.Rigid(layout.Spacer{Height: sectionGap}.Layout),
|
||||
layout.Rigid(detailLine(u.theme, "URL", item.URL)),
|
||||
layout.Rigid(layout.Spacer{Height: sectionGap}.Layout),
|
||||
layout.Rigid(detailLine(u.theme, "Tags", strings.Join(item.Tags, ", "))),
|
||||
)
|
||||
})
|
||||
},
|
||||
layout.Spacer{Height: unit.Dp(6)}.Layout,
|
||||
layout.Spacer{Height: sectionGap}.Layout,
|
||||
func(gtx layout.Context) layout.Dimensions {
|
||||
if u.mode == "phone" {
|
||||
return compactCard(gtx, func(gtx layout.Context) layout.Dimensions {
|
||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
return tonedButton(gtx, u.theme, &u.copyUser, "Copy User")
|
||||
lbl := material.Label(u.theme, unit.Sp(12), "PASSWORD")
|
||||
lbl.Color = mutedColor
|
||||
return lbl.Layout(gtx)
|
||||
}),
|
||||
layout.Rigid(layout.Spacer{Height: unit.Dp(4)}.Layout),
|
||||
layout.Rigid(u.passwordLine("Password", password)),
|
||||
layout.Rigid(layout.Spacer{Height: unit.Dp(8)}.Layout),
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
return tonedButton(gtx, u.theme, &u.copyPass, "Copy Password")
|
||||
}),
|
||||
layout.Rigid(layout.Spacer{Height: unit.Dp(8)}.Layout),
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
return tonedButton(gtx, u.theme, &u.copyURL, "Copy URL")
|
||||
if u.mode == "phone" {
|
||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
return tonedButton(gtx, u.theme, &u.copyPass, "Copy Password")
|
||||
}),
|
||||
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
return tonedButton(gtx, u.theme, &u.copyUser, "Copy Username")
|
||||
}),
|
||||
layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout),
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
return tonedButton(gtx, u.theme, &u.copyURL, "Copy URL")
|
||||
}),
|
||||
)
|
||||
}
|
||||
return layout.Flex{Spacing: layout.SpaceStart}.Layout(gtx,
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
return tonedButton(gtx, u.theme, &u.copyPass, "Copy Password")
|
||||
}),
|
||||
layout.Rigid(layout.Spacer{Width: unit.Dp(6)}.Layout),
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
return tonedButton(gtx, u.theme, &u.copyUser, "Copy Username")
|
||||
}),
|
||||
layout.Rigid(layout.Spacer{Width: unit.Dp(6)}.Layout),
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
return tonedButton(gtx, u.theme, &u.copyURL, "Copy URL")
|
||||
}),
|
||||
)
|
||||
}),
|
||||
)
|
||||
}
|
||||
return layout.Flex{}.Layout(gtx,
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
btn := material.Button(u.theme, &u.copyUser, "Copy User")
|
||||
return btn.Layout(gtx)
|
||||
}),
|
||||
layout.Rigid(layout.Spacer{Width: unit.Dp(8)}.Layout),
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
btn := material.Button(u.theme, &u.copyPass, "Copy Password")
|
||||
return btn.Layout(gtx)
|
||||
}),
|
||||
layout.Rigid(layout.Spacer{Width: unit.Dp(8)}.Layout),
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
btn := material.Button(u.theme, &u.copyURL, "Copy URL")
|
||||
return btn.Layout(gtx)
|
||||
}),
|
||||
)
|
||||
})
|
||||
},
|
||||
layout.Spacer{Height: unit.Dp(12)}.Layout,
|
||||
layout.Spacer{Height: unit.Dp(8)}.Layout,
|
||||
func(gtx layout.Context) layout.Dimensions {
|
||||
lbl := material.Label(u.theme, unit.Sp(12), "Notes")
|
||||
lbl.Color = mutedColor
|
||||
return lbl.Layout(gtx)
|
||||
return compactCard(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(12), "NOTES")
|
||||
lbl.Color = mutedColor
|
||||
return lbl.Layout(gtx)
|
||||
}),
|
||||
layout.Rigid(layout.Spacer{Height: unit.Dp(4)}.Layout),
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
lbl := material.Body1(u.theme, item.Notes)
|
||||
lbl.Color = mutedColor
|
||||
return lbl.Layout(gtx)
|
||||
}),
|
||||
)
|
||||
})
|
||||
},
|
||||
layout.Spacer{Height: unit.Dp(4)}.Layout,
|
||||
func(gtx layout.Context) layout.Dimensions {
|
||||
lbl := material.Body1(u.theme, item.Notes)
|
||||
lbl.Color = mutedColor
|
||||
return lbl.Layout(gtx)
|
||||
},
|
||||
layout.Spacer{Height: unit.Dp(12)}.Layout,
|
||||
layout.Spacer{Height: unit.Dp(8)}.Layout,
|
||||
u.attachmentSummaryPanel,
|
||||
layout.Spacer{Height: unit.Dp(12)}.Layout,
|
||||
layout.Spacer{Height: unit.Dp(8)}.Layout,
|
||||
u.historyPanel,
|
||||
layout.Spacer{Height: unit.Dp(12)}.Layout,
|
||||
layout.Spacer{Height: unit.Dp(8)}.Layout,
|
||||
func(gtx layout.Context) layout.Dimensions {
|
||||
switch u.state.Section {
|
||||
case appstate.SectionTemplates:
|
||||
@@ -4105,36 +4121,89 @@ func (u *ui) historyPanel(gtx layout.Context) layout.Dimensions {
|
||||
|
||||
func (u *ui) attachmentSummaryPanel(gtx layout.Context) layout.Dimensions {
|
||||
items := u.selectedAttachmentItems()
|
||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
lbl := material.Label(u.theme, unit.Sp(12), "Attachments")
|
||||
lbl.Color = mutedColor
|
||||
return lbl.Layout(gtx)
|
||||
}),
|
||||
layout.Rigid(layout.Spacer{Height: unit.Dp(4)}.Layout),
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
if len(items) == 0 {
|
||||
lbl := material.Label(u.theme, unit.Sp(12), "No attachments on this entry.")
|
||||
return compactCard(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(12), "ATTACHMENTS")
|
||||
lbl.Color = mutedColor
|
||||
return lbl.Layout(gtx)
|
||||
}
|
||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx, func() []layout.FlexChild {
|
||||
children := make([]layout.FlexChild, 0, len(items)*2)
|
||||
for i, item := range items {
|
||||
label := fmt.Sprintf("%s (%d B)", item.Name, item.Size)
|
||||
children = append(children, layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
lbl := material.Label(u.theme, unit.Sp(12), label)
|
||||
lbl.Color = accentColor
|
||||
return lbl.Layout(gtx)
|
||||
}))
|
||||
if i < len(items)-1 {
|
||||
children = append(children, layout.Rigid(layout.Spacer{Height: unit.Dp(4)}.Layout))
|
||||
}
|
||||
}),
|
||||
layout.Rigid(layout.Spacer{Height: unit.Dp(4)}.Layout),
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
lbl := material.Label(u.theme, unit.Sp(11), u.attachmentActionSummary())
|
||||
lbl.Color = mutedColor
|
||||
return lbl.Layout(gtx)
|
||||
}),
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
if len(items) == 0 {
|
||||
return layout.Dimensions{}
|
||||
}
|
||||
return children
|
||||
}()...)
|
||||
}),
|
||||
)
|
||||
return layout.Inset{Top: unit.Dp(8)}.Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
||||
return layout.Flex{Axis: layout.Vertical}.Layout(gtx, func() []layout.FlexChild {
|
||||
children := make([]layout.FlexChild, 0, len(items)*2)
|
||||
selectedName := strings.TrimSpace(u.attachmentName.Text())
|
||||
for i, item := range items {
|
||||
index := i
|
||||
name := item.Name
|
||||
selected := selectedName == name
|
||||
children = append(children, layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
for u.attachmentClicks[index].Clicked(gtx) {
|
||||
u.attachmentName.SetText(name)
|
||||
}
|
||||
return u.attachmentClicks[index].Layout(gtx, func(gtx layout.Context) layout.Dimensions {
|
||||
return layout.Stack{}.Layout(gtx,
|
||||
layout.Expanded(func(gtx layout.Context) layout.Dimensions {
|
||||
size := gtx.Constraints.Min
|
||||
if size.X == 0 {
|
||||
size.X = gtx.Constraints.Max.X
|
||||
}
|
||||
if size.Y == 0 {
|
||||
size.Y = gtx.Dp(unit.Dp(58))
|
||||
}
|
||||
bg := panelColor
|
||||
if selected {
|
||||
bg = selectedColor
|
||||
}
|
||||
paint.FillShape(gtx.Ops, bg, clip.Rect{Max: size}.Op())
|
||||
if selected {
|
||||
paint.FillShape(gtx.Ops, selectedEdge, clip.Rect{Max: image.Pt(4, size.Y)}.Op())
|
||||
}
|
||||
return layout.Dimensions{Size: size}
|
||||
}),
|
||||
layout.Stacked(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(12), name)
|
||||
lbl.Color = accentColor
|
||||
return lbl.Layout(gtx)
|
||||
}),
|
||||
layout.Rigid(layout.Spacer{Height: unit.Dp(2)}.Layout),
|
||||
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
|
||||
text := fmt.Sprintf("%d B", item.Size)
|
||||
if selected {
|
||||
text += " · selected"
|
||||
}
|
||||
lbl := material.Label(u.theme, unit.Sp(11), text)
|
||||
lbl.Color = mutedColor
|
||||
return lbl.Layout(gtx)
|
||||
}),
|
||||
)
|
||||
})
|
||||
}),
|
||||
)
|
||||
})
|
||||
}))
|
||||
if i < len(items)-1 {
|
||||
children = append(children, layout.Rigid(layout.Spacer{Height: unit.Dp(6)}.Layout))
|
||||
}
|
||||
}
|
||||
return children
|
||||
}()...)
|
||||
})
|
||||
}),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
func (u *ui) historyRow(gtx layout.Context, click *widget.Clickable, index int, item entry) layout.Dimensions {
|
||||
|
||||
Reference in New Issue
Block a user