ux(setup): rewrite captive-portal + AP/setup-screen copy

Beta tester called the previous setup wording "Chinglish."
Tighter, plainer language across all three surfaces:

- Captive portal (PORTAL_HTML): "Connect your frame", explicit
  "Home WiFi name / Home WiFi password", clearer footer.
- AP screen step list: 5-line plain-English checklist; no more
  Safari-specific reference.
- Setup screen: fixed step 2 wrapping mid-domain
  ("pictureframe / .edholm.me"), tightened steps 1 and 3.

Regenerated bg.bin to match the new gen_screens.py output.
NEEDS-FLASH: in-field beta unit still has prior copy.
This commit is contained in:
2026-05-09 15:17:15 -04:00
parent f1d867c659
commit c1bed8c218
8 changed files with 33 additions and 24 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

File diff suppressed because one or more lines are too long
Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 10 KiB

+20 -15
View File
@@ -222,17 +222,19 @@ def gen_ap(accent=YL, header="SETUP MODE — STEP 1 OF 2", qr_label="SCAN TO C
# 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.
# very first prompt is "Plug in the frame". Step 2 is unlock-phone
# because 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 a browser which forces the portal to render.
# NEW WORDING 2026-05-09 — beta tester called the prior copy
# "Chinglish." Tighter, plainer, no Safari-specific reference.
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"),
("Plug in the frame", ""),
("Unlock your phone", ""),
("Scan QR 1", "joins your phone to PictureFrame"),
("Scan QR 2", "opens the setup page"),
("Type your home WiFi password", "and tap Connect"),
]
sy = BODY_Y + 95
step_pitch = 32
@@ -361,13 +363,16 @@ def gen_setup():
bb = draw.textbbox((0,0), "ready.", font=F_HEAD)
draw.rectangle([28, BODY_Y+82, 28+bb[2]+2, BODY_Y+85], fill=GR)
draw.text((28, BODY_Y+96), "Scan to name this frame and", font=F_STEP, fill=(80,80,75))
draw.text((28, BODY_Y+110), "link it to your account.", font=F_STEP, fill=(80,80,75))
draw.text((28, BODY_Y+96), "Scan the QR to link this frame", font=F_STEP, fill=(80,80,75))
draw.text((28, BODY_Y+110), "to your account.", font=F_STEP, fill=(80,80,75))
# NEW WORDING 2026-05-09 — beta-tester feedback. Step 2 used to break
# mid-domain ("pictureframe / .edholm.me") which read as broken text;
# also tightened step 1 and 3.
steps = [
("Scan the QR with your phone", "camera or QR app"),
("Sign in at pictureframe", ".edholm.me"),
("Name the frame, choose", "orientation — done."),
("Scan the QR with your phone's", "camera"),
("Sign in or create an account", ""),
("Name your frame and pick", "orientation — done."),
]
sy = BODY_Y + 136
for i, (l1, l2) in enumerate(steps):
+12 -8
View File
@@ -54,6 +54,8 @@ static void show_setup_qr(const String& mac) {
}
// ── Captive portal HTML ───────────────────────────────────────────────────────
// NEW WORDING 2026-05-09 — beta-tester feedback called the previous copy
// "Chinglish." Needs flash test before going to a recipient.
static const char PORTAL_HTML[] PROGMEM = R"html(
<!DOCTYPE html><html lang="en">
@@ -64,26 +66,28 @@ static const char PORTAL_HTML[] PROGMEM = R"html(
min-height:100vh;margin:0;background:#fdf6ee;color:#3a2e22}
.card{width:100%;max-width:340px;margin:1rem;padding:1.5rem;background:#fff9f2;
border:1px solid #e8d9c4;border-radius:16px}
h1{font-size:1.25rem;margin:0 0 1.25rem}
h1{font-size:1.25rem;margin:0 0 .5rem}
.sub{font-size:.875rem;color:#8a7060;margin:0 0 1.25rem;line-height:1.4}
label{display:block;font-size:.8125rem;font-weight:600;color:#8a7060;margin-bottom:.3rem}
input{width:100%;min-height:44px;padding:0 .875rem;border:1px solid #e8d9c4;
border-radius:10px;background:#fff;font-size:1rem;color:#3a2e22;box-sizing:border-box;margin-bottom:1rem}
button{width:100%;min-height:44px;background:#c97c3a;color:#fff;border:none;
border-radius:9999px;font-size:1rem;font-weight:700;cursor:pointer}
p{font-size:.875rem;color:#8a7060;margin-top:1rem;text-align:center}
p.foot{font-size:.875rem;color:#8a7060;margin-top:1rem;text-align:center;line-height:1.4}
</style>
</head>
<body>
<div class="card">
<h1>Connect to WiFi</h1>
<h1>Connect your frame</h1>
<p class="sub">Type the name and password of your home WiFi so the frame can join it.</p>
<form method="POST" action="/connect">
<label for="s">WiFi network name</label>
<label for="s">Home WiFi name</label>
<input id="s" name="ssid" type="text" autocomplete="off" placeholder="e.g. HomeNetwork">
<label for="p">Password</label>
<label for="p">Home WiFi password</label>
<input id="p" name="pass" type="password" autocomplete="off">
<button type="submit">Connect</button>
</form>
<p>pictureFrame will join your network and display a setup QR code.</p>
<p class="foot">Once it connects, the frame's screen will update with the next step.</p>
</div>
</body></html>
)html";
@@ -93,9 +97,9 @@ static const char CONNECTING_HTML[] PROGMEM = R"html(
<title>Connecting</title>
<style>body{font-family:system-ui,sans-serif;display:flex;align-items:center;justify-content:center;
min-height:100vh;margin:0;background:#fdf6ee;color:#3a2e22;text-align:center}
.card{padding:2rem;max-width:300px}</style></head>
.card{padding:2rem;max-width:320px}p{line-height:1.5}</style></head>
<body><div class="card"><h2>Connecting…</h2>
<p>The frame is joining your network.<br>Watch the display for a setup QR code.</p></div></body></html>
<p>The frame is joining your WiFi. Look at the frame's screen a new QR code will appear there for the next step.</p></div></body></html>
)html";
// ── Web server handlers ───────────────────────────────────────────────────────