diff --git a/src/core/client.mjs b/src/core/client.mjs index b8f5d32..88461c9 100644 --- a/src/core/client.mjs +++ b/src/core/client.mjs @@ -54,6 +54,7 @@ export default async (api, db) => { _notionTheme = notionTheme; const msg = { namespace: "notion-enhancer", + hotkey: openMenuHotkey, theme: notionTheme, icon: menuButtonIconStyle, }; @@ -129,6 +130,11 @@ export default async (api, db) => { document.querySelector(notionSidebar)?.append($menuButton); window.addEventListener("focus", () => updateTheme(true)); + window.addEventListener("message", (event) => { + if (event.data?.namespace !== "notion-enhancer") return; + if (event.data?.action === "close-menu") closeMenu(); + if (event.data?.action === "open-menu") openMenu(); + }); addMutationListener("body", () => { if ($menuModal?.hasAttribute("open")) updateTheme(); }); diff --git a/src/core/menu/components.mjs b/src/core/menu/components.mjs index 77133f6..e8720a6 100644 --- a/src/core/menu/components.mjs +++ b/src/core/menu/components.mjs @@ -492,6 +492,7 @@ function Select({ values, _get, _set, ...props }) { $select.onclick = (event) => { onclick?.(event); $popup.setAttribute("open", true); + setState({ popupOpen: true }); }; useState(["rerender"], () => { _get?.().then((value) => { @@ -503,10 +504,16 @@ function Select({ values, _get, _set, ...props }) { setTimeout(() => { $select.style.width = ""; $select.style.background = ""; + setState({ popupOpen: false }); }, 200); } else $select.innerText = value; }); }); + document.addEventListener("click", (event) => { + if (!$popup.hasAttribute("open")) return; + if ($popup.contains(event.target) || event.target === $select) return; + _set?.($select.innerText); + }); return html`
${$select}${$popup} diff --git a/src/core/menu/menu.mjs b/src/core/menu/menu.mjs index 3fefcd5..5b6c052 100644 --- a/src/core/menu/menu.mjs +++ b/src/core/menu/menu.mjs @@ -165,13 +165,33 @@ const render = async () => { window.addEventListener("focus", () => setState({ rerender: true })); window.addEventListener("message", (event) => { if (event.data?.namespace !== "notion-enhancer") return; - const [theme, icon] = getState(["theme", "icon"]); + const [hotkey, theme, icon] = getState(["hotkey", "theme", "icon"]); setState({ rerender: true, + hotkey: event.data?.hotkey ?? hotkey, theme: event.data?.theme ?? theme, icon: event.data?.icon ?? icon, }); }); +useState(["hotkey"], ([hotkey]) => { + const { addKeyListener } = globalThis.__enhancerApi ?? {}, + [hotkeyRegistered] = getState(["hotkeyRegistered"]); + if (!hotkey || !addKeyListener || hotkeyRegistered) return; + setState({ hotkeyRegistered: true }); + addKeyListener(hotkey, (event) => { + event.preventDefault(); + const msg = { namespace: "notion-enhancer", action: "open-menu" }; + parent?.postMessage(msg, "*"); + }); + addKeyListener("Escape", () => { + const [popupOpen] = getState(["popupOpen"]); + if (!popupOpen) { + const msg = { namespace: "notion-enhancer", action: "close-menu" }; + parent?.postMessage(msg, "*"); + } else setState({ rerender: true }); + }); +}); + useState(["theme"], ([theme]) => { if (theme === "dark") document.body.classList.add("dark"); if (theme === "light") document.body.classList.remove("dark");