From dfefb12ccc4b1709de7e86c046142c8b22c0e264 Mon Sep 17 00:00:00 2001 From: Lukas Werner Date: Tue, 18 Nov 2025 13:05:53 -0800 Subject: [PATCH] feat: allow editing of bookmarks from chrome extension --- chrome-extension/src/api.js | 85 ++++++++++++++++++++++++++++++ chrome-extension/src/background.js | 15 ++---- chrome-extension/src/popup.js | 74 +++++++++++++++----------- store/database.go | 6 ++- 4 files changed, 135 insertions(+), 45 deletions(-) create mode 100644 chrome-extension/src/api.js diff --git a/chrome-extension/src/api.js b/chrome-extension/src/api.js new file mode 100644 index 0000000..8e6550b --- /dev/null +++ b/chrome-extension/src/api.js @@ -0,0 +1,85 @@ +async function createBookmark(apiKey, { + url, + title, + description, + tags, +}) { + const bookmark = { + + Url: url, + Title: title, + Description: description, + Tags: tags, + } + + const response = await fetch( + "http://localhost:1990/api/bookmarks", + { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${apiKey}`, + }, + body: JSON.stringify(bookmark), + }, + ); + + + return response; +} + + +async function updateBookmark(apiKey, original_url, { + url, + title, + description, + tags, +}) { + const bookmark = { + + Url: url, + Title: title, + Description: description, + Tags: tags, + } + + const response = await fetch( + `http://localhost:1990/api/bookmarks?url=${encodeURIComponent( + original_url, + ) + }`, + { + method: "PATCH", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${apiKey}`, + }, + body: JSON.stringify(bookmark), + }, + ); + + + return response; +} + +async function getBookmark(apiKey, url) { + const response = await fetch( + `http://localhost:1990/api/bookmarks?url=${encodeURIComponent( + url, + ) + }`, + { + method: "GET", + headers: { + Authorization: `Bearer ${apiKey}`, + }, + }, + ); + return response; +} + +export { + getBookmark, + updateBookmark, + createBookmark +} diff --git a/chrome-extension/src/background.js b/chrome-extension/src/background.js index 515646b..61b40e4 100644 --- a/chrome-extension/src/background.js +++ b/chrome-extension/src/background.js @@ -1,3 +1,5 @@ +import * as api from "./api.js"; + // Add listener for tab activation and update events chrome.tabs.onActivated.addListener((activeInfo) => { console.log("Tab activated:", activeInfo.tabId); @@ -32,18 +34,7 @@ async function checkIfBookmarked(tabId) { } // Check if the URL is bookmarked - const response = await fetch( - `http://localhost:1990/api/bookmarks?url=${encodeURIComponent( - tab_reponse.url, - ) - }`, - { - method: "GET", - headers: { - Authorization: `Bearer ${apiToken}`, - }, - }, - ); + const response = await api.getBookmark(apiToken, tab_reponse.url); if (response.ok) { // URL is bookmarked diff --git a/chrome-extension/src/popup.js b/chrome-extension/src/popup.js index ddc8009..5f37607 100644 --- a/chrome-extension/src/popup.js +++ b/chrome-extension/src/popup.js @@ -1,5 +1,6 @@ import { generateDescription } from "./description_generation"; import { generateTagsWithOllama } from "./tag_generation"; +import * as api from "./api.js"; function createTagElement(tag) { const tagElement = document.createElement("span"); @@ -37,9 +38,11 @@ function updateStatus(message) { let pageInfo = null; +let editing = false; +let bookmark = null; let tags = new Set(); -async function initializeDetailedSave() { +async function preFillPopup() { try { const tabs = await chrome.tabs.query({ active: true, currentWindow: true }); if (!tabs[0]) return; @@ -52,6 +55,28 @@ async function initializeDetailedSave() { } catch (error) { updateStatus("Error: Could not load page data"); console.error(error); + return; + } + + + const { apiToken } = await chrome.storage.sync.get([ + "apiToken", + ]); + if (!apiToken) { + updateStatus( + "Please set your API token in extension options", + ); + return; + } + + let resp = await api.getBookmark(apiToken, pageInfo.url); + if (resp.ok) { + editing = true; + bookmark = await resp.json(); + bookmark.Tags.map(addTag) + document.getElementById("title").value = bookmark.Title; + document.getElementById("description").value = bookmark.Description; + document.getElementById("saveBookmark").innerText = "Update Bookmark" } // Handle tag input @@ -114,45 +139,30 @@ async function initializeDetailedSave() { .getElementById("saveBookmark") .addEventListener("click", async () => { try { - const { apiToken } = await chrome.storage.sync.get([ - "apiToken", - ]); - if (!apiToken) { - updateStatus( - "Please set your API token in extension options", - ); - return; - } - if (!pageInfo) { updateStatus("Error: Page information not available"); return; } - const bookmark = { - Url: pageInfo.url, - Title: document.getElementById("title").value, - Description: document.getElementById("description").value, - Tags: Array.from(tags), - }; - - const response = await fetch( - "http://localhost:1990/api/bookmarks", - { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${apiToken}`, - }, - body: JSON.stringify(bookmark), - }, - ); + let data = { + url: pageInfo.url, + title: document.getElementById("title").value, + description: document.getElementById("description").value, + tags: Array.from(tags), + } + let response; + if (!editing) { + response = await api.createBookmark(apiToken, data); + } else { + data.url = bookmark.Url; // Keep bookmark URL the same + response = await api.updateBookmark(apiToken, bookmark.Url, data); + } + if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } - - updateStatus("Saved successfully!"); + updateStatus(editing ? "Bookmark updated!" : "Saved successfully!"); setTimeout(() => window.close(), 1000); } catch (error) { updateStatus(`Error: ${error.message}`); @@ -162,5 +172,5 @@ async function initializeDetailedSave() { document.addEventListener("DOMContentLoaded", function() { console.log("dom loaded!") - initializeDetailedSave() + preFillPopup() }); diff --git a/store/database.go b/store/database.go index e3c14c9..02d5821 100644 --- a/store/database.go +++ b/store/database.go @@ -218,7 +218,11 @@ func GetBookmark(db *DB, query_url string) (Bookmark, error) { if err != nil { return b, err } - b.Tags = strings.Split(tags, ", ") + if len(tags) > 0 { + b.Tags = strings.Split(tags, ", ") + } else { + b.Tags = []string{} + } i++ } -- 2.51.2