From cc1b0986b98fd0fc4332d13761051b51de4b9d9d Mon Sep 17 00:00:00 2001 From: Achiya Elyasaf <10044875+eggsterino@users.noreply.github.com> Date: Sun, 6 Aug 2023 09:36:03 +0300 Subject: [PATCH] Update version --- manifest.json | 5 ++-- popup/popup.js | 47 ++++++++++++++--------------------- scripts/content.js | 52 +++++++++++++++++++++------------------ scripts/service-worker.js | 6 ++--- scripts/utils.js | 32 ------------------------ 5 files changed, 50 insertions(+), 92 deletions(-) delete mode 100644 scripts/utils.js diff --git a/manifest.json b/manifest.json index 1409f28..fba3669 100644 --- a/manifest.json +++ b/manifest.json @@ -5,7 +5,7 @@ }, "content_scripts": [ { - "js": ["scripts/jquery.js", "scripts/content.js", "scripts/utils.js"], + "js": ["scripts/jquery.js", "scripts/content.js"], "matches": ["https://*.overleaf.com/project/*"] } ], @@ -36,8 +36,7 @@ } }, "background": { - "service_worker": "scripts/service-worker.js", - "type": "module" + "service_worker": "scripts/service-worker.js" }, "permissions": ["storage", "tabs"], "manifest_version": 3, diff --git a/popup/popup.js b/popup/popup.js index b3c9e84..292cb69 100644 --- a/popup/popup.js +++ b/popup/popup.js @@ -1,5 +1,3 @@ -import {setSetting} from '../scripts/utils.js' - const apiKeyRegex = /sk-[a-zA-Z0-9]{48}/ function addMessage(message) { @@ -21,16 +19,15 @@ async function refreshStorage() { chrome.storage.local.get(['Improve', 'Complete', 'Ask']).then((settings) => { let bindingFailures = Object.values(settings) - .filter(({ status }) => status === 'error') - .map(({ key, shortcut }) => `${shortcut} for ${key}`) - .join(', ') + .filter(({ status }) => status === 'error') + .map(({ key, shortcut }) => `${shortcut} for ${key}`) + .join(', ') if (bindingFailures.length > 0) { - addErrorMessage(`Could not bound the following shortcuts:\n${bindingFailures}.\nYou can set it manually at chrome://extensions/shortcuts.`) + addErrorMessage(`Could not bind the following shortcuts:\n${bindingFailures}.\nYou can set it manually at chrome://extensions/shortcuts.`) } Object.values(settings).forEach(({ key, status, shortcut }) => { $(`#settings-form input[name='text-${key}']:checkbox`).prop('checked', status === 'enabled') let shortcut2 = status === 'error' ? 'not set' : shortcut - console.log(`writing ${shortcut2} to shortcut-${key}`) $(`#shortcut-${key}`).html(`${shortcut2}`) }) }) @@ -51,12 +48,9 @@ async function handleAPITokenSet(event) { return } - try { - chrome.storage.local.set({ openAIAPIKey }).then(refreshStorage) - } catch (error) { - addErrorMessage('Failed to set API Token.') - return - } + chrome.storage.local.set({ openAIAPIKey }) + .then(refreshStorage) + .catch((error) => addErrorMessage(`Failed to remove API Token. Error: ${error}`)) } async function handleAPITokenClear(event) { @@ -65,29 +59,24 @@ async function handleAPITokenClear(event) { clearMessages() - try { - chrome.storage.local.remove('openAIAPIKey').then(refreshStorage) - } catch (error) { - console.log(error) - addErrorMessage('Failed to remove API Token.') - return - } + chrome.storage.local.remove('openAIAPIKey') + .then(refreshStorage) + .catch((error) => addErrorMessage(`Failed to remove API Token. Error: ${error}`)) } -function makeHandleSettingChange(key) { +async function makeHandleSettingChange(key) { return async (event) => { event.preventDefault() event.stopPropagation() clearMessages() const value = event.target.checked - chrome.storage.local.get(key).then(setting => { - if(setting[key].status !== 'error') { - setting[key].status = value ? 'enabled' : 'disabled' - setSetting(setting[key].key, setting[key]) - } - return refreshStorage() - }) + const setting = await chrome.storage.local.get(key) + if (setting[key].status !== 'error') { + setting[key].status = value ? 'enabled' : 'disabled' + await chrome.storage.local.set({ [key]: setting[key] }) + } + return refreshStorage() } } @@ -99,5 +88,5 @@ $(document).ready(async function () { commands.forEach((key) => { $(`#settings-form input[name='text-${key}']:checkbox`).on('change', makeHandleSettingChange(key)) }) - await refreshStorage() + return refreshStorage() }) diff --git a/scripts/content.js b/scripts/content.js index beea07a..35b76df 100644 --- a/scripts/content.js +++ b/scripts/content.js @@ -39,9 +39,8 @@ class OpenAIAPI { temperature: 0.5 } - const result = await this.query('completions', data) - - return result[0].text + return this.query('completions', data) + .then(result => result[0].text) } async improveText(text) { @@ -54,9 +53,8 @@ class OpenAIAPI { temperature: 0.5 } - const result = await this.query('edits', data) - - return result[0].text + return this.query('edits', data) + .then(result => result[0].text) } } @@ -70,14 +68,10 @@ function replaceSelectedText(replacementText, selection) { } } -async function settingIsEnabled(setting) { - let result - try { - result = await chrome.storage.local.get(setting) - } catch (error) { - return false - } - return result[setting] +async function settingIsEnabled(key) { + return chrome.storage.local.get(key) + .then(setting => 'enabled' === setting[key].status) + .catch(() => false) } function commentText(text) { @@ -91,7 +85,7 @@ function commentText(text) { } async function improveTextHandler(openAI) { - if (!(await settingIsEnabled('textImprovement'))) throw new Error('Text improvement is not enabled.') + if (!(await settingIsEnabled('Improve'))) throw new Error('Text improvement is not enabled.') const selection = window.getSelection() const selectedText = selection.toString() if (!selectedText) return @@ -101,7 +95,7 @@ async function improveTextHandler(openAI) { } async function completeTextHandler(openAI) { - if (!(await settingIsEnabled('textCompletion'))) throw new Error('Text completion is not enabled.') + if (!(await settingIsEnabled('Complete'))) throw new Error('Text completion is not enabled.') const selection = window.getSelection() const selectedText = selection.toString() if (!selectedText) return @@ -110,7 +104,7 @@ async function completeTextHandler(openAI) { } async function askHandler(openAI) { - if (!(await settingIsEnabled('textAsk'))) throw new Error('Text ask is not enabled.') + if (!(await settingIsEnabled('Ask'))) throw new Error('Ask is not enabled.') const selection = window.getSelection() const selectedText = selection.toString() if (!selectedText) return @@ -130,28 +124,38 @@ function setAPIKey(key) { currentAPIKey = key if (currentAPIKey) { openAI = new OpenAIAPI(currentAPIKey) - console.log('LeafLLM: OpenAI API key set, enabling LeafLLM features.') + log('OpenAI API key set, enabling LeafLLM features.') } else { openAI = undefined - console.log('LeafLLM: OpenAI API key is not set, LeafLLM features are disabled.') + log('OpenAI API key is not set, LeafLLM features are disabled.') } } function handleCommand(command) { if (command === 'Improve') { - improveTextHandler(openAI).catch(e => error(`Failed to execute the '${command}' command. Error message: ${e}`)) + improveTextHandler(openAI).catch(e => error(`Failed to execute the '${command}' command.`, e)) } else if (command === 'Complete') { - completeTextHandler(openAI).catch(e => error(`Failed to execute the '${command}' command. Error message: ${e}`)) + completeTextHandler(openAI).catch(e => error(`Failed to execute the '${command}' command.`, e)) } else if (command === 'Ask') { - askHandler(openAI).catch(e => error(`Failed to execute the '${command}' command. Error message: ${e}`)) + askHandler(openAI).catch(e => error(`Failed to execute the '${command}' command.`, e)) } } -function error(msg) { +function error(msg, error) { + if(error) { + msg += ` Error message: ${error.message}` + if(error.cause) { + console.error(`\nCause: ${JSON.stringify(error.cause)}`) + } + } customAlert(msg) console.error(`LeafLLM: ${msg}`) } +function log(msg) { + console.log(`LeafLLM: ${msg}`) +} + function customAlert(msg,duration) { if(!duration) duration = 4000; @@ -168,7 +172,7 @@ function customAlert(msg,duration) chrome.runtime.onMessage.addListener( function (request, sender, sendResponse) { - console.log(`Received request: ${JSON.stringify(request)}`) + log(`Received request: ${JSON.stringify(request)}`) if (request.command === 'setup') { setAPIKey(request.apiKey) } else { diff --git a/scripts/service-worker.js b/scripts/service-worker.js index 9ee3e70..2cf722e 100644 --- a/scripts/service-worker.js +++ b/scripts/service-worker.js @@ -1,5 +1,3 @@ -import {setSetting} from './utils.js' - const settings = [ { key: 'Complete', shortcut: 'Alt+C', status: 'enabled', type: 'Command' }, { key: 'Improve', shortcut: 'Alt+I', status: 'enabled', type: 'Command' }, @@ -9,7 +7,7 @@ const settings = [ async function sendMessage(message) { const [tab] = await chrome.tabs.query({ active: true, lastFocusedWindow: true }) if (tab == null || tab.url?.startsWith('chrome://')) return undefined - const response = await chrome.tabs.sendMessage(tab.id, message) + chrome.tabs.sendMessage(tab.id, message) // do something with response here, not outside the function // console.log(response) } @@ -41,7 +39,7 @@ async function checkCommandShortcuts() { if (shortcut === '') { command.status = 'error' } - setSetting(command.key, command) + chrome.storage.local.set({ [command.key]: command }) } } }) diff --git a/scripts/utils.js b/scripts/utils.js deleted file mode 100644 index e3b55ed..0000000 --- a/scripts/utils.js +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Set a setting in storage {@link https://developer.chrome.com/docs/extensions/reference/storage/#type-StorageArea:~:text=to%20the%20callback.-,set,-void} - * @param key - * @param value - * @param {function}[callback] Optional callback function - */ -export async function setSetting(key, value, callback) { - let obj = {} - obj[key] = value - if (typeof callback === 'undefined') { - chrome.storage.local.set(obj).catch(error => { - console.log(`Failed to set ${key} setting. Error: ${error}`) - }) - } else { - chrome.storage.local.set(obj, callback).catch(error => { - console.log(`Failed to set ${key} setting. Error: ${error}`) - }) - } -} - -/** - * Get a setting from storage - * @param {string | string[] | object} [keys=null] - The keys to get (see {@link https://developer.chrome.com/docs/extensions/reference/storage/#usage}) - * @param {function}[callback] Optional callback function - */ -export async function getSetting(keys = null, callback) { - if (typeof callback === 'undefined') { - return chrome.storage.local.get(keys, (items) => Object.values(items)) - }else { - return chrome.storage.local.get(keys, (items) => callback(Object.values(items))) - } -} \ No newline at end of file