diff --git a/browser-extension/background.js b/browser-extension/background.js index b3dba90..19cdb62 100644 --- a/browser-extension/background.js +++ b/browser-extension/background.js @@ -1,12 +1,18 @@ let serverUrl = ''; -browser.storage.sync.get('serverUrl').then(r => { - if (r.serverUrl) serverUrl = r.serverUrl.replace(/\/+$/, ''); -}); +function norm(v) { + return (v || '').replace(/\/+$/, ''); +} + +async function getServerUrl() { + const r = await browser.storage.sync.get('serverUrl'); + serverUrl = norm(r.serverUrl); + return serverUrl; +} browser.storage.onChanged.addListener(changes => { if (changes.serverUrl) { - serverUrl = changes.serverUrl.newValue.replace(/\/+$/, ''); + serverUrl = norm(changes.serverUrl.newValue); } }); @@ -22,10 +28,18 @@ browser.runtime.onMessage.addListener((msg, sender) => { }); async function request(path, opts) { - if (!serverUrl) throw new Error('Server URL not configured'); + const base = await getServerUrl(); + if (!base) { + throw new Error('Server URL not set — open snotes and click "Capture" → "Apply to Extension", or set it in Options'); + } opts = opts || {}; opts.credentials = 'include'; - const res = await fetch(serverUrl + path, opts); + let res; + try { + res = await fetch(base + path, opts); + } catch (e) { + throw new Error('Cannot reach ' + base + ' (' + e.message + ')'); + } if (!res.ok) { const err = await res.json().catch(() => ({})); throw new Error(err.detail || 'HTTP ' + res.status); diff --git a/browser-extension/popup.js b/browser-extension/popup.js index dfdc070..1bf427e 100644 --- a/browser-extension/popup.js +++ b/browser-extension/popup.js @@ -114,12 +114,19 @@ browser.runtime.openOptionsPage(); }); + function updateIndicator() { + var el = document.getElementById('server-indicator'); + var display = serverUrl ? serverUrl.replace(/^https?:\/\//, '') : 'Set server URL…'; + el.textContent = display; + el.title = serverUrl || ''; + } + browser.storage.sync.get('serverUrl').then(function (r) { serverUrl = (r.serverUrl || '').replace(/\/+$/, ''); - if (!serverUrl) showStatus('Set the server URL in Options', false); + updateIndicator(); + loadUsers(); }); - loadUsers(); captureContext(); noteEl.focus(); })(); diff --git a/static/app.css b/static/app.css index 9dcb77e..5e422a9 100644 --- a/static/app.css +++ b/static/app.css @@ -327,6 +327,10 @@ body { .tools-row { display: flex; align-items: center; gap: 12px; margin-top: 8px; flex-wrap: wrap; } .tools-row .muted { min-height: 1.2em; } +.tools-head { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; } +.tools-head h1 { margin: 0; } +.tools-logo { height: 40px; width: auto; } + .login-card { display: flex; flex-direction: column; diff --git a/static/app.js b/static/app.js index 7d81a2b..a805921 100644 --- a/static/app.js +++ b/static/app.js @@ -254,7 +254,10 @@ function showTools() { const qsApply = el("button", { class: "btn", text: "Apply to Extension" }); const card = el("div", { class: "help-card" }, [ - el("h1", { text: "Quick capture" }), + el("div", { class: "tools-head" }, [ + el("img", { src: "/static/snotes-logo.png", class: "tools-logo", alt: "quickSnote" }), + el("h1", { text: "Quick capture" }), + ]), el("p", { html: 'The quickSnote browser extension lets you jot a note from any page. It prefills the note with the text you\'ve selected, and a Page button inserts the current page\'s title and link.' }), el("h2", { text: "Firefox" }),