From f3f8dfb780e0401535ce2413ebb8936e0ba9d36f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Feb 2026 23:18:26 +0000 Subject: [PATCH 1/7] Initial plan From 4fe34fcdd4fd37f5b1ca8e2ba766569e5b8aed05 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Feb 2026 23:26:56 +0000 Subject: [PATCH 2/7] Add SidePanel option to link preview open modes Co-authored-by: ujiro99 <677231+ujiro99@users.noreply.github.com> --- packages/extension/public/_locales/de/messages.json | 9 +++++++++ packages/extension/public/_locales/en/messages.json | 9 +++++++++ packages/extension/public/_locales/es/messages.json | 9 +++++++++ packages/extension/public/_locales/fr/messages.json | 9 +++++++++ packages/extension/public/_locales/hi/messages.json | 9 +++++++++ packages/extension/public/_locales/id/messages.json | 9 +++++++++ packages/extension/public/_locales/it/messages.json | 9 +++++++++ packages/extension/public/_locales/ja/messages.json | 9 +++++++++ packages/extension/public/_locales/ko/messages.json | 9 +++++++++ packages/extension/public/_locales/ms/messages.json | 9 +++++++++ packages/extension/public/_locales/pt_BR/messages.json | 9 +++++++++ packages/extension/public/_locales/pt_PT/messages.json | 9 +++++++++ packages/extension/public/_locales/ru/messages.json | 9 +++++++++ packages/extension/public/_locales/zh_CN/messages.json | 9 +++++++++ packages/extension/src/action/linkPreview.ts | 8 ++++++++ packages/extension/src/components/option/SettingForm.tsx | 6 ++++++ packages/extension/src/const.ts | 1 + 17 files changed, 141 insertions(+) diff --git a/packages/extension/public/_locales/de/messages.json b/packages/extension/public/_locales/de/messages.json index 2cb260fe..4571d2fb 100644 --- a/packages/extension/public/_locales/de/messages.json +++ b/packages/extension/public/_locales/de/messages.json @@ -212,6 +212,12 @@ "Option_popupAutoCloseDelay_placeholder": { "message": "0 (sofort schließen)" }, + "Option_sidePanelAutoHide": { + "message": "Side Panel Auto-Hide" + }, + "Option_sidePanelAutoHide_desc": { + "message": "Automatically hide the side panel when the main panel is clicked." + }, "Option_inherit": { "message": "Erben" }, @@ -365,6 +371,9 @@ "Option_openMode_previewWindow": { "message": "Fenster" }, + "Option_openMode_previewSidePanel": { + "message": "Side Panel" + }, "Option_openModeSecondary": { "message": " ┗ Strg + Klick" }, diff --git a/packages/extension/public/_locales/en/messages.json b/packages/extension/public/_locales/en/messages.json index 2a6a37fd..2232d40f 100644 --- a/packages/extension/public/_locales/en/messages.json +++ b/packages/extension/public/_locales/en/messages.json @@ -212,6 +212,12 @@ "Option_popupAutoCloseDelay_placeholder": { "message": "0 (close immediately)" }, + "Option_sidePanelAutoHide": { + "message": "Side Panel Auto-Hide" + }, + "Option_sidePanelAutoHide_desc": { + "message": "Automatically hide the side panel when the main panel is clicked." + }, "Option_inherit": { "message": "Inherit" }, @@ -365,6 +371,9 @@ "Option_openMode_previewWindow": { "message": "Window" }, + "Option_openMode_previewSidePanel": { + "message": "Side Panel" + }, "Option_openModeSecondary": { "message": " ┗ Ctrl + Click" }, diff --git a/packages/extension/public/_locales/es/messages.json b/packages/extension/public/_locales/es/messages.json index 7ddb0d23..d9ee91d9 100644 --- a/packages/extension/public/_locales/es/messages.json +++ b/packages/extension/public/_locales/es/messages.json @@ -212,6 +212,12 @@ "Option_popupAutoCloseDelay_placeholder": { "message": "0 (cerrar inmediatamente)" }, + "Option_sidePanelAutoHide": { + "message": "Side Panel Auto-Hide" + }, + "Option_sidePanelAutoHide_desc": { + "message": "Automatically hide the side panel when the main panel is clicked." + }, "Option_inherit": { "message": "Heredar" }, @@ -365,6 +371,9 @@ "Option_openMode_previewWindow": { "message": "Ventana" }, + "Option_openMode_previewSidePanel": { + "message": "Side Panel" + }, "Option_openModeSecondary": { "message": " ┗ Ctrl + Clic" }, diff --git a/packages/extension/public/_locales/fr/messages.json b/packages/extension/public/_locales/fr/messages.json index f2f29ed6..16a7db05 100644 --- a/packages/extension/public/_locales/fr/messages.json +++ b/packages/extension/public/_locales/fr/messages.json @@ -212,6 +212,12 @@ "Option_popupAutoCloseDelay_placeholder": { "message": "0 (fermer immédiatement)" }, + "Option_sidePanelAutoHide": { + "message": "Side Panel Auto-Hide" + }, + "Option_sidePanelAutoHide_desc": { + "message": "Automatically hide the side panel when the main panel is clicked." + }, "Option_inherit": { "message": "Hériter" }, @@ -365,6 +371,9 @@ "Option_openMode_previewWindow": { "message": "Fenêtre" }, + "Option_openMode_previewSidePanel": { + "message": "Side Panel" + }, "Option_openModeSecondary": { "message": " ┗ Ctrl + Clic" }, diff --git a/packages/extension/public/_locales/hi/messages.json b/packages/extension/public/_locales/hi/messages.json index 700f4f31..69a6e195 100644 --- a/packages/extension/public/_locales/hi/messages.json +++ b/packages/extension/public/_locales/hi/messages.json @@ -212,6 +212,12 @@ "Option_popupAutoCloseDelay_placeholder": { "message": "0 (तुरंत बंद करें)" }, + "Option_sidePanelAutoHide": { + "message": "Side Panel Auto-Hide" + }, + "Option_sidePanelAutoHide_desc": { + "message": "Automatically hide the side panel when the main panel is clicked." + }, "Option_inherit": { "message": "प्राप्त करें" }, @@ -365,6 +371,9 @@ "Option_openMode_previewWindow": { "message": "विंडो" }, + "Option_openMode_previewSidePanel": { + "message": "Side Panel" + }, "Option_openModeSecondary": { "message": " ┗ Ctrl + क्लिक" }, diff --git a/packages/extension/public/_locales/id/messages.json b/packages/extension/public/_locales/id/messages.json index b1d44abc..d55297b1 100644 --- a/packages/extension/public/_locales/id/messages.json +++ b/packages/extension/public/_locales/id/messages.json @@ -212,6 +212,12 @@ "Option_popupAutoCloseDelay_placeholder": { "message": "0 (tutup segera)" }, + "Option_sidePanelAutoHide": { + "message": "Side Panel Auto-Hide" + }, + "Option_sidePanelAutoHide_desc": { + "message": "Automatically hide the side panel when the main panel is clicked." + }, "Option_inherit": { "message": "Warisi" }, @@ -365,6 +371,9 @@ "Option_openMode_previewWindow": { "message": "Jendela" }, + "Option_openMode_previewSidePanel": { + "message": "Side Panel" + }, "Option_openModeSecondary": { "message": " ┗ Ctrl + Klik" }, diff --git a/packages/extension/public/_locales/it/messages.json b/packages/extension/public/_locales/it/messages.json index 7381941f..d6139400 100644 --- a/packages/extension/public/_locales/it/messages.json +++ b/packages/extension/public/_locales/it/messages.json @@ -212,6 +212,12 @@ "Option_popupAutoCloseDelay_placeholder": { "message": "0 (chiudi immediatamente)" }, + "Option_sidePanelAutoHide": { + "message": "Side Panel Auto-Hide" + }, + "Option_sidePanelAutoHide_desc": { + "message": "Automatically hide the side panel when the main panel is clicked." + }, "Option_inherit": { "message": "Eredita" }, @@ -365,6 +371,9 @@ "Option_openMode_previewWindow": { "message": "Finestra" }, + "Option_openMode_previewSidePanel": { + "message": "Side Panel" + }, "Option_openModeSecondary": { "message": " ┗ Ctrl + clic" }, diff --git a/packages/extension/public/_locales/ja/messages.json b/packages/extension/public/_locales/ja/messages.json index 4d8fcad8..92cca044 100644 --- a/packages/extension/public/_locales/ja/messages.json +++ b/packages/extension/public/_locales/ja/messages.json @@ -212,6 +212,12 @@ "Option_popupAutoCloseDelay_placeholder": { "message": "0 (即座に閉じる)" }, + "Option_sidePanelAutoHide": { + "message": "サイドパネル自動非表示" + }, + "Option_sidePanelAutoHide_desc": { + "message": "メインのパネルをクリックしたときに、サイドパネルを自動的に非表示にします。" + }, "Option_inherit": { "message": "継承" }, @@ -365,6 +371,9 @@ "Option_openMode_previewWindow": { "message": "Window" }, + "Option_openMode_previewSidePanel": { + "message": "サイドパネル" + }, "Option_openModeSecondary": { "message": " ┗ Ctrl + クリック" }, diff --git a/packages/extension/public/_locales/ko/messages.json b/packages/extension/public/_locales/ko/messages.json index e2cfa418..0fd6fb5b 100644 --- a/packages/extension/public/_locales/ko/messages.json +++ b/packages/extension/public/_locales/ko/messages.json @@ -212,6 +212,12 @@ "Option_popupAutoCloseDelay_placeholder": { "message": "0 (즉시 닫기)" }, + "Option_sidePanelAutoHide": { + "message": "Side Panel Auto-Hide" + }, + "Option_sidePanelAutoHide_desc": { + "message": "Automatically hide the side panel when the main panel is clicked." + }, "Option_inherit": { "message": "상속" }, @@ -365,6 +371,9 @@ "Option_openMode_previewWindow": { "message": "창" }, + "Option_openMode_previewSidePanel": { + "message": "Side Panel" + }, "Option_openModeSecondary": { "message": " ┗ Ctrl + 클릭" }, diff --git a/packages/extension/public/_locales/ms/messages.json b/packages/extension/public/_locales/ms/messages.json index 7bbbbbb9..b9ebdaac 100644 --- a/packages/extension/public/_locales/ms/messages.json +++ b/packages/extension/public/_locales/ms/messages.json @@ -212,6 +212,12 @@ "Option_popupAutoCloseDelay_placeholder": { "message": "0 (tutup segera)" }, + "Option_sidePanelAutoHide": { + "message": "Side Panel Auto-Hide" + }, + "Option_sidePanelAutoHide_desc": { + "message": "Automatically hide the side panel when the main panel is clicked." + }, "Option_inherit": { "message": "Warisi" }, @@ -365,6 +371,9 @@ "Option_openMode_previewWindow": { "message": "Tetingkap" }, + "Option_openMode_previewSidePanel": { + "message": "Side Panel" + }, "Option_openModeSecondary": { "message": " ┗ Ctrl + Klik" }, diff --git a/packages/extension/public/_locales/pt_BR/messages.json b/packages/extension/public/_locales/pt_BR/messages.json index f1682e77..fd848617 100644 --- a/packages/extension/public/_locales/pt_BR/messages.json +++ b/packages/extension/public/_locales/pt_BR/messages.json @@ -212,6 +212,12 @@ "Option_popupAutoCloseDelay_placeholder": { "message": "0 (fechar imediatamente)" }, + "Option_sidePanelAutoHide": { + "message": "Side Panel Auto-Hide" + }, + "Option_sidePanelAutoHide_desc": { + "message": "Automatically hide the side panel when the main panel is clicked." + }, "Option_inherit": { "message": "Herdar" }, @@ -365,6 +371,9 @@ "Option_openMode_previewWindow": { "message": "Janela" }, + "Option_openMode_previewSidePanel": { + "message": "Side Panel" + }, "Option_openModeSecondary": { "message": " ┗ Ctrl + Clique" }, diff --git a/packages/extension/public/_locales/pt_PT/messages.json b/packages/extension/public/_locales/pt_PT/messages.json index f4f49e35..090fafcd 100644 --- a/packages/extension/public/_locales/pt_PT/messages.json +++ b/packages/extension/public/_locales/pt_PT/messages.json @@ -212,6 +212,12 @@ "Option_popupAutoCloseDelay_placeholder": { "message": "0 (fechar imediatamente)" }, + "Option_sidePanelAutoHide": { + "message": "Side Panel Auto-Hide" + }, + "Option_sidePanelAutoHide_desc": { + "message": "Automatically hide the side panel when the main panel is clicked." + }, "Option_inherit": { "message": "Herdar" }, @@ -365,6 +371,9 @@ "Option_openMode_previewWindow": { "message": "Janela" }, + "Option_openMode_previewSidePanel": { + "message": "Side Panel" + }, "Option_openModeSecondary": { "message": " ┗ Ctrl + Clique" }, diff --git a/packages/extension/public/_locales/ru/messages.json b/packages/extension/public/_locales/ru/messages.json index 039ec78e..8c0c8722 100644 --- a/packages/extension/public/_locales/ru/messages.json +++ b/packages/extension/public/_locales/ru/messages.json @@ -212,6 +212,12 @@ "Option_popupAutoCloseDelay_placeholder": { "message": "0 (закрыть немедленно)" }, + "Option_sidePanelAutoHide": { + "message": "Side Panel Auto-Hide" + }, + "Option_sidePanelAutoHide_desc": { + "message": "Automatically hide the side panel when the main panel is clicked." + }, "Option_inherit": { "message": "Наследовать" }, @@ -365,6 +371,9 @@ "Option_openMode_previewWindow": { "message": "Окно" }, + "Option_openMode_previewSidePanel": { + "message": "Side Panel" + }, "Option_openModeSecondary": { "message": " ┗ Ctrl + клик" }, diff --git a/packages/extension/public/_locales/zh_CN/messages.json b/packages/extension/public/_locales/zh_CN/messages.json index 9a43837c..389220f5 100644 --- a/packages/extension/public/_locales/zh_CN/messages.json +++ b/packages/extension/public/_locales/zh_CN/messages.json @@ -212,6 +212,12 @@ "Option_popupAutoCloseDelay_placeholder": { "message": "0(立即关闭)" }, + "Option_sidePanelAutoHide": { + "message": "Side Panel Auto-Hide" + }, + "Option_sidePanelAutoHide_desc": { + "message": "Automatically hide the side panel when the main panel is clicked." + }, "Option_inherit": { "message": "获取" }, @@ -365,6 +371,9 @@ "Option_openMode_previewWindow": { "message": "窗口" }, + "Option_openMode_previewSidePanel": { + "message": "Side Panel" + }, "Option_openModeSecondary": { "message": " ┗ Ctrl + 点击" }, diff --git a/packages/extension/src/action/linkPreview.ts b/packages/extension/src/action/linkPreview.ts index f55f24d1..bc8e347c 100644 --- a/packages/extension/src/action/linkPreview.ts +++ b/packages/extension/src/action/linkPreview.ts @@ -8,6 +8,7 @@ import { getScreenSize } from "@/services/screen" import { DRAG_OPEN_MODE, POPUP_TYPE } from "@/const" import { isEmpty } from "@/lib/utils" import type { ExecuteCommandParams } from "@/types" +import type { OpenSidePanelProps } from "@/services/chrome" export const LinkPreview = { async execute({ command, position, target }: ExecuteCommandParams) { @@ -15,6 +16,13 @@ export const LinkPreview = { const elm = findAnchorElementFromParent(target) as HTMLAnchorElement const href = elm?.href + if (command.openMode === DRAG_OPEN_MODE.PREVIEW_SIDE_PANEL) { + if (!isEmpty(href)) { + Ipc.send(BgCommand.openSidePanel, { url: href }) + } + return + } + const type = command.openMode === DRAG_OPEN_MODE.PREVIEW_POPUP ? POPUP_TYPE.POPUP diff --git a/packages/extension/src/components/option/SettingForm.tsx b/packages/extension/src/components/option/SettingForm.tsx index 8c8d6316..443a4b65 100644 --- a/packages/extension/src/components/option/SettingForm.tsx +++ b/packages/extension/src/components/option/SettingForm.tsx @@ -615,6 +615,12 @@ export function SettingForm({ className }: { className?: string }) { }} /> )} +
diff --git a/packages/extension/src/const.ts b/packages/extension/src/const.ts index 847d8546..5964c642 100644 --- a/packages/extension/src/const.ts +++ b/packages/extension/src/const.ts @@ -139,6 +139,7 @@ export enum ExecState { export enum DRAG_OPEN_MODE { PREVIEW_POPUP = "previewPopup", PREVIEW_WINDOW = "previewWindow", + PREVIEW_SIDE_PANEL = "previewSidePanel", } export enum SIDE { From 33d4b4834b7683a76d7932f2cb5b796bd4fc2e23 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Feb 2026 23:29:32 +0000 Subject: [PATCH 3/7] Add localized translations for previewSidePanel and sidePanelAutoHide keys Co-authored-by: ujiro99 <677231+ujiro99@users.noreply.github.com> --- packages/extension/public/_locales/de/messages.json | 6 +++--- packages/extension/public/_locales/es/messages.json | 6 +++--- packages/extension/public/_locales/fr/messages.json | 6 +++--- packages/extension/public/_locales/hi/messages.json | 6 +++--- packages/extension/public/_locales/id/messages.json | 6 +++--- packages/extension/public/_locales/it/messages.json | 6 +++--- packages/extension/public/_locales/ko/messages.json | 6 +++--- packages/extension/public/_locales/ms/messages.json | 6 +++--- packages/extension/public/_locales/pt_BR/messages.json | 6 +++--- packages/extension/public/_locales/pt_PT/messages.json | 6 +++--- packages/extension/public/_locales/ru/messages.json | 6 +++--- packages/extension/public/_locales/zh_CN/messages.json | 6 +++--- 12 files changed, 36 insertions(+), 36 deletions(-) diff --git a/packages/extension/public/_locales/de/messages.json b/packages/extension/public/_locales/de/messages.json index 4571d2fb..0305226d 100644 --- a/packages/extension/public/_locales/de/messages.json +++ b/packages/extension/public/_locales/de/messages.json @@ -213,10 +213,10 @@ "message": "0 (sofort schließen)" }, "Option_sidePanelAutoHide": { - "message": "Side Panel Auto-Hide" + "message": "Seitenbereich automatisch ausblenden" }, "Option_sidePanelAutoHide_desc": { - "message": "Automatically hide the side panel when the main panel is clicked." + "message": "Blendet den Seitenbereich automatisch aus, wenn in den Hauptbereich geklickt wird." }, "Option_inherit": { "message": "Erben" @@ -372,7 +372,7 @@ "message": "Fenster" }, "Option_openMode_previewSidePanel": { - "message": "Side Panel" + "message": "Seitenbereich" }, "Option_openModeSecondary": { "message": " ┗ Strg + Klick" diff --git a/packages/extension/public/_locales/es/messages.json b/packages/extension/public/_locales/es/messages.json index d9ee91d9..4fed6ad9 100644 --- a/packages/extension/public/_locales/es/messages.json +++ b/packages/extension/public/_locales/es/messages.json @@ -213,10 +213,10 @@ "message": "0 (cerrar inmediatamente)" }, "Option_sidePanelAutoHide": { - "message": "Side Panel Auto-Hide" + "message": "Ocultar panel lateral automáticamente" }, "Option_sidePanelAutoHide_desc": { - "message": "Automatically hide the side panel when the main panel is clicked." + "message": "Oculta automáticamente el panel lateral cuando se hace clic en el panel principal." }, "Option_inherit": { "message": "Heredar" @@ -372,7 +372,7 @@ "message": "Ventana" }, "Option_openMode_previewSidePanel": { - "message": "Side Panel" + "message": "Panel lateral" }, "Option_openModeSecondary": { "message": " ┗ Ctrl + Clic" diff --git a/packages/extension/public/_locales/fr/messages.json b/packages/extension/public/_locales/fr/messages.json index 16a7db05..ac9e3116 100644 --- a/packages/extension/public/_locales/fr/messages.json +++ b/packages/extension/public/_locales/fr/messages.json @@ -213,10 +213,10 @@ "message": "0 (fermer immédiatement)" }, "Option_sidePanelAutoHide": { - "message": "Side Panel Auto-Hide" + "message": "Masquage automatique du panneau latéral" }, "Option_sidePanelAutoHide_desc": { - "message": "Automatically hide the side panel when the main panel is clicked." + "message": "Masque automatiquement le panneau latéral lorsque le panneau principal est cliqué." }, "Option_inherit": { "message": "Hériter" @@ -372,7 +372,7 @@ "message": "Fenêtre" }, "Option_openMode_previewSidePanel": { - "message": "Side Panel" + "message": "Panneau latéral" }, "Option_openModeSecondary": { "message": " ┗ Ctrl + Clic" diff --git a/packages/extension/public/_locales/hi/messages.json b/packages/extension/public/_locales/hi/messages.json index 69a6e195..38bf12d8 100644 --- a/packages/extension/public/_locales/hi/messages.json +++ b/packages/extension/public/_locales/hi/messages.json @@ -213,10 +213,10 @@ "message": "0 (तुरंत बंद करें)" }, "Option_sidePanelAutoHide": { - "message": "Side Panel Auto-Hide" + "message": "साइड पैनल स्वतः छिपाएं" }, "Option_sidePanelAutoHide_desc": { - "message": "Automatically hide the side panel when the main panel is clicked." + "message": "मुख्य पैनल पर क्लिक करने पर साइड पैनल को स्वतः छिपा देता है।" }, "Option_inherit": { "message": "प्राप्त करें" @@ -372,7 +372,7 @@ "message": "विंडो" }, "Option_openMode_previewSidePanel": { - "message": "Side Panel" + "message": "साइड पैनल" }, "Option_openModeSecondary": { "message": " ┗ Ctrl + क्लिक" diff --git a/packages/extension/public/_locales/id/messages.json b/packages/extension/public/_locales/id/messages.json index d55297b1..60468134 100644 --- a/packages/extension/public/_locales/id/messages.json +++ b/packages/extension/public/_locales/id/messages.json @@ -213,10 +213,10 @@ "message": "0 (tutup segera)" }, "Option_sidePanelAutoHide": { - "message": "Side Panel Auto-Hide" + "message": "Sembunyikan Panel Samping Otomatis" }, "Option_sidePanelAutoHide_desc": { - "message": "Automatically hide the side panel when the main panel is clicked." + "message": "Secara otomatis menyembunyikan panel samping saat panel utama diklik." }, "Option_inherit": { "message": "Warisi" @@ -372,7 +372,7 @@ "message": "Jendela" }, "Option_openMode_previewSidePanel": { - "message": "Side Panel" + "message": "Panel Samping" }, "Option_openModeSecondary": { "message": " ┗ Ctrl + Klik" diff --git a/packages/extension/public/_locales/it/messages.json b/packages/extension/public/_locales/it/messages.json index d6139400..2c11648d 100644 --- a/packages/extension/public/_locales/it/messages.json +++ b/packages/extension/public/_locales/it/messages.json @@ -213,10 +213,10 @@ "message": "0 (chiudi immediatamente)" }, "Option_sidePanelAutoHide": { - "message": "Side Panel Auto-Hide" + "message": "Nascondi automaticamente il pannello laterale" }, "Option_sidePanelAutoHide_desc": { - "message": "Automatically hide the side panel when the main panel is clicked." + "message": "Nasconde automaticamente il pannello laterale quando si fa clic sul pannello principale." }, "Option_inherit": { "message": "Eredita" @@ -372,7 +372,7 @@ "message": "Finestra" }, "Option_openMode_previewSidePanel": { - "message": "Side Panel" + "message": "Pannello laterale" }, "Option_openModeSecondary": { "message": " ┗ Ctrl + clic" diff --git a/packages/extension/public/_locales/ko/messages.json b/packages/extension/public/_locales/ko/messages.json index 0fd6fb5b..efb0bfb7 100644 --- a/packages/extension/public/_locales/ko/messages.json +++ b/packages/extension/public/_locales/ko/messages.json @@ -213,10 +213,10 @@ "message": "0 (즉시 닫기)" }, "Option_sidePanelAutoHide": { - "message": "Side Panel Auto-Hide" + "message": "사이드 패널 자동 숨기기" }, "Option_sidePanelAutoHide_desc": { - "message": "Automatically hide the side panel when the main panel is clicked." + "message": "메인 패널을 클릭하면 사이드 패널이 자동으로 숨겨집니다." }, "Option_inherit": { "message": "상속" @@ -372,7 +372,7 @@ "message": "창" }, "Option_openMode_previewSidePanel": { - "message": "Side Panel" + "message": "사이드 패널" }, "Option_openModeSecondary": { "message": " ┗ Ctrl + 클릭" diff --git a/packages/extension/public/_locales/ms/messages.json b/packages/extension/public/_locales/ms/messages.json index b9ebdaac..314d6455 100644 --- a/packages/extension/public/_locales/ms/messages.json +++ b/packages/extension/public/_locales/ms/messages.json @@ -213,10 +213,10 @@ "message": "0 (tutup segera)" }, "Option_sidePanelAutoHide": { - "message": "Side Panel Auto-Hide" + "message": "Sembunyikan Panel Sisi Secara Automatik" }, "Option_sidePanelAutoHide_desc": { - "message": "Automatically hide the side panel when the main panel is clicked." + "message": "Menyembunyikan panel sisi secara automatik apabila panel utama diklik." }, "Option_inherit": { "message": "Warisi" @@ -372,7 +372,7 @@ "message": "Tetingkap" }, "Option_openMode_previewSidePanel": { - "message": "Side Panel" + "message": "Panel Sisi" }, "Option_openModeSecondary": { "message": " ┗ Ctrl + Klik" diff --git a/packages/extension/public/_locales/pt_BR/messages.json b/packages/extension/public/_locales/pt_BR/messages.json index fd848617..9effa52a 100644 --- a/packages/extension/public/_locales/pt_BR/messages.json +++ b/packages/extension/public/_locales/pt_BR/messages.json @@ -213,10 +213,10 @@ "message": "0 (fechar imediatamente)" }, "Option_sidePanelAutoHide": { - "message": "Side Panel Auto-Hide" + "message": "Ocultar painel lateral automaticamente" }, "Option_sidePanelAutoHide_desc": { - "message": "Automatically hide the side panel when the main panel is clicked." + "message": "Oculta automaticamente o painel lateral quando o painel principal é clicado." }, "Option_inherit": { "message": "Herdar" @@ -372,7 +372,7 @@ "message": "Janela" }, "Option_openMode_previewSidePanel": { - "message": "Side Panel" + "message": "Painel lateral" }, "Option_openModeSecondary": { "message": " ┗ Ctrl + Clique" diff --git a/packages/extension/public/_locales/pt_PT/messages.json b/packages/extension/public/_locales/pt_PT/messages.json index 090fafcd..83b10b1e 100644 --- a/packages/extension/public/_locales/pt_PT/messages.json +++ b/packages/extension/public/_locales/pt_PT/messages.json @@ -213,10 +213,10 @@ "message": "0 (fechar imediatamente)" }, "Option_sidePanelAutoHide": { - "message": "Side Panel Auto-Hide" + "message": "Ocultar painel lateral automaticamente" }, "Option_sidePanelAutoHide_desc": { - "message": "Automatically hide the side panel when the main panel is clicked." + "message": "Oculta automaticamente o painel lateral quando o painel principal é clicado." }, "Option_inherit": { "message": "Herdar" @@ -372,7 +372,7 @@ "message": "Janela" }, "Option_openMode_previewSidePanel": { - "message": "Side Panel" + "message": "Painel lateral" }, "Option_openModeSecondary": { "message": " ┗ Ctrl + Clique" diff --git a/packages/extension/public/_locales/ru/messages.json b/packages/extension/public/_locales/ru/messages.json index 8c0c8722..b14cdb7e 100644 --- a/packages/extension/public/_locales/ru/messages.json +++ b/packages/extension/public/_locales/ru/messages.json @@ -213,10 +213,10 @@ "message": "0 (закрыть немедленно)" }, "Option_sidePanelAutoHide": { - "message": "Side Panel Auto-Hide" + "message": "Автоматически скрывать боковую панель" }, "Option_sidePanelAutoHide_desc": { - "message": "Automatically hide the side panel when the main panel is clicked." + "message": "Автоматически скрывает боковую панель при клике на основную панель." }, "Option_inherit": { "message": "Наследовать" @@ -372,7 +372,7 @@ "message": "Окно" }, "Option_openMode_previewSidePanel": { - "message": "Side Panel" + "message": "Боковая панель" }, "Option_openModeSecondary": { "message": " ┗ Ctrl + клик" diff --git a/packages/extension/public/_locales/zh_CN/messages.json b/packages/extension/public/_locales/zh_CN/messages.json index 389220f5..0e12c8f4 100644 --- a/packages/extension/public/_locales/zh_CN/messages.json +++ b/packages/extension/public/_locales/zh_CN/messages.json @@ -213,10 +213,10 @@ "message": "0(立即关闭)" }, "Option_sidePanelAutoHide": { - "message": "Side Panel Auto-Hide" + "message": "侧边栏自动隐藏" }, "Option_sidePanelAutoHide_desc": { - "message": "Automatically hide the side panel when the main panel is clicked." + "message": "点击主面板时自动隐藏侧边栏。" }, "Option_inherit": { "message": "获取" @@ -372,7 +372,7 @@ "message": "窗口" }, "Option_openMode_previewSidePanel": { - "message": "Side Panel" + "message": "侧边栏" }, "Option_openModeSecondary": { "message": " ┗ Ctrl + 点击" From d87e39f29f915d87d2fe736a0ec998dda339643a Mon Sep 17 00:00:00 2001 From: ujiro99 Date: Sun, 1 Mar 2026 17:27:48 +0900 Subject: [PATCH 4/7] Update: Enables to autoclose the sidePanel. --- packages/extension/src/action/helper.ts | 47 +++++++++++++++-- packages/extension/src/action/linkPreview.ts | 5 +- packages/extension/src/background_script.ts | 13 ++--- packages/extension/src/components/Popup.tsx | 2 + .../src/components/option/SettingForm.tsx | 45 +++++++++------- .../components/option/field/SwitchField.tsx | 30 ++++++++++- .../extension/src/hooks/useSettings.test.tsx | 1 + .../src/hooks/useSidePanelAutoClose.ts | 52 +++++++++++++++++++ .../extension/src/services/backgroundData.ts | 2 + packages/extension/src/services/chrome.ts | 22 ++------ .../src/services/option/defaultSettings.ts | 2 + .../src/services/settings/settings.ts | 14 +++++ .../src/services/windowStackManager.test.ts | 1 + packages/extension/src/types/index.ts | 1 + 14 files changed, 184 insertions(+), 53 deletions(-) create mode 100644 packages/extension/src/hooks/useSidePanelAutoClose.ts diff --git a/packages/extension/src/action/helper.ts b/packages/extension/src/action/helper.ts index 7044af4f..766a7cf2 100644 --- a/packages/extension/src/action/helper.ts +++ b/packages/extension/src/action/helper.ts @@ -123,10 +123,19 @@ export const openSidePanel = ( .then(() => { // Register the tab ID for tracking if (tabId) { + // Update BgData to include the new side panel tab ID + // If it's a link command, add to linkCommandSidePanelTabs; otherwise, add to sidePanelTabs. return BgData.update((data) => ({ - sidePanelTabs: data.sidePanelTabs.includes(tabId) - ? data.sidePanelTabs - : [...data.sidePanelTabs, tabId], + sidePanelTabs: !param.isLinkCommand + ? data.sidePanelTabs.includes(tabId) + ? data.sidePanelTabs + : [...data.sidePanelTabs, tabId] + : data.sidePanelTabs.filter((id) => id !== tabId), + linkCommandSidePanelTabs: param.isLinkCommand + ? data.linkCommandSidePanelTabs.includes(tabId) + ? data.linkCommandSidePanelTabs + : [...data.linkCommandSidePanelTabs, tabId] + : data.linkCommandSidePanelTabs.filter((id) => id !== tabId), })) } }) @@ -150,7 +159,6 @@ export const closeSidePanel = ( if (tabId == null) { return false } - enhancedSettings.get().then(async (settings) => { const sidePanelAutoHide = settings.windowOption.sidePanelAutoHide if (sidePanelAutoHide) { @@ -159,12 +167,43 @@ export const closeSidePanel = ( await _closeSidePanel(tabId) } } + const linkCommandSidePanelAutoHide = settings.linkCommand.sidePanelAutoHide + if (linkCommandSidePanelAutoHide) { + const bgData = BgData.get() + if (bgData.linkCommandSidePanelTabs.includes(tabId)) { + await _closeSidePanel(tabId) + } + } response(true) }) return true } +/** + * Handle side panel closed event for a tab + * @param {number} tabId - The ID of the tab whose side panel was closed + * @return {Promise} A promise that resolves when the side panel closed event is handled + * This function is called when a side panel is closed, either by user action or programmatically. + */ +export const sidePanelClosed = async (tabId?: number): Promise => { + if (!tabId) return + try { + BgData.update((data) => { + const { [tabId]: _, ...rest } = data.sidePanelUrls + return { + sidePanelTabs: data.sidePanelTabs.filter((id) => id !== tabId), + linkCommandSidePanelTabs: data.linkCommandSidePanelTabs.filter( + (id) => id !== tabId, + ), + sidePanelUrls: rest, + } + }) + } catch (e) { + console.warn("Failed to cleanup side panel:", e) + } +} + export const navigateSidePanel = ( param: NavigateSidePanelProps, _sender: Sender, diff --git a/packages/extension/src/action/linkPreview.ts b/packages/extension/src/action/linkPreview.ts index bc8e347c..709dec44 100644 --- a/packages/extension/src/action/linkPreview.ts +++ b/packages/extension/src/action/linkPreview.ts @@ -18,7 +18,10 @@ export const LinkPreview = { if (command.openMode === DRAG_OPEN_MODE.PREVIEW_SIDE_PANEL) { if (!isEmpty(href)) { - Ipc.send(BgCommand.openSidePanel, { url: href }) + Ipc.send(BgCommand.openSidePanel, { + url: href, + isLinkCommand: true, + }) } return } diff --git a/packages/extension/src/background_script.ts b/packages/extension/src/background_script.ts index d6eb43eb..a652bb17 100644 --- a/packages/extension/src/background_script.ts +++ b/packages/extension/src/background_script.ts @@ -618,15 +618,10 @@ chrome.commands.onCommand.addListener(async (commandName) => { // SidePanel auto-hide functionality // Track tabs with active side panels -chrome.tabs.onRemoved.addListener((tabId) => { - BgData.update((data) => { - const { [tabId]: _, ...rest } = data.sidePanelUrls - return { - sidePanelTabs: data.sidePanelTabs.filter((id) => id !== tabId), - sidePanelUrls: rest, - } - }) -}) +chrome.tabs.onRemoved.addListener(ActionHelper.sidePanelClosed) +chrome.sidePanel.onClosed.addListener(({ tabId }) => + ActionHelper.sidePanelClosed(tabId), +) // Export functions for testing export const testExports = { diff --git a/packages/extension/src/components/Popup.tsx b/packages/extension/src/components/Popup.tsx index 4926b9c4..67f61e95 100644 --- a/packages/extension/src/components/Popup.tsx +++ b/packages/extension/src/components/Popup.tsx @@ -5,6 +5,7 @@ import { useUserSettings } from "@/hooks/useSettings" import { useDetectStartup } from "@/hooks/useDetectStartup" import { useTabCommandReceiver } from "@/hooks/useTabCommandReceiver" import { useSidePanelNavigation } from "@/hooks/useSidePanelNavigation" +import { useSidePanelAutoClose } from "@/hooks/useSidePanelAutoClose" import { hexToHsl, isMac, onHover, cn } from "@/lib/utils" import { t } from "@/services/i18n" import { STYLE_VARIABLE, EXIT_DURATION, SIDE, ALIGN } from "@/const" @@ -29,6 +30,7 @@ export const Popup = forwardRef( (props: PopupProps, ref) => { useTabCommandReceiver() useSidePanelNavigation() + useSidePanelAutoClose() const { userSettings } = useUserSettings() const [inTransition, setInTransition] = useState(false) diff --git a/packages/extension/src/components/option/SettingForm.tsx b/packages/extension/src/components/option/SettingForm.tsx index fb074f27..e3275faa 100644 --- a/packages/extension/src/components/option/SettingForm.tsx +++ b/packages/extension/src/components/option/SettingForm.tsx @@ -100,6 +100,7 @@ const formSchema = z .refine((v) => v !== LINK_COMMAND_ENABLED.INHERIT), openMode: z.nativeEnum(DRAG_OPEN_MODE), showIndicator: z.boolean(), + sidePanelAutoHide: z.boolean(), startupMethod: z .object({ method: z.nativeEnum(LINK_COMMAND_STARTUP_METHOD), @@ -561,31 +562,37 @@ export function SettingForm({ className }: { className?: string }) { )} {linkCommandMethod === LINK_COMMAND_STARTUP_METHOD.LEFT_CLICK_HOLD && ( - - )} + + )} +
diff --git a/packages/extension/src/components/option/field/SwitchField.tsx b/packages/extension/src/components/option/field/SwitchField.tsx index e906d12f..4f39aeab 100644 --- a/packages/extension/src/components/option/field/SwitchField.tsx +++ b/packages/extension/src/components/option/field/SwitchField.tsx @@ -1,3 +1,4 @@ +import { useRef } from "react" import { Switch } from "@/components/ui/switch" import { @@ -8,12 +9,16 @@ import { FormLabel, FormMessage, } from "@/components/ui/form" +import { Info } from "lucide-react" +import { Tooltip } from "@/components/Tooltip" +import { cn } from "@/lib/utils" type SwitchFieldType = { control: any name: string formLabel: string description?: string + tooltip?: string } export const SwitchField = ({ @@ -21,7 +26,10 @@ export const SwitchField = ({ name, formLabel, description, + tooltip, }: SwitchFieldType) => { + const span = useRef(null) + return ( (
- {formLabel} + + {formLabel} + {tooltip && ( + + + + )} + {description && {description}} + {tooltip && ( + + )}
diff --git a/packages/extension/src/hooks/useSettings.test.tsx b/packages/extension/src/hooks/useSettings.test.tsx index c5a0330c..74b297be 100644 --- a/packages/extension/src/hooks/useSettings.test.tsx +++ b/packages/extension/src/hooks/useSettings.test.tsx @@ -63,6 +63,7 @@ const createMockUserSettings = ( enabled: LINK_COMMAND_ENABLED.ENABLE, openMode: DRAG_OPEN_MODE.PREVIEW_POPUP, showIndicator: true, + sidePanelAutoHide: false, startupMethod: { method: LINK_COMMAND_STARTUP_METHOD.KEYBOARD, keyboardParam: KEYBOARD.SHIFT, diff --git a/packages/extension/src/hooks/useSidePanelAutoClose.ts b/packages/extension/src/hooks/useSidePanelAutoClose.ts new file mode 100644 index 00000000..c01f6293 --- /dev/null +++ b/packages/extension/src/hooks/useSidePanelAutoClose.ts @@ -0,0 +1,52 @@ +import { useEffect, useState } from "react" +import { Ipc, BgCommand } from "@/services/ipc" +import { BgData } from "@/services/backgroundData" +import { useTabContext } from "./useTabContext" +import { useUserSettings } from "./useSettings" + +export function useSidePanelAutoClose() { + const { tabId } = useTabContext() + const { userSettings } = useUserSettings() + const [sidePanelVisible, setSidePanelVisible] = useState(false) + const [isLinkCommand, setIsLinkCommand] = useState(false) + + useEffect(() => { + const update = (data: BgData) => { + if (tabId == null) { + setSidePanelVisible(false) + setIsLinkCommand(false) + return + } + setSidePanelVisible( + data.sidePanelTabs.includes(tabId) || + data.linkCommandSidePanelTabs.includes(tabId), + ) + setIsLinkCommand(data.linkCommandSidePanelTabs.includes(tabId)) + } + + const initialData = BgData.get() + update(initialData) + + return BgData.watch((newVal) => update(newVal)) + }, [tabId]) + + useEffect(() => { + if (tabId == null) return + if (!sidePanelVisible) return + + // Determine which setting to use based on whether this is a link command + const autoHideEnabled = isLinkCommand + ? userSettings?.linkCommand?.sidePanelAutoHide + : userSettings?.windowOption?.sidePanelAutoHide + + // Only enable auto-close if the setting is enabled + if (!autoHideEnabled) return + + const close = () => Ipc.send(BgCommand.closeSidePanel) + + window.addEventListener("click", close) + return () => { + window.removeEventListener("click", close) + } + }, [tabId, sidePanelVisible, userSettings, isLinkCommand]) +} diff --git a/packages/extension/src/services/backgroundData.ts b/packages/extension/src/services/backgroundData.ts index d614480e..9479f937 100644 --- a/packages/extension/src/services/backgroundData.ts +++ b/packages/extension/src/services/backgroundData.ts @@ -15,6 +15,7 @@ export class BgData { public activeScreenId: string | null public connectedTabs: number[] public sidePanelTabs: number[] + public linkCommandSidePanelTabs: number[] public sidePanelUrls: Record private constructor(val: BgData | undefined) { @@ -24,6 +25,7 @@ export class BgData { this.activeScreenId = val?.activeScreenId ?? null this.connectedTabs = val?.connectedTabs ?? [] this.sidePanelTabs = val?.sidePanelTabs ?? [] + this.linkCommandSidePanelTabs = val?.linkCommandSidePanelTabs ?? [] this.sidePanelUrls = val?.sidePanelUrls ?? {} } diff --git a/packages/extension/src/services/chrome.ts b/packages/extension/src/services/chrome.ts index 38f94409..088bcc3a 100644 --- a/packages/extension/src/services/chrome.ts +++ b/packages/extension/src/services/chrome.ts @@ -332,11 +332,11 @@ const readClipboardContent = async ( ): Promise => { try { const result = await new Promise((resolve) => { - chrome.runtime.onConnect.addListener(function (port) { + chrome.runtime.onConnect.addListener(function(port) { if (port.sender?.tab?.id !== tabId) { return } - port.onMessage.addListener(function (msg) { + port.onMessage.addListener(function(msg) { if (msg.command === BgCommand.setClipboard) { resolve(msg.data) } @@ -621,6 +621,7 @@ export async function closeWindow( export type OpenSidePanelProps = { url: string | UrlParam tabId?: number + isLinkCommand?: boolean } export type UpdateSidePanelUrlProps = { @@ -673,23 +674,6 @@ export const closeSidePanel = async (tabId: number): Promise => { } catch (e) { console.warn("Failed to close side panel:", e) } - - // Cleanup regardless of whether close succeeded - try { - await BgData.update((data) => { - const { [tabId]: _, ...rest } = data.sidePanelUrls - return { - sidePanelTabs: data.sidePanelTabs.filter((id) => id !== tabId), - sidePanelUrls: rest, - } - }) - await chrome.sidePanel.setOptions({ - tabId: tabId, - enabled: false, - }) - } catch (e) { - console.warn("Failed to cleanup side panel:", e) - } } /** diff --git a/packages/extension/src/services/option/defaultSettings.ts b/packages/extension/src/services/option/defaultSettings.ts index 1f8533c1..a0e3f5b6 100644 --- a/packages/extension/src/services/option/defaultSettings.ts +++ b/packages/extension/src/services/option/defaultSettings.ts @@ -40,6 +40,7 @@ export const emptySettings: SettingsType = { enabled: LINK_COMMAND_ENABLED.ENABLE, openMode: DRAG_OPEN_MODE.PREVIEW_POPUP, showIndicator: true, + sidePanelAutoHide: false, startupMethod: { method: LINK_COMMAND_STARTUP_METHOD.KEYBOARD, keyboardParam: KEYBOARD.SHIFT, @@ -71,6 +72,7 @@ export default { enabled: LINK_COMMAND_ENABLED.ENABLE, openMode: DRAG_OPEN_MODE.PREVIEW_POPUP, showIndicator: true, + sidePanelAutoHide: false, startupMethod: { method: LINK_COMMAND_STARTUP_METHOD.KEYBOARD, keyboardParam: KEYBOARD.SHIFT, diff --git a/packages/extension/src/services/settings/settings.ts b/packages/extension/src/services/settings/settings.ts index fc2e130a..dc8736ac 100644 --- a/packages/extension/src/services/settings/settings.ts +++ b/packages/extension/src/services/settings/settings.ts @@ -243,6 +243,10 @@ export const migrate = async (data: SettingsType): Promise => { data.settingVersion = VERSION as Version data = migrate0_14_3(data) } + if (versionDiff(data.settingVersion, "0.15.0") === VersionDiff.Old) { + data.settingVersion = VERSION as Version + data = migrate0_15_0(data) + } return data } @@ -352,3 +356,13 @@ const migrate0_14_3 = (data: SettingsType): SettingsType => { } return data } + +const migrate0_15_0 = (data: SettingsType): SettingsType => { + // Add linkCommand.sidePanelAutoHide if not exists + if (data.linkCommand != null && data.linkCommand.sidePanelAutoHide == null) { + data.linkCommand.sidePanelAutoHide = + DefaultSettings.linkCommand.sidePanelAutoHide + console.debug("migrate 0.15.0: added linkCommand.sidePanelAutoHide") + } + return data +} diff --git a/packages/extension/src/services/windowStackManager.test.ts b/packages/extension/src/services/windowStackManager.test.ts index 8e86413b..94bdbdfe 100644 --- a/packages/extension/src/services/windowStackManager.test.ts +++ b/packages/extension/src/services/windowStackManager.test.ts @@ -35,6 +35,7 @@ describe("WindowStackManager", () => { activeScreenId: null, connectedTabs: [], sidePanelTabs: [], + linkCommandSidePanelTabs: [], sidePanelUrls: {}, }) diff --git a/packages/extension/src/types/index.ts b/packages/extension/src/types/index.ts index aa2bcf69..ada419d3 100644 --- a/packages/extension/src/types/index.ts +++ b/packages/extension/src/types/index.ts @@ -96,6 +96,7 @@ type LinkCommandSettings = { openMode: DRAG_OPEN_MODE showIndicator: boolean startupMethod: LinkCommandStartupMethod + sidePanelAutoHide: boolean } export type CommandFolder = { From f2fb9e62b9ae13a6f5e21baf6234aadc21dafae8 Mon Sep 17 00:00:00 2001 From: ujiro99 Date: Sun, 1 Mar 2026 18:38:18 +0900 Subject: [PATCH 5/7] Update: Fix state management method and enable navigation on the SidePanel. --- packages/extension/src/action/helper.test.ts | 17 ++++---- packages/extension/src/action/helper.ts | 41 ++++++------------- .../src/hooks/useSidePanelAutoClose.ts | 8 ++-- .../extension/src/services/backgroundData.ts | 9 ++-- .../src/services/sidePanelDetector.test.ts | 6 +-- .../src/services/sidePanelDetector.ts | 2 +- .../src/services/windowStackManager.test.ts | 1 - 7 files changed, 36 insertions(+), 48 deletions(-) diff --git a/packages/extension/src/action/helper.test.ts b/packages/extension/src/action/helper.test.ts index c045166a..97cfa530 100644 --- a/packages/extension/src/action/helper.test.ts +++ b/packages/extension/src/action/helper.test.ts @@ -35,7 +35,7 @@ describe("helper", () => { const sender = {} as any vi.mocked(BgData.get).mockReturnValue({ - sidePanelTabs: [123], + sidePanelTabs: [{ tabId: 123, isLinkCommand: false }], } as any) const result = navigateSidePanel(param, sender) @@ -48,7 +48,7 @@ describe("helper", () => { const sender = {} as any vi.mocked(BgData.get).mockReturnValue({ - sidePanelTabs: [123], + sidePanelTabs: [{ tabId: 123, isLinkCommand: false }], } as any) const result = navigateSidePanel(param, sender) @@ -61,7 +61,7 @@ describe("helper", () => { const sender = {} as any vi.mocked(BgData.get).mockReturnValue({ - sidePanelTabs: [123], + sidePanelTabs: [{ tabId: 123, isLinkCommand: false }], } as any) const result = navigateSidePanel(param, sender) @@ -74,7 +74,10 @@ describe("helper", () => { const sender = {} as any vi.mocked(BgData.get).mockReturnValue({ - sidePanelTabs: [456, 789], // Different tab IDs + sidePanelTabs: [ + { tabId: 456, isLinkCommand: false }, + { tabId: 789, isLinkCommand: false }, + ], // Different tab IDs } as any) const result = navigateSidePanel(param, sender) @@ -89,7 +92,7 @@ describe("helper", () => { const sender = {} as any vi.mocked(BgData.get).mockReturnValue({ - sidePanelTabs: [tabId], + sidePanelTabs: [{ tabId, isLinkCommand: false }], sidePanelUrls: {}, } as any) @@ -113,7 +116,7 @@ describe("helper", () => { const sender = {} as any vi.mocked(BgData.get).mockReturnValue({ - sidePanelTabs: [tabId], + sidePanelTabs: [{ tabId, isLinkCommand: false }], sidePanelUrls: {}, } as any) @@ -147,7 +150,7 @@ describe("helper", () => { const sender = {} as any const mockData = { - sidePanelTabs: [tabId], + sidePanelTabs: [{ tabId, isLinkCommand: false }], sidePanelUrls: {}, } as any diff --git a/packages/extension/src/action/helper.ts b/packages/extension/src/action/helper.ts index 766a7cf2..5ac005ab 100644 --- a/packages/extension/src/action/helper.ts +++ b/packages/extension/src/action/helper.ts @@ -123,19 +123,11 @@ export const openSidePanel = ( .then(() => { // Register the tab ID for tracking if (tabId) { - // Update BgData to include the new side panel tab ID - // If it's a link command, add to linkCommandSidePanelTabs; otherwise, add to sidePanelTabs. + const newEntry = { tabId, isLinkCommand: param.isLinkCommand ?? false } return BgData.update((data) => ({ - sidePanelTabs: !param.isLinkCommand - ? data.sidePanelTabs.includes(tabId) - ? data.sidePanelTabs - : [...data.sidePanelTabs, tabId] - : data.sidePanelTabs.filter((id) => id !== tabId), - linkCommandSidePanelTabs: param.isLinkCommand - ? data.linkCommandSidePanelTabs.includes(tabId) - ? data.linkCommandSidePanelTabs - : [...data.linkCommandSidePanelTabs, tabId] - : data.linkCommandSidePanelTabs.filter((id) => id !== tabId), + sidePanelTabs: data.sidePanelTabs.some((t) => t.tabId === tabId) + ? data.sidePanelTabs.map((t) => (t.tabId === tabId ? newEntry : t)) + : [...data.sidePanelTabs, newEntry], })) } }) @@ -160,17 +152,13 @@ export const closeSidePanel = ( return false } enhancedSettings.get().then(async (settings) => { - const sidePanelAutoHide = settings.windowOption.sidePanelAutoHide - if (sidePanelAutoHide) { - const bgData = BgData.get() - if (bgData.sidePanelTabs.includes(tabId)) { - await _closeSidePanel(tabId) - } - } - const linkCommandSidePanelAutoHide = settings.linkCommand.sidePanelAutoHide - if (linkCommandSidePanelAutoHide) { - const bgData = BgData.get() - if (bgData.linkCommandSidePanelTabs.includes(tabId)) { + const bgData = BgData.get() + const tab = bgData.sidePanelTabs.find((t) => t.tabId === tabId) + if (tab) { + const autoHideEnabled = tab.isLinkCommand + ? settings.linkCommand.sidePanelAutoHide + : settings.windowOption.sidePanelAutoHide + if (autoHideEnabled) { await _closeSidePanel(tabId) } } @@ -192,10 +180,7 @@ export const sidePanelClosed = async (tabId?: number): Promise => { BgData.update((data) => { const { [tabId]: _, ...rest } = data.sidePanelUrls return { - sidePanelTabs: data.sidePanelTabs.filter((id) => id !== tabId), - linkCommandSidePanelTabs: data.linkCommandSidePanelTabs.filter( - (id) => id !== tabId, - ), + sidePanelTabs: data.sidePanelTabs.filter((t) => t.tabId !== tabId), sidePanelUrls: rest, } }) @@ -230,7 +215,7 @@ export const navigateSidePanel = ( // Check if tab is in sidePanelTabs const bgData = BgData.get() - if (!bgData.sidePanelTabs.includes(tabId)) { + if (!bgData.sidePanelTabs.some((t) => t.tabId === tabId)) { console.warn("[navigateSidePanel] Tab is not in sidePanelTabs:", tabId) return false } diff --git a/packages/extension/src/hooks/useSidePanelAutoClose.ts b/packages/extension/src/hooks/useSidePanelAutoClose.ts index c01f6293..ea7b03fa 100644 --- a/packages/extension/src/hooks/useSidePanelAutoClose.ts +++ b/packages/extension/src/hooks/useSidePanelAutoClose.ts @@ -17,11 +17,9 @@ export function useSidePanelAutoClose() { setIsLinkCommand(false) return } - setSidePanelVisible( - data.sidePanelTabs.includes(tabId) || - data.linkCommandSidePanelTabs.includes(tabId), - ) - setIsLinkCommand(data.linkCommandSidePanelTabs.includes(tabId)) + const tab = data.sidePanelTabs.find((t) => t.tabId === tabId) + setSidePanelVisible(tab != null) + setIsLinkCommand(tab?.isLinkCommand ?? false) } const initialData = BgData.get() diff --git a/packages/extension/src/services/backgroundData.ts b/packages/extension/src/services/backgroundData.ts index 9479f937..70d04d4f 100644 --- a/packages/extension/src/services/backgroundData.ts +++ b/packages/extension/src/services/backgroundData.ts @@ -6,6 +6,11 @@ type updaterPartial = (val: BgData) => Partial type watchCallback = (newVal: BgData, oldVal: BgData) => void +export type SidePanelTab = { + tabId: number + isLinkCommand: boolean +} + export class BgData { private static instance: BgData @@ -14,8 +19,7 @@ export class BgData { public pageActionStop: boolean public activeScreenId: string | null public connectedTabs: number[] - public sidePanelTabs: number[] - public linkCommandSidePanelTabs: number[] + public sidePanelTabs: SidePanelTab[] public sidePanelUrls: Record private constructor(val: BgData | undefined) { @@ -25,7 +29,6 @@ export class BgData { this.activeScreenId = val?.activeScreenId ?? null this.connectedTabs = val?.connectedTabs ?? [] this.sidePanelTabs = val?.sidePanelTabs ?? [] - this.linkCommandSidePanelTabs = val?.linkCommandSidePanelTabs ?? [] this.sidePanelUrls = val?.sidePanelUrls ?? {} } diff --git a/packages/extension/src/services/sidePanelDetector.test.ts b/packages/extension/src/services/sidePanelDetector.test.ts index a337a947..c3301ba1 100644 --- a/packages/extension/src/services/sidePanelDetector.test.ts +++ b/packages/extension/src/services/sidePanelDetector.test.ts @@ -25,7 +25,7 @@ describe("sidePanelDetector", () => { it("SPD-01-a: Should continue checking when tabId is undefined (treated same as null)", () => { vi.mocked(BgData.get).mockReturnValue({ - sidePanelTabs: [789], // activeTabId not in list + sidePanelTabs: [{ tabId: 789, isLinkCommand: false }], } as any) const result = isSidePanel(undefined, 789) @@ -41,7 +41,7 @@ describe("sidePanelDetector", () => { it("SPD-03: Should return false when activeTabId is not in sidePanelTabs", () => { vi.mocked(BgData.get).mockReturnValue({ - sidePanelTabs: [789], // activeTabId not in list + sidePanelTabs: [{ tabId: 789, isLinkCommand: false }], // activeTabId not in list } as any) const result = isSidePanel(null, 456) @@ -52,7 +52,7 @@ describe("sidePanelDetector", () => { it("SPD-04: Should return true when all conditions are met", () => { vi.mocked(BgData.get).mockReturnValue({ - sidePanelTabs: [456], + sidePanelTabs: [{ tabId: 456, isLinkCommand: false }], } as any) const result = isSidePanel(null, 456) diff --git a/packages/extension/src/services/sidePanelDetector.ts b/packages/extension/src/services/sidePanelDetector.ts index 4b021229..606a4b06 100644 --- a/packages/extension/src/services/sidePanelDetector.ts +++ b/packages/extension/src/services/sidePanelDetector.ts @@ -17,7 +17,7 @@ export const isSidePanel = ( // Check if tab is in sidePanelTabs const bgData = BgData.get() - if (!bgData.sidePanelTabs.includes(activeTabId)) return false + if (!bgData.sidePanelTabs.some((t) => t.tabId === activeTabId)) return false return true } diff --git a/packages/extension/src/services/windowStackManager.test.ts b/packages/extension/src/services/windowStackManager.test.ts index 94bdbdfe..8e86413b 100644 --- a/packages/extension/src/services/windowStackManager.test.ts +++ b/packages/extension/src/services/windowStackManager.test.ts @@ -35,7 +35,6 @@ describe("WindowStackManager", () => { activeScreenId: null, connectedTabs: [], sidePanelTabs: [], - linkCommandSidePanelTabs: [], sidePanelUrls: {}, }) From 1c06cdb45ca1d80364261260c7ec1518b8bd10b6 Mon Sep 17 00:00:00 2001 From: ujiro99 Date: Sun, 1 Mar 2026 19:00:19 +0900 Subject: [PATCH 6/7] Update: translations. --- .../public/_locales/de/messages.json | 8 ++- .../public/_locales/en/messages.json | 8 ++- .../public/_locales/es/messages.json | 8 ++- .../public/_locales/fr/messages.json | 8 ++- .../public/_locales/hi/messages.json | 8 ++- .../public/_locales/id/messages.json | 8 ++- .../public/_locales/it/messages.json | 8 ++- .../public/_locales/ja/messages.json | 12 +++- .../public/_locales/ko/messages.json | 8 ++- .../public/_locales/ms/messages.json | 8 ++- .../public/_locales/pt_BR/messages.json | 8 ++- .../public/_locales/pt_PT/messages.json | 8 ++- .../public/_locales/ru/messages.json | 8 ++- .../public/_locales/zh_CN/messages.json | 8 ++- .../src/components/option/SettingForm.tsx | 60 +++++++++++-------- 15 files changed, 134 insertions(+), 42 deletions(-) diff --git a/packages/extension/public/_locales/de/messages.json b/packages/extension/public/_locales/de/messages.json index 0305226d..468a18f2 100644 --- a/packages/extension/public/_locales/de/messages.json +++ b/packages/extension/public/_locales/de/messages.json @@ -216,7 +216,13 @@ "message": "Seitenbereich automatisch ausblenden" }, "Option_sidePanelAutoHide_desc": { - "message": "Blendet den Seitenbereich automatisch aus, wenn in den Hauptbereich geklickt wird." + "message": "Blendet den Seitenbereich automatisch aus, wenn in den Hauptbereich geklickt wird, während der Seitenbereich über einen Befehl geöffnet ist." + }, + "Option_sidePanelAutoHide_link": { + "message": "Seitenbereich automatisch ausblenden" + }, + "Option_sidePanelAutoHide_link_desc": { + "message": "Blendet den Seitenbereich automatisch aus, wenn in den Hauptbereich geklickt wird, während die Linkvorschau angezeigt wird." }, "Option_inherit": { "message": "Erben" diff --git a/packages/extension/public/_locales/en/messages.json b/packages/extension/public/_locales/en/messages.json index 2232d40f..98085c63 100644 --- a/packages/extension/public/_locales/en/messages.json +++ b/packages/extension/public/_locales/en/messages.json @@ -216,7 +216,13 @@ "message": "Side Panel Auto-Hide" }, "Option_sidePanelAutoHide_desc": { - "message": "Automatically hide the side panel when the main panel is clicked." + "message": "Automatically hide the side panel when the main panel is clicked while the side panel is open via a command." + }, + "Option_sidePanelAutoHide_link": { + "message": "Side Panel Auto-Hide" + }, + "Option_sidePanelAutoHide_link_desc": { + "message": "Automatically hide the side panel when the main panel is clicked while displaying the link preview." }, "Option_inherit": { "message": "Inherit" diff --git a/packages/extension/public/_locales/es/messages.json b/packages/extension/public/_locales/es/messages.json index 4fed6ad9..dbe48076 100644 --- a/packages/extension/public/_locales/es/messages.json +++ b/packages/extension/public/_locales/es/messages.json @@ -216,7 +216,13 @@ "message": "Ocultar panel lateral automáticamente" }, "Option_sidePanelAutoHide_desc": { - "message": "Oculta automáticamente el panel lateral cuando se hace clic en el panel principal." + "message": "Oculta automáticamente el panel lateral cuando se hace clic en el panel principal mientras el panel lateral está abierto a través de un comando." + }, + "Option_sidePanelAutoHide_link": { + "message": "Ocultar panel lateral automáticamente" + }, + "Option_sidePanelAutoHide_link_desc": { + "message": "Oculta automáticamente el panel lateral cuando se hace clic en el panel principal mientras se muestra la vista previa del enlace." }, "Option_inherit": { "message": "Heredar" diff --git a/packages/extension/public/_locales/fr/messages.json b/packages/extension/public/_locales/fr/messages.json index ac9e3116..118e2cd8 100644 --- a/packages/extension/public/_locales/fr/messages.json +++ b/packages/extension/public/_locales/fr/messages.json @@ -216,7 +216,13 @@ "message": "Masquage automatique du panneau latéral" }, "Option_sidePanelAutoHide_desc": { - "message": "Masque automatiquement le panneau latéral lorsque le panneau principal est cliqué." + "message": "Masque automatiquement le panneau latéral lorsque le panneau principal est cliqué pendant que le panneau latéral est ouvert via une commande." + }, + "Option_sidePanelAutoHide_link": { + "message": "Masquage automatique du panneau latéral" + }, + "Option_sidePanelAutoHide_link_desc": { + "message": "Masque automatiquement le panneau latéral lorsque le panneau principal est cliqué pendant l'affichage de l'aperçu du lien." }, "Option_inherit": { "message": "Hériter" diff --git a/packages/extension/public/_locales/hi/messages.json b/packages/extension/public/_locales/hi/messages.json index 38bf12d8..d87aed3f 100644 --- a/packages/extension/public/_locales/hi/messages.json +++ b/packages/extension/public/_locales/hi/messages.json @@ -216,7 +216,13 @@ "message": "साइड पैनल स्वतः छिपाएं" }, "Option_sidePanelAutoHide_desc": { - "message": "मुख्य पैनल पर क्लिक करने पर साइड पैनल को स्वतः छिपा देता है।" + "message": "कमांड के माध्यम से साइड पैनल खुले होने पर मुख्य पैनल पर क्लिक करने पर साइड पैनल को स्वतः छिपा देता है।" + }, + "Option_sidePanelAutoHide_link": { + "message": "साइड पैनल स्वतः छिपाएं" + }, + "Option_sidePanelAutoHide_link_desc": { + "message": "लिंक पूर्वावलोकन प्रदर्शित करते समय मुख्य पैनल पर क्लिक करने पर साइड पैनल को स्वतः छिपा देता है।" }, "Option_inherit": { "message": "प्राप्त करें" diff --git a/packages/extension/public/_locales/id/messages.json b/packages/extension/public/_locales/id/messages.json index 60468134..c9dfae34 100644 --- a/packages/extension/public/_locales/id/messages.json +++ b/packages/extension/public/_locales/id/messages.json @@ -216,7 +216,13 @@ "message": "Sembunyikan Panel Samping Otomatis" }, "Option_sidePanelAutoHide_desc": { - "message": "Secara otomatis menyembunyikan panel samping saat panel utama diklik." + "message": "Secara otomatis menyembunyikan panel samping saat panel utama diklik saat panel samping terbuka melalui perintah." + }, + "Option_sidePanelAutoHide_link": { + "message": "Sembunyikan Panel Samping Otomatis" + }, + "Option_sidePanelAutoHide_link_desc": { + "message": "Secara otomatis menyembunyikan panel samping saat panel utama diklik saat menampilkan pratinjau tautan." }, "Option_inherit": { "message": "Warisi" diff --git a/packages/extension/public/_locales/it/messages.json b/packages/extension/public/_locales/it/messages.json index 2c11648d..6465bcea 100644 --- a/packages/extension/public/_locales/it/messages.json +++ b/packages/extension/public/_locales/it/messages.json @@ -216,7 +216,13 @@ "message": "Nascondi automaticamente il pannello laterale" }, "Option_sidePanelAutoHide_desc": { - "message": "Nasconde automaticamente il pannello laterale quando si fa clic sul pannello principale." + "message": "Nasconde automaticamente il pannello laterale quando si fa clic sul pannello principale mentre il pannello laterale è aperto tramite un comando." + }, + "Option_sidePanelAutoHide_link": { + "message": "Nascondi automaticamente il pannello laterale" + }, + "Option_sidePanelAutoHide_link_desc": { + "message": "Nasconde automaticamente il pannello laterale quando si fa clic sul pannello principale durante la visualizzazione dell'anteprima del collegamento." }, "Option_inherit": { "message": "Eredita" diff --git a/packages/extension/public/_locales/ja/messages.json b/packages/extension/public/_locales/ja/messages.json index 92cca044..d2cfb9a2 100644 --- a/packages/extension/public/_locales/ja/messages.json +++ b/packages/extension/public/_locales/ja/messages.json @@ -216,7 +216,13 @@ "message": "サイドパネル自動非表示" }, "Option_sidePanelAutoHide_desc": { - "message": "メインのパネルをクリックしたときに、サイドパネルを自動的に非表示にします。" + "message": "コマンドによりサイドパネルを表示している時、メインのパネルをクリックしたときに、サイドパネルを自動的に非表示にします。" + }, + "Option_sidePanelAutoHide_link": { + "message": "サイドパネル自動非表示" + }, + "Option_sidePanelAutoHide_link_desc": { + "message": "リンクプレビューの表示中、メインのパネルをクリックしたときに、サイドパネルを自動的に非表示にします。" }, "Option_inherit": { "message": "継承" @@ -366,10 +372,10 @@ "message": "実験的" }, "Option_openMode_previewPopup": { - "message": "Popup" + "message": "ポップアップ" }, "Option_openMode_previewWindow": { - "message": "Window" + "message": "ウィンドウ" }, "Option_openMode_previewSidePanel": { "message": "サイドパネル" diff --git a/packages/extension/public/_locales/ko/messages.json b/packages/extension/public/_locales/ko/messages.json index efb0bfb7..860308f0 100644 --- a/packages/extension/public/_locales/ko/messages.json +++ b/packages/extension/public/_locales/ko/messages.json @@ -216,7 +216,13 @@ "message": "사이드 패널 자동 숨기기" }, "Option_sidePanelAutoHide_desc": { - "message": "메인 패널을 클릭하면 사이드 패널이 자동으로 숨겨집니다." + "message": "명령을 통해 사이드 패널이 열려 있는 동안 메인 패널을 클릭하면 사이드 패널이 자동으로 숨겨집니다." + }, + "Option_sidePanelAutoHide_link": { + "message": "사이드 패널 자동 숨기기" + }, + "Option_sidePanelAutoHide_link_desc": { + "message": "링크 미리보기 표시 중 메인 패널을 클릭하면 사이드 패널이 자동으로 숨겨집니다." }, "Option_inherit": { "message": "상속" diff --git a/packages/extension/public/_locales/ms/messages.json b/packages/extension/public/_locales/ms/messages.json index 314d6455..d96eb7d1 100644 --- a/packages/extension/public/_locales/ms/messages.json +++ b/packages/extension/public/_locales/ms/messages.json @@ -216,7 +216,13 @@ "message": "Sembunyikan Panel Sisi Secara Automatik" }, "Option_sidePanelAutoHide_desc": { - "message": "Menyembunyikan panel sisi secara automatik apabila panel utama diklik." + "message": "Menyembunyikan panel sisi secara automatik apabila panel utama diklik semasa panel sisi dibuka melalui perintah." + }, + "Option_sidePanelAutoHide_link": { + "message": "Sembunyikan Panel Sisi Secara Automatik" + }, + "Option_sidePanelAutoHide_link_desc": { + "message": "Menyembunyikan panel sisi secara automatik apabila panel utama diklik semasa memaparkan pratonton pautan." }, "Option_inherit": { "message": "Warisi" diff --git a/packages/extension/public/_locales/pt_BR/messages.json b/packages/extension/public/_locales/pt_BR/messages.json index 9effa52a..62f53f54 100644 --- a/packages/extension/public/_locales/pt_BR/messages.json +++ b/packages/extension/public/_locales/pt_BR/messages.json @@ -216,7 +216,13 @@ "message": "Ocultar painel lateral automaticamente" }, "Option_sidePanelAutoHide_desc": { - "message": "Oculta automaticamente o painel lateral quando o painel principal é clicado." + "message": "Oculta automaticamente o painel lateral quando o painel principal é clicado enquanto o painel lateral está aberto via um comando." + }, + "Option_sidePanelAutoHide_link": { + "message": "Ocultar painel lateral automaticamente" + }, + "Option_sidePanelAutoHide_link_desc": { + "message": "Oculta automaticamente o painel lateral quando o painel principal é clicado durante a exibição da pré-visualização do link." }, "Option_inherit": { "message": "Herdar" diff --git a/packages/extension/public/_locales/pt_PT/messages.json b/packages/extension/public/_locales/pt_PT/messages.json index 83b10b1e..9e2042dd 100644 --- a/packages/extension/public/_locales/pt_PT/messages.json +++ b/packages/extension/public/_locales/pt_PT/messages.json @@ -216,7 +216,13 @@ "message": "Ocultar painel lateral automaticamente" }, "Option_sidePanelAutoHide_desc": { - "message": "Oculta automaticamente o painel lateral quando o painel principal é clicado." + "message": "Oculta automaticamente o painel lateral quando o painel principal é clicado enquanto o painel lateral está aberto via um comando." + }, + "Option_sidePanelAutoHide_link": { + "message": "Ocultar painel lateral automaticamente" + }, + "Option_sidePanelAutoHide_link_desc": { + "message": "Oculta automaticamente o painel lateral quando o painel principal é clicado durante a visualização da pré-visualização do link." }, "Option_inherit": { "message": "Herdar" diff --git a/packages/extension/public/_locales/ru/messages.json b/packages/extension/public/_locales/ru/messages.json index b14cdb7e..d4c5587c 100644 --- a/packages/extension/public/_locales/ru/messages.json +++ b/packages/extension/public/_locales/ru/messages.json @@ -216,7 +216,13 @@ "message": "Автоматически скрывать боковую панель" }, "Option_sidePanelAutoHide_desc": { - "message": "Автоматически скрывает боковую панель при клике на основную панель." + "message": "Автоматически скрывает боковую панель при клике на основную панель, пока боковая панель открыта через команду." + }, + "Option_sidePanelAutoHide_link": { + "message": "Автоматически скрывать боковую панель" + }, + "Option_sidePanelAutoHide_link_desc": { + "message": "Автоматически скрывает боковую панель при клике на основную панель во время отображения предварительного просмотра ссылки." }, "Option_inherit": { "message": "Наследовать" diff --git a/packages/extension/public/_locales/zh_CN/messages.json b/packages/extension/public/_locales/zh_CN/messages.json index 0e12c8f4..f87db698 100644 --- a/packages/extension/public/_locales/zh_CN/messages.json +++ b/packages/extension/public/_locales/zh_CN/messages.json @@ -216,7 +216,13 @@ "message": "侧边栏自动隐藏" }, "Option_sidePanelAutoHide_desc": { - "message": "点击主面板时自动隐藏侧边栏。" + "message": "通过命令打开侧边栏时,点击主面板自动隐藏侧边栏。" + }, + "Option_sidePanelAutoHide_link": { + "message": "侧边栏自动隐藏" + }, + "Option_sidePanelAutoHide_link_desc": { + "message": "显示链接预览时,点击主面板自动隐藏侧边栏。" }, "Option_inherit": { "message": "获取" diff --git a/packages/extension/src/components/option/SettingForm.tsx b/packages/extension/src/components/option/SettingForm.tsx index e3275faa..72b4517e 100644 --- a/packages/extension/src/components/option/SettingForm.tsx +++ b/packages/extension/src/components/option/SettingForm.tsx @@ -165,6 +165,12 @@ export function SettingForm({ className }: { className?: string }) { defaultValue: LINK_COMMAND_STARTUP_METHOD.KEYBOARD, }) + const linkCommandOpenMode = useWatch({ + control: form.control, + name: "linkCommand.openMode", + defaultValue: DRAG_OPEN_MODE.PREVIEW_POPUP, + }) + // Common function to load and transform settings data const loadSettingsData = async () => { const settings = await enhancedSettings.get({ excludeOptions: true }) @@ -562,37 +568,39 @@ export function SettingForm({ className }: { className?: string }) { )} {linkCommandMethod === LINK_COMMAND_STARTUP_METHOD.LEFT_CLICK_HOLD && ( - - )} + + )} - + {linkCommandOpenMode === DRAG_OPEN_MODE.PREVIEW_SIDE_PANEL && ( + + )}
@@ -625,7 +633,7 @@ export function SettingForm({ className }: { className?: string }) { control={form.control} name="windowOption.sidePanelAutoHide" formLabel={t("sidePanelAutoHide")} - description={t("sidePanelAutoHide_desc")} + tooltip={t("sidePanelAutoHide_desc")} />
From eb6f85ccdb14b85661b40a861cbfb9b53ed9149e Mon Sep 17 00:00:00 2001 From: ujiro99 Date: Sun, 1 Mar 2026 19:34:19 +0900 Subject: [PATCH 7/7] Fix: Mock of sidePanel. --- packages/extension/src/test/setup.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/extension/src/test/setup.ts b/packages/extension/src/test/setup.ts index 2a49bb42..ed6089d7 100644 --- a/packages/extension/src/test/setup.ts +++ b/packages/extension/src/test/setup.ts @@ -341,6 +341,12 @@ global.chrome = { addListener: vi.fn(), }, }, + sidePanel: { + onClosed: { + addListener: vi.fn(), + removeListener: vi.fn(), + }, + }, } as any // Mock window.matchMedia