ux(provisioning): step 1 is now "Plug in power"

Frames will ship with the battery disconnected to preserve shelf life
— the setup screen polling is non-trivial draw on e-ink, and a unit
that sits on a shelf for weeks before unboxing would arrive flat.
Surface "plug in power" as the prerequisite step ahead of unlock and
scan, so the recipient can't miss it.

Step list grows from 4 to 5; pitch shrinks from 38 → 32 px to keep
the manual-help QR clear of the bottom edge.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-09 13:41:49 -04:00
parent 1399cc3756
commit f1d867c659
5 changed files with 9 additions and 6 deletions
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

+9 -6
View File
@@ -220,19 +220,22 @@ def gen_ap(accent=YL, header="SETUP MODE — STEP 1 OF 2", qr_label="SCAN TO C
bb = draw.textbbox((0,0), "WiFi", font=F_HEAD)
draw.rectangle([28, BODY_Y+82, 28+bb[2]+2, BODY_Y+85], fill=accent)
# Steps — step 1 is the unlock-first prompt (iOS won't fire the
# captive UI from a locked-phone scan). Two-QR flow because iOS
# in recent versions doesn't auto-open the captive portal even
# after CNA detects it; scanning the second QR opens Safari
# which forces the portal to render.
# Steps — frames ship with battery unplugged to preserve shelf life
# (idle setup-screen polling is non-trivial draw on e-ink), so the
# very first prompt is "Plug in power". Step 2 is unlock-first (iOS
# won't fire the captive UI from a locked-phone scan). Two-QR flow
# because iOS in recent versions doesn't auto-open the captive
# portal even after CNA detects it; scanning the second QR opens
# Safari which forces the portal to render.
steps = [
("Plug in power", ""),
("Unlock your phone first", ""),
("Scan QR 1 →", "joins PictureFrame WiFi"),
("Scan QR 2 →", "page opens in Safari"),
("Enter your WiFi password", "and tap Connect"),
]
sy = BODY_Y + 95
step_pitch = 38
step_pitch = 32
for i, (l1, l2) in enumerate(steps):
bx, by = 28, sy + i*step_pitch
draw.rectangle([bx, by, bx+24, by+24], fill=BK)