From b1d25b3f4f2885c4851f051ac65a2c2bf9e6e9e1 Mon Sep 17 00:00:00 2001 From: Rustem Mussabekov Date: Fri, 3 Nov 2023 12:11:14 +0300 Subject: [PATCH] - New hotkey: Open sidepanel in Chrome (Alt+Shift+B) - Save tabs and open the side panel, app, or settings by right-clicking on the Raindrop extension button and selecting the desired option from the context menu --- src/routes/extension/tabs/useTabs.js | 23 +++++++++-- src/target/extension/background/commands.js | 10 +++-- .../extension/background/contextMenus.js | 40 ++++++++++++++++++- src/target/extension/background/popup.js | 8 ++-- src/target/extension/manifest/index.js | 9 +++++ src/target/extension/manifest/locales.js | 12 ++++++ 6 files changed, 90 insertions(+), 12 deletions(-) diff --git a/src/routes/extension/tabs/useTabs.js b/src/routes/extension/tabs/useTabs.js index 23a34b73..6a39d016 100644 --- a/src/routes/extension/tabs/useTabs.js +++ b/src/routes/extension/tabs/useTabs.js @@ -7,8 +7,17 @@ async function preload() { if (!await browser.permissions.contains({ permissions: ['tabs'] })) return [] - const tabs = await browser.tabs.query({ currentWindow: true }) - return cache = tabs.filter(({url})=>/^https?/i.test(url)) + let tabs = await browser.tabs.query( + (await browser.windows.getCurrent())?.type == 'popup' ? + //in case runing in separate popup window + { windowType: 'normal' } : + //normal behaviour + { currentWindow: true } + ) + + return cache = tabs.filter(({url, pinned})=> + /^https?/i.test(url) && !pinned + ) } export { preload } @@ -16,10 +25,18 @@ export { preload } export default function useTabs() { const [tabs, setTabs] = useState(cache) + useEffect(()=>{ + preload().then(setTabs) + }, []) + useEffect(()=>{ browser.permissions.request({ permissions: ['tabs'] }) .then(preload) - .then(setTabs).catch(Error) + .then(setTabs) + .catch(e=>{ + if (e?.message != 'This function must be called during a user gesture') + Error(e) + }) }, []) return [tabs, setTabs] diff --git a/src/target/extension/background/commands.js b/src/target/extension/background/commands.js index 55266d0a..96a01c62 100644 --- a/src/target/extension/background/commands.js +++ b/src/target/extension/background/commands.js @@ -1,6 +1,5 @@ import browser from 'webextension-polyfill' import config from '~config' -import { currentTab } from '~target' import { open } from './popup' import { addCurrentTabSelection } from './highlights' @@ -9,10 +8,10 @@ function getSelectedText() { return s && s.rangeCount>0 && !s.isCollapsed && s.toString().trim().length>0 } -async function onCommand(command) { +async function onCommand(command, tab) { switch(command) { case 'save_page':{ - const { url='', id } = await currentTab() + const { url='', id } = tab //save highlight if text is selected const [res] = await browser.scripting.executeScript({ @@ -31,6 +30,11 @@ async function onCommand(command) { url: config.links.app.index, active: true }) + + case 'execute_side_panel': { + const { windowId } = tab + return browser.sidePanel.open({ windowId }) + } } } diff --git a/src/target/extension/background/contextMenus.js b/src/target/extension/background/contextMenus.js index bab507af..9fa5e13a 100644 --- a/src/target/extension/background/contextMenus.js +++ b/src/target/extension/background/contextMenus.js @@ -3,7 +3,7 @@ import { open } from './popup' import { addCurrentTabSelection } from './highlights' import { environment } from '../environment' -async function onClicked({ menuItemId, pageUrl, srcUrl, linkUrl }, ) { +async function onClicked({ menuItemId, pageUrl, srcUrl, linkUrl }, { windowId }) { switch(menuItemId) { case 'save_page': return open(`/add?link=${encodeURIComponent(pageUrl)}`) @@ -19,6 +19,18 @@ async function onClicked({ menuItemId, pageUrl, srcUrl, linkUrl }, ) { case 'save_highlight': return addCurrentTabSelection() + + case 'save_tabs': + return open('/extension/tabs/-1') + + case 'open_app': + return open('/', { width: 1280, height: 800, autoClose: false }) + + case 'settings': + return open('/settings', { width: 800, height: 700, autoClose: false }) + + case 'execute_side_panel': + return browser.sidePanel.open({ windowId }) } } @@ -59,6 +71,32 @@ async function init() { id: 'save_highlight', title: browser.i18n.getMessage('saveHighlight')+suffix, contexts: ['selection'] + }), + + ...(environment.includes('chrome') ? [ + browser.contextMenus.create({ + id: 'execute_side_panel', + title: browser.i18n.getMessage('openSidePanel'), + contexts: ['action'] + }) + ] : []), + + browser.contextMenus.create({ + id: 'open_app', + title: browser.i18n.getMessage('openApp'), + contexts: ['action'] + }), + + browser.contextMenus.create({ + id: 'save_tabs', + title: browser.i18n.getMessage('saveTabs'), + contexts: ['action'] + }), + + browser.contextMenus.create({ + id: 'settings', + title: browser.i18n.getMessage('settings'), + contexts: ['action'] }) ]) } diff --git a/src/target/extension/background/popup.js b/src/target/extension/background/popup.js index d85aa99b..d83812e9 100644 --- a/src/target/extension/background/popup.js +++ b/src/target/extension/background/popup.js @@ -7,10 +7,7 @@ const base = environment.includes('safari') ? '/index.html#' const winIds = new Set() -export async function open(path) { - const width = 420; - const height = 600; - +export async function open(path, { width = 420, height = 600, autoClose = true } = {}) { let origin = { left: 0, top: 0, width: 0, height: 0 } try{ origin = await browser.windows.getCurrent() @@ -28,7 +25,8 @@ export async function open(path) { }) //delay autoclose on blur, otherwise buggy on arch linux - setTimeout(() => { winIds.add(id) }, 100) + if (autoClose) + setTimeout(() => { winIds.add(id) }, 100) } /* Close all open popups when focused window change */ diff --git a/src/target/extension/manifest/index.js b/src/target/extension/manifest/index.js index ea23c492..c8707867 100644 --- a/src/target/extension/manifest/index.js +++ b/src/target/extension/manifest/index.js @@ -142,6 +142,15 @@ module.exports = ({ vendor, production=false }, l) => { description: '__MSG_openRaindrop__', }, + ...(vendor == 'chrome' ? { + execute_side_panel: { + suggested_key: { + default: 'Alt+Shift+B' + }, + description: '__MSG_openSidePanel__' + } + }: {}), + ...(vendor == 'firefox' || vendor == 'opera' ? { _execute_sidebar_action: { suggested_key: { diff --git a/src/target/extension/manifest/locales.js b/src/target/extension/manifest/locales.js index 2308d34d..61b31f77 100644 --- a/src/target/extension/manifest/locales.js +++ b/src/target/extension/manifest/locales.js @@ -57,6 +57,10 @@ module.exports = ({ emitFile })=>{ message: s(lang, 'save') + ' ' + s(lang, 'highlights').toLowerCase(), description: '' }, + saveTabs: { + message: s(lang, 'save') + ' ' + s(lang, 'tabs').toLowerCase(), + description: '' + }, openRaindrop: { message: s(lang, 'open') + ' Raindrop.io web-' + s(lang, 'site').toLowerCase(), description: '' @@ -65,9 +69,17 @@ module.exports = ({ emitFile })=>{ message: s(lang, 'open') + ' ' + s(lang, 'sidebar').toLowerCase(), description: '' }, + openApp: { + message: s(lang, 'open') + ' ' + s(lang, 'app').toLowerCase(), + description: '' + }, in: { message: s(lang, 'in'), description: '' + }, + settings: { + message: s(lang, 'settings'), + description: '' } }, null,