Skip to content

Commit 4b03be9

Browse files
Make the home add-device card clearer and clickable (#1968)
* Make the add-device card clearer and clickable * Align pairing hierarchy with the shared palette rules * Keep command emphasis across wrapped instruction lines * Describe pairing focus and heading-only hover against current dev * Use keyboard selection ground for the focused pairing field
1 parent 334cab9 commit 4b03be9

5 files changed

Lines changed: 66 additions & 8 deletions

File tree

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
kind: changed
3+
title: Make the add-device card clearer and clickable
4+
pr: 1968
5+
surface: [chat, docs]
6+
invalidates:
7+
- "The add-device card toggled from clicks throughout its prose without hover feedback. Only the visible heading now toggles the instructions and it underlines under the pointer."
8+
- "The add-device description repeated its title and the instructions had uniform emphasis. The card now separates the description from the steps and emphasizes the command."
9+
---
10+
11+
The heading, supporting text, command and key hints use the existing theme's
12+
text hierarchy. Only the heading's visible cells respond to the pointer;
13+
description text and surrounding space stay passive. The editable link field
14+
uses dim placeholder text and a shaded focus state. The keyboard shortcut
15+
and pairing approval flow are unchanged.

‎internal/manual/chat/add-or-remove-a-computer.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ While you have only one device, home shows a card at the foot:
1212

1313
```
1414
+ Add another device
15-
Add another device — pick up your work anywhere, exactly where you left it.
15+
Pick up your work anywhere, exactly where you left it.
1616
alt+d how
1717
```
1818

19-
Click **+ Add another device** to open the steps, or press `alt+d`. Click the heading or press `alt+d` again to close them:
19+
Click `+ Add another device` or press `alt+d` to open the steps. Click the heading or press `alt+d` again to close them. The heading underlines while the pointer is over it; the description and empty space do not act as buttons. The command `codeaf pair` stands out from the instructions, and the link field is shaded while it holds the keyboard:
2020

2121
```
2222
1. On the new device, install and run: codeaf pair

‎internal/tui3/app.go‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5238,6 +5238,7 @@ func (a *app) route(msg tea.Msg) (tea.Model, tea.Cmd) {
52385238
// mean the same thing on every page, so the button under the pointer
52395239
// takes its ground wherever a person is standing (topnav.go's
52405240
// [app.headHover]).
5241+
a.hoverAddMachine(msg.Mouse().X, msg.Mouse().Y)
52415242
a.hoverDraftSeam(msg.Mouse().X, msg.Mouse().Y)
52425243
if a.headHover(msg.Mouse().X, msg.Mouse().Y) {
52435244
// AND THE HEAD TAKES THE POINTER OFF HOME'S PROJECT NAMES, which

‎internal/tui3/homeband_addmachine.go‎

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ const (
4747
fleetAskTimeout = 5 * time.Second
4848

4949
addMachineHeading = "+ Add another device"
50-
addMachinePitch = "Add another device — pick up your work anywhere, exactly where you left it."
50+
addMachinePitch = "Pick up your work anywhere, exactly where you left it."
5151
addMachineStepRun = "1. On the new device, install and run: codeaf pair"
5252
addMachineStepPut = "2. It shows a link. Paste it here:"
5353
addMachineField = "> "
@@ -79,6 +79,7 @@ type addMachine struct {
7979
asking bool
8080
// open says the steps are showing.
8181
open bool
82+
hovered bool
8283
targets []addMachineTarget
8384
focused bool
8485
box editor
@@ -134,6 +135,7 @@ func (a *app) toggleAddMachine() tea.Cmd {
134135
return nil
135136
}
136137
m.open = !m.open
138+
m.hovered = false
137139
m.focused = m.open
138140
a.touch()
139141
return nil
@@ -159,11 +161,16 @@ func drawAddMachineBand(a *app, ctx bandContext) []string {
159161
return nil
160162
}
161163
m := a.addMachine
162-
rows := []string{ctx.pal.muted(fit(addMachineHeading, ctx.width))}
164+
heading := ctx.pal.bold(ctx.pal.muted(fit(addMachineHeading, ctx.width)))
165+
if m.hovered {
166+
heading = ctx.pal.underline(heading)
167+
}
168+
rows := []string{heading}
163169
for _, line := range wrap(addMachinePitch, ctx.width) {
164170
rows = append(rows, ctx.pal.dim(fit(line, ctx.width)))
165171
}
166172
if m.open {
173+
rows = append(rows, "")
167174
rows = append(rows, a.addMachineHow(ctx)...)
168175
}
169176
key := addMachineShow
@@ -181,8 +188,10 @@ func drawAddMachineBand(a *app, ctx bandContext) []string {
181188
func (a *app) addMachineHow(ctx bandContext) []string {
182189
var rows []string
183190
for _, line := range []string{addMachineStepRun, addMachineStepPut} {
184-
for _, wrapped := range wrap(line, ctx.width) {
185-
rows = append(rows, ctx.pal.ink(fit(wrapped, ctx.width)))
191+
text := ctx.pal.muted(line)
192+
text = strings.ReplaceAll(text, "codeaf pair", ctx.pal.bold(ctx.pal.data("codeaf pair")))
193+
for _, wrapped := range wrap(text, ctx.width) {
194+
rows = append(rows, fit(wrapped, ctx.width))
186195
}
187196
}
188197
line, _ := a.addMachineLine(ctx.width, ctx.pal)
@@ -208,6 +217,9 @@ func (a *app) addMachinePress(x, y, width int) (tea.Cmd, bool) {
208217
a.touch()
209218
return nil, true
210219
}
220+
if !a.addMachineAt(x, y, a.home.painted.lines) {
221+
return nil, false
222+
}
211223
return a.toggleAddMachine(), true
212224
}
213225

@@ -231,7 +243,14 @@ func (a *app) addMachineLine(width int, pal palette) (string, int) {
231243
if b.empty() {
232244
shown = "Paste pairing link"
233245
}
234-
line := pal.accent(addMachineField) + pal.ink(fit(shown, max(0, width-ansi.StringWidth(addMachineField))))
246+
ink := pal.ink
247+
if b.empty() {
248+
ink = pal.dim
249+
}
250+
line := pal.accent(addMachineField) + ink(fit(shown, max(0, width-ansi.StringWidth(addMachineField))))
251+
if a.addMachine.focused {
252+
line = pal.selected(line, width)
253+
}
235254

236255
return line, column
237256
}
@@ -285,3 +304,26 @@ func (a *app) addMachineInputKey(msg tea.KeyPressMsg) (tea.Cmd, bool) {
285304
}
286305
return nil, true
287306
}
307+
308+
// addMachineAt resolves only the heading's painted cells, so description text
309+
// and blank space never promise to open the instructions.
310+
func (a *app) addMachineAt(x, y int, lines []string) bool {
311+
if !a.at(pageHome) || !a.addMachineWanted() || y < 0 || y >= len(lines) {
312+
return false
313+
}
314+
line := ansi.Strip(lines[y])
315+
at := strings.Index(line, addMachineHeading)
316+
if at < 0 {
317+
return false
318+
}
319+
from := ansi.StringWidth(line[:at])
320+
return x >= from && x < from+ansi.StringWidth(addMachineHeading)
321+
}
322+
323+
func (a *app) hoverAddMachine(x, y int) {
324+
next := a.addMachineAt(x, y, a.home.painted.lines)
325+
if next != a.addMachine.hovered {
326+
a.addMachine.hovered = next
327+
a.touch()
328+
}
329+
}

‎internal/tui3/homeband_addmachine_test.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func addMachineFrame(a *app, width int) string {
3838
func TestAddMachineCardShowsForAFleetOfOne(t *testing.T) {
3939
a := addMachineRig(&fakeApprovals{}, 1, true)
4040
got := addMachineFrame(a, 80)
41-
for _, want := range []string{"Add another device", "pick up your work anywhere, exactly where you left it.", addMachineShow} {
41+
for _, want := range []string{"Add another device", "Pick up your work anywhere, exactly where you left it.", addMachineShow} {
4242
if !strings.Contains(strings.Join(strings.Fields(got), " "), want) {
4343
t.Fatalf("card lacks %q:\n%s", want, got)
4444
}

0 commit comments

Comments
 (0)