From 85c664739504e1fc75db88b780475c64082f0ac3 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 26 Mar 2026 02:30:09 +0000 Subject: [PATCH] feat: first-run setup banner when identity is unconfigured Shows a red warning banner at the top of the popup when no identity, email, username, or explicit mappings are configured. The status dot turns orange (instead of green) to indicate the extension is active but not protecting anything yet. Banner disappears as soon as the user saves their identity. Prevents users from thinking they're protected when nothing has been configured. https://claude.ai/code/session_01Dvgwe7XMoSxnWXkih8p1Cw --- src/popup/popup.css | 34 ++++++++++++++++++++++++++++++++++ src/popup/popup.html | 9 +++++++++ src/popup/popup.js | 24 ++++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/src/popup/popup.css b/src/popup/popup.css index 583838f..ded12a4 100644 --- a/src/popup/popup.css +++ b/src/popup/popup.css @@ -242,6 +242,40 @@ body { white-space: nowrap; } +/* First-run banner */ +.first-run-banner { + display: flex; + align-items: flex-start; + gap: 10px; + padding: 10px 16px; + background: #fef2f2; + border-bottom: 1px solid #fecaca; +} + +.first-run-icon { + width: 22px; + height: 22px; + border-radius: 50%; + background: #dc2626; + color: #fff; + font-size: 14px; + font-weight: 700; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; +} + +.first-run-text { + font-size: 12px; + color: #991b1b; + line-height: 1.4; +} + +.first-run-text strong { + font-weight: 600; +} + /* Identity tab */ .id-section { margin-bottom: 12px; diff --git a/src/popup/popup.html b/src/popup/popup.html index 4412485..bf9204e 100644 --- a/src/popup/popup.html +++ b/src/popup/popup.html @@ -35,6 +35,15 @@ + + +

Tell Silent Send who you are. It auto-catches all variations.

diff --git a/src/popup/popup.js b/src/popup/popup.js index 8d3cbb3..0e24c94 100644 --- a/src/popup/popup.js +++ b/src/popup/popup.js @@ -23,6 +23,7 @@ document.addEventListener('DOMContentLoaded', async () => { renderActivity(); loadIdentityForm(); updateStatusDot(); + checkFirstRun(); $('#enableToggle').checked = settings.enabled; @@ -196,6 +197,7 @@ async function saveIdentity() { }; await Storage.saveIdentity(identity); + checkFirstRun(); // Flash save button const btn = $('#btnSaveIdentity'); @@ -207,6 +209,28 @@ async function saveIdentity() { }, 1500); } +// --- First-Run Check --- +function checkFirstRun() { + const hasNames = (identity.names || []).length > 0; + const hasEmails = (identity.emails || []).length > 0 || !!identity.catchAllEmail; + const hasUsernames = (identity.usernames || []).length > 0; + const hasMappings = mappings.length > 0; + + // Show banner if nothing is configured at all + const isConfigured = hasNames || hasEmails || hasUsernames || hasMappings; + const banner = $('#firstRunBanner'); + banner.style.display = isConfigured ? 'none' : 'flex'; + + // Also update the status dot — orange if unconfigured + const dot = $('#statusDot'); + if (!isConfigured && settings.enabled) { + dot.classList.add('off-site'); + dot.classList.remove('disabled'); + } else { + dot.classList.remove('off-site'); + } +} + // --- Add Mapping --- async function addMapping() { const real = $('#inputReal').value.trim();