commit
3f16901010
11 changed files with 195 additions and 57 deletions
|
|
@ -4,6 +4,12 @@
|
|||
|
||||
|
||||
|
||||
<h2>Version 2.1.2 - 04/09/2024</h2>
|
||||
<ul>
|
||||
<li><i>[ChatGPT API]</i> The URL in the prompt sending error message is now correctly clickable [<a href="https://github.com/micz/ThunderAI/issues/123">#123</a>].</li>
|
||||
<li><i>[ChatGPT API]</i> If the web interface loads slowly, a button is now shown to retry sending the prompt [<a href="https://github.com/micz/ThunderAI/issues/122">#122</a>].</li>
|
||||
<li><i>[ChatGPT API]</i> Improved the methods to open the ChatGPT window and interact with it.</li>
|
||||
</ul>
|
||||
<h2>Version 2.1.1 - 28/08/2024</h2>
|
||||
<ul>
|
||||
<li><i>[ChatGPT API]</i> Fixed a bug in handling the chat window.</li>
|
||||
|
|
|
|||
|
|
@ -220,7 +220,17 @@
|
|||
"description": ""
|
||||
},
|
||||
"chatgpt_textarea_not_found_error": {
|
||||
"message": "Es gibt einen Fehler beim Senden der Eingabeaufforderung an ChatGPT. Bitte versuchen Sie es erneut. Wenn das Problem weiterhin besteht, überprüfen Sie bitte den <a href=\"https://micz.it/thunderbird-addon-thunderai/status/\">Dienststatus</a>.",
|
||||
"message": "Es scheint, dass die ChatGPT-Seite zu lange zum Laden braucht. Wenn sie fertig geladen ist, klicken Sie auf den Button rechts. Wenn das Problem weiterhin besteht, überprüfen Sie bitte den <a href=\"$URL$\">Dienststatus</a>.",
|
||||
"description": "",
|
||||
"placeholders": {
|
||||
"url": {
|
||||
"content": "$1",
|
||||
"example": "https://micz.it/thunderbird-addon-thunderai/status/"
|
||||
}
|
||||
}
|
||||
},
|
||||
"chatgpt_btn_retry": {
|
||||
"message": "Wiederholen",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_sendbutton_not_found_error": {
|
||||
|
|
|
|||
|
|
@ -220,7 +220,17 @@
|
|||
"description": ""
|
||||
},
|
||||
"chatgpt_textarea_not_found_error": {
|
||||
"message": "There is an error sending the prompt to ChatGPT, please retry. If the problem persists, please <a href=\"https://micz.it/thunderbird-addon-thunderai/status/\">check the service status</a>.",
|
||||
"message": "It seems that the ChatGPT page is taking too long to load. If it finishes loading, click the button on the right. If the problem persists, please <a href=\"$URL$\">check the service status</a>.",
|
||||
"description": "",
|
||||
"placeholders": {
|
||||
"url": {
|
||||
"content": "$1",
|
||||
"example": "https://micz.it/thunderbird-addon-thunderai/status/"
|
||||
}
|
||||
}
|
||||
},
|
||||
"chatgpt_btn_retry": {
|
||||
"message": "Retry",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_sendbutton_not_found_error": {
|
||||
|
|
|
|||
|
|
@ -220,7 +220,17 @@
|
|||
"description": ""
|
||||
},
|
||||
"chatgpt_textarea_not_found_error": {
|
||||
"message": "Il y a une erreur lors de l'envoi de la proposition à ChatGPT, veuillez réessayer. Si le problème persiste, veuillez <a href=\"https://micz.it/thunderbird-addon-thunderai/status/\">vérifier le statut du service</a>.",
|
||||
"message": "Il semble que la page ChatGPT mette trop de temps à charger. Si elle finit de charger, cliquez sur le bouton à droite. Si le problème persiste, veuillez <a href=\"$URL$\">vérifier le statut du service</a>.",
|
||||
"description": "",
|
||||
"placeholders": {
|
||||
"url": {
|
||||
"content": "$1",
|
||||
"example": "https://micz.it/thunderbird-addon-thunderai/status/"
|
||||
}
|
||||
}
|
||||
},
|
||||
"chatgpt_btn_retry": {
|
||||
"message": "Réessayer",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_sendbutton_not_found_error": {
|
||||
|
|
|
|||
|
|
@ -220,7 +220,17 @@
|
|||
"description": ""
|
||||
},
|
||||
"chatgpt_textarea_not_found_error": {
|
||||
"message": "C'è stato un errore nell'invio del prompt a ChatGPT, per favore riprova. Se il problema persiste, per favore <a href=\"https://micz.it/thunderbird-addon-thunderai/status/\">controlla lo stato del servizio</a>.",
|
||||
"message": "Sembra che la pagina di ChatGPT impieghi troppo tempo a caricarsi. Se finisce di caricarsi, clicca sul pulsante a destra. Se il problema persiste, per favore <a href=\"$URL$\">controlla lo stato del servizio</a>.",
|
||||
"description": "",
|
||||
"placeholders": {
|
||||
"url": {
|
||||
"content": "$1",
|
||||
"example": "https://micz.it/thunderbird-addon-thunderai/status/"
|
||||
}
|
||||
}
|
||||
},
|
||||
"chatgpt_btn_retry": {
|
||||
"message": "Riprova",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_sendbutton_not_found_error": {
|
||||
|
|
|
|||
27
js/mzta-chatgpt-loader.js
Normal file
27
js/mzta-chatgpt-loader.js
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* ThunderAI [https://micz.it/thunderbird-addon-thunderai/]
|
||||
* Copyright (C) 2024 Mic (m@micz.it)
|
||||
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const call_id = urlParams.get('call_id');
|
||||
|
||||
async function page_ready(call_id){
|
||||
await browser.runtime.sendMessage({command: "chatgpt_web_ready_" + call_id});
|
||||
}
|
||||
|
||||
page_ready(call_id);
|
||||
//console.log(">>>>>>>>>>> [ThunderAI] call_id: " + call_id)
|
||||
|
|
@ -22,8 +22,11 @@
|
|||
|
||||
export const mzta_script = `
|
||||
let force_go = false;
|
||||
let do_force_completion = false;
|
||||
let current_message = null;
|
||||
let current_action = null;
|
||||
let current_tabId = null;
|
||||
let current_mailMessageId = null;
|
||||
let selectionChangeTimeout = null;
|
||||
let isDragging = false;
|
||||
|
||||
|
|
@ -59,19 +62,22 @@ async function chatgpt_sendMsg(msg, method ='') { // return -1 send button
|
|||
async function chatgpt_isIdle() {
|
||||
return new Promise(resolve => {
|
||||
const intervalId = setInterval(() => {
|
||||
if (chatgpt_getRegenerateButton()) {
|
||||
if (chatgpt_getRegenerateButton() || do_force_completion) {
|
||||
clearInterval(intervalId); resolve(true);
|
||||
}}, 100);});}
|
||||
|
||||
function chatgpt_getRegenerateButton() {
|
||||
for (const mainSVG of document.querySelectorAll('main svg')) {
|
||||
if (mainSVG.querySelector('path[d*="M3.07 10.876C3.623"]')) // regen icon found
|
||||
if (mainSVG.querySelector('path[d^="M3.06957"]')) // regen icon found
|
||||
return mainSVG.parentNode.parentNode;
|
||||
}
|
||||
}
|
||||
|
||||
function chatpgt_scrollToBottom () {
|
||||
try { document.querySelector('button[class*="cursor"][class*="bottom"]').click(); }
|
||||
try {
|
||||
//document.querySelector('button[class*="cursor"][class*="bottom"]').click();
|
||||
document.querySelector('path[d^="M12 21C11.7348"]').parentNode.parentNode.click();
|
||||
}
|
||||
catch (err) { console.error('[ThunderAI] ', err); }
|
||||
}
|
||||
|
||||
|
|
@ -139,7 +145,7 @@ function addCustomDiv(prompt_action,tabId,mailMessageId) {
|
|||
force_completion_div.textContent = mztaForceCompletionDesc;
|
||||
force_completion_div.title = mztaForceCompletionTitle;
|
||||
force_completion_div.addEventListener('click', function() {
|
||||
operation_done();
|
||||
do_force_completion = true;
|
||||
});
|
||||
fixedDiv.appendChild(force_completion_div);
|
||||
|
||||
|
|
@ -288,7 +294,7 @@ async function doProceed(message, customText = ''){
|
|||
}
|
||||
//await chatgpt.isLoaded();
|
||||
let send_result = await chatgpt_sendMsg(message.prompt+' '+customText,'click');
|
||||
console.log(">>>>>>>>>>> send_result: " + send_result);
|
||||
//console.log(">>>>>>>>>>> send_result: " + send_result);
|
||||
switch(send_result){
|
||||
case -1: // send button not found
|
||||
let curr_msg = document.getElementById('mzta-curr_msg');
|
||||
|
|
@ -297,16 +303,38 @@ async function doProceed(message, customText = ''){
|
|||
break;
|
||||
case -2: // textarea not found
|
||||
let curr_model_warn = document.getElementById('mzta-model_warn');
|
||||
curr_model_warn.textContent = browser.i18n.getMessage("chatgpt_textarea_not_found_error");
|
||||
let message = browser.i18n.getMessage("chatgpt_textarea_not_found_error","https://micz.it/thunderbird-addon-thunderai/status/");
|
||||
let parts = message.split(/<a href="([^"]+)">([^<]+)<\\/a>/);
|
||||
curr_model_warn.textContent = parts[0];
|
||||
let link = document.createElement('a');
|
||||
link.href = parts[1];
|
||||
link.textContent = parts[2];
|
||||
curr_model_warn.appendChild(link);
|
||||
curr_model_warn.appendChild(document.createTextNode(parts[3]));
|
||||
curr_model_warn.style.display = 'inline-block';
|
||||
document.getElementById('mzta-curr_msg').textContent = "";
|
||||
document.getElementById('mzta-loading').style.display = 'none';
|
||||
let btn_retry = document.createElement('button');
|
||||
btn_retry.id="mzta-btn_retry";
|
||||
btn_retry.classList.add('mzta-btn');
|
||||
btn_retry.style.position = 'absolute';
|
||||
btn_retry.style.top = '5px';
|
||||
btn_retry.style.right = '5px';
|
||||
btn_retry.textContent = browser.i18n.getMessage("chatgpt_btn_retry");
|
||||
btn_retry.addEventListener('click', function() {
|
||||
doRetry();
|
||||
});
|
||||
curr_model_warn.insertAdjacentElement('afterend', btn_retry);
|
||||
break;
|
||||
}
|
||||
await chatgpt_isIdle();
|
||||
operation_done();
|
||||
}
|
||||
|
||||
function doRetry(){
|
||||
doProceed(current_message);
|
||||
}
|
||||
|
||||
|
||||
function removeTagsAndReturnHTML(rootElement, removeTags, preserveTags) {
|
||||
const fragment = document.createDocumentFragment();
|
||||
|
|
@ -470,30 +498,50 @@ function selectContentOnClick(event) {
|
|||
}
|
||||
}
|
||||
|
||||
function run(){
|
||||
if(!checkLoggedIn()){
|
||||
// User not logged in
|
||||
alert(browser.i18n.getMessage("chatgpt_user_not_logged_in"));
|
||||
}else{
|
||||
addCustomDiv(current_action,current_tabId,current_mailMessageId);
|
||||
(async () => {
|
||||
if(mztaDoCustomText === 1){
|
||||
showCustomTextField();
|
||||
} else {
|
||||
await doProceed(current_message);
|
||||
}
|
||||
// Add an event listener to the document to detect clicks
|
||||
document.addEventListener('mousedown', selectContentOnMouseDown);
|
||||
document.addEventListener('mousemove', selectContentOnMouseMove);
|
||||
document.addEventListener('mouseup', selectContentOnMouseUp);
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
// In the content script
|
||||
browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
if (message.command === "chatgpt_send") {
|
||||
if(!checkLoggedIn()){
|
||||
// User not logged in
|
||||
alert(browser.i18n.getMessage("chatgpt_user_not_logged_in"));
|
||||
}else{
|
||||
//console.log(">>>>>>>>>>>>> content.js onMessage: " + JSON.stringify(message));
|
||||
switch(message.command) {
|
||||
case "chatgpt_send":
|
||||
current_action = message.action;
|
||||
addCustomDiv(message.action,message.tabId,message.mailMessageId);
|
||||
(async () => {
|
||||
if(mztaDoCustomText === 1){
|
||||
current_message = message;
|
||||
showCustomTextField();
|
||||
} else {
|
||||
await doProceed(message);
|
||||
}
|
||||
// Add an event listener to the document to detect clicks
|
||||
document.addEventListener('mousedown', selectContentOnMouseDown);
|
||||
document.addEventListener('mousemove', selectContentOnMouseMove);
|
||||
document.addEventListener('mouseup', selectContentOnMouseUp);
|
||||
})();
|
||||
}
|
||||
current_message = message;
|
||||
current_tabId = message.tabId;
|
||||
current_mailMessageId = message.mailMessageId;
|
||||
run();
|
||||
break;
|
||||
case "chatgpt_alive":
|
||||
sendResponse({isAlive: true});
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
let checkTab = setInterval(() => {
|
||||
let customDiv = document.getElementById('mzta-custom_text');
|
||||
if(customDiv){
|
||||
clearInterval(checkTab);
|
||||
}else{
|
||||
run();
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
`
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ function compareThunderbirdVersions(v1, v2) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
export function generateCallID(length) {
|
||||
export function generateCallID(length = 10) {
|
||||
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let result = '';
|
||||
const charactersLength = characters.length;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"manifest_version": 2,
|
||||
"name": "ThunderAI",
|
||||
"description": "__MSG_extensionDescription__",
|
||||
"version": "2.1.1",
|
||||
"version": "2.1.2",
|
||||
"author": "Mic (m@micz.it)",
|
||||
"homepage_url": "https://micz.it/thunderbird-addon-thunderai/",
|
||||
"browser_specific_settings": {
|
||||
|
|
|
|||
|
|
@ -56,6 +56,12 @@ for (let messageTab of messageTabs) {
|
|||
}
|
||||
}
|
||||
|
||||
browser.contentScripts.register({
|
||||
matches: ["https://*.chatgpt.com/*"],
|
||||
js: [{file: "js/mzta-chatgpt-loader.js"}],
|
||||
runAt: "document_idle"
|
||||
});
|
||||
|
||||
messenger.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
|
||||
// Check what type of message we have received and invoke the appropriate
|
||||
// handler function.
|
||||
|
|
@ -161,30 +167,38 @@ async function openChatGPT(promptText, action, curr_tabId, prompt_name = '', do_
|
|||
|
||||
switch(prefs.connection_type){
|
||||
case 'chatgpt_web':
|
||||
|
||||
let rand_call_id = '_chatgptweb_' + generateCallID();
|
||||
|
||||
// We are using the ChatGPT web interface
|
||||
let newWindow = await browser.windows.create({
|
||||
url: "https://chatgpt.com",
|
||||
url: "https://chatgpt.com?call_id=" + rand_call_id,
|
||||
type: "popup",
|
||||
width: prefs.chatgpt_win_width,
|
||||
height: prefs.chatgpt_win_height
|
||||
});
|
||||
|
||||
taLog.log("[ThunderAI] ChatGPT web interface script started...");
|
||||
let createdTab = newWindow.tabs[0];
|
||||
let newWindowId = newWindow.id;
|
||||
let createdTab = newWindow.tabs[0];
|
||||
|
||||
let pre_script = `let mztaWinId = `+ newWindowId +`;
|
||||
let mztaStatusPageDesc="`+ browser.i18n.getMessage("prefs_status_page") +`";
|
||||
let mztaForceCompletionDesc="`+ browser.i18n.getMessage("chatgpt_force_completion") +`";
|
||||
let mztaForceCompletionTitle="`+ browser.i18n.getMessage("chatgpt_force_completion_title") +`";
|
||||
let mztaDoCustomText=`+ do_custom_text +`;
|
||||
let mztaPromptName="[`+ i18nConditionalGet(prompt_name) +`]";
|
||||
`;
|
||||
const listener = async (message, sender, sendResponse) => {
|
||||
|
||||
let done1 = false;
|
||||
if (message.command === "chatgpt_web_ready_" + rand_call_id) {
|
||||
|
||||
while(!done1){
|
||||
try {
|
||||
taLog.log("[ThunderAI] ChatGPT web interface script started...");
|
||||
|
||||
let pre_script = `let mztaWinId = `+ newWindowId +`;
|
||||
let mztaStatusPageDesc="`+ browser.i18n.getMessage("prefs_status_page") +`";
|
||||
let mztaForceCompletionDesc="`+ browser.i18n.getMessage("chatgpt_force_completion") +`";
|
||||
let mztaForceCompletionTitle="`+ browser.i18n.getMessage("chatgpt_force_completion_title") +`";
|
||||
let mztaDoCustomText=`+ do_custom_text +`;
|
||||
let mztaPromptName="[`+ i18nConditionalGet(prompt_name) +`]";
|
||||
`;
|
||||
|
||||
taLog.log("Waiting 1 sec");
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
taLog.log("Waiting 1 sec done");
|
||||
|
||||
await browser.tabs.executeScript(createdTab.id, { code: pre_script + mzta_script, matchAboutBlank: false });
|
||||
let mailMessage = await browser.messageDisplay.getDisplayedMessage(curr_tabId);
|
||||
let mailMessageId = -1;
|
||||
|
|
@ -192,23 +206,20 @@ async function openChatGPT(promptText, action, curr_tabId, prompt_name = '', do_
|
|||
browser.tabs.sendMessage(createdTab.id, { command: "chatgpt_send", prompt: promptText, action: action, tabId: curr_tabId, mailMessageId: mailMessageId});
|
||||
taLog.log('[ChatGPT Web] Connection succeded!');
|
||||
taLog.log("[ThunderAI] ChatGPT Web script injected successfully");
|
||||
done1 = true;
|
||||
} catch (error) {
|
||||
taLog.warn('[ChatGPT Web] Error connecting to the window chat: ', error);
|
||||
taLog.warn('[ChatGPT Web] Trying again...');
|
||||
done1 = false;
|
||||
browser.runtime.onMessage.removeListener(listener);
|
||||
}
|
||||
await new Promise(resolve => setTimeout(resolve, 500));
|
||||
}
|
||||
break; // chatgpt_web
|
||||
|
||||
browser.runtime.onMessage.addListener(listener);
|
||||
break; // chatgpt_web
|
||||
|
||||
case 'chatgpt_api':
|
||||
// We are using the ChatGPT API
|
||||
|
||||
let rand_call_id = '_openai_' + generateCallID();
|
||||
let rand_call_id2 = '_openai_' + generateCallID();
|
||||
|
||||
await browser.windows.create({
|
||||
url: browser.runtime.getURL('api_webchat/index.html?llm='+prefs.connection_type+'&call_id='+rand_call_id),
|
||||
url: browser.runtime.getURL('api_webchat/index.html?llm='+prefs.connection_type+'&call_id='+rand_call_id2),
|
||||
type: "popup",
|
||||
width: prefs.chatgpt_win_width,
|
||||
height: prefs.chatgpt_win_height
|
||||
|
|
@ -216,7 +227,7 @@ async function openChatGPT(promptText, action, curr_tabId, prompt_name = '', do_
|
|||
|
||||
const listener2 = async (message, sender, sendResponse) => {
|
||||
|
||||
if (message.command === "openai_api_ready_"+rand_call_id) {
|
||||
if (message.command === "openai_api_ready_"+rand_call_id2) {
|
||||
|
||||
let newWindow2 = await browser.windows.get(message.window_id, {populate: true});
|
||||
let createdTab2 = newWindow2.tabs[0];
|
||||
|
|
@ -250,10 +261,10 @@ async function openChatGPT(promptText, action, curr_tabId, prompt_name = '', do_
|
|||
|
||||
taLog.log("Ollama API window opening...");
|
||||
|
||||
let rand_call_id2 = '_ollama_' + generateCallID();
|
||||
let rand_call_id3 = '_ollama_' + generateCallID();
|
||||
|
||||
await browser.windows.create({
|
||||
url: browser.runtime.getURL('api_webchat/index.html?llm='+prefs.connection_type+'&call_id='+rand_call_id2),
|
||||
url: browser.runtime.getURL('api_webchat/index.html?llm='+prefs.connection_type+'&call_id='+rand_call_id3),
|
||||
type: "popup",
|
||||
width: prefs.chatgpt_win_width,
|
||||
height: prefs.chatgpt_win_height
|
||||
|
|
@ -261,7 +272,7 @@ async function openChatGPT(promptText, action, curr_tabId, prompt_name = '', do_
|
|||
|
||||
const listener3 = async (message, sender, sendResponse) => {
|
||||
|
||||
if (message.command === "ollama_api_ready_"+rand_call_id2) {
|
||||
if (message.command === "ollama_api_ready_"+rand_call_id3) {
|
||||
taLog.log("Ollama API window ready.");
|
||||
taLog.log("message.window_id: " + message.window_id)
|
||||
let newWindow3 = await browser.windows.get(message.window_id, {populate: true});
|
||||
|
|
|
|||
|
|
@ -7,6 +7,12 @@
|
|||
<body>
|
||||
<div id="miczBackPrefs"><a href="mzta-options.html">__MSG_backToOptionsText__</a></div>
|
||||
<div id="miczRelNotes"><h1>ThunderAI Release Notes</h1>
|
||||
<h2>Version 2.1.2 - 04/09/2024</h2>
|
||||
<ul>
|
||||
<li><i>[ChatGPT API]</i> The URL in the prompt sending error message is now correctly clickable [<a href="https://github.com/micz/ThunderAI/issues/123">#123</a>].</li>
|
||||
<li><i>[ChatGPT API]</i> If the web interface loads slowly, a button is now shown to retry sending the prompt [<a href="https://github.com/micz/ThunderAI/issues/122">#122</a>].</li>
|
||||
<li><i>[ChatGPT API]</i> Improved the methods to open the ChatGPT window and interact with it.</li>
|
||||
</ul>
|
||||
<h2>Version 2.1.1 - 28/08/2024</h2>
|
||||
<ul>
|
||||
<li><i>[ChatGPT API]</i> Fixed a bug in handling the chat window.</li>
|
||||
|
|
|
|||
Loading…
Reference in a new issue