Clarify start, locked, and recycle flows

This commit is contained in:
Joe Julian
2026-04-01 16:29:53 -07:00
parent 1675811aa3
commit 54ec195e61
3 changed files with 168 additions and 74 deletions
+39 -10
View File
@@ -1599,6 +1599,10 @@ func (u *ui) listEmptyMessage() string {
query := strings.TrimSpace(u.search.Text())
if query != "" {
switch u.state.Section {
case appstate.SectionAPITokens:
return fmt.Sprintf("No API tokens match %q. Clear or refine the search.", query)
case appstate.SectionAPIAudit:
return fmt.Sprintf("No audit events match %q. Clear or refine the search.", query)
case appstate.SectionTemplates:
return fmt.Sprintf("No templates match %q. Clear or refine the search.", query)
case appstate.SectionRecycleBin:
@@ -1615,10 +1619,10 @@ func (u *ui) listEmptyMessage() string {
case appstate.SectionTemplates:
return "Templates are not available in this build."
case appstate.SectionRecycleBin:
return "Recycle Bin is empty."
return "Recycle Bin is empty. Deleted entries will appear here until restored."
default:
if len(u.displayPath()) > 0 {
return "No entries in this group yet. Add one or open a subgroup."
return "No entries in this group yet. Add one, search below this point, or open a subgroup."
}
return "Create or open a vault, then add an entry to get started."
}
@@ -1635,14 +1639,20 @@ func (u *ui) detailPlaceholderMessage() string {
}
switch u.state.Section {
case appstate.SectionAPITokens:
return "Select an API token or issue a new one."
return "Select an API token, issue a new one, or search to narrow the list."
case appstate.SectionAPIAudit:
return "Select an audit event to inspect it."
return "Select an audit event to inspect it, or filter the list with Search vault."
case appstate.SectionTemplates:
return "Select a template or start a reusable entry."
case appstate.SectionRecycleBin:
return "Select a recycle-bin entry to review or restore it."
return "Select a deleted entry to review or restore it."
default:
if strings.TrimSpace(u.search.Text()) != "" {
return "Select a matching entry from the filtered list or clear the search."
}
if len(u.displayPath()) == 0 {
return "Select an entry from the vault root or open a group."
}
return "Select an entry or start a new one."
}
}
@@ -2480,13 +2490,23 @@ func (u *ui) headerActions(gtx layout.Context) layout.Dimensions {
}
func (u *ui) syncButtonGroup(gtx layout.Context) layout.Dimensions {
label := "Synchronize"
spacing := unit.Dp(4)
if u.mode == "phone" {
label = "Sync"
spacing = unit.Dp(3)
}
return layout.Flex{Alignment: layout.Middle}.Layout(gtx,
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
btn := material.Button(u.theme, &u.synchronizeVault, "Synchronize")
btn := material.Button(u.theme, &u.synchronizeVault, label)
btn.CornerRadius = unit.Dp(10)
if u.mode == "phone" {
btn.TextSize = unit.Sp(13)
btn.Inset = layout.Inset{Top: 8, Bottom: 8, Left: 12, Right: 12}
}
return btn.Layout(gtx)
}),
layout.Rigid(layout.Spacer{Width: unit.Dp(4)}.Layout),
layout.Rigid(layout.Spacer{Width: spacing}.Layout),
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
return u.syncMenuToggle(gtx)
}),
@@ -2505,6 +2525,10 @@ func (u *ui) syncMenuToggle(gtx layout.Context) layout.Dimensions {
btn.Color = color.NRGBA{R: 255, G: 252, B: 247, A: 255}
btn.Size = unit.Dp(18)
btn.Inset = layout.UniformInset(unit.Dp(8))
if u.mode == "phone" {
btn.Size = unit.Dp(16)
btn.Inset = layout.UniformInset(unit.Dp(7))
}
return btn.Layout(gtx)
}
@@ -2712,6 +2736,7 @@ func (u *ui) entryRow(gtx layout.Context, click *widget.Clickable, idx int, item
}
row := func(gtx layout.Context) layout.Dimensions {
return layout.UniformInset(inset).Layout(gtx, func(gtx layout.Context) layout.Dimensions {
showPath := strings.TrimSpace(u.search.Text()) != "" || len(u.displayPath()) == 0 || u.state.Section == appstate.SectionRecycleBin
return layout.Flex{Axis: layout.Vertical}.Layout(gtx,
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
lbl := material.Label(u.theme, titleSize, item.Title)
@@ -2730,10 +2755,10 @@ func (u *ui) entryRow(gtx layout.Context, click *widget.Clickable, idx int, item
return lbl.Layout(gtx)
}),
layout.Rigid(func(gtx layout.Context) layout.Dimensions {
if strings.TrimSpace(u.search.Text()) == "" {
if !showPath {
return layout.Dimensions{}
}
lbl := material.Label(u.theme, unit.Sp(11), strings.Join(item.Path, " / "))
lbl := material.Label(u.theme, unit.Sp(11), strings.Join(u.displayEntryPath(item.Path), " / "))
lbl.Color = mutedColor
return lbl.Layout(gtx)
}),
@@ -2761,6 +2786,10 @@ func (u *ui) entryRow(gtx layout.Context, click *widget.Clickable, idx int, item
}
fillColor := selectedColor
edgeColor := selectedEdge
if u.state.Section == appstate.SectionRecycleBin {
fillColor = color.NRGBA{R: 245, G: 234, B: 226, A: 255}
edgeColor = color.NRGBA{R: 144, G: 74, B: 49, A: 255}
}
if u.isFocused(listFocusID(idx)) && item.ID != u.state.SelectedEntryID {
fillColor = color.NRGBA{R: 235, G: 241, B: 238, A: 255}
edgeColor = accentColor
@@ -3265,7 +3294,7 @@ func (u *ui) historyRow(gtx layout.Context, click *widget.Clickable, index int,
func (u *ui) pathBar(gtx layout.Context) layout.Dimensions {
if u.state.Section == appstate.SectionRecycleBin {
lbl := material.Label(u.theme, unit.Sp(13), "Recycle Bin")
lbl := material.Label(u.theme, unit.Sp(13), "Recycle Bin / Deleted entries")
lbl.Color = mutedColor
return lbl.Layout(gtx)
}