Skip to content

Commit 6302a82

Browse files
committed
Clean up subject card UI: align URL rows, drop redundant arrows
Two small follow-ups to the dual-URL work: Align URL rows with the table's label column Previously the Details/Verify lines were rendered as standalone faint-styled strings with a hardcoded " " prefix, so they sat at a fixed left indent while ID/Type/Hash labels were right-aligned in a table column whose width varies by section. The labels didn't line up. Fix: append the URL lines as rows of the SAME table so they inherit the right-aligned-label / value-column alignment. Applied to all four cards that emit URLs — beacon listing, download, create, and the verify Proof section. Tradeoff: URL cells use the table's Value color instead of faint styling. Consistent alignment beats the visual dimming. Drop the "→ " arrows With the labels now in a proper column, the arrow between Details/Verify and the URL was redundant visual noise. Removed from all four cards; the column gap produced by the table's StyleFunc provides the same separation. Output shape now matches across every card (beacon / download / create / verify Proof): Hash <64-hex> Timestamp <iso> ID <uuidv7> Previous <64-hex> Details <url> Verify <url> Full test suite + task lint green.
1 parent 0a34003 commit 6302a82

4 files changed

Lines changed: 46 additions & 42 deletions

File tree

cmd/beacon.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -183,17 +183,22 @@ func renderBeaconCard(w io.Writer, apiURL string, b *beacons.Beacon) {
183183
Row("ID", b.ID).
184184
Row("Previous", b.PreviousHash)
185185

186+
// Append URL rows to the SAME table so they inherit the
187+
// right-aligned-label / value-column alignment. Adding as separate
188+
// faint-styled lines would leave the labels dangling at a fixed
189+
// left indent and visually break the column grid.
190+
if detail := ui.BeaconDetailURL(apiURL, b.Hash); detail != "" {
191+
tbl = tbl.Row("Details", detail)
192+
}
193+
if verify := ui.BeaconVerifyURL(apiURL, b.ID); verify != "" {
194+
tbl = tbl.Row("Verify", verify)
195+
}
196+
186197
// Plain newline-join — see note in internal/verify/presenter.go
187198
// Present(). lipgloss.JoinVertical pads every line to match the
188199
// widest line, which can blow up vertical spacing when a long line
189200
// forces terminal wrap on every row.
190201
fmt.Fprintln(w, strings.Join([]string{header, "", tbl.String()}, "\n"))
191-
if detail := ui.BeaconDetailURL(apiURL, b.Hash); detail != "" {
192-
fmt.Fprintln(w, ui.FaintStyle().Render(" Details → "+detail))
193-
}
194-
if verify := ui.BeaconVerifyURL(apiURL, b.ID); verify != "" {
195-
fmt.Fprintln(w, ui.FaintStyle().Render(" Verify → "+verify))
196-
}
197202
}
198203

199204
// timestampWithRelative appends a coarse "N minutes ago" hint to an ISO

cmd/create.go

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -435,21 +435,22 @@ func presentCreate(resp *items.CreateItemResponse) {
435435
tbl = tbl.Row("Team", resp.TeamID)
436436
}
437437

438-
// Plain newline-join — see note in internal/verify/presenter.go
439-
// Present(). lipgloss.JoinVertical pad-to-widest can cause phantom
440-
// blank lines after every table row on narrow terminals.
441-
lipgloss.Println(strings.Join([]string{header, tbl.String()}, "\n"))
442-
443-
// Shareable public-web links for the newly-created item. Note the
444-
// verify link will render "not yet committed" until the item lands
445-
// in a finalized block — still useful to surface the stable URL
446-
// format so the user can check back later.
438+
// Shareable public-web links as rows of the SAME table — they share
439+
// the right-aligned-label / value column alignment. Note the verify
440+
// link will render "not yet committed" until the item lands in a
441+
// finalized block — still useful to surface the stable URL format
442+
// so the user can come back later.
447443
if detail := ui.SubjectDetailURL(appConfig.APIURL, "item", resp.ID); detail != "" {
448-
lipgloss.Println(ui.FaintStyle().Render(" Details → " + detail))
444+
tbl = tbl.Row("Details", detail)
449445
}
450446
if verify := ui.SubjectVerifyURL(appConfig.APIURL, "item", resp.ID); verify != "" {
451-
lipgloss.Println(ui.FaintStyle().Render(" Verify → " + verify))
447+
tbl = tbl.Row("Verify", verify)
452448
}
449+
450+
// Plain newline-join — see note in internal/verify/presenter.go
451+
// Present(). lipgloss.JoinVertical pad-to-widest can cause phantom
452+
// blank lines after every table row on narrow terminals.
453+
lipgloss.Println(strings.Join([]string{header, tbl.String()}, "\n"))
453454
}
454455

