diff options
| author | kamtschatka <simon.schatka@gmx.at> | 2024-08-18 20:52:51 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-18 21:52:51 +0300 |
| commit | 0710147ab1a3274b517acefffdaa17ece7cdd744 (patch) | |
| tree | 127ecb3521e4df8a2ee849dc9a466a8c8857e3e1 /apps | |
| parent | c7f9febf04541ac9b68a4cb6cb48251e41b51d05 (diff) | |
| download | karakeep-0710147ab1a3274b517acefffdaa17ece7cdd744.tar.zst | |
[extension] Add context menu item in the browser extension. Fixes #155 (#278)
* Add context menu item in the browser extension #155
Added a context menu entry to add links directly to hoarder
* Formalize protocol between extension and service worker, add support for text/images beside links
* fix build
---------
Co-authored-by: MohamedBassem <me@mbassem.com>
Diffstat (limited to 'apps')
| -rw-r--r-- | apps/browser-extension/package.json | 1 | ||||
| -rw-r--r-- | apps/browser-extension/src/SavePage.tsx | 50 | ||||
| -rw-r--r-- | apps/browser-extension/src/background/background.ts | 50 | ||||
| -rw-r--r-- | apps/browser-extension/src/background/protocol.ts | 1 |
4 files changed, 82 insertions, 20 deletions
diff --git a/apps/browser-extension/package.json b/apps/browser-extension/package.json index 6c40d372..7ede2c05 100644 --- a/apps/browser-extension/package.json +++ b/apps/browser-extension/package.json @@ -13,6 +13,7 @@ }, "dependencies": { "@hoarder/shared-react": "workspace:^0.1.0", + "@hoarder/shared": "workspace:^0.1.0", "@hoarder/trpc": "workspace:^0.1.0", "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-popover": "^1.0.7", diff --git a/apps/browser-extension/src/SavePage.tsx b/apps/browser-extension/src/SavePage.tsx index c6f85b3b..06530f9d 100644 --- a/apps/browser-extension/src/SavePage.tsx +++ b/apps/browser-extension/src/SavePage.tsx @@ -1,7 +1,13 @@ import { useEffect, useState } from "react"; import { Navigate } from "react-router-dom"; -import { BookmarkTypes } from "../../../packages/shared/types/bookmarks"; +import { + BookmarkTypes, + ZNewBookmarkRequest, + zNewBookmarkRequestSchema, +} from "@hoarder/shared/types/bookmarks"; + +import { NEW_BOOKMARK_REQUEST_KEY_NAME } from "./background/protocol"; import Spinner from "./Spinner"; import { api } from "./utils/trpc"; @@ -19,23 +25,37 @@ export default function SavePage() { }); useEffect(() => { + async function getNewBookmarkRequestFromBackgroundScriptIfAny(): Promise<ZNewBookmarkRequest | null> { + const { [NEW_BOOKMARK_REQUEST_KEY_NAME]: req } = + await chrome.storage.session.get(NEW_BOOKMARK_REQUEST_KEY_NAME); + if (!req) { + return null; + } + // Delete the request immediately to avoid issues with lingering values + await chrome.storage.session.remove(NEW_BOOKMARK_REQUEST_KEY_NAME); + return zNewBookmarkRequestSchema.parse(req); + } + async function runSave() { - let currentUrl; - const [currentTab] = await chrome.tabs.query({ - active: true, - lastFocusedWindow: true, - }); - if (currentTab?.url) { - currentUrl = currentTab.url; - } else { - setError("Couldn't find the URL of the current tab"); - return; + let newBookmarkRequest = + await getNewBookmarkRequestFromBackgroundScriptIfAny(); + if (!newBookmarkRequest) { + const [currentTab] = await chrome.tabs.query({ + active: true, + lastFocusedWindow: true, + }); + if (currentTab?.url) { + newBookmarkRequest = { + type: BookmarkTypes.LINK, + url: currentTab.url, + }; + } else { + setError("Couldn't find the URL of the current tab"); + return; + } } - createBookmark({ - type: BookmarkTypes.LINK, - url: currentUrl, - }); + createBookmark(newBookmarkRequest); } runSave(); }, [createBookmark]); diff --git a/apps/browser-extension/src/background/background.ts b/apps/browser-extension/src/background/background.ts index 9c4604af..cab58aa9 100644 --- a/apps/browser-extension/src/background/background.ts +++ b/apps/browser-extension/src/background/background.ts @@ -1,40 +1,79 @@ import {
+ BookmarkTypes,
+ ZNewBookmarkRequest,
+} from "@hoarder/shared/types/bookmarks.ts";
+
+import {
getPluginSettings,
Settings,
subscribeToSettingsChanges,
} from "../utils/settings.ts";
+import { NEW_BOOKMARK_REQUEST_KEY_NAME } from "./protocol.ts";
const OPEN_HOARDER_ID = "open-hoarder";
+const ADD_LINK_TO_HOARDER_ID = "add-link";
function checkSettingsState(settings: Settings) {
if (settings?.address) {
- registerContextMenu();
+ registerContextMenus();
} else {
- chrome.contextMenus.remove(OPEN_HOARDER_ID);
+ removeContextMenus();
}
}
+function removeContextMenus() {
+ chrome.contextMenus.remove(OPEN_HOARDER_ID);
+ chrome.contextMenus.remove(ADD_LINK_TO_HOARDER_ID);
+}
+
/**
- * Registers a context menu button to open a tab with the currently configured hoarder instance
+ * Registers
+ * * a context menu button to open a tab with the currently configured hoarder instance
+ * * a context menu button to add a link to hoarder without loading the page
*/
-function registerContextMenu() {
+function registerContextMenus() {
chrome.contextMenus.create({
id: OPEN_HOARDER_ID,
title: "Open Hoarder",
contexts: ["action"],
});
+ chrome.contextMenus.create({
+ id: ADD_LINK_TO_HOARDER_ID,
+ title: "Add to Hoarder",
+ contexts: ["link", "page", "selection", "image"],
+ });
}
/**
* Reads the current settings and opens a new tab with hoarder
* @param info the information about the click in the context menu
*/
-function handleContextMenuClick(info: chrome.contextMenus.OnClickData) {
+async function handleContextMenuClick(info: chrome.contextMenus.OnClickData) {
const { menuItemId } = info;
if (menuItemId === OPEN_HOARDER_ID) {
getPluginSettings().then((settings: Settings) => {
chrome.tabs.create({ url: settings.address, active: true });
});
+ } else if (menuItemId === ADD_LINK_TO_HOARDER_ID) {
+ let newBookmark: ZNewBookmarkRequest | null = null;
+ if (info.selectionText) {
+ newBookmark = {
+ type: BookmarkTypes.TEXT,
+ text: info.selectionText,
+ // TODO: Include a source url in the snippet
+ };
+ } else if (info.srcUrl ?? info.linkUrl ?? info.pageUrl) {
+ newBookmark = {
+ type: BookmarkTypes.LINK,
+ url: info.srcUrl ?? info.linkUrl ?? info.pageUrl,
+ };
+ }
+ if (newBookmark) {
+ await chrome.storage.session.set({
+ [NEW_BOOKMARK_REQUEST_KEY_NAME]: newBookmark,
+ });
+ await chrome.action.openPopup();
+ }
}
}
@@ -46,4 +85,5 @@ subscribeToSettingsChanges((settings) => { checkSettingsState(settings);
});
+// eslint-disable-next-line @typescript-eslint/no-misused-promises -- Manifest V3 allows async functions for all callbacks
chrome.contextMenus.onClicked.addListener(handleContextMenuClick);
diff --git a/apps/browser-extension/src/background/protocol.ts b/apps/browser-extension/src/background/protocol.ts new file mode 100644 index 00000000..f4bcbcd8 --- /dev/null +++ b/apps/browser-extension/src/background/protocol.ts @@ -0,0 +1 @@ +export const NEW_BOOKMARK_REQUEST_KEY_NAME = "hoarder-new-bookmark"; |
