26cd2586ed62
stop the flex column stealing the bird stage's height to fit what is below it, and pay for the two new rows on the invitation screen by moving what the code contains onto the text view where the string is actually visible (v4.2.6)
- time
- 2026-07-26 17:05 UTC · 3 months ago
- machine
- koh2
- agent
- claude-opus-5
- session
- sync settings ux and relay surfacing
- parent
- c626a5aa8656
↓ peach-browser-26cd2586.tar.gzatlas at this save
files changed6 files
manifest.firefox.json+1 −1manifest.json+1 −1package.json+1 −1src/popup/styles/popup.css+4 −0src/popup/views/PairDevice.test.tsx+2 −1src/popup/views/PairDevice.tsx+18 −5manifest.firefox.json+1 −1
@@ -1,7 +1,7 @@11 {22 "manifest_version": 3,33 "name": "Peach Password Manager",4- "version": "4.2.5",4+ "version": "4.2.6",55 "description": "Zero-knowledge password manager",66 "browser_specific_settings": {77 "gecko": {manifest.json+1 −1
@@ -1,7 +1,7 @@11 {22 "manifest_version": 3,33 "name": "Peach Password Manager",4- "version": "4.2.5",4+ "version": "4.2.6",55 "description": "Zero-knowledge password manager",66 "action": {77 "default_popup": "src/popup/index.html",package.json+1 −1
@@ -1,6 +1,6 @@11 {22 "name": "peach",3- "version": "4.2.5",3+ "version": "4.2.6",44 "description": "Zero-knowledge password manager",55 "license": "GPL-3.0-only",66 "type": "module",src/popup/styles/popup.css+4 −0
@@ -9541,6 +9541,10 @@95419541 /* Bird stage ----------------------------------------------------------- */95429542 .peach-pair-stage {95439543 position: relative;9544+ /* Never let the flex column steal the stage's height to fit whatever is9545+ below it — that is what clipped the birds to their legs before. Anything9546+ that does not fit has to give somewhere else. */9547+ flex: none;95449548 margin: 14px 0 8px;95459549 height: 180px;95469550 border-radius: 12px;src/popup/views/PairDevice.test.tsx+2 −1
@@ -90,7 +90,6 @@9090 expect(container.querySelector("svg.peach-pair-qr")).toBeTruthy();9191 // The QR is the default — the text form is behind an explicit fallback.9292 expect(container.querySelector("#pairing-invitation-manual")).toBeNull();93- expect(container.textContent).toContain("single-use token");9493 });9594 9695 it("offers the same invitation as text when a camera won't cooperate", async () => {@@ -107,6 +106,8 @@107106 108107 const text = container.querySelector<HTMLTextAreaElement>("#pairing-invitation-manual");109108 expect(text?.value).toBe(SOURCE_INVITATION);109+ // What the code contains is disclosed where the user can see the string.110+ expect(container.textContent).toContain("single-use token");110111 // One invitation, two renderings — never two live codes on screen.111112 expect(container.querySelector("svg.peach-pair-qr")).toBeNull();112113 src/popup/views/PairDevice.tsx+18 −5
@@ -211,17 +211,30 @@211211 <Show when={sharePhase() === "invitation"}>212212 <div class="peach-adoption-source-invitation">213213 <Show when={!changingRelay()}>214- <div class="peach-pair-headline">Scan this in Peach</div>215- <div class="peach-pair-sub">216- Open Peach on your phone, choose “Scan a code”, and point it here.217- The code carries only the relay address and a single-use token.214+ <div class="peach-pair-headline">215+ {showTextCode() ? "Enter this in Peach" : "Scan this in Peach"}218216 </div>217+ {/* The QR screen is the tallest in the flow and the popup does not218+ scroll, so what the code contains is said on the text view —219+ where the user is looking straight at the string — rather than220+ pushing the QR below the fold to say it twice. */}219221 <Show220222 when={showTextCode()}221- fallback={<PairingQrCode value={invitation()} size={188} />}223+ fallback={224+ <>225+ <div class="peach-pair-sub">226+ Open Peach on your phone, choose “Scan a code”, and point it here.227+ </div>228+ <PairingQrCode value={invitation()} size={176} />229+ </>230+ }222231 >223232 {/* Fallback for a camera that won't focus, a phone with no224233 camera permission, or pairing two windows on one machine. */}234+ <div class="peach-pair-sub">235+ Type or paste this into Peach on your other device. The whole236+ code is a relay address and a single-use token.237+ </div>225238 <textarea226239 id="pairing-invitation-manual"227240 class="peach-pair-invitation-text"