455456
func init() {

cmd/download.go

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -219,24 +219,23 @@ func presentDownload(filename, format, id, typeFlag string, size int) {
219219
Row("ID", id).
220220
Row("Type", typeFlag)
221221

222-
// Plain newline-join — see note in internal/verify/presenter.go
223-
// Present(). Long filenames (e.g. truestamp-entropy-bitcoin-<uuidv7>.cbor)
224-
// won't inflate every other table row on narrow terminals.
225-
lipgloss.Println(strings.Join([]string{header, "", tbl.String()}, "\n"))
226-
227-
// Shareable public-web links for the subject. Both suppress against
228-
// dev hosts (plain http / localhost / 127.0.0.1) so transcripts
229-
// don't leak internal URLs. subjectDetailURL routes beacon
230-
// downloads to /blocks/<id> (see the note on subjectDetailPath):
231-
// the id we have on hand keys into the underlying block page —
232-
// the hash-keyed /beacons/<hash> form lives on the beacon listing
233-
// card where the hash is available from the API.
222+
// Append URL rows to the SAME table so they share the
223+
// right-aligned-label / value column alignment. subjectDetailURL
224+
// routes beacon downloads to /blocks/<id> because the id we have
225+
// is the block id; the hash-keyed /beacons/<hash> form lives on
226+
// the beacon listing card where the hash comes directly from the
227+
// API response.
234228
if detail := ui.SubjectDetailURL(appConfig.APIURL, typeFlag, id); detail != "" {
235-
lipgloss.Println(ui.FaintStyle().Render(" Details → " + detail))
229+
tbl = tbl.Row("Details", detail)
236230
}
237231
if verify := ui.SubjectVerifyURL(appConfig.APIURL, typeFlag, id); verify != "" {
238-
lipgloss.Println(ui.FaintStyle().Render(" Verify → " + verify))
232+
tbl = tbl.Row("Verify", verify)
239233
}
234+
235+
// Plain newline-join — see note in internal/verify/presenter.go
236+
// Present(). Long filenames (e.g. truestamp-entropy-bitcoin-<uuidv7>.cbor)
237+
// won't inflate every other table row on narrow terminals.
238+
lipgloss.Println(strings.Join([]string{header, "", tbl.String()}, "\n"))
240239
}
241240

242241
func formatSize(size int) string {

internal/verify/presenter.go

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -103,23 +103,22 @@ func renderProofSection(r *Report) string {
103103
tbl = tbl.Row("ID", r.SubjectID)
104104
tbl = tbl.Row("Type", ptype.Humanize(subjectCodeForName(r.SubjectType)))
105105

106-
out := header + "\n" + tbl.String()
107-
108-
// Append two shareable public-web links (Details + Verify), same
109-
// pattern as the beacon / download / create cards. r.APIURL is set
110-
// by the verify cmd via opts.APIURL so we don't reach into a global
111-
// from a pure-logic package. Empty APIURL → no links (e.g. in unit
112-
// tests that exercise Present without a configured API host, or
113-
// callers that deliberately suppress them).
106+
// Append shareable public-web links as rows of the SAME table so
107+
// they inherit the right-aligned-label / value column alignment.
108+
// r.APIURL is set by the verify cmd via opts.APIURL so we don't
109+
// reach into a global from a pure-logic package. Empty APIURL →
110+
// no links (e.g. in unit tests that exercise Present without a
111+
// configured API host).
114112
if r.APIURL != "" && r.SubjectType != "" && r.SubjectID != "" {
115113
if detail := ui.SubjectDetailURL(r.APIURL, r.SubjectType, r.SubjectID); detail != "" {
116-
out += "\n" + ui.FaintStyle().Render(" Details → "+detail)
114+
tbl = tbl.Row("Details", detail)
117115
}
118116
if verify := ui.SubjectVerifyURL(r.APIURL, r.SubjectType, r.SubjectID); verify != "" {
119-
out += "\n" + ui.FaintStyle().Render(" Verify → "+verify)
117+
tbl = tbl.Row("Verify", verify)
120118
}
121119
}
122-
return out
120+
121+
return header + "\n" + tbl.String()
123122
}
124123

125124
// --- Subject Section ---

0 commit comments

Comments
 (0)