/** * Removes a tab with the specified tab ID in Google Chrome. * @param {number} tabId - The ID of the tab to be removed. * @returns {Promise} A promise that resolves when the tab is successfully removed or fails to remove. */ function removeChromeTab(tabId) { return new Promise((resolve) => { chrome.tabs.remove(tabId) .then(resolve) .catch(resolve); }); } /** * Executes a script file in a specific tab in Google Chrome. * @param {number} tabId - The ID of the tab where the script should be executed. * @param {string} file - The file path or URL of the script to be executed. * @returns {Promise} A promise that resolves when the script is successfully executed or fails to execute. */ function executeScriptInTab(tabId, file) { return new Promise((resolve) => { chrome.scripting.executeScript( { target: { tabId }, files: [file], }, () => { resolve(); } ); }); } /** * Opens the options page of the Chrome extension in a new pinned tab. * @returns {Promise} A promise that resolves with the created tab object. */ function openExtensionOptions() { return new Promise((resolve) => { chrome.tabs.create( { pinned: true, active: false, url: `chrome-extension://${chrome.runtime.id}/options.html`, }, (tab) => { resolve(tab); } ); }); } /** * Retrieves the value associated with the specified key from the local storage in Google Chrome. * @param {string} key - The key of the value to retrieve from the local storage. * @returns {Promise} A promise that resolves with the retrieved value from the local storage. */ function getLocalStorageValue(key) { return new Promise((resolve) => { chrome.storage.local.get([key], (result) => { resolve(result[key]); }); }); } /** * Sends a message to a specific tab in Google Chrome. * @param {number} tabId - The ID of the tab to send the message to. * @param {any} data - The data to be sent as the message. * @returns {Promise} A promise that resolves with the response from the tab. */ function sendMessageToTab(tabId, data) { return new Promise((resolve) => { chrome.tabs.sendMessage(tabId, data, (response) => { resolve(response); }); }); } /** * Delays the execution for a specified duration. * @param {number} ms - The duration to sleep in milliseconds (default: 0). * @returns {Promise} A promise that resolves after the specified duration. */ function delayExecution(ms = 0) { return new Promise((resolve) => setTimeout(resolve, ms)); } /** * Sets a value associated with the specified key in the local storage of Google Chrome. * @param {string} key - The key to set in the local storage. * @param {any} value - The value to associate with the key in the local storage. * @returns {Promise} A promise that resolves with the value that was set in the local storage. */ function setLocalStorageValue(key, value) { return new Promise((resolve) => { chrome.storage.local.set( { [key]: value, }, () => { resolve(value); } ); }); } /** * Retrieves the tab object with the specified tabId. * @param {number} tabId - The ID of the tab to retrieve. * @returns {Promise} - A Promise that resolves to the tab object. */ async function getTab(tabId) { return new Promise((resolve) => { chrome.tabs.get(tabId, (tab) => { resolve(tab); }); }); } /** * Starts the capture process for the specified tab. * @param {number} tabId - The ID of the tab to start capturing. * @returns {Promise} - A Promise that resolves when the capture process is started successfully. */ async function startCapture(options) { const { tabId } = options; const optionTabId = await getLocalStorageValue("optionTabId"); if (optionTabId) { await removeChromeTab(optionTabId); } try { const currentTab = await getTab(tabId); if (currentTab.audible) { await setLocalStorageValue("currentTabId", currentTab.id); await executeScriptInTab(currentTab.id, "content.js"); await delayExecution(500); const optionTab = await openExtensionOptions(); await setLocalStorageValue("optionTabId", optionTab.id); await delayExecution(500); await sendMessageToTab(optionTab.id, { type: "start_capture", data: { currentTabId: currentTab.id, host: options.host, port: options.port, multilingual: options.useMultilingual, language: options.language, task: options.task }, }); } else { console.log("No Audio"); } } catch (error) { console.error("Error occurred while starting capture:", error); } } /** * Stops the capture process and performs cleanup. * @returns {Promise} - A Promise that resolves when the capture process is stopped successfully. */ async function stopCapture() { const optionTabId = await getLocalStorageValue("optionTabId"); const currentTabId = await getLocalStorageValue("currentTabId"); if (optionTabId) { res = await sendMessageToTab(currentTabId, { type: "STOP", data: { currentTabId: currentTabId }, }); await removeChromeTab(optionTabId); } } /** * Listens for messages from the runtime and performs corresponding actions. * @param {Object} message - The message received from the runtime. */ chrome.runtime.onMessage.addListener(async (message) => { if (message.action === "startCapture") { startCapture(message); } else if (message.action === "stopCapture") { stopCapture(); } else if (message.action === "updateSelectedLanguage") { const detectedLanguage = message.detectedLanguage; chrome.runtime.sendMessage({ action: "updateSelectedLanguage", detectedLanguage }); chrome.storage.local.set({ selectedLanguage: detectedLanguage }); } else if (message.action === "toggleCaptureButtons") { chrome.runtime.sendMessage({ action: "toggleCaptureButtons", data: false }); chrome.storage.local.set({ capturingState: { isCapturing: false } }) stopCapture(); } });