commit
798e683674
21 changed files with 677 additions and 75 deletions
|
|
@ -7,8 +7,11 @@
|
||||||
|
|
||||||
<h2>Version 3.1.0 - ??/??/2025</h2>
|
<h2>Version 3.1.0 - ??/??/2025</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Added Google Gemini API support [<a href="https://github.com/micz/ThunderAI/issues/204">#204</a>, <a href="https://github.com/micz/ThunderAI/issues/217">#2174</a>].</li>
|
<li><i>[ChatGPT API][Ollama API][OpenAI Comp API][Gemini API]</i> Added a special prompt to get calendar events data from emails [<a href="https://github.com/micz/ThunderAI/issues/182">#182</a>]. To use this feature, you must install also the <a href="https://addons.thunderbird.net/it/thunderbird/addon/thunderai-sparks/">Sparks</a> add-on.</li>
|
||||||
|
<li>Added Google Gemini API support [<a href="https://github.com/micz/ThunderAI/issues/204">#204</a>, <a href="https://github.com/micz/ThunderAI/issues/217">#217</a>].</li>
|
||||||
<li>Added <i>{%mail_typed_text%}</i> data placeholder to get the text inserted before the quoted mail body when replying [<a href="https://github.com/micz/ThunderAI/issues/196">#196</a>].</li>
|
<li>Added <i>{%mail_typed_text%}</i> data placeholder to get the text inserted before the quoted mail body when replying [<a href="https://github.com/micz/ThunderAI/issues/196">#196</a>].</li>
|
||||||
|
<li>Added <i>{%mail_datetime%}</i> data placeholder to get the date and time of the email [<a href="https://github.com/micz/ThunderAI/issues/223">#223</a>].</li>
|
||||||
|
<li>Added <i>{%current_datetime%}</i> data placeholder to get the current date and time [<a href="https://github.com/micz/ThunderAI/issues/224">#224</a>].</li>
|
||||||
<li>Added an info text about using the new <i>{%tags_full_list%}</i> placeholder in the "Add Tags Prompt" page [<a href="https://github.com/micz/ThunderAI/issues/215">#215</a>].</li>
|
<li>Added an info text about using the new <i>{%tags_full_list%}</i> placeholder in the "Add Tags Prompt" page [<a href="https://github.com/micz/ThunderAI/issues/215">#215</a>].</li>
|
||||||
<li>...</li>
|
<li>...</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
ThunderAI is a Thunderbird Addon that uses the capabilities of ChatGPT | Google Gemini | Ollama to enhance email management.
|
ThunderAI is a Thunderbird Addon that uses the capabilities of ChatGPT | Google Gemini | Ollama to enhance email management.
|
||||||
|
|
||||||
It enables users to analyse, write, correct, assign tags and optimize their emails, facilitating more effective and professional communication.
|
It enables users to analyse, write, correct, assign tags, create calendar events and optimize their emails, facilitating more effective and professional communication.
|
||||||
|
|
||||||
ThunderAI is a tool for anyone looking to improve their email quality, both in content and grammar, making the writing process quicker and more intuitive.
|
ThunderAI is a tool for anyone looking to improve their email quality, both in content and grammar, making the writing process quicker and more intuitive.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -954,5 +954,57 @@
|
||||||
"placeholder_mail_typed_text": {
|
"placeholder_mail_typed_text": {
|
||||||
"message": "Typed text before the quoted mail body",
|
"message": "Typed text before the quoted mail body",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
},
|
||||||
|
"prompt_get_calendar_event": {
|
||||||
|
"message": "Add a new calendar event",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prompt_get_calendar_event_full_text": {
|
||||||
|
"message": "Extract all relevant details required to generate a calendar event from the following text. The extracted information should include:\n- Event Title\n- Start Date and Time (including timezone, if specified)\n- End Date and Time (including timezone, if specified)\n- Full day (if mentioned)\nEnsure the data is formatted clearly and consistently so that it can be directly used for creating a calendar event.\nIf there are relative time references, consider that the date and time of the email are \"{%mail_datetime%}\". Calculate the start date and time based on this reference. If the calculated start date and time are earlier than \"{%current_datetime%}\", recalculate the start date and time using \"{%current_datetime%}\" as the base.\nIf the duration is not specified, set it to one hour.\nIf you're not able to get one or more of the required information, please respond with an empty string.\nGenerate a response in JSON format only. Do not include any additional text or explanations; provide only the JSON. Here is the format to be used:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Calendar event summary here\",\n\"forceAllDay\": false\n}\nHere's the text:\"{%selected_text%}\"",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_get_calendar_event": {
|
||||||
|
"message": "Add a new calendar event from selected text",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_get_calendar_event_Info": {
|
||||||
|
"message": "If checked, an item will be included in the menu to get a calendar event information from selected text.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_btnManageCalendarEventInfo": {
|
||||||
|
"message": "Manage calendar events settings",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"GetCalendarEvent_PageTitle": {
|
||||||
|
"message": "Manage Calendar Events Settings",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"GetCalendarEvent_info_default": {
|
||||||
|
"message": "In this page you can modify the default prompt used to get a calendar event from selected text.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"GetCalendarEvent_prompt_text_title": {
|
||||||
|
"message": "Current prompt text",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_GetCalendarEvent_infoline2": {
|
||||||
|
"message": "You can change the prompt as you wish, but the response received from the AI must be in JSON format as specified in the default prompt!",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_get_calendar_event_Sparks_not_present": {
|
||||||
|
"message": "To use the calendar event feature, please install the ThunderAI Sparks addon.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_download_now": {
|
||||||
|
"message": "Download ThunderAI Sparks now!",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"placeholder_mail_datetime": {
|
||||||
|
"message": "The date and time of the email",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"placeholder_current_datetime": {
|
||||||
|
"message": "The current date and time",
|
||||||
|
"description": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -228,12 +228,12 @@ switch (message.command) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "getTags":
|
case "getTags":
|
||||||
console.log(">>>>>>>>>>>>>> getTags: " + JSON.stringify(message.tags));
|
// console.log(">>>>>>>>>>>>>> getTags: " + JSON.stringify(message.tags));
|
||||||
|
|
||||||
// ===== These methods are also defined in the file /js/mzta-addatags-exclusion-list.js
|
// ===== These methods are also defined in the file /js/mzta-addatags-exclusion-list.js
|
||||||
async function addTags_getExclusionList() {
|
async function addTags_getExclusionList() {
|
||||||
let prefs_excluded_tags = await browser.storage.local.get({add_tags_exclusions: []});
|
let prefs_excluded_tags = await browser.storage.local.get({add_tags_exclusions: []});
|
||||||
console.log(">>>>>>>>>>>>>>> addTags_getExclusionList prefs_excluded_tags: " + JSON.stringify(prefs_excluded_tags));
|
// console.log(">>>>>>>>>>>>>>> addTags_getExclusionList prefs_excluded_tags: " + JSON.stringify(prefs_excluded_tags));
|
||||||
return prefs_excluded_tags.add_tags_exclusions;
|
return prefs_excluded_tags.add_tags_exclusions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -358,7 +358,7 @@ switch (message.command) {
|
||||||
// Parse the input string into labels
|
// Parse the input string into labels
|
||||||
const words = inputString.split(',').map(word => word.trim()).filter(word => word !== '');
|
const words = inputString.split(',').map(word => word.trim()).filter(word => word !== '');
|
||||||
|
|
||||||
console.log(">>>>>>>>>>>>> words: " + JSON.stringify(words));
|
// console.log(">>>>>>>>>>>>> words: " + JSON.stringify(words));
|
||||||
|
|
||||||
if(words.length == 0){
|
if(words.length == 0){
|
||||||
const message = document.createElement('div');
|
const message = document.createElement('div');
|
||||||
|
|
@ -371,7 +371,7 @@ switch (message.command) {
|
||||||
let prefs_tags = await browser.storage.sync.get({add_tags_hide_exclusions: false});
|
let prefs_tags = await browser.storage.sync.get({add_tags_hide_exclusions: false});
|
||||||
let add_tags_exclusions_list = await addTags_getExclusionList();
|
let add_tags_exclusions_list = await addTags_getExclusionList();
|
||||||
|
|
||||||
console.log(">>>>>>>>>>>>> add_tags_exclusions_list: " + JSON.stringify(add_tags_exclusions_list));
|
// console.log(">>>>>>>>>>>>> add_tags_exclusions_list: " + JSON.stringify(add_tags_exclusions_list));
|
||||||
|
|
||||||
const words_final = words
|
const words_final = words
|
||||||
.filter(word => word !== '')
|
.filter(word => word !== '')
|
||||||
|
|
@ -386,7 +386,7 @@ switch (message.command) {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(">>>>>>>>>>>>> words_final: " + JSON.stringify(words_final));
|
// console.log(">>>>>>>>>>>>> words_final: " + JSON.stringify(words_final));
|
||||||
|
|
||||||
// Create the form
|
// Create the form
|
||||||
const form = document.createElement('form');
|
const form = document.createElement('form');
|
||||||
|
|
@ -505,7 +505,7 @@ switch (message.command) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return createDialog(message.tags, (selected) => {
|
return createDialog(message.tags, (selected) => {
|
||||||
console.log('>>>>>>>>>>>> Selected tags:', selected);
|
// console.log('>>>>>>>>>>>> Selected tags:', selected);
|
||||||
browser.runtime.sendMessage({ command: "assign_tags", tags: selected, messageId: message.messageId });
|
browser.runtime.sendMessage({ command: "assign_tags", tags: selected, messageId: message.messageId });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import { getPrompts } from './mzta-prompts.js';
|
||||||
import { getLanguageDisplayName, getMenuContextCompose, getMenuContextDisplay, i18nConditionalGet, getMailSubject, getTagsList, transformTagsLabels } from './mzta-utils.js'
|
import { getLanguageDisplayName, getMenuContextCompose, getMenuContextDisplay, i18nConditionalGet, getMailSubject, getTagsList, transformTagsLabels } from './mzta-utils.js'
|
||||||
import { taLogger } from './mzta-logger.js';
|
import { taLogger } from './mzta-logger.js';
|
||||||
import { placeholdersUtils } from './mzta-placeholders.js';
|
import { placeholdersUtils } from './mzta-placeholders.js';
|
||||||
import { mzta_specialCommand_AddTags } from './special_commands/mzta-add-tags.js';
|
import { mzta_specialCommand } from './mzta-special-commands.js';
|
||||||
|
|
||||||
export class mzta_Menus {
|
export class mzta_Menus {
|
||||||
|
|
||||||
|
|
@ -51,7 +51,7 @@ export class mzta_Menus {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
async initialize(also_special = false) {
|
async initialize(also_special = []) { // also_special is an array of active special prompts ids
|
||||||
this.allPrompts = [];
|
this.allPrompts = [];
|
||||||
this.rootMenu = [];
|
this.rootMenu = [];
|
||||||
this.shortcutMenu = [];
|
this.shortcutMenu = [];
|
||||||
|
|
@ -63,7 +63,7 @@ export class mzta_Menus {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async reload(also_special = false) {
|
async reload(also_special = []) {
|
||||||
await browser.menus.removeAll().catch(error => {
|
await browser.menus.removeAll().catch(error => {
|
||||||
console.error("[ThunderAI] ERROR removing the menus: ", error);
|
console.error("[ThunderAI] ERROR removing the menus: ", error);
|
||||||
});
|
});
|
||||||
|
|
@ -175,6 +175,12 @@ export class mzta_Menus {
|
||||||
case 'junk_score':
|
case 'junk_score':
|
||||||
finalSubs['junk_score'] = curr_message.junkScore;
|
finalSubs['junk_score'] = curr_message.junkScore;
|
||||||
break;
|
break;
|
||||||
|
case 'mail_datetime':
|
||||||
|
finalSubs['mail_datetime'] = curr_message.date;
|
||||||
|
break;
|
||||||
|
case 'current_datetime':
|
||||||
|
finalSubs['current_datetime'] = new Date().toString();
|
||||||
|
break;
|
||||||
case 'tags_current_email':
|
case 'tags_current_email':
|
||||||
let tags_current_email_array = await transformTagsLabels(curr_message.tags, tags_full_list[1]);
|
let tags_current_email_array = await transformTagsLabels(curr_message.tags, tags_full_list[1]);
|
||||||
finalSubs['tags_current_email'] = tags_current_email_array.join(", ");
|
finalSubs['tags_current_email'] = tags_current_email_array.join(", ");
|
||||||
|
|
@ -212,7 +218,7 @@ export class mzta_Menus {
|
||||||
//browser.runtime.sendMessage({command: "chatgpt_open", prompt: fullPrompt, action: curr_prompt.action, tabId: tabs[0].id});
|
//browser.runtime.sendMessage({command: "chatgpt_open", prompt: fullPrompt, action: curr_prompt.action, tabId: tabs[0].id});
|
||||||
if(curr_prompt.is_special == '1'){ // Special prompts
|
if(curr_prompt.is_special == '1'){ // Special prompts
|
||||||
switch(curr_prompt.id){
|
switch(curr_prompt.id){
|
||||||
case 'prompt_add_tags': // Add tags to the email
|
case 'prompt_add_tags': { // Add tags to the email
|
||||||
let tags_current_email = '';
|
let tags_current_email = '';
|
||||||
let prefs_at = await browser.storage.sync.get({add_tags_maxnum: 3, connection_type: '', add_tags_force_lang: true, default_chatgpt_lang: ''});
|
let prefs_at = await browser.storage.sync.get({add_tags_maxnum: 3, connection_type: '', add_tags_force_lang: true, default_chatgpt_lang: ''});
|
||||||
if((prefs_at.connection_type === '')||(prefs_at.connection_type === null)||(prefs_at.connection_type === undefined)||(prefs_at.connection_type === 'chatgpt_web')){
|
if((prefs_at.connection_type === '')||(prefs_at.connection_type === null)||(prefs_at.connection_type === undefined)||(prefs_at.connection_type === 'chatgpt_web')){
|
||||||
|
|
@ -230,7 +236,7 @@ export class mzta_Menus {
|
||||||
// TODO: use the current API, abort if using chatgpt web
|
// TODO: use the current API, abort if using chatgpt web
|
||||||
// COMMENTED TO DO TESTS
|
// COMMENTED TO DO TESTS
|
||||||
// tags_current_email = "recipients, TEST, home, work, CAR, light";
|
// tags_current_email = "recipients, TEST, home, work, CAR, light";
|
||||||
let cmd_addTags = new mzta_specialCommand_AddTags(fullPrompt,prefs_at.connection_type,true);
|
let cmd_addTags = new mzta_specialCommand(fullPrompt,prefs_at.connection_type,true);
|
||||||
await cmd_addTags.initWorker();
|
await cmd_addTags.initWorker();
|
||||||
try{
|
try{
|
||||||
tags_current_email = await cmd_addTags.sendPrompt();
|
tags_current_email = await cmd_addTags.sendPrompt();
|
||||||
|
|
@ -241,10 +247,42 @@ export class mzta_Menus {
|
||||||
return {ok:'0'};
|
return {ok:'0'};
|
||||||
}
|
}
|
||||||
this.logger.log("tags_current_email: " + tags_current_email);
|
this.logger.log("tags_current_email: " + tags_current_email);
|
||||||
console.log(">>>>>>>>>>>> tags_full_list: " + JSON.stringify(tags_full_list));
|
// console.log(">>>>>>>>>>>> tags_full_list: " + JSON.stringify(tags_full_list));
|
||||||
browser.tabs.sendMessage(tabs[0].id, {command: "getTags", tags: tags_current_email, messageId: curr_message.id});
|
browser.tabs.sendMessage(tabs[0].id, {command: "getTags", tags: tags_current_email, messageId: curr_message.id});
|
||||||
return {ok:'1'};
|
return {ok:'1'};
|
||||||
break;
|
break; // Add tags to the email - END
|
||||||
|
}
|
||||||
|
case 'prompt_get_calendar_event': { // Get a calendar event info
|
||||||
|
let calendar_event_data = '';
|
||||||
|
let prefs_at = await browser.storage.sync.get({connection_type: ''});
|
||||||
|
if((prefs_at.connection_type === '')||(prefs_at.connection_type === null)||(prefs_at.connection_type === undefined)||(prefs_at.connection_type === 'chatgpt_web')){
|
||||||
|
console.error("[ThunderAI | GetCalendarEvent] Invalid connection type: " + prefs_at.connection_type);
|
||||||
|
return {ok:'0'};
|
||||||
|
}
|
||||||
|
/* We expect to receive from the AI a JSON object like this:
|
||||||
|
* {
|
||||||
|
* "startDate": "20250104T183000Z",
|
||||||
|
* "endDate": "20250104T193000Z",
|
||||||
|
* "summary": "ThunderAI Sparks",
|
||||||
|
* "forceAllDay": false
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
this.logger.log("fullPrompt: " + fullPrompt);
|
||||||
|
let cmd_GetCalendarEvent = new mzta_specialCommand(fullPrompt,prefs_at.connection_type,true);
|
||||||
|
await cmd_GetCalendarEvent.initWorker();
|
||||||
|
try{
|
||||||
|
calendar_event_data = await cmd_GetCalendarEvent.sendPrompt();
|
||||||
|
// console.log(">>>>>>>>>>> calendar_event_data: " + calendar_event_data);
|
||||||
|
}catch(err){
|
||||||
|
console.error("[ThunderAI] Error getting calendar event data: ", JSON.stringify(err));
|
||||||
|
browser.tabs.sendMessage(tabs[0].id, { command: "sendAlert", curr_tab_type: tabs[0].type, message: "Error getting calendar event data: " + JSON.stringify(err) });
|
||||||
|
return {ok:'0'};
|
||||||
|
}
|
||||||
|
this.logger.log("calendar_event_data: " + calendar_event_data);
|
||||||
|
browser.runtime.sendMessage('thunderai-sparks@micz.it',{action: "openCalendarEventDialog", calendar_event_data: calendar_event_data})
|
||||||
|
return {ok:'1'};
|
||||||
|
break; // Get a calendar event info - END
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
console.error("[ThunderAI] Unknown special prompt id: " + curr_prompt.id);
|
console.error("[ThunderAI] Unknown special prompt id: " + curr_prompt.id);
|
||||||
break;
|
break;
|
||||||
|
|
@ -278,7 +316,7 @@ export class mzta_Menus {
|
||||||
this.shortcutMenu.push(curr_menu_entry);
|
this.shortcutMenu.push(curr_menu_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadMenus(also_special = false) {
|
async loadMenus(also_special = []) {
|
||||||
await this.initialize(also_special);
|
await this.initialize(also_special);
|
||||||
await this.addMenu(this.rootMenu);
|
await this.addMenu(this.rootMenu);
|
||||||
this.addClickListener();
|
this.addClickListener();
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ================= PROMPTS PROPERTIES ========================================
|
/* ================= PLACEHOLDERS PROPERTIES ========================================
|
||||||
|
|
||||||
================ BASE PROPERTIES
|
================ BASE PROPERTIES
|
||||||
|
|
||||||
|
|
@ -103,6 +103,20 @@ const defaultPlaceholders = [
|
||||||
type: 0,
|
type: 0,
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'mail_datetime',
|
||||||
|
name: "__MSG_placeholder_mail_datetime__",
|
||||||
|
default_value: "",
|
||||||
|
type: 1,
|
||||||
|
is_default: "1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'current_datetime',
|
||||||
|
name: "__MSG_placeholder_current_datetime__",
|
||||||
|
default_value: "",
|
||||||
|
type: 0,
|
||||||
|
is_default: "1",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'tags_current_email',
|
id: 'tags_current_email',
|
||||||
name: "__MSG_placeholder_tags_current_email__",
|
name: "__MSG_placeholder_tags_current_email__",
|
||||||
|
|
|
||||||
|
|
@ -182,18 +182,44 @@ const specialPrompts = [
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
is_special: "1",
|
is_special: "1",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'prompt_get_calendar_event',
|
||||||
|
name: "__MSG_prompt_get_calendar_event__",
|
||||||
|
text: "prompt_get_calendar_event_full_text",
|
||||||
|
type: "1",
|
||||||
|
action: "0",
|
||||||
|
need_selected: "1",
|
||||||
|
need_signature: "0",
|
||||||
|
need_custom_text: "0",
|
||||||
|
define_response_lang: "0",
|
||||||
|
is_default: "1",
|
||||||
|
is_special: "1",
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
export async function getPrompts(onlyEnabled = false, includeSpecial = false){
|
export async function getPrompts(onlyEnabled = false, includeSpecial = []){ // includeSpecial is an array of active special prompts ids
|
||||||
const _defaultPrompts = await getDefaultPrompts_withProps();
|
const _defaultPrompts = await getDefaultPrompts_withProps();
|
||||||
// console.log('>>>>>>>>>>>> getPrompts _defaultPrompts: ' + JSON.stringify(_defaultPrompts));
|
// console.log('>>>>>>>>>>>> getPrompts _defaultPrompts: ' + JSON.stringify(_defaultPrompts));
|
||||||
const customPrompts = await getCustomPrompts();
|
const customPrompts = await getCustomPrompts();
|
||||||
// console.log('>>>>>>>>>>>> getPrompts customPrompts: ' + JSON.stringify(customPrompts));
|
// console.log('>>>>>>>>>>>> getPrompts customPrompts: ' + JSON.stringify(customPrompts));
|
||||||
const specialPrompts = await getSpecialPrompts();
|
const specialPrompts = await getSpecialPrompts();
|
||||||
let output = specialPrompts.concat(_defaultPrompts).concat(customPrompts);
|
let output = specialPrompts.concat(_defaultPrompts).concat(customPrompts);
|
||||||
if(!includeSpecial){
|
if(includeSpecial.length == 0){
|
||||||
output = output.filter(obj => obj.is_special != 1); // we do not want special prompts
|
output = output.filter(obj => obj.is_special != 1); // we do not want special prompts
|
||||||
|
}else{
|
||||||
|
// console.log(">>>>>>>>>> getPrompts includeSpecial: " + JSON.stringify(includeSpecial));
|
||||||
|
output = output.filter(obj => includeSpecial.includes(obj.id) || obj.is_special != 1);
|
||||||
|
// output = output.filter(obj => {
|
||||||
|
// const isIncluded = includeSpecial.includes(obj.id);
|
||||||
|
// const isNotSpecial = obj.is_special != 1;
|
||||||
|
|
||||||
|
// console.log(`>>>>>>>>>> Checking obj:`, obj);
|
||||||
|
// console.log(`>>>>>>>>>> isIncluded: ${isIncluded}`);
|
||||||
|
// console.log(`>>>>>>>>>> isNotSpecial: ${isNotSpecial}`);
|
||||||
|
|
||||||
|
// return isIncluded || isNotSpecial;
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
if(onlyEnabled){
|
if(onlyEnabled){
|
||||||
output = output.filter(obj => obj.enabled != 0);
|
output = output.filter(obj => obj.enabled != 0);
|
||||||
|
|
@ -311,7 +337,21 @@ export async function getSpecialPrompts(){
|
||||||
})
|
})
|
||||||
return def_specPrompts;
|
return def_specPrompts;
|
||||||
} else {
|
} else {
|
||||||
return prefs._special_prompts;
|
let updatedPrompts = [...prefs._special_prompts];
|
||||||
|
|
||||||
|
specialPrompts.forEach((defaultPrompt) => {
|
||||||
|
if (!updatedPrompts.some((prompt) => prompt.id === defaultPrompt.id)) {
|
||||||
|
let newPrompt = { ...defaultPrompt };
|
||||||
|
newPrompt.text = browser.i18n.getMessage(newPrompt.text);
|
||||||
|
updatedPrompts.push(newPrompt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (updatedPrompts.length !== prefs._special_prompts.length) {
|
||||||
|
await browser.storage.local.set({ _special_prompts: updatedPrompts });
|
||||||
|
}
|
||||||
|
|
||||||
|
return updatedPrompts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,13 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
// Call the API to get the tags
|
// Call the API to use a special prompt
|
||||||
|
|
||||||
import { taLogger } from '../mzta-logger.js';
|
|
||||||
|
import { taLogger } from './mzta-logger.js';
|
||||||
|
|
||||||
|
|
||||||
export class mzta_specialCommand_AddTags {
|
export class mzta_specialCommand {
|
||||||
|
|
||||||
prompt = "";
|
prompt = "";
|
||||||
worker = null;
|
worker = null;
|
||||||
|
|
@ -32,20 +33,20 @@
|
||||||
constructor(prompt, llm, do_debug = false) {
|
constructor(prompt, llm, do_debug = false) {
|
||||||
this.prompt = prompt;
|
this.prompt = prompt;
|
||||||
this.llm = llm;
|
this.llm = llm;
|
||||||
this.logger = new taLogger('mzta_specialCommand_AddTags', do_debug);
|
this.logger = new taLogger('mzta_specialCommand', do_debug);
|
||||||
this.do_debug = do_debug;
|
this.do_debug = do_debug;
|
||||||
switch (this.llm) {
|
switch (this.llm) {
|
||||||
case "chatgpt_api":
|
case "chatgpt_api":
|
||||||
this.worker = new Worker(new URL('../workers/model-worker-openai.js', import.meta.url), { type: 'module' });
|
this.worker = new Worker(new URL('./workers/model-worker-openai.js', import.meta.url), { type: 'module' });
|
||||||
break;
|
break;
|
||||||
case "google_gemini_api":
|
case "google_gemini_api":
|
||||||
this.worker = new Worker(new URL('../workers/model-worker-google_gemini.js', import.meta.url), { type: 'module' });
|
this.worker = new Worker(new URL('./workers/model-worker-google_gemini.js', import.meta.url), { type: 'module' });
|
||||||
break;
|
break;
|
||||||
case "ollama_api":
|
case "ollama_api":
|
||||||
this.worker = new Worker(new URL('../workers/model-worker-ollama.js', import.meta.url), { type: 'module' });
|
this.worker = new Worker(new URL('./workers/model-worker-ollama.js', import.meta.url), { type: 'module' });
|
||||||
break;
|
break;
|
||||||
case "openai_comp_api":
|
case "openai_comp_api":
|
||||||
this.worker = new Worker(new URL('../workers/model-worker-openai_comp.js', import.meta.url), { type: 'module' });
|
this.worker = new Worker(new URL('./workers/model-worker-openai_comp.js', import.meta.url), { type: 'module' });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -69,7 +70,7 @@
|
||||||
}
|
}
|
||||||
case "openai_comp_api": {
|
case "openai_comp_api": {
|
||||||
let prefs_api = await browser.storage.sync.get({openai_comp_host: '', openai_comp_model: '', openai_comp_api_key: '', openai_comp_use_v1: true, openai_comp_chat_name: '', do_debug: false});
|
let prefs_api = await browser.storage.sync.get({openai_comp_host: '', openai_comp_model: '', openai_comp_api_key: '', openai_comp_use_v1: true, openai_comp_chat_name: '', do_debug: false});
|
||||||
console.log(">>>>>>>>>>>> [ThunderAI] prefs_api: " + JSON.stringify(prefs_api));
|
// console.log(">>>>>>>>>>>> [ThunderAI] prefs_api: " + JSON.stringify(prefs_api));
|
||||||
this.worker.postMessage({ type: 'init', openai_comp_host: prefs_api.openai_comp_host, openai_comp_model: prefs_api.openai_comp_model, openai_comp_api_key: prefs_api.openai_comp_api_key, openai_comp_use_v1: prefs_api.openai_comp_use_v1, do_debug: this.do_debug, i18nStrings: ''});
|
this.worker.postMessage({ type: 'init', openai_comp_host: prefs_api.openai_comp_host, openai_comp_model: prefs_api.openai_comp_model, openai_comp_api_key: prefs_api.openai_comp_api_key, openai_comp_use_v1: prefs_api.openai_comp_use_v1, do_debug: this.do_debug, i18nStrings: ''});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -89,7 +90,7 @@
|
||||||
this.full_message += payload.token;
|
this.full_message += payload.token;
|
||||||
break;
|
break;
|
||||||
case 'tokensDone':
|
case 'tokensDone':
|
||||||
console.log(">>>>>>>>>>>> [ThunderAI] tokensDone: " + this.full_message);
|
// console.log(">>>>>>>>>>>> [ThunderAI] tokensDone: " + this.full_message);
|
||||||
resolve(this.full_message); // Resolve the promise with the full message
|
resolve(this.full_message); // Resolve the promise with the full message
|
||||||
break;
|
break;
|
||||||
case 'error':
|
case 'error':
|
||||||
|
|
@ -254,8 +254,8 @@ function generateHexColorForTag() {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function transformTagsLabels(labels, tags_list) {
|
export async function transformTagsLabels(labels, tags_list) {
|
||||||
console.log(">>>>>>>>> transformTagsLabels labels: " + labels);
|
// console.log(">>>>>>>>> transformTagsLabels labels: " + labels);
|
||||||
console.log(">>>>>>>>> transformTagsLabels tags_list: " + tags_list);
|
// console.log(">>>>>>>>> transformTagsLabels tags_list: " + tags_list);
|
||||||
let output = [];
|
let output = [];
|
||||||
for(let label of labels) {
|
for(let label of labels) {
|
||||||
output.push(tags_list[label].tag);
|
output.push(tags_list[label].tag);
|
||||||
|
|
@ -263,6 +263,30 @@ export async function transformTagsLabels(labels, tags_list) {
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getActiveSpecialPromptsIDs(addtags = false, get_calendar_event = false, is_chatgpt_web = false) {
|
||||||
|
let output = [];
|
||||||
|
// console.log(">>>>>>>>>> getActiveSpecialPromptsIDs addtags: " + addtags + " get_calendar_event: " + get_calendar_event + " is_chatgpt_web: " + is_chatgpt_web);
|
||||||
|
if(is_chatgpt_web){
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
if(addtags){
|
||||||
|
output.push('prompt_add_tags');
|
||||||
|
}
|
||||||
|
if(get_calendar_event){
|
||||||
|
output.push('prompt_get_calendar_event');
|
||||||
|
}
|
||||||
|
// console.log(">>>>>>>>>> getActiveSpecialPromptsIDs output: " + JSON.stringify(output));
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function checkSparksPresence() {
|
||||||
|
try {
|
||||||
|
return (await browser.runtime.sendMessage('thunderai-sparks@micz.it',{action: "checkPresence"}) === 'ok');
|
||||||
|
} catch (error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// The following methods are a modified version derived from https://github.com/ali-raheem/Aify/blob/13ff87583bc520fb80f555ab90a90c5c9df797a7/plugin/content_scripts/compose.js
|
// The following methods are a modified version derived from https://github.com/ali-raheem/Aify/blob/13ff87583bc520fb80f555ab90a90c5c9df797a7/plugin/content_scripts/compose.js
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"name": "ThunderAI",
|
"name": "ThunderAI",
|
||||||
"description": "__MSG_extensionDescription__",
|
"description": "__MSG_extensionDescription__",
|
||||||
"version": "3.1.0",
|
"version": "3.1.0pre1",
|
||||||
"author": "Mic (m@micz.it)",
|
"author": "Mic (m@micz.it)",
|
||||||
"homepage_url": "https://micz.it/thunderbird-addon-thunderai/",
|
"homepage_url": "https://micz.it/thunderbird-addon-thunderai/",
|
||||||
"browser_specific_settings": {
|
"browser_specific_settings": {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import { mzta_script } from './js/mzta-chatgpt.js';
|
||||||
import { prefs_default } from './options/mzta-options-default.js';
|
import { prefs_default } from './options/mzta-options-default.js';
|
||||||
import { mzta_Menus } from './js/mzta-menus.js';
|
import { mzta_Menus } from './js/mzta-menus.js';
|
||||||
import { taLogger } from './js/mzta-logger.js';
|
import { taLogger } from './js/mzta-logger.js';
|
||||||
import { getCurrentIdentity, getOriginalBody, replaceBody, setBody, i18nConditionalGet, generateCallID, migrateCustomPromptsStorage, migrateDefaultPromptsPropStorage, getGPTWebModelString, getTagsList, createTag, assignTagsToMessage, checkIfTagExists } from './js/mzta-utils.js';
|
import { getCurrentIdentity, getOriginalBody, replaceBody, setBody, i18nConditionalGet, generateCallID, migrateCustomPromptsStorage, migrateDefaultPromptsPropStorage, getGPTWebModelString, getTagsList, createTag, assignTagsToMessage, checkIfTagExists, getActiveSpecialPromptsIDs, checkSparksPresence } from './js/mzta-utils.js';
|
||||||
|
|
||||||
await migrateCustomPromptsStorage();
|
await migrateCustomPromptsStorage();
|
||||||
await migrateDefaultPromptsPropStorage();
|
await migrateDefaultPromptsPropStorage();
|
||||||
|
|
@ -28,9 +28,11 @@ await migrateDefaultPromptsPropStorage();
|
||||||
var original_html = '';
|
var original_html = '';
|
||||||
var modified_html = '';
|
var modified_html = '';
|
||||||
|
|
||||||
let prefs_init = await browser.storage.sync.get({do_debug: false, add_tags: true, connection_type: 'chatgpt_web'});
|
let prefs_init = await browser.storage.sync.get({do_debug: false, add_tags: true, get_calendar_event: true, connection_type: 'chatgpt_web'});
|
||||||
let taLog = new taLogger("mzta-background",prefs_init.do_debug);
|
let taLog = new taLogger("mzta-background",prefs_init.do_debug);
|
||||||
|
|
||||||
|
let special_prompts_ids = getActiveSpecialPromptsIDs(prefs_init.add_tags, await doGetCalendarEvent(prefs_init.get_calendar_event), (prefs_init.connection_type === "chatgpt_web"));
|
||||||
|
|
||||||
browser.composeScripts.register({
|
browser.composeScripts.register({
|
||||||
js: [{file: "/js/mzta-compose-script.js"}]
|
js: [{file: "/js/mzta-compose-script.js"}]
|
||||||
});
|
});
|
||||||
|
|
@ -211,8 +213,11 @@ messenger.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||||
break;
|
break;
|
||||||
case 'reload_menus':
|
case 'reload_menus':
|
||||||
async function _reload_menus() {
|
async function _reload_menus() {
|
||||||
let prefs_reload = await browser.storage.sync.get({add_tags: true, connection_type: 'chatgpt_web'});
|
let prefs_reload = await browser.storage.sync.get({add_tags: true, get_calendar_event: false, connection_type: 'chatgpt_web'});
|
||||||
menus.reload(prefs_reload.add_tags && (prefs_reload.connection_type !== "chatgpt_web"));
|
doGetCalendarEvent(prefs_reload.get_calendar_event).then(calendarEvent => {
|
||||||
|
const special_prompts_ids = getActiveSpecialPromptsIDs(prefs_reload.add_tags, calendarEvent, (prefs_reload.connection_type === "chatgpt_web"));
|
||||||
|
menus.reload(special_prompts_ids);
|
||||||
|
});
|
||||||
taLog.log("Reloading menus");
|
taLog.log("Reloading menus");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -573,23 +578,59 @@ function checkScreenDimensions(prefs){
|
||||||
return prefs;
|
return prefs;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register the listener for storage changes
|
async function doGetCalendarEvent(get_calendar_event) {
|
||||||
browser.storage.onChanged.addListener((changes, areaName) => {
|
if(get_calendar_event) {
|
||||||
// Check if the change happened in the 'sync' storage area
|
return await checkSparksPresence();
|
||||||
if (areaName === 'sync') {
|
} else {
|
||||||
// Check if 'add_tags' has changed
|
return false;
|
||||||
//console.log(">>>>>>>>>>>>> changes: " + JSON.stringify(changes));
|
|
||||||
if (changes.add_tags) {
|
|
||||||
menus.reload(changes.add_tags.newValue && (prefs_init.connection_type !== "chatgpt_web"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if 'connection_type' has changed
|
|
||||||
if (changes.connection_type) {
|
|
||||||
menus.reload(prefs_init.add_tags && (changes.connection_type.newValue !== "chatgpt_web"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
async function reload_pref_init(){
|
||||||
|
prefs_init = await await browser.storage.sync.get({do_debug: false, add_tags: true, get_calendar_event: true, connection_type: 'chatgpt_web'});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Register the listener for storage changes
|
||||||
|
function setupStorageChangeListener() {
|
||||||
|
browser.storage.onChanged.addListener((changes, areaName) => {
|
||||||
|
// Check if the change happened in the 'sync' storage area
|
||||||
|
if (areaName === 'sync') {
|
||||||
|
// Process 'add_tags' changes
|
||||||
|
if (changes.add_tags) {
|
||||||
|
const newTags = changes.add_tags.newValue;
|
||||||
|
doGetCalendarEvent(prefs_init.get_calendar_event).then(calendarEvent => {
|
||||||
|
const special_prompts_ids = getActiveSpecialPromptsIDs(newTags, calendarEvent, (prefs_init.connection_type === "chatgpt_web"));
|
||||||
|
menus.reload(special_prompts_ids);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process 'get_calendar_event' changes
|
||||||
|
if (changes.get_calendar_event) {
|
||||||
|
const newCalendarEvent = changes.get_calendar_event.newValue;
|
||||||
|
doGetCalendarEvent(newCalendarEvent).then(calendarEvent => {
|
||||||
|
const special_prompts_ids = getActiveSpecialPromptsIDs(prefs_init.add_tags, calendarEvent, (prefs_init.connection_type === "chatgpt_web"));
|
||||||
|
menus.reload(special_prompts_ids);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process 'connection_type' changes
|
||||||
|
if (changes.connection_type) {
|
||||||
|
const newConnectionType = changes.connection_type.newValue;
|
||||||
|
doGetCalendarEvent(prefs_init.get_calendar_event).then(calendarEvent => {
|
||||||
|
const special_prompts_ids = getActiveSpecialPromptsIDs(prefs_init.add_tags, calendarEvent, (newConnectionType === "chatgpt_web"));
|
||||||
|
menus.reload(special_prompts_ids);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
reload_pref_init();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call the function to set up the listener
|
||||||
|
setupStorageChangeListener();
|
||||||
|
|
||||||
|
|
||||||
// Menus handling
|
// Menus handling
|
||||||
const menus = new mzta_Menus(openChatGPT, prefs_init.do_debug);
|
const menus = new mzta_Menus(openChatGPT, prefs_init.do_debug);
|
||||||
menus.loadMenus(prefs_init.add_tags && (prefs_init.connection_type !== "chatgpt_web"));
|
menus.loadMenus(special_prompts_ids);
|
||||||
|
|
@ -46,4 +46,5 @@ export const prefs_default = {
|
||||||
add_tags_hide_exclusions: false,
|
add_tags_hide_exclusions: false,
|
||||||
add_tags_first_uppercase: true,
|
add_tags_first_uppercase: true,
|
||||||
add_tags_force_lang: true,
|
add_tags_force_lang: true,
|
||||||
|
get_calendar_event: true,
|
||||||
}
|
}
|
||||||
|
|
@ -118,6 +118,12 @@ tr.conntype_google_gemini_api, tr.conntype_google_gemini_api2{
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#no_sparks td{
|
||||||
|
text-align: center;
|
||||||
|
padding: 1em !important;
|
||||||
|
background: #bbf7f1;
|
||||||
|
}
|
||||||
|
|
||||||
textarea.option-textarea{
|
textarea.option-textarea{
|
||||||
width: -moz-available;
|
width: -moz-available;
|
||||||
height: 10em;
|
height: 10em;
|
||||||
|
|
@ -244,4 +250,7 @@ input.option-input[type="text"]{
|
||||||
background-color: rgb(2, 0, 100);
|
background-color: rgb(2, 0, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#no_sparks td{
|
||||||
|
background: #3b514f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -334,6 +334,22 @@
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr class="get_calendar_event_tr">
|
||||||
|
<td><span>__MSG_prefs_OptionText_get_calendar_event__</span>
|
||||||
|
<br><button id="btnManageCalendarEventInfo" class="btn_small">__MSG_prefs_OptionText_btnManageCalendarEventInfo__</button></td>
|
||||||
|
<td>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" id="get_calendar_event" name="get_calendar_event" class="option-input" />
|
||||||
|
__MSG_prefs_OptionText_get_calendar_event_Info__
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="get_calendar_event_tr" id="no_sparks">
|
||||||
|
<td colspan="2">
|
||||||
|
<span>__MSG_prefs_OptionText_get_calendar_event_Sparks_not_present__</span>
|
||||||
|
<br><a href="https://addons.thunderbird.net/it/thunderbird/addon/thunderai-sparks">__MSG_prefs_OptionText_download_now__</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td style="width:20em"><label>
|
<td style="width:20em"><label>
|
||||||
<span>__MSG_Debug__</span>
|
<span>__MSG_Debug__</span>
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import { OpenAI } from '../js/api/openai.js';
|
||||||
import { Ollama } from '../js/api/ollama.js';
|
import { Ollama } from '../js/api/ollama.js';
|
||||||
import { OpenAIComp } from '../js/api/openai_comp.js'
|
import { OpenAIComp } from '../js/api/openai_comp.js'
|
||||||
import { GoogleGemini } from '../js/api/google_gemini.js';
|
import { GoogleGemini } from '../js/api/google_gemini.js';
|
||||||
|
import { checkSparksPresence } from '../js/mzta-utils.js';
|
||||||
|
|
||||||
let taLog = new taLogger("mzta-options",true);
|
let taLog = new taLogger("mzta-options",true);
|
||||||
|
|
||||||
|
|
@ -100,6 +101,7 @@ async function restoreOptions() {
|
||||||
function showConnectionOptions() {
|
function showConnectionOptions() {
|
||||||
disable_MaxPromptLength();
|
disable_MaxPromptLength();
|
||||||
disable_AddTags();
|
disable_AddTags();
|
||||||
|
disable_GetCalendarEvent();
|
||||||
let chatgpt_web_display = 'table-row';
|
let chatgpt_web_display = 'table-row';
|
||||||
let chatgpt_api_display = 'none';
|
let chatgpt_api_display = 'none';
|
||||||
let ollama_api_display = 'none';
|
let ollama_api_display = 'none';
|
||||||
|
|
@ -252,12 +254,27 @@ function disable_MaxPromptLength(){
|
||||||
|
|
||||||
function disable_AddTags(){
|
function disable_AddTags(){
|
||||||
let add_tags = document.getElementById('add_tags');
|
let add_tags = document.getElementById('add_tags');
|
||||||
|
let conntype_select = document.getElementById("connection_type");
|
||||||
|
add_tags.disabled = (conntype_select.value === "chatgpt_web");
|
||||||
let add_tags_tr_elements = document.querySelectorAll('.add_tags_tr');
|
let add_tags_tr_elements = document.querySelectorAll('.add_tags_tr');
|
||||||
add_tags_tr_elements.forEach(add_tags_tr => {
|
add_tags_tr_elements.forEach(add_tags_tr => {
|
||||||
add_tags_tr.style.display = (add_tags.disabled) ? 'none' : 'table-row';
|
add_tags_tr.style.display = (add_tags.disabled) ? 'none' : 'table-row';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function disable_GetCalendarEvent(){
|
||||||
|
let get_calendar_event = document.getElementById('get_calendar_event');
|
||||||
|
let no_sparks_tr = document.getElementById('no_sparks');
|
||||||
|
let is_spark_present = await checkSparksPresence()
|
||||||
|
let conntype_select = document.getElementById("connection_type");
|
||||||
|
get_calendar_event.disabled = (conntype_select.value === "chatgpt_web") || !is_spark_present;
|
||||||
|
let get_calendar_event_tr_elements = document.querySelectorAll('.get_calendar_event_tr');
|
||||||
|
get_calendar_event_tr_elements.forEach(get_calendar_event_tr => {
|
||||||
|
get_calendar_event_tr.style.display = get_calendar_event.disabled ? 'none' : 'table-row';
|
||||||
|
});
|
||||||
|
no_sparks_tr.style.display = is_spark_present ? 'none' : 'table-row';
|
||||||
|
}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', async () => {
|
document.addEventListener('DOMContentLoaded', async () => {
|
||||||
await restoreOptions();
|
await restoreOptions();
|
||||||
|
|
||||||
|
|
@ -286,6 +303,13 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
addtags_info_btn.disabled = event.target.checked ? '' : 'disabled';
|
addtags_info_btn.disabled = event.target.checked ? '' : 'disabled';
|
||||||
});
|
});
|
||||||
addtags_info_btn.disabled = addtags_el.checked ? '' : 'disabled';
|
addtags_info_btn.disabled = addtags_el.checked ? '' : 'disabled';
|
||||||
|
|
||||||
|
let get_calendar_event_el = document.getElementById('get_calendar_event');
|
||||||
|
let get_calendar_event_info_btn = document.getElementById('btnManageCalendarEventInfo');
|
||||||
|
get_calendar_event_el.addEventListener('click', (event) => {
|
||||||
|
get_calendar_event_info_btn.disabled = event.target.checked ? '' : 'disabled';
|
||||||
|
});
|
||||||
|
get_calendar_event_info_btn.disabled = get_calendar_event_el.checked ? '' : 'disabled';
|
||||||
|
|
||||||
document.getElementById('btnManagePrompts').addEventListener('click', () => {
|
document.getElementById('btnManagePrompts').addEventListener('click', () => {
|
||||||
// check if the tab is already there
|
// check if the tab is already there
|
||||||
|
|
@ -313,6 +337,19 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.getElementById('btnManageCalendarEventInfo').addEventListener('click', () => {
|
||||||
|
// check if the tab is already there
|
||||||
|
browser.tabs.query({url: browser.runtime.getURL('../pages/get-calendar-event/mzta-get-calendar-event.html')}).then((tabs) => {
|
||||||
|
if (tabs.length > 0) {
|
||||||
|
// if the tab is already there, focus it
|
||||||
|
browser.tabs.update(tabs[0].id, {active: true});
|
||||||
|
} else {
|
||||||
|
// if the tab is not there, create it
|
||||||
|
browser.tabs.create({url: browser.runtime.getURL('../pages/get-calendar-event/mzta-get-calendar-event.html')});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
document.getElementById('btnOpenAICompForceModel').addEventListener('click', () => {
|
document.getElementById('btnOpenAICompForceModel').addEventListener('click', () => {
|
||||||
let modelName = prompt(browser.i18n.getMessage('OpenAIComp_force_model_ask')).trim();
|
let modelName = prompt(browser.i18n.getMessage('OpenAIComp_force_model_ask')).trim();
|
||||||
if ((modelName !== null) && (modelName !== undefined) && (modelName !== '')) {
|
if ((modelName !== null) && (modelName !== undefined) && (modelName !== '')) {
|
||||||
|
|
@ -332,6 +369,8 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
conntype_select.addEventListener("change", warn_Ollama_HostEmpty);
|
conntype_select.addEventListener("change", warn_Ollama_HostEmpty);
|
||||||
conntype_select.addEventListener("change", warn_OpenAIComp_HostEmpty);
|
conntype_select.addEventListener("change", warn_OpenAIComp_HostEmpty);
|
||||||
conntype_select.addEventListener("change", warn_GoogleGemini_APIKeyEmpty);
|
conntype_select.addEventListener("change", warn_GoogleGemini_APIKeyEmpty);
|
||||||
|
conntype_select.addEventListener("change", disable_AddTags);
|
||||||
|
conntype_select.addEventListener("change", disable_GetCalendarEvent);
|
||||||
document.getElementById("chatgpt_api_key").addEventListener("change", warn_ChatGPT_APIKeyEmpty);
|
document.getElementById("chatgpt_api_key").addEventListener("change", warn_ChatGPT_APIKeyEmpty);
|
||||||
document.getElementById("ollama_host").addEventListener("change", warn_Ollama_HostEmpty);
|
document.getElementById("ollama_host").addEventListener("change", warn_Ollama_HostEmpty);
|
||||||
document.getElementById("openai_comp_host").addEventListener("change", warn_OpenAIComp_HostEmpty);
|
document.getElementById("openai_comp_host").addEventListener("change", warn_OpenAIComp_HostEmpty);
|
||||||
|
|
@ -524,6 +563,7 @@ select_openai_comp_model.addEventListener("change", warn_OpenAIComp_HostEmpty);
|
||||||
warn_GoogleGemini_APIKeyEmpty();
|
warn_GoogleGemini_APIKeyEmpty();
|
||||||
disable_MaxPromptLength();
|
disable_MaxPromptLength();
|
||||||
disable_AddTags();
|
disable_AddTags();
|
||||||
|
disable_GetCalendarEvent();
|
||||||
|
|
||||||
const passwordField_chatgpt_api_key = document.getElementById('chatgpt_api_key');
|
const passwordField_chatgpt_api_key = document.getElementById('chatgpt_api_key');
|
||||||
const toggleIcon_chatgpt_api_key = document.getElementById('toggle_chatgpt_api_key');
|
const toggleIcon_chatgpt_api_key = document.getElementById('toggle_chatgpt_api_key');
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,11 @@
|
||||||
<div id="miczRelNotes"><h1>ThunderAI Release Notes</h1>
|
<div id="miczRelNotes"><h1>ThunderAI Release Notes</h1>
|
||||||
<h2>Version 3.1.0 - ??/??/2025</h2>
|
<h2>Version 3.1.0 - ??/??/2025</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Added Google Gemini API support [<a href="https://github.com/micz/ThunderAI/issues/204">#204</a>, <a href="https://github.com/micz/ThunderAI/issues/217">#2174</a>].</li>
|
<li><i>[ChatGPT API][Ollama API][OpenAI Comp API][Gemini API]</i> Added a special prompt to get calendar events data from emails [<a href="https://github.com/micz/ThunderAI/issues/182">#182</a>]. To use this feature, you must install also the <a href="https://addons.thunderbird.net/it/thunderbird/addon/thunderai-sparks/">Sparks</a> add-on.</li>
|
||||||
|
<li>Added Google Gemini API support [<a href="https://github.com/micz/ThunderAI/issues/204">#204</a>, <a href="https://github.com/micz/ThunderAI/issues/217">#217</a>].</li>
|
||||||
<li>Added <i>{%mail_typed_text%}</i> data placeholder to get the text inserted before the quoted mail body when replying [<a href="https://github.com/micz/ThunderAI/issues/196">#196</a>].</li>
|
<li>Added <i>{%mail_typed_text%}</i> data placeholder to get the text inserted before the quoted mail body when replying [<a href="https://github.com/micz/ThunderAI/issues/196">#196</a>].</li>
|
||||||
|
<li>Added <i>{%mail_datetime%}</i> data placeholder to get the date and time of the email [<a href="https://github.com/micz/ThunderAI/issues/223">#223</a>].</li>
|
||||||
|
<li>Added <i>{%current_datetime%}</i> data placeholder to get the current date and time [<a href="https://github.com/micz/ThunderAI/issues/224">#224</a>].</li>
|
||||||
<li>Added an info text about using the new <i>{%tags_full_list%}</i> placeholder in the "Add Tags Prompt" page [<a href="https://github.com/micz/ThunderAI/issues/215">#215</a>].</li>
|
<li>Added an info text about using the new <i>{%tags_full_list%}</i> placeholder in the "Add Tags Prompt" page [<a href="https://github.com/micz/ThunderAI/issues/215">#215</a>].</li>
|
||||||
<li>...</li>
|
<li>...</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
87
pages/get-calendar-event/mzta-get-calendar-event.css
Normal file
87
pages/get-calendar-event/mzta-get-calendar-event.css
Normal file
|
|
@ -0,0 +1,87 @@
|
||||||
|
#get_calendar_event_prompt_container{
|
||||||
|
width: 90%;
|
||||||
|
margin: 20px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#get_calendar_event_prompt_text{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.infoline{
|
||||||
|
font-size: 0.8em;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn_div{
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-container {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-list {
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: white;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
z-index: 1000;
|
||||||
|
max-height: 200px;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
list-style: none;
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-list li {
|
||||||
|
padding: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-list li:hover {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-list li.active {
|
||||||
|
background-color: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unsaved{
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
body {
|
||||||
|
background-color: #1C1B22;
|
||||||
|
color: rgb(251, 251, 254);
|
||||||
|
}
|
||||||
|
|
||||||
|
a:link { color: #409EFF; }
|
||||||
|
a:visited { color: #409EFF; }
|
||||||
|
a:hover { color: #66B1FF; }
|
||||||
|
a:active { color: #66B1FF; }
|
||||||
|
a:active { color: #66B1FF; }
|
||||||
|
|
||||||
|
.autocomplete-list {
|
||||||
|
background-color: #2E2F36;
|
||||||
|
border: 1px solid #2E2F36;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-list li:hover {
|
||||||
|
background-color: #4c4e58;
|
||||||
|
}
|
||||||
|
|
||||||
|
.autocomplete-list li.active {
|
||||||
|
background-color: #4c4e58;
|
||||||
|
}
|
||||||
|
}
|
||||||
30
pages/get-calendar-event/mzta-get-calendar-event.html
Normal file
30
pages/get-calendar-event/mzta-get-calendar-event.html
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>ThunderAI - __MSG_GetCalendarEvent_PageTitle__</title>
|
||||||
|
<link rel="stylesheet" href="mzta-get-calendar-event.css">
|
||||||
|
<link rel="icon" href="../../images/icon-16px.png">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<h1 class="page_title">__MSG_GetCalendarEvent_PageTitle__</h1>
|
||||||
|
<p>__MSG_GetCalendarEvent_info_default__</p>
|
||||||
|
</div>
|
||||||
|
<i>Work in progress...</i>
|
||||||
|
<div id="get_calendar_event_container">
|
||||||
|
<span class="section_title">__MSG_GetCalendarEvent_prompt_text_title__</span><span id="get_calendar_event_prompt_unsaved" class="unsaved hidden"> __MSG_customPrompts_unsaved_changes__</span>
|
||||||
|
<br><span class="infoline">__MSG_prefs_OptionText_btnManagePrompts_infoline__ <a href="https://micz.it/thunderbird-addon-thunderai/data-placeholders/">__MSG_customPrompts_managePrompts_help__</a>
|
||||||
|
<br><b>__MSG_prefs_OptionText_GetCalendarEvent_infoline2__</b></span>
|
||||||
|
<br>
|
||||||
|
<div class="autocomplete-container">
|
||||||
|
<textarea id="get_calendar_event_prompt_text" rows="15"></textarea>
|
||||||
|
<ul class="autocomplete-list hidden"></ul>
|
||||||
|
</div>
|
||||||
|
<div id="get_calendar_event_info_additional_statements"></div>
|
||||||
|
<div class="btn_div"><button id="btn_reset_prompt" disabled>__MSG_reset_default__</button><button id="btn_save_prompt" disabled>__MSG_save__</button></div>
|
||||||
|
</div>
|
||||||
|
<script src="mzta-get-calendar-event.js" type="module"></script>
|
||||||
|
<script src="../../js/mzta-i18n.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
149
pages/get-calendar-event/mzta-get-calendar-event.js
Normal file
149
pages/get-calendar-event/mzta-get-calendar-event.js
Normal file
|
|
@ -0,0 +1,149 @@
|
||||||
|
/*
|
||||||
|
* ThunderAI [https://micz.it/thunderbird-addon-thunderai/]
|
||||||
|
* Copyright (C) 2024 - 2025 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { prefs_default } from '../../options/mzta-options-default.js';
|
||||||
|
import { taLogger } from '../../js/mzta-logger.js';
|
||||||
|
import { getSpecialPrompts, setSpecialPrompts } from "../../js/mzta-prompts.js";
|
||||||
|
import { getPlaceholders } from "../../js/mzta-placeholders.js";
|
||||||
|
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
||||||
|
|
||||||
|
let autocompleteSuggestions = [];
|
||||||
|
let taLog = new taLogger("mzta-get-calendar-event-page",true);
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', async () => {
|
||||||
|
|
||||||
|
i18n.updateDocument();
|
||||||
|
await restoreOptions();
|
||||||
|
|
||||||
|
document.querySelectorAll(".option-input").forEach(element => {
|
||||||
|
element.addEventListener("change", saveOptions);
|
||||||
|
});
|
||||||
|
|
||||||
|
let get_calendar_event_textarea = document.getElementById('get_calendar_event_prompt_text');
|
||||||
|
let get_calendar_event_save_btn = document.getElementById('btn_save_prompt');
|
||||||
|
let get_calendar_event_reset_btn = document.getElementById('btn_reset_prompt');
|
||||||
|
|
||||||
|
let specialPrompts = await getSpecialPrompts();
|
||||||
|
let get_calendar_event_prompt = specialPrompts.find(prompt => prompt.id === 'prompt_get_calendar_event');
|
||||||
|
|
||||||
|
get_calendar_event_textarea.addEventListener('input', (event) => {
|
||||||
|
get_calendar_event_reset_btn.disabled = (event.target.value === browser.i18n.getMessage('prompt_get_calendar_event_full_text'));
|
||||||
|
get_calendar_event_save_btn.disabled = (event.target.value === get_calendar_event_prompt.text);
|
||||||
|
if(get_calendar_event_save_btn.disabled){
|
||||||
|
document.getElementById('get_calendar_event_prompt_unsaved').classList.add('hidden');
|
||||||
|
} else {
|
||||||
|
document.getElementById('get_calendar_event_prompt_unsaved').classList.remove('hidden');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
get_calendar_event_reset_btn.addEventListener('click', () => {
|
||||||
|
get_calendar_event_textarea.value = browser.i18n.getMessage('prompt_get_calendar_event_full_text');
|
||||||
|
get_calendar_event_reset_btn.disabled = true;
|
||||||
|
let event = new Event('input', { bubbles: true, cancelable: true });
|
||||||
|
get_calendar_event_textarea.dispatchEvent(event);
|
||||||
|
});
|
||||||
|
|
||||||
|
get_calendar_event_save_btn.addEventListener('click', () => {
|
||||||
|
specialPrompts.find(prompt => prompt.id === 'prompt_get_calendar_event').text = get_calendar_event_textarea.value;
|
||||||
|
setSpecialPrompts(specialPrompts);
|
||||||
|
get_calendar_event_save_btn.disabled = true;
|
||||||
|
document.getElementById('get_calendar_event_prompt_unsaved').classList.add('hidden');
|
||||||
|
browser.runtime.sendMessage({command: "reload_menus"});
|
||||||
|
});
|
||||||
|
|
||||||
|
if(get_calendar_event_prompt.text === 'prompt_get_calendar_event_full_text'){
|
||||||
|
get_calendar_event_prompt.text = browser.i18n.getMessage(get_calendar_event_prompt.text);
|
||||||
|
}
|
||||||
|
get_calendar_event_textarea.value = get_calendar_event_prompt.text;
|
||||||
|
get_calendar_event_reset_btn.disabled = (get_calendar_event_textarea.value === browser.i18n.getMessage('prompt_get_calendar_event_full_text'));
|
||||||
|
|
||||||
|
autocompleteSuggestions = (await getPlaceholders(true)).filter(p => !(p.id === 'additional_text')).map(p => ({command: '{%'+p.id+'%}', type: p.type}));
|
||||||
|
textareaAutocomplete(get_calendar_event_textarea, autocompleteSuggestions, 1); // type_value = 1, only when reading an email
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Methods to manage options, derived from: /options/mzta-options.js
|
||||||
|
|
||||||
|
function saveOptions(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
let options = {};
|
||||||
|
let element = e.target;
|
||||||
|
|
||||||
|
switch (element.type) {
|
||||||
|
case 'checkbox':
|
||||||
|
options[element.id] = element.checked;
|
||||||
|
break;
|
||||||
|
case 'number':
|
||||||
|
options[element.id] = element.valueAsNumber;
|
||||||
|
break;
|
||||||
|
case 'text':
|
||||||
|
case 'password':
|
||||||
|
options[element.id] = element.value.trim();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (element.tagName === 'SELECT') {
|
||||||
|
options[element.id] = element.value;
|
||||||
|
}else{
|
||||||
|
console.error("[ThunderAI] Unhandled input type:", element.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
browser.storage.sync.set(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function restoreOptions() {
|
||||||
|
function setCurrentChoice(result) {
|
||||||
|
document.querySelectorAll(".option-input").forEach(element => {
|
||||||
|
taLog.log("Options restoring " + element.id + " = " + (element.id=="chatgpt_api_key" || element.id=="openai_comp_api_key" ? "****************" : result[element.id]));
|
||||||
|
switch (element.type) {
|
||||||
|
case 'checkbox':
|
||||||
|
element.checked = result[element.id] || false;
|
||||||
|
break;
|
||||||
|
case 'number':
|
||||||
|
let default_number_value = 0;
|
||||||
|
if(element.id == 'chatgpt_win_height') default_number_value = prefs_default.chatgpt_win_height;
|
||||||
|
if(element.id == 'chatgpt_win_width') default_number_value = prefs_default.chatgpt_win_width;
|
||||||
|
element.value = result[element.id] ?? default_number_value;
|
||||||
|
break;
|
||||||
|
case 'text':
|
||||||
|
case 'password':
|
||||||
|
let default_text_value = '';
|
||||||
|
if(element.id == 'default_chatgpt_lang') default_text_value = prefs_default.default_chatgpt_lang;
|
||||||
|
element.value = result[element.id] || default_text_value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (element.tagName === 'SELECT') {
|
||||||
|
let default_select_value = '';
|
||||||
|
if(element.id == 'reply_type') default_select_value = 'reply_all';
|
||||||
|
if(element.id == 'connection_type') default_select_value = 'chatgpt_web';
|
||||||
|
element.value = result[element.id] || default_select_value;
|
||||||
|
if (element.value === '') {
|
||||||
|
element.selectedIndex = -1;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
console.error("[ThunderAI] Unhandled input type:", element.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let getting = await browser.storage.sync.get(prefs_default);
|
||||||
|
setCurrentChoice(getting);
|
||||||
|
}
|
||||||
|
|
@ -64,7 +64,7 @@ body {
|
||||||
background-color: #e9e9e9;
|
background-color: #e9e9e9;
|
||||||
}
|
}
|
||||||
|
|
||||||
.prompt_add_tags{
|
.special_prompt{
|
||||||
background-color: #cfe9ff;
|
background-color: #cfe9ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -102,7 +102,7 @@ body {
|
||||||
background-color: #444444;
|
background-color: #444444;
|
||||||
}
|
}
|
||||||
|
|
||||||
.prompt_add_tags{
|
.special_prompt{
|
||||||
background-color: #353542;
|
background-color: #353542;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -17,15 +17,18 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { taLogger } from "../js/mzta-logger.js";
|
import { taLogger } from "../js/mzta-logger.js";
|
||||||
|
import { checkSparksPresence } from "../js/mzta-utils.js";
|
||||||
|
|
||||||
let menuSendImmediately = false;
|
let menuSendImmediately = false;
|
||||||
let taLog = console;
|
let taLog = console;
|
||||||
let connection_type = 'chatgpt_web';
|
let connection_type = 'chatgpt_web';
|
||||||
let add_tags = false;
|
let add_tags = false;
|
||||||
|
let get_calendar_event = false;
|
||||||
let tabType;
|
let tabType;
|
||||||
|
let num_special_menu_items = 0;
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', async () => {
|
document.addEventListener('DOMContentLoaded', async () => {
|
||||||
let prefs = await browser.storage.sync.get({do_debug: false, dynamic_menu_force_enter: false, add_tags: false, connection_type: 'chatgpt_web'});
|
let prefs = await browser.storage.sync.get({do_debug: false, dynamic_menu_force_enter: false, add_tags: true, get_calendar_event: true, connection_type: 'chatgpt_web'});
|
||||||
taLog = new taLogger("mzta-popup",prefs.do_debug);
|
taLog = new taLogger("mzta-popup",prefs.do_debug);
|
||||||
i18n.updateDocument();
|
i18n.updateDocument();
|
||||||
let reponse = await browser.runtime.sendMessage({command: "popup_menu_ready"});
|
let reponse = await browser.runtime.sendMessage({command: "popup_menu_ready"});
|
||||||
|
|
@ -40,6 +43,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
menuSendImmediately = prefs.dynamic_menu_force_enter;
|
menuSendImmediately = prefs.dynamic_menu_force_enter;
|
||||||
connection_type = prefs.connection_type;
|
connection_type = prefs.connection_type;
|
||||||
add_tags = prefs.add_tags;
|
add_tags = prefs.add_tags;
|
||||||
|
get_calendar_event = prefs.get_calendar_event;
|
||||||
searchPrompt(active_prompts, tabId, tabType);
|
searchPrompt(active_prompts, tabId, tabType);
|
||||||
i18n.updateDocument();
|
i18n.updateDocument();
|
||||||
}, { once: true });
|
}, { once: true });
|
||||||
|
|
@ -95,20 +99,56 @@ async function searchPrompt(allPrompts, tabId, tabType){
|
||||||
|
|
||||||
|
|
||||||
// Prepend numbers to the first 10 items
|
// Prepend numbers to the first 10 items
|
||||||
// If add_tags is true and connection_type is not 'chatgpt_web' reserve 0 position for prompt_add_tags
|
// If add_tags is true and connection_type is not 'chatgpt_web' reserve 0 position for prompt_add_tags and 1 for prompt_get_calendar_event (0, if no prompt_add_tags is disabled)
|
||||||
let max_num_el = 10
|
let max_num_el = 10
|
||||||
let first_num_el = 0;
|
let first_num_el = 0;
|
||||||
if(checkDoAddTags()){
|
|
||||||
max_num_el = 9;
|
let do_add_tags = checkDoAddTags();
|
||||||
first_num_el = 1;
|
let do_get_calendar_event = checkDoCalendarEvent();
|
||||||
filteredData = ensurePromptAddTagsFirst(filteredData);
|
|
||||||
if (!filteredData[0].numberPrepended) {
|
// console.log(">>>>>>>>>>> do_add_tags: " + do_add_tags);
|
||||||
filteredData[0].numberPrepended = 'true';
|
// console.log(">>>>>>>>>>> do_get_calendar_event: " + do_get_calendar_event);
|
||||||
filteredData[0].label = '0. ' + filteredData[0].label;
|
// console.log(">>>>>>>>>>> filteredData: " + JSON.stringify(filteredData));
|
||||||
|
|
||||||
|
if(do_add_tags){
|
||||||
|
num_special_menu_items++;
|
||||||
|
}
|
||||||
|
if(do_get_calendar_event){
|
||||||
|
num_special_menu_items++;
|
||||||
|
}
|
||||||
|
// console.log(">>>>>>>>>>>> num_special_menu_items: " + num_special_menu_items);
|
||||||
|
if(num_special_menu_items > 0){
|
||||||
|
max_num_el -= num_special_menu_items;
|
||||||
|
first_num_el = num_special_menu_items;
|
||||||
|
// console.log(">>>>>>>>>>>>> max_num_el: " + max_num_el);
|
||||||
|
// console.log(">>>>>>>>>>>>> first_num_el: " + first_num_el);
|
||||||
|
if(do_add_tags){
|
||||||
|
filteredData = ensurePromptAddTagsFirst(filteredData);
|
||||||
|
if (!filteredData[0].numberPrepended) {
|
||||||
|
filteredData[0].numberPrepended = 'true';
|
||||||
|
filteredData[0].label = '0. ' + filteredData[0].label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(do_get_calendar_event){
|
||||||
|
filteredData = ensurePromptGetCalendarEventFirst(filteredData, do_add_tags);
|
||||||
|
let gce_curr_pos = do_add_tags ? 1 : 0;
|
||||||
|
if (!filteredData[gce_curr_pos].numberPrepended) {
|
||||||
|
filteredData[gce_curr_pos].numberPrepended = 'true';
|
||||||
|
filteredData[gce_curr_pos].label = gce_curr_pos + '. ' + filteredData[gce_curr_pos].label;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// if(checkDoAddTags()){
|
||||||
|
// max_num_el = 9;
|
||||||
|
// first_num_el = 1;
|
||||||
|
// filteredData = ensurePromptAddTagsFirst(filteredData);
|
||||||
|
// if (!filteredData[0].numberPrepended) {
|
||||||
|
// filteredData[0].numberPrepended = 'true';
|
||||||
|
// filteredData[0].label = '0. ' + filteredData[0].label;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
Array.from(filteredData).slice(first_num_el, max_num_el).forEach((item, index) => {
|
Array.from(filteredData).slice(first_num_el, max_num_el).forEach((item, index) => {
|
||||||
let number = (index < 9) ? (index + 1).toString() : '0';
|
let number = (index + first_num_el).toString();
|
||||||
// Check if the number is already prepended to avoid duplication
|
// Check if the number is already prepended to avoid duplication
|
||||||
if (!item.numberPrepended) {
|
if (!item.numberPrepended) {
|
||||||
item.label = `${number}. ${item.label}`;
|
item.label = `${number}. ${item.label}`;
|
||||||
|
|
@ -118,21 +158,14 @@ async function searchPrompt(allPrompts, tabId, tabType){
|
||||||
|
|
||||||
// console.log(">>>>>>>>>>>>> filteredData: " + JSON.stringify(filteredData));
|
// console.log(">>>>>>>>>>>>> filteredData: " + JSON.stringify(filteredData));
|
||||||
|
|
||||||
// add the prompt_add_tags if add_tags is true and connection_type is not 'chatgpt_web'
|
|
||||||
// if(checkDoAddTags()){
|
|
||||||
// let number = '0';
|
|
||||||
// let item = {label: `${number}. ${browser.i18n.getMessage('prompt_add_tags')}`, id: 'prompt_add_tags', numberPrepended: 'true'};
|
|
||||||
// filteredData.unshift(item);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Create a div for each filtered result
|
// Create a div for each filtered result
|
||||||
filteredData.forEach(item => {
|
filteredData.forEach(item => {
|
||||||
const itemDiv = document.createElement('div');
|
const itemDiv = document.createElement('div');
|
||||||
itemDiv.classList.add('mzta_autocomplete-item');
|
itemDiv.classList.add('mzta_autocomplete-item');
|
||||||
itemDiv.textContent = item.label;
|
itemDiv.textContent = item.label;
|
||||||
itemDiv.setAttribute('data-id', item.id);
|
itemDiv.setAttribute('data-id', item.id);
|
||||||
if(item.id === 'prompt_add_tags'){
|
if((item.id === 'prompt_add_tags')||(item.id === 'prompt_get_calendar_event')){
|
||||||
itemDiv.className += ' prompt_add_tags';
|
itemDiv.className += ' special_prompt';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a mousedown event to select the item
|
// Add a mousedown event to select the item
|
||||||
|
|
@ -293,6 +326,10 @@ function checkDoAddTags(){
|
||||||
return add_tags && (connection_type !== "chatgpt_web" && tabType !== 'messageCompose');
|
return add_tags && (connection_type !== "chatgpt_web" && tabType !== 'messageCompose');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkDoCalendarEvent(){
|
||||||
|
return get_calendar_event && (connection_type !== "chatgpt_web" && tabType !== 'messageCompose') && checkSparksPresence();
|
||||||
|
}
|
||||||
|
|
||||||
function ensurePromptAddTagsFirst(arr) {
|
function ensurePromptAddTagsFirst(arr) {
|
||||||
// Find the index of the object with id "prompt_add_tags"
|
// Find the index of the object with id "prompt_add_tags"
|
||||||
const index = arr.findIndex(item => item.id === "prompt_add_tags");
|
const index = arr.findIndex(item => item.id === "prompt_add_tags");
|
||||||
|
|
@ -305,5 +342,22 @@ function ensurePromptAddTagsFirst(arr) {
|
||||||
arr.unshift(promptAddTags);
|
arr.unshift(promptAddTags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ensurePromptGetCalendarEventFirst(arr, do_add_tags) {
|
||||||
|
// Find the index of the object with id "prompt_get_calendar_event"
|
||||||
|
const index = arr.findIndex(item => item.id === "prompt_get_calendar_event");
|
||||||
|
|
||||||
|
// If found and needs repositioning
|
||||||
|
if (index !== -1 && (do_add_tags ? index !== 1 : index !== 0)) {
|
||||||
|
// Remove it from its current position
|
||||||
|
const [promptAddTags] = arr.splice(index, 1);
|
||||||
|
|
||||||
|
// Add it to the specified position
|
||||||
|
const targetPosition = do_add_tags ? 1 : 0;
|
||||||
|
arr.splice(targetPosition, 0, promptAddTags);
|
||||||
|
}
|
||||||
|
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
Loading…
Reference in a new issue