diff --git a/package.json b/package.json index 167779fe..f889fde0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "selection-command-monorepo", - "version": "0.16.0", + "version": "0.17.0", "private": true, "description": "Selection Command - Monorepo for Chrome Extension and Hub", "author": "ujiro99", diff --git a/packages/extension/manifest.json b/packages/extension/manifest.json index 71377c7d..addd9092 100644 --- a/packages/extension/manifest.json +++ b/packages/extension/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 3, "name": "__MSG_extName__", "description": "__MSG_extDescription__", - "version": "0.16.0", + "version": "0.17.0", "default_locale": "en", "icons": { "128": "icon128.png" diff --git a/packages/extension/package.json b/packages/extension/package.json index bc82c435..8994a87d 100644 --- a/packages/extension/package.json +++ b/packages/extension/package.json @@ -1,6 +1,6 @@ { "name": "@selection-command/extension", - "version": "0.16.0", + "version": "0.17.0", "private": true, "author": "ujiro99", "license": "MIT", diff --git a/packages/extension/src/action/sidePanel.ts b/packages/extension/src/action/sidePanel.ts index f59f2cd8..bd25ec90 100644 --- a/packages/extension/src/action/sidePanel.ts +++ b/packages/extension/src/action/sidePanel.ts @@ -1,8 +1,9 @@ -import { isValidString, toUrl } from "@/lib/utils" +import { isValidString, toUrl, isEmpty } from "@/lib/utils" import { SPACE_ENCODING } from "@/const" -import type { ExecuteCommandParams } from "@/types" +import type { ExecuteCommandParams, ShowToastParam } from "@/types" import type { OpenSidePanelProps } from "@/services/chrome" -import { Ipc, BgCommand } from "@/services/ipc" +import { Ipc, BgCommand, TabCommand } from "@/services/ipc" +import { t } from "@/services/i18n" export const SidePanel = { async execute({ @@ -14,14 +15,33 @@ export const SidePanel = { console.error("searchUrl is not valid.") return } - + // Read clipboard text for interpolation, but don't block execution if it fails. + let clipboardText: string = "" try { - const url = toUrl({ - searchUrl: command.searchUrl, - spaceEncoding: command.spaceEncoding ?? SPACE_ENCODING.PLUS, - selectionText, - useClipboard: useClipboard ?? false, + if (useClipboard && isEmpty(selectionText)) { + clipboardText = await navigator.clipboard.readText() + } + } catch (e) { + console.warn("Failed to read clipboard text:", e) + + const tabId = await Ipc.getActiveTabId() + await Ipc.sendTab(tabId, TabCommand.showToast, { + title: t("clipboard_error_title"), + description: t("clipboard_error_description"), + action: t("clipboard_error_action"), }) + } + + try { + const url = toUrl( + { + searchUrl: command.searchUrl, + spaceEncoding: command.spaceEncoding ?? SPACE_ENCODING.PLUS, + selectionText, + useClipboard: useClipboard ?? false, + }, + clipboardText, + ) Ipc.send(BgCommand.openSidePanel, { url, diff --git a/packages/extension/src/background_script.ts b/packages/extension/src/background_script.ts index 736f6034..409c41e8 100644 --- a/packages/extension/src/background_script.ts +++ b/packages/extension/src/background_script.ts @@ -580,19 +580,12 @@ chrome.commands.onCommand.addListener(async (commandName) => { return } - // Get active tab - const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }) const command = settings.commands.find((c) => c.id === shortcut.commandId) if (!command) { console.warn(`Command not found: ${shortcut.commandId}`) return } - const enableSendTab = - tab?.id && - !tab.url?.startsWith("chrome") && - !tab.url?.includes("chromewebstore.google.com") - const selectionText = await Storage.get( SESSION_STORAGE_KEY.SELECTION_TEXT, ) @@ -613,6 +606,13 @@ chrome.commands.onCommand.addListener(async (commandName) => { } } + // Get active tab + const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }) + const enableSendTab = + tab?.id && + !tab.url?.startsWith("chrome") && + !tab.url?.includes("chromewebstore.google.com") + let ret: unknown if (enableSendTab) { // Execute command in tab diff --git a/packages/extension/src/services/chrome.ts b/packages/extension/src/services/chrome.ts index 65afe51f..946fe324 100644 --- a/packages/extension/src/services/chrome.ts +++ b/packages/extension/src/services/chrome.ts @@ -681,8 +681,7 @@ export const openSidePanel = async ( ): Promise<{ tabId: number | undefined }> => { const { url, tabId } = param - const targetTabId = tabId - if (!targetTabId) { + if (!tabId) { console.warn("No valid tab ID for side panel") return { tabId: undefined, @@ -692,17 +691,20 @@ export const openSidePanel = async ( // Set the side panel options for the tab // Do not await here because sidePanel.open() must be executed within a user gesture. chrome.sidePanel.setOptions({ - tabId: targetTabId, + tabId, path: toUrl(url), enabled: true, }) // Open the side panel - await chrome.sidePanel.open({ tabId: targetTabId }) - - return { - tabId: targetTabId, + try { + await chrome.sidePanel.open({ tabId }) + } catch (e) { + console.error("Failed to open side panel:", e) + throw e } + + return { tabId } } const SIDE_PANEL_CLOSE_ANIMATION = 1000