a669788a81dd

unify vault history and advanced toggles, scroll-down unveils card, scroll-up minimizes with 300ms guard (v3.6.25)

time
2026-05-19 15:01 UTC · 5 months ago
machine
koh2
parent
8a204ae5858d
6 files manifest.firefox.json+1 −1manifest.json+1 −1package.json+1 −1src/popup/components/settings/StackDeck.tsx+8 −5src/popup/styles/popup.css+0 −27src/popup/views/Settings.tsx+5 −9
manifest.firefox.json+1 −1
@@ -2,7 +2,7 @@22   "_comment_audio_capture": "Firefox does not honor the Chrome 'audioCapture' optional_permission — getUserMedia in WebExtensions is gated solely by the runtime permission prompt. Microphone access for chirp pairing works from the popup under the existing '<all_urls>' host permission; no manifest entry is required or accepted here.",33   "manifest_version": 3,44   "name": "Peach",5-  "version": "3.6.24",5+  "version": "3.6.25",66   "description": "Zero-knowledge password manager",77   "browser_specific_settings": {88     "gecko": {

view file

manifest.json+1 −1
@@ -1,7 +1,7 @@11 {22   "manifest_version": 3,33   "name": "Peach",4-  "version": "3.6.24",4+  "version": "3.6.25",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": "3.6.24",3+  "version": "3.6.25",44   "description": "Zero-knowledge password manager",55   "type": "module",66   "scripts": {

view file

src/popup/components/settings/StackDeck.tsx+8 −5
@@ -17,6 +17,7 @@1717 1818 export function StackDeck(props: StackDeckProps) {1919   const [deckOpen, setDeckOpen] = createSignal(true);20+  let focusedAt = 0;2021 2122   function handleBack() {2223     if (!deckOpen()) {@@ -60,12 +61,14 @@6061         class={`stk-deck ${deckOpen() ? "is-open" : "is-focused"}`}6162         onWheel={(e) => {6263           const cardEl = (e.target as HTMLElement).closest<HTMLElement>("[data-settings-card-id]");63-          if (!cardEl) return;64-          const isActive = cardEl.dataset.active === "true";65-          if (!isActive && deckOpen() && e.deltaY > 3) {66-            props.onActiveChange(cardEl.dataset.settingsCardId as CardId);64+          if (!cardEl || cardEl.dataset.active !== "true") return;65+          if (deckOpen() && e.deltaY > 5) {66+            // Scroll down on active card → unveil to focus mode6767             setDeckOpen(false);68-          } else if (isActive && !deckOpen() && e.deltaY < -3) {68+            focusedAt = Date.now();69+          } else if (!deckOpen() && e.deltaY < -5 && Date.now() - focusedAt > 300) {70+            // Scroll up at top of focused card → minimize back to deck71+            // 300ms guard prevents fighting right after unveil6972             const body = cardEl.querySelector<HTMLElement>(".stk-card-body");7073             if (!body || body.scrollTop === 0) setDeckOpen(true);7174           }

view file

src/popup/styles/popup.css+0 −27
@@ -7364,33 +7364,6 @@73647364 73657365 /* Vault History — Settings → Vault sub-view */73667366 7367-.peach-history-toggle {7368-  display: flex;7369-  align-items: center;7370-  justify-content: space-between;7371-  width: 100%;7372-  margin: 12px 0 4px;7373-  padding: 0;7374-  background: none;7375-  border: none;7376-  cursor: pointer;7377-  font-family: "IBM Plex Mono", monospace;7378-  font-size: 0.5rem;7379-  text-transform: uppercase;7380-  letter-spacing: 0.18em;7381-  color: var(--peach-t2);7382-}7383-.peach-history-toggle:hover {7384-  color: var(--peach-t1);7385-}7386-.peach-history-chevron {7387-  transition: transform 200ms var(--peach-curve-arrival);7388-  flex-shrink: 0;7389-}7390-.peach-history-chevron.is-open {7391-  transform: rotate(180deg);7392-}7393-73947367 .peach-history-list {73957368   border: 1px solid var(--peach-border);73967369   border-radius: 8px;

view file

src/popup/views/Settings.tsx+5 −9
@@ -1056,18 +1056,14 @@10561056           </div>10571057 10581058           <button1059-            class="peach-history-toggle"1059+            class="peach-settings-advanced-toggle"10601060             onClick={() => setHistoryOpen((v) => !v)}10611061             aria-expanded={historyOpen()}10621062           >1063-            <span>VAULT HISTORY</span>1064-            <svg1065-              class={`peach-history-chevron${historyOpen() ? " is-open" : ""}`}1066-              width="10" height="6" viewBox="0 0 10 6" fill="none"1067-              stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"1068-            >1069-              <path d="M1 1L5 5L9 1" />1070-            </svg>1063+            <span class="peach-settings-sub-label" style="margin:0">VAULT HISTORY</span>1064+            <span class="peach-settings-advanced-chevron">1065+              {historyOpen() ? "▲" : "▼"}1066+            </span>10711067           </button>10721068           <Show when={historyOpen()}>10731069             <Show when={historyLoading()}>

view file