summaryrefslogtreecommitdiffstats
path: root/popup.js
diff options
context:
space:
mode:
authorLeonardo Bishop <me@leonardobishop.net>2025-09-17 20:14:09 +0100
committerLeonardo Bishop <me@leonardobishop.net>2025-09-17 20:14:09 +0100
commit61e27eef33da20a9f174d2debee151cb8b100389 (patch)
tree454fcbe8fdac7c9e306a7df3c7bcaa907eb5a65f /popup.js
Initial commit
Diffstat (limited to 'popup.js')
-rw-r--r--popup.js202
1 files changed, 202 insertions, 0 deletions
diff --git a/popup.js b/popup.js
new file mode 100644
index 0000000..1a5cfc6
--- /dev/null
+++ b/popup.js
@@ -0,0 +1,202 @@
+import { setIcon } from "./util.js";
+
+let pageSaveState;
+let pageMetadata;
+
+function updatePageDescription() {
+ const pageTitle = document.getElementById("pageTitle");
+ const pageUrl = document.getElementById("pageUrl");
+ const pageDescription = document.getElementById("pageDescription");
+
+ const { title, url, description } = pageMetadata;
+
+ pageTitle.textContent = title;
+ pageUrl.textContent = url;
+ pageDescription.textContent = description;
+}
+
+function enablePageButtons(kind) {
+ Array.from(document.getElementsByTagName("button"))
+ .filter((element) => element.dataset.kind !== kind)
+ .forEach((element) => element.removeAttribute("disabled"));
+}
+
+function disablePageButtons() {
+ Array.from(document.getElementsByTagName("button"))
+ .filter((element) => element.classList.contains("control"))
+ .forEach((element) => element.setAttribute("disabled", "disabled"));
+}
+
+function loadSaveState(tabId) {
+ setIcon(tabId, "wait");
+
+ return browser.storage.local
+ .get(["apiUrl", "authToken"])
+ .then(({ apiUrl, authToken }) => {
+ if (!apiUrl) {
+ document.getElementById("status").textContent =
+ "API URL not configured";
+ return;
+ }
+
+ fetch(`${apiUrl}/entry`, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: authToken ? `Bearer ${authToken}` : undefined,
+ },
+ body: JSON.stringify({ url: pageMetadata.url }),
+ })
+ .then((response) => response.json())
+ .then((data) => {
+ document.getElementById("status").textContent = "";
+ if (data.code === 200) {
+ pageSaveState = data.data;
+ enablePageButtons(data.data["kind_name"]);
+ setIcon(tabId, "saved");
+ } else {
+ enablePageButtons();
+ setIcon(tabId, "ready");
+ }
+ })
+ .catch((error) => {
+ console.log(error);
+ document.getElementById("status").textContent =
+ error.status === 404 ? "" : "Request failed";
+ });
+ });
+}
+
+function savePage(kind) {
+ disablePageButtons()
+
+ browser.tabs.query({ active: true, currentWindow: true }, function (tabs) {
+ const tab = tabs[0];
+
+ setIcon(tab.id, "wait");
+
+ return browser.storage.local
+ .get(["apiUrl", "authToken"])
+ .then(({ apiUrl, authToken }) => {
+ if (!apiUrl) {
+ document.getElementById("status").textContent =
+ "API URL not configured";
+ return;
+ }
+
+ let request = pageSaveState === undefined ? {
+ method: "POST",
+ body: JSON.stringify({ kind, ...pageMetadata })
+ } : {
+ method: "PUT",
+ body: JSON.stringify({ id: pageSaveState.id, kind })
+ }
+ request.headers = {
+ "Content-Type": "application/json",
+ Authorization: authToken ? `Bearer ${authToken}` : undefined,
+ };
+
+ fetch(`${apiUrl}/record`, request)
+ .then((response) => response.json())
+ .then((data) => {
+ document.getElementById("status").textContent = "";
+ if (data.code === 200 || data.code === 201) {
+ pageSaveState = data.data;
+ enablePageButtons(kind);
+ setIcon(tab.id, "saved");
+ } else {
+ enablePageButtons();
+ setIcon(tab.id, "ready");
+ }
+ browser.runtime.sendMessage({ action: "addSavedUrl", data: { url: pageMetadata.url } });
+ })
+ .catch((error) => {
+ console.log(error);
+ document.getElementById("status").textContent =
+ error.status === 404 ? "" : "Request failed";
+ });
+ });
+ });
+}
+
+function clearPage() {
+ disablePageButtons()
+
+ browser.tabs.query({ active: true, currentWindow: true }, function (tabs) {
+ const tab = tabs[0];
+
+ setIcon(tab.id, "wait");
+
+ return browser.storage.local
+ .get(["apiUrl", "authToken"])
+ .then(({ apiUrl, authToken }) => {
+ if (!apiUrl) {
+ document.getElementById("status").textContent =
+ "API URL not configured";
+ return;
+ }
+
+ fetch(`${apiUrl}/record`, {
+ method: "DELETE",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: authToken ? `Bearer ${authToken}` : undefined,
+ },
+ body: JSON.stringify({ id: pageSaveState.id })
+ })
+ .then((response) => response.json())
+ .then(() => {
+ pageSaveState = undefined;
+ enablePageButtons();
+ setIcon(tab.id, "ready");
+ browser.runtime.sendMessage({ action: "removeSavedUrl", data: { url: pageMetadata.url } });
+ })
+ .catch((error) => {
+ console.log(error);
+ document.getElementById("status").textContent = "Request failed";
+ });
+ });
+ });
+}
+
+document.addEventListener("DOMContentLoaded", () => {
+ Array.from(document.getElementsByTagName("button"))
+ .filter((element) => element.dataset.kind !== undefined)
+ .forEach((element) => element.addEventListener('click', () => savePage(element.dataset.kind)));
+ document.getElementById("clear").addEventListener('click', () => clearPage());
+ document.getElementById("saved").addEventListener('click', () => {
+ browser.storage.local
+ .get(["apiUrl"])
+ .then(({ apiUrl }) => {
+ if (!apiUrl) {
+ document.getElementById("status").textContent =
+ "API URL not configured";
+ return;
+ }
+
+ window.open(apiUrl + "/html", "_blank").focus();
+ window.close();
+ });
+ });
+
+ browser.tabs.query({ active: true, currentWindow: true }, function (tabs) {
+ const tab = tabs[0];
+
+ browser.tabs.sendMessage(
+ tab.id,
+ { action: "getMetadata" },
+ function (metadata) {
+ if (!metadata) {
+ document.getElementById("status").textContent =
+ "Error extracting metadata";
+ return;
+ }
+
+ pageMetadata = metadata;
+
+ updatePageDescription();
+ loadSaveState(tab.id);
+ }
+ );
+ });
+});