diff --git a/CHANGELOG.md b/CHANGELOG.md
index 960876ab..816fcbf9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,13 @@
+
Version 1.2.1 - 20/07/2024
+
+ - Fixed changes in the ChatGPT web interface when importing in plain text [#87].
+ - Added an option to the prompts to specify the default language for the response [#86].
+ - Not adding to the prompt the statement about using the default language if asking for a translation [#85].
+ - [Thunderbird 128+ only] Added a warning message when closing the Custom Prompts page with unsaved changes [#88].
+
Version 1.2.0 - 17/07/2024
- If no default language is set in the options, the language present in the text sent to ChatGPT will be used [#53].
diff --git a/_locales/de/messages.json b/_locales/de/messages.json
index 6486dfc2..dabc7ec9 100644
--- a/_locales/de/messages.json
+++ b/_locales/de/messages.json
@@ -382,5 +382,9 @@
"currently_used_prompt": {
"message": "Derzeit verwendeter Prompt-Name",
"description": ""
+ },
+ "customprompts_form_label_define_response_lang": {
+ "message": "Definieren Sie die Antwortsprache im Prompt.",
+ "description": ""
}
}
\ No newline at end of file
diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index 82ee1781..1d516cd8 100644
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -382,5 +382,9 @@
"currently_used_prompt": {
"message": "Currently used prompt name",
"description": ""
+ },
+ "customprompts_form_label_define_response_lang": {
+ "message": "Define the reponse languange in the prompt",
+ "description": ""
}
}
\ No newline at end of file
diff --git a/_locales/fr/messages.json b/_locales/fr/messages.json
index 76919b58..6bd52602 100644
--- a/_locales/fr/messages.json
+++ b/_locales/fr/messages.json
@@ -382,5 +382,9 @@
"currently_used_prompt": {
"message": "Nom du prompt actuellement utilisé",
"description": ""
+ },
+ "customprompts_form_label_define_response_lang": {
+ "message": "Définir la langue de réponse dans le prompt.",
+ "description": ""
}
}
\ No newline at end of file
diff --git a/_locales/it/messages.json b/_locales/it/messages.json
index 3fee6be5..741b8af5 100644
--- a/_locales/it/messages.json
+++ b/_locales/it/messages.json
@@ -382,5 +382,9 @@
"currently_used_prompt": {
"message": "Nome del prompt attualmente utilizzato",
"description": ""
+ },
+ "customprompts_form_label_define_response_lang": {
+ "message": "Definisci la lingua di risposta nel prompt.",
+ "description": ""
}
}
\ No newline at end of file
diff --git a/customprompts/mzta-custom-prompts.html b/customprompts/mzta-custom-prompts.html
index 59e01931..fa8a17eb 100644
--- a/customprompts/mzta-custom-prompts.html
+++ b/customprompts/mzta-custom-prompts.html
@@ -51,6 +51,8 @@
+
+
diff --git a/customprompts/mzta-custom-prompts.js b/customprompts/mzta-custom-prompts.js
index 779b59e1..1440506a 100644
--- a/customprompts/mzta-custom-prompts.js
+++ b/customprompts/mzta-custom-prompts.js
@@ -17,6 +17,7 @@
*/
import { getPrompts, setDefaultPromptsProperties, setCustomPrompts, preparePromptsForExport, preparePromptsForImport } from "../js/mzta-prompts.js";
+import { isThunderbird128OrGreater } from "../js/mzta-utils.js";
var promptsList = null;
var somethingChanged = false;
@@ -114,6 +115,7 @@ document.addEventListener('DOMContentLoaded', async () => {
var checkboxNeedSelectedNew = document.getElementById('checkboxNeedSelectedNew');
var checkboxNeedSignatureNew = document.getElementById('checkboxNeedSignatureNew');
var checkboxNeedCustomTextNew = document.getElementById('checkboxNeedCustomTextNew');
+ var checkboxDefineResponseLangNew = document.getElementById('checkboxDefineResponseLangNew');
const btnAddNew = document.getElementById('btnAddNew');
btnAddNew.addEventListener('click', (e) => {
@@ -130,6 +132,7 @@ document.addEventListener('DOMContentLoaded', async () => {
need_selected: (checkboxNeedSelectedNew.checked) ? 1 : 0,
need_signature: (checkboxNeedSignatureNew.checked) ? 1 : 0,
need_custom_text: (checkboxNeedCustomTextNew.checked) ? 1 : 0,
+ define_response_lang: (checkboxDefineResponseLangNew.checked) ? 1 : 0,
enabled: 1,
position_compose: positionMax_compose + 1,
position_display: positionMax_display + 1,
@@ -273,6 +276,7 @@ function showItemRowEditor(tr) {
tr.querySelector('input.need_selected').disabled = false;
tr.querySelector('input.need_signature').disabled = false;
tr.querySelector('input.need_custom_text').disabled = false;
+ tr.querySelector('input.define_response_lang').disabled = false;
}
function hideItemRowEditor(tr) {
@@ -289,6 +293,7 @@ function hideItemRowEditor(tr) {
tr.querySelector('input.need_selected').disabled = true;
tr.querySelector('input.need_signature').disabled = true;
tr.querySelector('input.need_custom_text').disabled = true;
+ tr.querySelector('input.define_response_lang').disabled = true;
}
// Confirm and log deletion action
@@ -354,7 +359,7 @@ function handleInputChange(e) {
function loadPromptsList(values){
let options = {
- valueNames: [ { data: ['idnum'] }, 'is_default', 'id', 'name', 'text', 'type', 'action', 'position_compose', 'position_display', { name: 'need_selected', attr: 'checked_val'}, { name: 'need_signature', attr: 'checked_val'}, { name: 'need_custom_text', attr: 'checked_val'}, { name: 'enabled', attr: 'checked_val'} ],
+ valueNames: [ { data: ['idnum'] }, 'is_default', 'id', 'name', 'text', 'type', 'action', 'position_compose', 'position_display', { name: 'need_selected', attr: 'checked_val'}, { name: 'need_signature', attr: 'checked_val'}, { name: 'need_custom_text', attr: 'checked_val'}, { name: 'define_response_lang', attr: 'checked_val'}, { name: 'enabled', attr: 'checked_val'} ],
item: function(values) {
let type_output = '';
switch(String(values.type)){
@@ -410,6 +415,8 @@ function loadPromptsList(values){
__MSG_customPrompts_form_label_need_custom_text__
+ __MSG_customPrompts_form_label_define_response_lang__
+
__MSG_customPrompts_form_label_enabled__
@@ -547,6 +554,7 @@ function checkSelectedBoxes(checkboxes = null) {
...document.querySelectorAll('.need_selected[type="checkbox"]'),
...document.querySelectorAll('.need_signature[type="checkbox"]'),
...document.querySelectorAll('.need_custom_text[type="checkbox"]'),
+ ...document.querySelectorAll('.define_response_lang[type="checkbox"]'),
...document.querySelectorAll('.enabled[type="checkbox"]'),
];
}
@@ -611,9 +619,11 @@ function clearMessage() {
}
-// window.addEventListener('beforeunload', function (event) {
-// // Check if any changes have been made
-// if (somethingChanged) {
-// event.preventDefault();
-// }
-// });
\ No newline at end of file
+if(await isThunderbird128OrGreater()){
+ window.addEventListener('beforeunload', function (event) {
+ // Check if any changes have been made (Only for Thunderbird 128+ see https://github.com/micz/ThunderAI/issues/88)
+ if (somethingChanged) {
+ event.preventDefault();
+ }
+ });
+}
diff --git a/js/mzta-chatgpt.js b/js/mzta-chatgpt.js
index 03140558..6a19bd7f 100644
--- a/js/mzta-chatgpt.js
+++ b/js/mzta-chatgpt.js
@@ -65,6 +65,7 @@ function chatgpt_getRegenerateButton() {
async function chatgpt_getFromDOM(pos) {
const responseDivs = document.querySelectorAll('div[data-testid*="conversation-turn"]:nth-child(odd)'),
strPos = pos.toString().toLowerCase();
+ //console.log(">>>>>>>>>>>>> responseDivs.length: "+ responseDivs.length);
let response = '';
if (responseDivs.length) {
if (/last|final/.test(strPos)){ // get last response
@@ -74,13 +75,9 @@ async function chatgpt_getFromDOM(pos) {
let doc = parser.parseFromString(responseDivs[responseDivs.length - 1].innerHTML, 'text/html');
if(!mztaKeepFormatting) { // Return only TEXT
// Select the div with class 'empty:hidden'
- let divToRemove = doc.querySelector('div.empty\\\\:hidden');
- if (divToRemove) {
- divToRemove.remove();
- }
- // Extract the new HTML string
- responseDivs[responseDivs.length - 1].innerHTML = doc.body.innerHTML;
- response = responseDivs[responseDivs.length - 1].textContent;
+ let correct_div = responseDivs[responseDivs.length - 1].querySelector('div[data-message-author-role="assistant"]');
+ response = correct_div.textContent;
+ //console.log(">>>>>>>>>> response: " + response);
response = response.replace(/^ChatGPT(?:ChatGPT)?/, ''); // strip sender name
response = response.trim().replace(/^"|"$/g, ''); // strip quotation marks
response = "" + response + "
";
@@ -90,7 +87,6 @@ async function chatgpt_getFromDOM(pos) {
//console.log(">>>>>>>>> doc_response: " + JSON.stringify(doc_response.body.innerHTML));
replaceNewlinesWithBr(doc_response.body)
response = doc_response.body.innerHTML;
- // response = responseDivs[responseDivs.length - 1].innerHTML;
} else { // Return HTML
// Tags to exclude
//console.log(">>>>>>>>> doc.body.innerHTML original: " + doc.body.innerHTML);
diff --git a/js/mzta-menus.js b/js/mzta-menus.js
index 707ebfc5..9b709e19 100644
--- a/js/mzta-menus.js
+++ b/js/mzta-menus.js
@@ -93,13 +93,16 @@ export class mzta_Menus {
}
//open chatgpt window
//console.log("Click menu item...");
- let prefs = await browser.storage.sync.get({default_chatgpt_lang: ''});
- let chatgpt_lang = prefs.default_chatgpt_lang;
- //console.log(" >>>>>>>>>>>> chatgpt_lang: " + chatgpt_lang);
- if(chatgpt_lang === ''){
- chatgpt_lang = 'Reply in the language it is written.';
- }else{
- chatgpt_lang = browser.i18n.getMessage("prompt_lang") + " " + chatgpt_lang + ".";
+ let chatgpt_lang = '';
+ if(String(curr_prompt.define_response_lang) == "1"){
+ let prefs = await browser.storage.sync.get({default_chatgpt_lang: ''});
+ chatgpt_lang = prefs.default_chatgpt_lang;
+ //console.log(" >>>>>>>>>>>> chatgpt_lang: " + chatgpt_lang);
+ if(chatgpt_lang === ''){
+ chatgpt_lang = 'Reply in the same language.';
+ }else{
+ chatgpt_lang = browser.i18n.getMessage("prompt_lang") + " " + chatgpt_lang + ".";
+ }
}
var fullPrompt = curr_prompt.text + (String(curr_prompt.need_signature) == "1" ? " " + await this.getDefaultSignature():"") + " " + chatgpt_lang + " \"" + body_text + "\" ";
diff --git a/js/mzta-prompts.js b/js/mzta-prompts.js
index 564a18b7..4f341200 100644
--- a/js/mzta-prompts.js
+++ b/js/mzta-prompts.js
@@ -44,6 +44,10 @@
0: No custom text needed
1: Custom text needed
+ Define response language (define_response_lang attribute):
+ 0: Do not include a statement about the response language in the prompt.
+ 1: Include a statement about the response language in the prompt.
+
================ USER PROPERTIES
Enabled (enabled attribute):
0: Disabled
@@ -67,6 +71,7 @@ const defaultPrompts = [
need_selected: "0",
need_signature: "1",
need_custom_text: "0",
+ define_response_lang: "1",
is_default: "1",
},
{
@@ -78,6 +83,7 @@ const defaultPrompts = [
need_selected: "1",
need_signature: "0",
need_custom_text: "0",
+ define_response_lang: "1",
is_default: "1",
},
{
@@ -89,6 +95,7 @@ const defaultPrompts = [
need_selected: "1",
need_signature: "0",
need_custom_text: "0",
+ define_response_lang: "1",
is_default: "1",
},
{
@@ -100,6 +107,7 @@ const defaultPrompts = [
need_selected: "0",
need_signature: "0",
need_custom_text: "0",
+ define_response_lang: "1",
is_default: "1",
},
{
@@ -111,6 +119,7 @@ const defaultPrompts = [
need_selected: "0",
need_signature: "0",
need_custom_text: "0",
+ define_response_lang: "1",
is_default: "1",
},
{
@@ -122,6 +131,7 @@ const defaultPrompts = [
need_selected: "0",
need_signature: "0",
need_custom_text: "0",
+ define_response_lang: "0",
is_default: "1",
},
{
@@ -133,6 +143,7 @@ const defaultPrompts = [
need_selected: "1",
need_signature: "0",
need_custom_text: "0",
+ define_response_lang: "0",
is_default: "1",
},
];
diff --git a/js/mzta-utils.js b/js/mzta-utils.js
index fc87deee..2e359c13 100644
--- a/js/mzta-utils.js
+++ b/js/mzta-utils.js
@@ -87,6 +87,43 @@ export async function replaceBody(tabId, replyHtml) {
await messenger.compose.setComposeDetails(tabId, {body: fullBody});
}
+export function i18nConditionalGet(str) {
+ // if we are getting a string that starts with '__MSG_' and ends with '__' we return the translated string
+ // using the browser.i18n API
+ // else we return the original string
+ // Check if the string starts with '__MSG_' and ends with '__'
+ if (str.startsWith('__MSG_') && str.endsWith('__')) {
+ // Remove '__MSG_' from the beginning and '__' from the end
+ return browser.i18n.getMessage(str.substring(6, str.length - 2));
+ }
+ return str; // Return the original string if the conditions are not met
+}
+
+export async function isThunderbird128OrGreater(){
+ try {
+ const info = await browser.runtime.getBrowserInfo();
+ const version = info.version;
+ return compareThunderbirdVersions(version, '128.0') >= 0;
+ } catch (error) {
+ console.error('[ThunderAI] Error retrieving browser information:', error);
+ return false;
+ }
+}
+
+function compareThunderbirdVersions(v1, v2) {
+ const v1parts = v1.split('.').map(Number);
+ const v2parts = v2.split('.').map(Number);
+
+ for (let i = 0; i < Math.max(v1parts.length, v2parts.length); i++) {
+ const v1part = v1parts[i] || 0;
+ const v2part = v2parts[i] || 0;
+ if (v1part > v2part) return 1;
+ if (v1part < v2part) return -1;
+ }
+ return 0;
+}
+
+
// The following methods are a modified version derived from https://github.com/ali-raheem/Aify/blob/13ff87583bc520fb80f555ab90a90c5c9df797a7/plugin/content_scripts/compose.js
@@ -135,15 +172,3 @@ const insertHtml = function (replyHtml, fullBody_string) {
fullBody.body.insertBefore(fragment, fullBody.body.firstChild);
return fullBody.body.innerHTML;
}
-
-export function i18nConditionalGet(str) {
- // if we are getting a string that starts with '__MSG_' and ends with '__' we return the translated string
- // using the browser.i18n API
- // else we return the original string
- // Check if the string starts with '__MSG_' and ends with '__'
- if (str.startsWith('__MSG_') && str.endsWith('__')) {
- // Remove '__MSG_' from the beginning and '__' from the end
- return browser.i18n.getMessage(str.substring(6, str.length - 2));
- }
- return str; // Return the original string if the conditions are not met
-}
\ No newline at end of file
diff --git a/manifest.json b/manifest.json
index df8f5f8f..c8df3d51 100644
--- a/manifest.json
+++ b/manifest.json
@@ -2,7 +2,7 @@
"manifest_version": 2,
"name": "ThunderAI",
"description": "__MSG_extensionDescription__",
- "version": "1.2.0",
+ "version": "1.2.1",
"author": "Mic (m@micz.it)",
"homepage_url": "https://micz.it/thunderbird-addon-thunderai/",
"browser_specific_settings": {
diff --git a/options/mzta-release-notes.html b/options/mzta-release-notes.html
index 941d9d67..433d2c2e 100644
--- a/options/mzta-release-notes.html
+++ b/options/mzta-release-notes.html
@@ -7,6 +7,13 @@
ThunderAI Release Notes
+
Version 1.2.1 - 20/07/2024
+
+ - Fixed changes in the ChatGPT web interface when importing in plain text [#87].
+ - Added an option to the prompts to specify the default language for the response [#86].
+ - Not adding to the prompt the statement about using the default language if asking for a translation [#85].
+ - [Thunderbird 128+ only] Added a warning message when closing the Custom Prompts page with unsaved changes [#88].
+
Version 1.2.0 - 17/07/2024
- If no default language is set in the options, the language present in the text sent to ChatGPT will be used [#53].