2ac38e92f4de

before settings fix + emoji-to-PeachMark replacements (v2.27.0)

time
2026-05-01 19:45 UTC · 5 months ago
machine
koh2
parent
136af2969805
8 files manifest.firefox.json+1 −1manifest.json+1 −1src/popup/App.tsx+2 −2src/popup/styles/popup.css+15 −1src/popup/views/Lock.tsx+13 −7src/popup/views/ProCelebration.tsx+2 −1src/shared/chrome-shim.ts+7 −0vite.config.mobile.ts+4 −0
manifest.firefox.json+1 −1
@@ -1,7 +1,7 @@11 {22   "manifest_version": 3,33   "name": "Peach",4-  "version": "2.26.0",4+  "version": "2.27.0",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.26.0",4+  "version": "2.27.0",55   "description": "Zero-knowledge password manager",66   "action": {77     "default_popup": "src/popup/index.html",

view file

src/popup/App.tsx+2 −2
@@ -17,7 +17,7 @@1717 import { VaultView, type SortOrder } from "./views/Vault";1818 import { EntryView } from "./views/Entry";1919 import { AddView } from "./views/Add";20-import { PeachWordmark } from "./components/PeachMark";20+import { PeachMark, PeachWordmark } from "./components/PeachMark";2121 import { PasskeyApprovalView } from "./views/PasskeyApproval";2222 import { extractDomain } from "../shared/domain";2323 import { popupCopy } from "./copy";@@ -1302,7 +1302,7 @@13021302             <Show when={incomingPair() !== null}>13031303               <div class="peach-pair-request-banner" role="dialog" aria-label="Pairing request">13041304                 <div class="peach-pair-request-header">1305-                  <span class="peach-pair-request-mark">🍑</span>1305+                  <span class="peach-pair-request-mark"><PeachMark class="peach-pair-request-icon" /></span>13061306                   <span class="peach-pair-request-title">Pairing request</span>13071307                   <span class="peach-pair-request-countdown">{incomingPairSecondsLeft()}s</span>13081308                 </div>

view file

src/popup/styles/popup.css+15 −1
@@ -6217,11 +6217,18 @@62176217 }62186218 62196219 .peach-pro-bloom-target {6220-  font-size: 48px;6220+  display: flex;6221+  align-items: center;6222+  justify-content: center;62216223   animation: peach-pro-bloom 600ms cubic-bezier(0.16, 1, 0.3, 1) forwards;62226224   margin-bottom: 12px;62236225 }62246226 6227+.peach-pro-bloom-icon {6228+  width: 48px;6229+  height: 48px;6230+}6231+62256232 .peach-pro-wordmark {62266233   font-family: var(--font-display);62276234   font-size: 22px;@@ -6315,6 +6322,13 @@63156322 63166323 .peach-pair-request-mark {63176324   font-size: 0.875rem;6325+  display: inline-flex;6326+  align-items: center;6327+}6328+6329+.peach-pair-request-icon {6330+  width: 1em;6331+  height: 1em;63186332 }63196333 63206334 .peach-pair-request-title {

view file

src/popup/views/Lock.tsx+13 −7
@@ -12,6 +12,15 @@1212 import { parsePayload } from "../../crypto/peachPayload";1313 import { parseImportSource } from "../../shared/import";1414 15+const peachMarkImg = new Image();16+peachMarkImg.src = `data:image/svg+xml,${encodeURIComponent(17+  '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">' +18+  '<path d="M32 54C16 54 8 44 8 31C8 18 17 10 27 10C28 7 30 5.5 32 5.5C34 5.5 36 7 37 10C47 10 56 18 56 31C56 44 48 54 32 54Z" fill="#D96830"/>' +19+  '<path d="M37 8.5C40.5 3.5 48 5 46 10.5C42 11 37 8.5 37 8.5Z" fill="#7B9060"/>' +20+  '<path d="M32 5.5Q35.5 1 39 2.5" stroke="#7B9060" stroke-width="1.5" stroke-linecap="round"/>' +21+  '</svg>'22+)}`;23+1524 // Lazy-load zxcvbn — it's heavy (~800 kB) and only needed during vault creation1625 let _zxcvbn: ((password: string) => { score: number }) | null = null;1726 async function getZxcvbn() {@@ -680,15 +689,12 @@680689       const markAlpha = markT < 0.5 ? markT * 2 : 2 - markT * 2;681690       if (markAlpha > 0) {682691         ctx.save();692+        ctx.globalAlpha = markAlpha;693+        ctx.shadowColor = `rgba(217, 104, 48, ${markAlpha * 0.8})`;694+        ctx.shadowBlur = 30;683695         ctx.translate(W / 2, H / 2);684696         ctx.scale(markScale, markScale);685-        ctx.font = `bold 64px serif`;686-        ctx.fillStyle = `rgba(232, 149, 109, ${markAlpha})`;687-        ctx.shadowColor = `rgba(232, 149, 109, ${markAlpha * 0.8})`;688-        ctx.shadowBlur = 30;689-        ctx.textAlign = "center";690-        ctx.textBaseline = "middle";691-        ctx.fillText("🍑", 0, 0);697+        ctx.drawImage(peachMarkImg, -32, -32, 64, 64);692698         ctx.restore();693699       }694700       if (t < 1) {

view file

src/popup/views/ProCelebration.tsx+2 −1
@@ -1,4 +1,5 @@11 import { createSignal, onCleanup, onMount } from "solid-js";2+import { PeachMark } from "../components/PeachMark";23 34 export function ProCelebration() {45   const [leaving, setLeaving] = createSignal(false);@@ -10,7 +11,7 @@1011 1112   return (1213     <div class="peach-pro-celebration" classList={{ "is-leaving": leaving() }}>13-      <div class="peach-pro-bloom-target">🍑</div>14+      <div class="peach-pro-bloom-target"><PeachMark class="peach-pro-bloom-icon" /></div>1415       <div class="peach-pro-wordmark">peach pro</div>1516       <div class="peach-pro-thankyou">thank you.</div>1617     </div>

view file

src/shared/chrome-shim.ts+7 −0
@@ -3,6 +3,8 @@33 44 import { Preferences } from "@capacitor/preferences";55 6+declare const __APP_VERSION__: string;7+68 type Listener<T extends (...args: any[]) => void> = {79   addListener: (_listener: T) => void;810   removeListener: (_listener: T) => void;@@ -64,6 +66,11 @@6466 const chromeShim = {6567   runtime: {6668     id: "peach-mobile",69+    getManifest: () => ({70+      name: "Peach",71+      version: typeof __APP_VERSION__ !== "undefined" ? __APP_VERSION__ : "0.0.0",72+      manifest_version: 3,73+    }),6774     sendMessage: (_msg: unknown, cb?: (response: unknown) => void) => {6875       const response = { ok: false, error: "NO_SERVICE_WORKER" };6976       cb?.(response);

view file

vite.config.mobile.ts+4 −0
@@ -1,6 +1,9 @@1+import { readFileSync } from "fs";12 import { defineConfig } from "vite";23 import solidPlugin from "vite-plugin-solid";34 5+const appManifest = JSON.parse(readFileSync("manifest.json", "utf-8"));6+47 export default defineConfig({58   plugins: [69     solidPlugin(),@@ -40,5 +43,6 @@4043   define: {4144     "import.meta.env.PEACH_PLATFORM": JSON.stringify("android"),4245     __PEACH_E2E_PASSKEYS__: JSON.stringify(false),46+    __APP_VERSION__: JSON.stringify(appManifest.version),4347   },4448 });

view file