diff --git a/browser-extension/popup.html b/browser-extension/popup.html
index d0660de..97c73d6 100644
--- a/browser-extension/popup.html
+++ b/browser-extension/popup.html
@@ -11,7 +11,7 @@
-
+
diff --git a/browser-extension/popup.js b/browser-extension/popup.js
index e0d725e..31ea835 100644
--- a/browser-extension/popup.js
+++ b/browser-extension/popup.js
@@ -65,7 +65,7 @@
var link = '[' + (title || url) + '](' + (url || '') + ')';
var v = noteEl.value;
if (v && !/\n$/.test(v)) v += '\n';
- noteEl.value = v + link + '\n';
+ noteEl.value = v + link + ' #bookmark\n';
captureBtn.disabled = true;
showStatus('Capturing full page…', true);
diff --git a/static/app.css b/static/app.css
index 04f16c8..56ce895 100644
--- a/static/app.css
+++ b/static/app.css
@@ -212,7 +212,7 @@ body {
z-index: 10;
}
-.brand { display: flex; align-items: center; gap: 8px; font-weight: 700; font-size: 18px; }
+.brand { display: flex; align-items: center; gap: 8px; font-weight: 700; font-size: 18px; cursor: pointer; }
.brand-logo { height: 65px; width: auto; object-fit: contain; }
.search {
@@ -267,6 +267,27 @@ body {
.btn.danger { color: var(--danger); border-color: var(--danger); }
.btn.ghost { background: transparent; border-color: transparent; }
+.back-btn {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 36px;
+ height: 36px;
+ flex-shrink: 0;
+ border: 1px solid var(--border);
+ border-radius: 50%;
+ background: var(--surface);
+ color: var(--text);
+ cursor: pointer;
+ padding: 0;
+}
+.back-btn:hover { background: var(--bg-hover); border-color: var(--primary); }
+.back-icon { display: inline-flex; }
+.back-icon svg { width: 18px; height: 18px; }
+
+.results-head { display: flex; align-items: center; gap: 10px; }
+.results-head h2 { margin: 0; font-size: 20px; }
+
.layout {
display: grid;
grid-template-columns: 1fr 300px;
diff --git a/static/app.js b/static/app.js
index bca8ec8..ff8f455 100644
--- a/static/app.js
+++ b/static/app.js
@@ -200,7 +200,7 @@ function header() {
el("span", {}), el("span", {}), el("span", {}),
]);
return el("header", { class: "topbar" }, [
- el("div", { class: "brand" }, [
+ el("div", { class: "brand", onclick: showHome, title: "Home", role: "button" }, [
el("img", { src: "/static/snotes-logo.png", class: "brand-logo", alt: "snotes" }),
]),
burger,
@@ -214,7 +214,7 @@ function showHelp() {
root.innerHTML = "";
state.editor?.destroy(); state.editor = null;
- const back = el("button", { class: "btn ghost", text: "← Back", onclick: showHome });
+ const back = backButton(showHome);
const wrap = el("div", { class: "editor-wrap" }, [
el("div", { class: "editor-topbar" }, [back]),
el("div", { class: "help-card" }, [
@@ -254,7 +254,7 @@ function showTools() {
root.innerHTML = "";
state.editor?.destroy(); state.editor = null;
- const back = el("button", { class: "btn ghost", text: "← Back", onclick: showHome });
+ const back = backButton(showHome);
const extStatus = el("div", { class: "muted", text: "" });
const installBtn = el("button", { class: "btn primary", text: "Install Browser Extension" });
@@ -422,11 +422,13 @@ function noteList(notes) {
if (isCommon) meta.appendChild(el("span", { class: "common-badge", text: "common" }));
meta.appendChild(document.createTextNode(`${n.username} · edited ${relTime(n.updated_at)} · created ${fmtDate(n.created_at)}`));
if (n.attachments) meta.appendChild(el("span", { class: "attach-count", text: n.attachments + " attachment" + (n.attachments === 1 ? "" : "s") }));
+ let snippetHtml = n.snippet ? marked.parse(n.snippet) : "";
+ if (n.image) snippetHtml = snippetHtml.replace(/
]*>/g, "").trim();
const bodyEl = el("div", { class: "note-body" }, [
el("div", { class: "note-title", text: n.title || "Untitled" }),
meta,
el("div", { class: "note-tags", text: tags }),
- n.snippet ? el("div", { class: "note-snippet", html: marked.parse(n.snippet) }) : null,
+ snippetHtml ? el("div", { class: "note-snippet", html: snippetHtml }) : null,
]);
ul.appendChild(el("li", { class: isCommon ? "note-item note-common" : "note-item", onclick: () => openNote(n.id) }, [
n.image ? el("img", { class: "note-banner", src: n.image, alt: "", loading: "lazy" }) : null,
@@ -442,7 +444,7 @@ async function onSearch(e) {
const results = await api("GET", "/api/search?q=" + encodeURIComponent(q));
const box = document.getElementById("search-results");
box.innerHTML = "";
- box.appendChild(el("h2", { text: `Results for "${q}"` }));
+ box.appendChild(searchHeader(q));
box.appendChild(noteList(results));
}
@@ -451,10 +453,23 @@ async function searchFor(q) {
const results = await api("GET", "/api/search?q=" + encodeURIComponent(q));
const box = document.getElementById("search-results");
box.innerHTML = "";
- box.appendChild(el("h2", { text: `Results for "${q}"` }));
+ box.appendChild(searchHeader(q));
box.appendChild(noteList(results));
}
+function searchHeader(q) {
+ return el("div", { class: "results-head" }, [
+ backButton(clearSearch),
+ el("h2", { text: `Results for "${q}"` }),
+ ]);
+}
+
+async function clearSearch() {
+ document.getElementById("search").value = "";
+ document.getElementById("search-results").innerHTML = "";
+ await loadRecent();
+}
+
function fmtDate(iso) {
if (!iso) return "";
const d = new Date(iso.replace(" ", "T") + "Z");
@@ -494,7 +509,7 @@ function renderEditor(body, owner) {
state.editor?.destroy();
const isNew = !state.noteId;
- const back = el("button", { class: "btn ghost", text: "← Back", onclick: exitEditor });
+ const back = backButton(exitEditor);
const del = state.noteId ? el("button", { class: "btn danger", text: "Delete", onclick: deleteNote }) : null;
const hist = state.noteId ? el("button", { class: "btn ghost", text: "History", onclick: showHistory }) : null;
@@ -570,6 +585,12 @@ function renderEditor(body, owner) {
function sep() { return el("span", { class: "sep" }); }
+function backButton(onclick) {
+ return el("button", { class: "back-btn", title: "Back", "aria-label": "Back", onclick }, [
+ el("span", { class: "back-icon", html: '' }),
+ ]);
+}
+
function toolbarBtn(label, action) {
return el("button", { class: "tool-btn", text: label, onclick: () => runToolbar(action) });
}