From 9752b1852981939e8c3c8253834a58ecf78748cb Mon Sep 17 00:00:00 2001 From: Bruno Charest Date: Tue, 26 May 2026 20:19:58 -0400 Subject: [PATCH] Add dark theme support and bookmark status to share view - Implement dark/light theme toggle with persistent preference via localStorage - Add a sticky toolbar with theme toggle, Markdown export, and PDF export buttons - Update bookmark button to reflect current state with visual feedback - Introduce CSS custom properties for theming and responsive layout improvements --- backend/main.py | 46 +++++++++++++++++++++++++++++++++++++++++----- frontend/app.js | 16 ++++++++++++++-- frontend/style.css | 9 +++++++++ 3 files changed, 64 insertions(+), 7 deletions(-) diff --git a/backend/main.py b/backend/main.py index 8b090aa..abf1068 100644 --- a/backend/main.py +++ b/backend/main.py @@ -2812,12 +2812,48 @@ async def public_share_view(token: str): post = parse_markdown_file(raw) html = _render_markdown(post.content, share["vault"], file_path) title = post.metadata.get("title", file_path.stem) - return HTMLResponse(f""" + return HTMLResponse(f""" {title} — ObsiGate Share - -
📄 Document partagé via ObsiGate

{title}

{html}""") + + +
📄 Document partagé via ObsiGate
+
+ {title} + + + +
+
{html}
+""") # --------------------------------------------------------------------------- diff --git a/frontend/app.js b/frontend/app.js index 1fdc10e..5d25192 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -3283,11 +3283,23 @@ })(); shareBtn.addEventListener("click", () => openShareDialog(data.vault, data.path)); - // Bookmark button - const bookmarkBtn = el("button", { class: "btn-action", title: "Ajouter/Retirer des bookmarks" }, [icon("bookmark-plus", 14), document.createTextNode("Bookmark")]); + // Bookmark button — check if already bookmarked + const bookmarkBtn = el("button", { class: "btn-action btn-bookmark", title: "Ajouter/Retirer des bookmarks" }, [icon("bookmark-plus", 14), document.createTextNode("Bookmark")]); + // Check bookmark status and color the button + (async () => { + try { + const bms = await api("/api/bookmarks"); + if (Array.isArray(bms) && bms.some(b => b.vault === data.vault && b.path === data.path)) { + bookmarkBtn.classList.add("active"); + bookmarkBtn.title = "Retirer des bookmarks"; + } + } catch (e) { /* ignore */ } + })(); bookmarkBtn.addEventListener("click", async () => { try { const res = await api("/api/bookmarks/toggle", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ vault: data.vault, path: data.path, title: data.title }) }); + bookmarkBtn.classList.toggle("active", res.bookmarked); + bookmarkBtn.title = res.bookmarked ? "Retirer des bookmarks" : "Ajouter aux bookmarks"; showToast(res.bookmarked ? "Ajouté aux bookmarks" : "Retiré des bookmarks", "success"); if (typeof DashboardBookmarkWidget !== "undefined") DashboardBookmarkWidget.load(); } catch (err) { showToast("Erreur: " + err.message, "error"); } diff --git a/frontend/style.css b/frontend/style.css index 1589bc2..4503ac4 100644 --- a/frontend/style.css +++ b/frontend/style.css @@ -5830,6 +5830,15 @@ body.popup-mode .content-area { .search-replace-btn.destructive { border-color: var(--text-error); color: var(--text-error); } /* ── Active search result highlight ── */ +.btn-bookmark.active { + color: #059669; + border-color: #059669; + background: rgba(5, 150, 105, 0.08); +} +.btn-bookmark.active:hover { + background: rgba(5, 150, 105, 0.15); +} + .btn-share.shared { color: #059669; border-color: #059669;