143b4046bad8

Aztec 3-retry fix + SyncComingSoonBanner on clean v2.53.3 baseline (v2.53.4)

time
2026-05-18 01:01 UTC · 5 months ago
machine
koh2
parent
5f40c4d44cbb
7 files manifest.firefox.json+1 −1manifest.json+1 −1package.json+1 −1src/popup/codex/aztec.ts+9 −2src/popup/components/SyncComingSoonBanner.tsx+16 −0src/popup/styles/popup.css+30 −0src/popup/views/SyncPairing.tsx+3 −0
manifest.firefox.json+1 −1
@@ -1,7 +1,7 @@11 {22   "manifest_version": 3,33   "name": "Peach",4-  "version": "2.53.3",4+  "version": "2.53.4",55   "description": "Zero-knowledge password manager",66   "browser_specific_settings": {77     "gecko": {

view file

manifest.json+1 −1
@@ -1,7 +1,7 @@11 {22   "manifest_version": 3,33   "name": "Peach",4-  "version": "2.53.3",4+  "version": "2.53.4",55   "description": "Zero-knowledge password manager",66   "action": {77     "default_popup": "src/popup/index.html",

view file

package.json+1 −1
@@ -1,6 +1,6 @@11 {22   "name": "peach",3-  "version": "2.53.3",3+  "version": "2.53.4",44   "description": "Zero-knowledge password manager",55   "type": "module",66   "scripts": {

view file

src/popup/codex/aztec.ts+9 −2
@@ -235,11 +235,18 @@235235     return image;236236   }237237 238-  const decoded = await decodeAztecFromPng(image.pngBytes);238+  // @zxing occasionally returns null on a valid barcode due to transient239+  // rasterisation issues. Three attempts avoids aborting a full Codex build240+  // for a momentary DOM hiccup. Content-mismatch is never retried.241+  let decoded: string | null = null;242+  for (let attempt = 0; attempt < 3; attempt++) {243+    decoded = await decodeAztecFromPng(image.pngBytes);244+    if (decoded !== null) break;245+  }239246   if (decoded === null) {240247     throw new CodexError(241248       "AZTEC_ROUNDTRIP_FAILED",242-      `Chunk ${envelope.i} generated but cannot be decoded back. This Codex cannot be trusted.`,249+      `Chunk ${envelope.i} generated but cannot be decoded back after 3 attempts. This Codex cannot be trusted.`,243250     );244251   }245252   if (decoded !== envelopeJson) {

view file

src/popup/components/SyncComingSoonBanner.tsx+16 −0
@@ -0,0 +1,16 @@1+export function SyncComingSoonBanner() {2+  return (3+    <div class="peach-sync-coming-soon">4+      <div class="peach-sync-coming-soon__icon">5+        <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round">6+          <circle cx="8" cy="8" r="6.5" />7+          <path d="M8 5v3.5l2 1.5" />8+        </svg>9+      </div>10+      <div>11+        <p class="peach-sync-coming-soon__title">Sync requires the mobile app</p>12+        <p class="peach-sync-coming-soon__body">Download Peach for iOS or Android to pair and sync your vault between devices.</p>13+      </div>14+    </div>15+  );16+}

view file

src/popup/styles/popup.css+30 −0
@@ -7854,6 +7854,36 @@78547854 78557855 /* ── Sync screen ── */78567856 7857+.peach-sync-coming-soon {7858+  display: flex;7859+  align-items: flex-start;7860+  gap: 10px;7861+  padding: 12px 14px;7862+  background: var(--peach-s1);7863+  border: 1px solid color-mix(in srgb, var(--peach-accent) 18%, transparent);7864+  border-radius: 10px;7865+}7866+.peach-sync-coming-soon__icon {7867+  flex-shrink: 0;7868+  color: var(--peach-accent);7869+  margin-top: 1px;7870+  line-height: 0;7871+}7872+.peach-sync-coming-soon__title {7873+  font-family: 'Cormorant Garamond', serif;7874+  font-weight: 500;7875+  font-size: 13px;7876+  color: var(--peach-accent);7877+  margin: 0 0 5px;7878+  line-height: 1.3;7879+}7880+.peach-sync-coming-soon__body {7881+  font-size: 12px;7882+  color: var(--peach-t1);7883+  line-height: 1.55;7884+  margin: 0;7885+}7886+78577887 .peach-sync-screen {78587888   display: flex;78597889   flex-direction: column;

view file

src/popup/views/SyncPairing.tsx+3 −0
@@ -3,6 +3,7 @@33 import { sendMessage } from '../App';44 import type { PairedDevice } from '../../shared/sync-types';55 import { getHasPaired, setHasPaired } from '../../background/sync-storage';6+import { SyncComingSoonBanner } from '../components/SyncComingSoonBanner';67 import { SyncInfoSheet } from '../components/SyncInfoSheet';78 import { isNativePlatform } from '../../shared/native';89 @@ -106,6 +107,8 @@106107       </div>107108 108109       <div class="peach-sync-content">110+111+        <SyncComingSoonBanner />109112 110113         {/* ── State A: Never paired ── */}111114         <Show when={!hasPaired()}>

view file