From 8c4282519ffeedf388017326584b8435bbf55deb Mon Sep 17 00:00:00 2001 From: mic Date: Sun, 13 Apr 2025 07:48:34 +0200 Subject: [PATCH 001/127] version set to 3.4.0 --- CHANGELOG.md | 4 ++++ manifest.json | 2 +- options/mzta-release-notes.html | 4 ++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b5aee93..e3147576 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ +

Version 3.4.0 - ??/??/2025

+

Version 3.3.3 - 12/04/2025

Version 3.3.3 - 12/04/2025

From 708005edb27034c16295773d23cd0dcb21b8217d Mon Sep 17 00:00:00 2001 From: Mic Date: Wed, 16 Apr 2025 00:11:00 +0200 Subject: [PATCH 025/127] Optimize calculation of special menu items in searchPrompt function. --- popup/mzta-popup.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/popup/mzta-popup.js b/popup/mzta-popup.js index 590f0019..08e98b8d 100644 --- a/popup/mzta-popup.js +++ b/popup/mzta-popup.js @@ -121,12 +121,7 @@ async function searchPrompt(allPrompts, tabId, tabType){ // console.log(">>>>>>>>>>> do_get_calendar_event: " + do_get_calendar_event); // console.log(">>>>>>>>>>> filteredData: " + JSON.stringify(filteredData)); - if(do_add_tags){ - num_special_menu_items++; - } - if(do_get_calendar_event){ - num_special_menu_items++; - } + num_special_menu_items = (do_add_tags ? 1 : 0) + (do_get_calendar_event ? 1 : 0); // console.log(">>>>>>>>>>>> num_special_menu_items: " + num_special_menu_items); if(num_special_menu_items > 0){ max_num_el -= num_special_menu_items; From a833766250b5ee2113032047ebb6114a2cedee1a Mon Sep 17 00:00:00 2001 From: mic Date: Wed, 16 Apr 2025 22:39:27 +0200 Subject: [PATCH 026/127] Add new task prompts for task extraction functionality. See #333 --- _locales/en/messages.json | 8 ++++++++ js/mzta-prompts.js | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 95c3d121..ebecbf2a 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -999,6 +999,14 @@ "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)\n- Attendees\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.\nThese are the attendees: {%author%}, {%recipients%}, {%cc_list%}. If present, exclude my address: {%account_email_address%}.\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\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nHere's the text:\"{%selected_text%}\"", "description": "" }, + "prompt_get_task": { + "message": "Add a new task", + "description": "" + }, + "prompt_get_task_full_text": { + "message": "Extract all relevant details required to generate a task from the following text. The extracted information should include:\n- Due Date and Time (including timezone, if specified)\n- Task summary\n- Initial Date and Time (including timezone, if specified)\nEnsure the data is formatted clearly and consistently so that it can be directly used for creating a task.\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 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\"InitialDate\": \"YYYYMMDDTHHMMSS\",\n\"dueDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Task summary here\",\n}\nHere's the text:\"{%selected_text%}\"", + "description": "" + }, "prefs_OptionText_get_calendar_event": { "message": "Add a new calendar event from selected text", "description": "" diff --git a/js/mzta-prompts.js b/js/mzta-prompts.js index f5b2bb77..29bdd311 100644 --- a/js/mzta-prompts.js +++ b/js/mzta-prompts.js @@ -223,6 +223,20 @@ const specialPrompts = [ is_default: "1", is_special: "1", }, + { + id: 'prompt_get_task', + name: "__MSG_prompt_get_task__", + text: "prompt_get_task_full_text", + type: "1", + action: "0", + need_selected: "1", + need_signature: "0", + need_custom_text: "0", + define_response_lang: "0", + use_diff_viewer: "0", + is_default: "1", + is_special: "1", + }, { id: 'prompt_spamfilter', name: "__MSG_prompt_spamfilter__", From 3e9bb3e68c5fdaf5ab670f7b1f89c846b5bebc36 Mon Sep 17 00:00:00 2001 From: Mic Date: Wed, 16 Apr 2025 22:47:58 +0200 Subject: [PATCH 027/127] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a9993453..42ef821e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ThunderAI is a Thunderbird Addon that uses the capabilities of ChatGPT, Google Gemini or Ollama to enhance email management. -It enables users to analyse, write, correct, assign tags, create calendar events and optimize their emails, facilitating more effective and professional communication. +It enables users to analyse, write, correct, assign tags, create calendar events or tasks 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. From 4dce654482bc397f4552536d17e96851b68ff75a Mon Sep 17 00:00:00 2001 From: Mic Date: Wed, 16 Apr 2025 23:34:00 +0200 Subject: [PATCH 028/127] typo fixed --- _locales/en/messages.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index ebecbf2a..e25b269e 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -1004,7 +1004,7 @@ "description": "" }, "prompt_get_task_full_text": { - "message": "Extract all relevant details required to generate a task from the following text. The extracted information should include:\n- Due Date and Time (including timezone, if specified)\n- Task summary\n- Initial Date and Time (including timezone, if specified)\nEnsure the data is formatted clearly and consistently so that it can be directly used for creating a task.\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 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\"InitialDate\": \"YYYYMMDDTHHMMSS\",\n\"dueDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Task summary here\",\n}\nHere's the text:\"{%selected_text%}\"", + "message": "Extract all relevant details required to generate a task from the following text. The extracted information should include:\n- Due Date and Time (including timezone, if specified)\n- Task summary\n- Initial Date and Time (including timezone, if specified)\nEnsure the data is formatted clearly and consistently so that it can be directly used for creating a task.\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 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\"InitialDate\": \"YYYYMMDDTHHMMSS\",\n\"dueDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Task summary here\"\n}\nHere's the text:\"{%selected_text%}\"", "description": "" }, "prefs_OptionText_get_calendar_event": { From 13cfed9c56d01fd75a80a693678a40d7be7b51bf Mon Sep 17 00:00:00 2001 From: Mic Date: Wed, 16 Apr 2025 23:34:00 +0200 Subject: [PATCH 029/127] get_task feature added in mzta-menu.js. see #333 --- _locales/en/messages.json | 8 +++++ js/mzta-menus.js | 68 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index e25b269e..e05c3f41 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -1079,6 +1079,14 @@ "message": "Error opening the calendar event dialog", "description": "" }, + "task_getting_data_error": { + "message": "Error getting task data", + "description": "" + }, + "task_opening_dialog_error": { + "message": "Error opening the task dialog", + "description": "" + }, "sparks_not_installed": { "message": "ThunderAI Sparks not installed!", "description": "" diff --git a/js/mzta-menus.js b/js/mzta-menus.js index 89be4316..6e81aa85 100644 --- a/js/mzta-menus.js +++ b/js/mzta-menus.js @@ -266,6 +266,74 @@ export class mzta_Menus { } break; // Get a calendar event info - END } + case 'prompt_get_task': { // Get a task info + let task_data = ''; + let prefs_at = await browser.storage.sync.get({connection_type: '', calendar_enforce_timezone: false, calendar_timezone: '',}); + if((prefs_at.connection_type === '')||(prefs_at.connection_type === null)||(prefs_at.connection_type === undefined)||(prefs_at.connection_type === 'chatgpt_web')){ + console.error("[ThunderAI | GetTask] Invalid connection type: " + prefs_at.connection_type); + taWorkingStatus.stopWorking(); + return {ok:'0'}; + } + /* We expect to receive from the AI a JSON object like this: + * { + * "InitialDate": "YYYYMMDDTHHMMSS", + * "dueDate": "YYYYMMDDTHHMMSS", + * "summary": "Task summary here" + * } + */ + this.logger.log("fullPrompt: " + fullPrompt); + let cmd_GetTask = new mzta_specialCommand(fullPrompt,prefs_at.connection_type,true); + await cmd_GetTask.initWorker(); + try{ + task_data = await cmd_GetTask.sendPrompt(); + // console.log(">>>>>>>>>>> task_data: " + task_data); + }catch(err){ + console.error("[ThunderAI] Error getting task data: ", err.message); + browser.tabs.sendMessage(tabs[0].id, { command: "sendAlert", curr_tab_type: tabs[0].type, message: browser.i18n.getMessage("task_getting_data_error") + ": " + err.message }); + taWorkingStatus.stopWorking(); + return {ok:'0'}; + } + let task_data_obj = {}; + try{ + task_data_obj = extractJsonObject(task_data); + }catch(err){ + console.error("[ThunderAI] Error extracting JSON object from task data: ", err.message); + browser.tabs.sendMessage(tabs[0].id, { command: "sendAlert", curr_tab_type: tabs[0].type, message: browser.i18n.getMessage("task_getting_data_error") + ": " + err.message }); + taWorkingStatus.stopWorking(); + return {ok:'0'}; + } + // Timezone management + task_data_obj.use_timezone = false; + if(prefs_at.calendar_enforce_timezone){ + task_data_obj.use_timezone = true; + task_data_obj.timezone = prefs_at.calendar_timezone; + } + let task_data_str = JSON.stringify(task_data_obj); + // Timezone management - END + this.logger.log("task_data: " + task_data); + this.logger.log("task_data_obj: " + task_data_str); + try{ + let result_openTaskDialog = await browser.runtime.sendMessage('thunderai-sparks@micz.it',{action: "openTaskDialog", task_data: task_data_str}) + if(result_openTaskDialog == 'ok'){ + taWorkingStatus.stopWorking(); + return {ok:'1'}; + } else { + let err = result_openTaskDialog.error; + if (err && typeof err === 'string' && err.startsWith('|>>')) { + result_openTaskDialog.error = browser.i18n.getMessage(result_openTaskDialog.error.substring(3)); + } + browser.tabs.sendMessage(tabs[0].id, { command: "sendAlert", curr_tab_type: tabs[0].type, message: browser.i18n.getMessage("task_opening_dialog_error") + ": " + result_openTaskDialog.error }); + taWorkingStatus.stopWorking(); + return {ok:'0'}; + } + }catch(err){ + console.error("[ThunderAI] Error opening task dialog: ", err); + browser.tabs.sendMessage(tabs[0].id, { command: "sendAlert", curr_tab_type: tabs[0].type, message: browser.i18n.getMessage("task_opening_dialog_error") + ": " + browser.i18n.getMessage("sparks_not_installed") }); + taWorkingStatus.stopWorking(); + return {ok:'0'}; + } + break; + } // Get a task info - END default: console.error("[ThunderAI] Unknown special prompt id: " + curr_prompt.id); taWorkingStatus.stopWorking(); From b49875992a93aecc63c53675c0c6c6b8b5150fd4 Mon Sep 17 00:00:00 2001 From: Mic Date: Wed, 16 Apr 2025 23:39:00 +0200 Subject: [PATCH 030/127] Remove unused preferences retrieval in getPlaceholders function --- js/mzta-placeholders.js | 1 - 1 file changed, 1 deletion(-) diff --git a/js/mzta-placeholders.js b/js/mzta-placeholders.js index 363feee2..4dfb6d0e 100644 --- a/js/mzta-placeholders.js +++ b/js/mzta-placeholders.js @@ -197,7 +197,6 @@ export async function getPlaceholders(onlyEnabled = false){ output.sort((a, b) => a.id.localeCompare(b.id)); } // console.log('>>>>>>>>>>>> getPlaceholders output: ' + JSON.stringify(output)); - let prefs = await browser.storage.local.get({ add_tags: false }); return output; } From 6df9f8624442f146ef34b5635d1c28b8d7eefa7a Mon Sep 17 00:00:00 2001 From: Mic Date: Wed, 16 Apr 2025 23:39:00 +0200 Subject: [PATCH 031/127] Refactor preference retrieval to use default values in storage queries --- mzta-background.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mzta-background.js b/mzta-background.js index 1b17e355..f0fe01ec 100644 --- a/mzta-background.js +++ b/mzta-background.js @@ -146,7 +146,7 @@ function preparePopupMenu(tab) { } async function _reload_menus() { - let prefs_reload = await browser.storage.sync.get({add_tags: true, get_calendar_event: false, connection_type: 'chatgpt_web'}); + let prefs_reload = await browser.storage.sync.get({add_tags: prefs_default.add_tags, get_calendar_event: prefs_default.get_calendar_event, connection_type: prefs_default.connection_type}); 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); @@ -202,7 +202,7 @@ messenger.runtime.onMessage.addListener((message, sender, sendResponse) => { async function _replyMessage(message) { const paragraphsHtmlString = message.text; //console.log(">>>>>>>>>>>> paragraphsHtmlString: " + paragraphsHtmlString); - let prefs = await browser.storage.sync.get({reply_type: 'reply_all'}); + let prefs = await browser.storage.sync.get({reply_type: prefs_default.reply_type}); //console.log('reply_type: ' + prefs.reply_type); let replyType = 'replyToAll'; if(prefs.reply_type === 'reply_sender'){ @@ -628,7 +628,7 @@ async function doGetCalendarEvent(get_calendar_event) { } async function reload_pref_init(){ - prefs_init = await browser.storage.sync.get({do_debug: false, add_tags: false, get_calendar_event: true, connection_type: 'chatgpt_web', add_tags_auto: false, add_tags_auto_force_existing: false, add_tags_auto_only_inbox: true, spamfilter: false, spamfilter_threshold: 70, dynamic_menu_force_enter: false, add_tags_context_menu: true, spamfilter_context_menu: true}); + prefs_init = await browser.storage.sync.get({do_debug: prefs_default.do_debug, add_tags: prefs_default.add_tags, get_calendar_event: prefs_default.get_calendar_event, connection_type: prefs_default.connection_type, add_tags_auto: prefs_default.add_tags_auto, add_tags_auto_force_existing: prefs_default.add_tags_auto_force_existing, add_tags_auto_only_inbox: prefs_default.add_tags_auto_only_inbox, spamfilter: prefs_default.spamfilter, spamfilter_threshold: prefs_default.spamfilter_threshold, dynamic_menu_force_enter: prefs_default.dynamic_menu_force_enter, add_tags_context_menu: prefs_default.add_tags_context_menu, spamfilter_context_menu: prefs_default.spamfilter_context_menu}); _process_incoming = prefs_init.add_tags_auto || prefs_init.spamfilter; } @@ -821,7 +821,7 @@ async function processEmails(messages, addTagsAuto, spamFilter) { let tags_full_list = await getTagsList(); let chatgpt_lang = await taPromptUtils.getDefaultLang(curr_prompt_add_tags); specialFullPrompt_add_tags = await taPromptUtils.preparePrompt(curr_prompt_add_tags, message, chatgpt_lang, '', body_text, curr_fullMessage.headers.subject, msg_text, '', tags_full_list); - let prefs_aat = await browser.storage.sync.get({ add_tags_maxnum: 3, connection_type: '', add_tags_force_lang: true, default_chatgpt_lang: '', add_tags_auto_force_existing: false }); + let prefs_aat = await browser.storage.sync.get({ add_tags_maxnum: prefs_default.add_tags_maxnum, connection_type: prefs_default.connection_type, add_tags_force_lang: prefs_default.add_tags_force_lang, default_chatgpt_lang: prefs_default.default_chatgpt_lang, add_tags_auto_force_existing: prefs_default.add_tags_auto_force_existing }); specialFullPrompt_add_tags = taPromptUtils.finalizePrompt_add_tags(specialFullPrompt_add_tags, prefs_aat.add_tags_maxnum, prefs_aat.add_tags_force_lang, prefs_aat.default_chatgpt_lang); taLog.log("Special prompt: " + specialFullPrompt_add_tags); let cmd_addTags = new mzta_specialCommand(specialFullPrompt_add_tags, prefs_aat.connection_type, prefs_init.do_debug); From 15159452eac884e5761720c4ab3308102e9f6d66 Mon Sep 17 00:00:00 2001 From: Mic Date: Wed, 16 Apr 2025 23:44:00 +0200 Subject: [PATCH 032/127] Add 'get task' feature to the options page and added the get_task settings managing page. see #333 --- _locales/en/messages.json | 32 ++++++- options/mzta-options-default.js | 1 + options/mzta-options.html | 10 ++ options/mzta-options.js | 20 ++++ pages/get-task/mzta-get-task.css | 119 ++++++++++++++++++++++++ pages/get-task/mzta-get-task.html | 73 +++++++++++++++ pages/get-task/mzta-get-task.js | 149 ++++++++++++++++++++++++++++++ 7 files changed, 400 insertions(+), 4 deletions(-) create mode 100644 pages/get-task/mzta-get-task.css create mode 100644 pages/get-task/mzta-get-task.html create mode 100644 pages/get-task/mzta-get-task.js diff --git a/_locales/en/messages.json b/_locales/en/messages.json index e05c3f41..af6e4e97 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -1012,13 +1012,25 @@ "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.", + "message": "If checked, an item will be included in the menu to get calendar event information from selected text.", "description": "" }, "get_calendar_event_prompt_prefs_title": { "message": "Calendar Events Options", "description": "" }, + "prefs_OptionText_get_task": { + "message": "Add a new task from selected text", + "description": "" + }, + "prefs_OptionText_get_task_Info": { + "message": "If checked, an item will be included in the menu to get task information from selected text.", + "description": "" + }, + "get_task_prompt_prefs_title": { + "message": "Tasks Options", + "description": "" + }, "Select_your_timezone": { "message": "Select your timezone", "description": "" @@ -1028,7 +1040,7 @@ "description": "" }, "prefs_OptionText_calendar_enforce_timezone_Info": { - "message": "If checked, the specified timezone will be enforced for the calendar events.", + "message": "If checked, the specified timezone will be enforced for the calendar events and the tasks.", "description": "" }, "prefs_OptionText_btnManageCalendarEventInfo": { @@ -1052,11 +1064,23 @@ "description": "" }, "prefs_OptionText_get_calendar_event_Sparks_not_present": { - "message": "To use the calendar event feature, please install the ThunderAI Sparks addon.", + "message": "To use the calendar event and task features, please install the ThunderAI Sparks addon.", "description": "" }, "prefs_OptionText_get_calendar_event_Sparks_wrong_version": { - "message": "To use the calendar event feature, please install an updated version of ThunderAI Sparks addon.", + "message": "To use the calendar event and task features, please install an updated version of ThunderAI Sparks addon.", + "description": "" + }, + "GetTask_PageTitle": { + "message": "Manage Tasks Settings", + "description": "" + }, + "GetTask_info_default": { + "message": "In this page you can modify the default prompt used to get a task from selected text.", + "description": "" + }, + "prefs_OptionText_btnManageTaskInfo": { + "message": "Manage tasks settings", "description": "" }, "prefs_OptionText_download_now": { diff --git a/options/mzta-options-default.js b/options/mzta-options-default.js index 573d2085..c4674218 100644 --- a/options/mzta-options-default.js +++ b/options/mzta-options-default.js @@ -52,6 +52,7 @@ export const prefs_default = { add_tags_auto_only_inbox: true, add_tags_context_menu: true, get_calendar_event: true, + get_task: true, calendar_enforce_timezone: false, calendar_timezone: '', spamfilter: false, diff --git a/options/mzta-options.html b/options/mzta-options.html index 30b8a790..08d987b1 100644 --- a/options/mzta-options.html +++ b/options/mzta-options.html @@ -374,6 +374,16 @@ + + __MSG_prefs_OptionText_get_task__ +
+ + + + __MSG_prefs_OptionText_get_calendar_event_Sparks_not_present__ diff --git a/options/mzta-options.js b/options/mzta-options.js index ee575645..07376d81 100644 --- a/options/mzta-options.js +++ b/options/mzta-options.js @@ -386,6 +386,13 @@ document.addEventListener('DOMContentLoaded', async () => { get_calendar_event_info_btn.disabled = event.target.checked ? '' : 'disabled'; }); get_calendar_event_info_btn.disabled = get_calendar_event_el.checked ? '' : 'disabled'; + + let get_task_el = document.getElementById('get_task'); + let get_task_info_btn = document.getElementById('btnManageTaskInfo'); + get_task_el.addEventListener('click', (event) => { + get_task_info_btn.disabled = event.target.checked ? '' : 'disabled'; + }); + get_task_info_btn.disabled = get_task_el.checked ? '' : 'disabled'; document.getElementById('btnManagePrompts').addEventListener('click', () => { // check if the tab is already there @@ -439,6 +446,19 @@ document.addEventListener('DOMContentLoaded', async () => { }) }); + document.getElementById('btnManageTaskInfo').addEventListener('click', () => { + // check if the tab is already there + browser.tabs.query({url: browser.runtime.getURL('../pages/get-task/mzta-get-task.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-task/mzta-get-task.html')}); + } + }) + }); + document.getElementById('btnOpenAICompForceModel').addEventListener('click', () => { let modelName = prompt(browser.i18n.getMessage('OpenAIComp_force_model_ask')).trim(); if ((modelName !== null) && (modelName !== undefined) && (modelName !== '')) { diff --git a/pages/get-task/mzta-get-task.css b/pages/get-task/mzta-get-task.css new file mode 100644 index 00000000..0ce83ec5 --- /dev/null +++ b/pages/get-task/mzta-get-task.css @@ -0,0 +1,119 @@ +#get_task_prompt_container{ + width: 90%; + margin: 20px auto; +} + +#get_task_prompt_text{ + width: 100%; +} + +.infoline{ + font-size: 0.8em; + font-style: italic; +} + +.btn_div{ + width: 100%; + display: flex; + justify-content: space-between; +} + +table#miczPrefs { + padding: 10px; + border-spacing: 0px; + width: 90%; + margin: 0px auto 40px auto; + border: 1px solid #ccc; +} + +.get_task_table_title{ + width: 90%; + margin: auto; +} + +.section_title{ + font-weight: bold; +} + +table#miczPrefs td{ + border-top: 1px solid #ccc; + border-bottom: 1px solid #ccc; + vertical-align: top; + padding: 2px; +} + +table#miczPrefs tr:first-child td { + border-top: none; +} + +table#miczPrefs tr:last-child td { + border-bottom: none; +} + +.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; + } +} \ No newline at end of file diff --git a/pages/get-task/mzta-get-task.html b/pages/get-task/mzta-get-task.html new file mode 100644 index 00000000..98027d85 --- /dev/null +++ b/pages/get-task/mzta-get-task.html @@ -0,0 +1,73 @@ + + + + + ThunderAI - __MSG_GetTask_PageTitle__ + + + + +
+

__MSG_GetTask_PageTitle__

+

__MSG_GetTask_info_default__

+
+
__MSG_get_calendar_event_prompt_prefs_title__
+ + + + + +
__MSG_prefs_OptionText_calendar_enforce_timezone__ + +
+
+ __MSG_GetCalendarEvent_prompt_text_title__ +
__MSG_prefs_OptionText_btnManagePrompts_infoline__ __MSG_customPrompts_managePrompts_help__ +
__MSG_prefs_OptionText_GetCalendarEvent_infoline2__
+
+
+ + +
+
+
+
+ + + + \ No newline at end of file diff --git a/pages/get-task/mzta-get-task.js b/pages/get-task/mzta-get-task.js new file mode 100644 index 00000000..2b33e297 --- /dev/null +++ b/pages/get-task/mzta-get-task.js @@ -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 . + */ + +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_task_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_task'); + + get_calendar_event_textarea.addEventListener('input', (event) => { + get_calendar_event_reset_btn.disabled = (event.target.value === browser.i18n.getMessage('prompt_get_task_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_task_prompt_unsaved').classList.add('hidden'); + } else { + document.getElementById('get_task_prompt_unsaved').classList.remove('hidden'); + } + }); + + get_calendar_event_reset_btn.addEventListener('click', () => { + get_calendar_event_textarea.value = browser.i18n.getMessage('prompt_get_task_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_task').text = get_calendar_event_textarea.value; + setSpecialPrompts(specialPrompts); + get_calendar_event_save_btn.disabled = true; + document.getElementById('get_task_prompt_unsaved').classList.add('hidden'); + browser.runtime.sendMessage({command: "reload_menus"}); + }); + + if(get_calendar_event_prompt.text === 'prompt_get_task_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_task_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); +} \ No newline at end of file From eea691f0b5985b1bc41f829705c2dc4bf7933a86 Mon Sep 17 00:00:00 2001 From: Mic Date: Wed, 16 Apr 2025 23:44:00 +0200 Subject: [PATCH 033/127] Add 'get_task' parameter to getActiveSpecialPromptsIDs function. see #333 --- js/mzta-utils.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/js/mzta-utils.js b/js/mzta-utils.js index d314faf0..a07bf53a 100644 --- a/js/mzta-utils.js +++ b/js/mzta-utils.js @@ -332,7 +332,7 @@ export async function transformTagsLabels(labels, tags_list) { return output; } -export function getActiveSpecialPromptsIDs(addtags = false, get_calendar_event = false, is_chatgpt_web = false) { +export function getActiveSpecialPromptsIDs(addtags = false, get_calendar_event = false, get_task = 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){ @@ -344,6 +344,9 @@ export function getActiveSpecialPromptsIDs(addtags = false, get_calendar_event = if(get_calendar_event){ output.push('prompt_get_calendar_event'); } + if(get_task){ + output.push('prompt_get_task'); + } // console.log(">>>>>>>>>> getActiveSpecialPromptsIDs output: " + JSON.stringify(output)); return output; } From 9e22a9db46f452325c3eb5f84cc0fcd23f8dd2b4 Mon Sep 17 00:00:00 2001 From: Mic Date: Wed, 16 Apr 2025 23:49:00 +0200 Subject: [PATCH 034/127] Add openTab function to streamline tab management in mzta-options.js --- js/mzta-utils.js | 13 ++++++++++ options/mzta-options.js | 57 +++++------------------------------------ 2 files changed, 19 insertions(+), 51 deletions(-) diff --git a/js/mzta-utils.js b/js/mzta-utils.js index a07bf53a..63750e10 100644 --- a/js/mzta-utils.js +++ b/js/mzta-utils.js @@ -198,6 +198,19 @@ export function getGPTWebModelString(model) { } } +export function openTab(url){ + // check if the tab is already there + browser.tabs.query({url: browser.runtime.getURL(url)}).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(url)}); + } + }) +} + 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 diff --git a/options/mzta-options.js b/options/mzta-options.js index 07376d81..c4d61f80 100644 --- a/options/mzta-options.js +++ b/options/mzta-options.js @@ -22,7 +22,7 @@ import { OpenAI } from '../js/api/openai.js'; import { Ollama } from '../js/api/ollama.js'; import { OpenAIComp } from '../js/api/openai_comp.js' import { GoogleGemini } from '../js/api/google_gemini.js'; -import { checkSparksPresence, isThunderbird128OrGreater } from '../js/mzta-utils.js'; +import { checkSparksPresence, isThunderbird128OrGreater, openTab } from '../js/mzta-utils.js'; let taLog = new taLogger("mzta-options",true); let _isThunderbird128OrGreater = true; @@ -395,68 +395,23 @@ document.addEventListener('DOMContentLoaded', async () => { get_task_info_btn.disabled = get_task_el.checked ? '' : 'disabled'; document.getElementById('btnManagePrompts').addEventListener('click', () => { - // check if the tab is already there - browser.tabs.query({url: browser.runtime.getURL('../pages/customprompts/mzta-custom-prompts.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/customprompts/mzta-custom-prompts.html')}); - } - }) + openTab('../pages/customprompts/mzta-custom-prompts.html'); }); document.getElementById('btnManageTagsInfo').addEventListener('click', () => { - // check if the tab is already there - browser.tabs.query({url: browser.runtime.getURL('../pages/addtags/mzta-add-tags.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/addtags/mzta-add-tags.html')}); - } - }) + openTab('../pages/addtags/mzta-add-tags.html'); }); document.getElementById('btnManageSpamFilterInfo').addEventListener('click', () => { - // check if the tab is already there - browser.tabs.query({url: browser.runtime.getURL('../pages/spamfilter/mzta-spamfilter.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/spamfilter/mzta-spamfilter.html')}); - } - }) + openTab('../pages/spamfilter/mzta-spamfilter.html'); }); 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')}); - } - }) + openTab('../pages/get-calendar-event/mzta-get-calendar-event.html'); }); document.getElementById('btnManageTaskInfo').addEventListener('click', () => { - // check if the tab is already there - browser.tabs.query({url: browser.runtime.getURL('../pages/get-task/mzta-get-task.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-task/mzta-get-task.html')}); - } - }) + openTab('../pages/get-task/mzta-get-task.html'); }); document.getElementById('btnOpenAICompForceModel').addEventListener('click', () => { From cfa65c4934c9dfb9a9b56f84c442625a603a96af Mon Sep 17 00:00:00 2001 From: Mic Date: Wed, 16 Apr 2025 23:49:00 +0200 Subject: [PATCH 035/127] Rename doGetCalendarEvent to doGetSparkFeature for clarity and update related function calls --- mzta-background.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mzta-background.js b/mzta-background.js index f0fe01ec..ba34b270 100644 --- a/mzta-background.js +++ b/mzta-background.js @@ -52,7 +52,7 @@ await reload_pref_init(); let taLog = new taLogger("mzta-background",prefs_init.do_debug); taWorkingStatus.taLog = taLog; -let special_prompts_ids = getActiveSpecialPromptsIDs(prefs_init.add_tags, await doGetCalendarEvent(prefs_init.get_calendar_event), (prefs_init.connection_type === "chatgpt_web")); +let special_prompts_ids = getActiveSpecialPromptsIDs(prefs_init.add_tags, await doGetSparkFeature(prefs_init.get_calendar_event), (prefs_init.connection_type === "chatgpt_web")); browser.composeScripts.register({ js: [{file: "/js/mzta-compose-script.js"}] @@ -147,7 +147,7 @@ function preparePopupMenu(tab) { async function _reload_menus() { let prefs_reload = await browser.storage.sync.get({add_tags: prefs_default.add_tags, get_calendar_event: prefs_default.get_calendar_event, connection_type: prefs_default.connection_type}); - doGetCalendarEvent(prefs_reload.get_calendar_event).then(calendarEvent => { + doGetSparkFeature(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); }); @@ -619,8 +619,8 @@ function checkScreenDimensions(prefs){ return prefs; } -async function doGetCalendarEvent(get_calendar_event) { - if(get_calendar_event) { +async function doGetSparkFeature(spark_feature_active) { + if(spark_feature_active) { return (await checkSparksPresence() == 1); } else { return false; @@ -641,7 +641,7 @@ function setupStorageChangeListener() { // Process 'add_tags' changes if (changes.add_tags) { const newTags = changes.add_tags.newValue; - doGetCalendarEvent(prefs_init.get_calendar_event).then(calendarEvent => { + doGetSparkFeature(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); }); @@ -650,7 +650,7 @@ function setupStorageChangeListener() { // Process 'get_calendar_event' changes if (changes.get_calendar_event) { const newCalendarEvent = changes.get_calendar_event.newValue; - doGetCalendarEvent(newCalendarEvent).then(calendarEvent => { + doGetSparkFeature(newCalendarEvent).then(calendarEvent => { const special_prompts_ids = getActiveSpecialPromptsIDs(prefs_init.add_tags, calendarEvent, (prefs_init.connection_type === "chatgpt_web")); menus.reload(special_prompts_ids); }); @@ -659,7 +659,7 @@ function setupStorageChangeListener() { // Process 'connection_type' changes if (changes.connection_type) { const newConnectionType = changes.connection_type.newValue; - doGetCalendarEvent(prefs_init.get_calendar_event).then(calendarEvent => { + doGetSparkFeature(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); }); From c449f68cc129746fe39bbefefe6c34996917cb84 Mon Sep 17 00:00:00 2001 From: Mic Date: Wed, 16 Apr 2025 23:54:00 +0200 Subject: [PATCH 036/127] Refactor getActiveSpecialPromptsIDs function to accept a single argument object for improved readability and maintainability --- js/mzta-utils.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/js/mzta-utils.js b/js/mzta-utils.js index 63750e10..e4514a18 100644 --- a/js/mzta-utils.js +++ b/js/mzta-utils.js @@ -345,19 +345,20 @@ export async function transformTagsLabels(labels, tags_list) { return output; } -export function getActiveSpecialPromptsIDs(addtags = false, get_calendar_event = false, get_task = false, is_chatgpt_web = false) { +export function getActiveSpecialPromptsIDs(args = {}) { + const { addtags = false, get_calendar_event = false, get_task = false, is_chatgpt_web = false } = args; let output = []; - // console.log(">>>>>>>>>> getActiveSpecialPromptsIDs addtags: " + addtags + " get_calendar_event: " + get_calendar_event + " is_chatgpt_web: " + is_chatgpt_web); - if(is_chatgpt_web){ + // console.log(">>>>>>>>>> getActiveSpecialPromptsIDs args: " + JSON.stringify(args)); + if (is_chatgpt_web) { return output; } - if(addtags){ + if (addtags) { output.push('prompt_add_tags'); } - if(get_calendar_event){ + if (get_calendar_event) { output.push('prompt_get_calendar_event'); } - if(get_task){ + if (get_task) { output.push('prompt_get_task'); } // console.log(">>>>>>>>>> getActiveSpecialPromptsIDs output: " + JSON.stringify(output)); From 12d54d8a313bdd8d1b3b3b4a14fb2c84dc913929 Mon Sep 17 00:00:00 2001 From: Mic Date: Wed, 16 Apr 2025 23:54:00 +0200 Subject: [PATCH 037/127] Refactor getActiveSpecialPromptsIDs calls to use an argument object for improved clarity and consistency --- mzta-background.js | 59 +++++++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/mzta-background.js b/mzta-background.js index ba34b270..023d362d 100644 --- a/mzta-background.js +++ b/mzta-background.js @@ -52,7 +52,12 @@ await reload_pref_init(); let taLog = new taLogger("mzta-background",prefs_init.do_debug); taWorkingStatus.taLog = taLog; -let special_prompts_ids = getActiveSpecialPromptsIDs(prefs_init.add_tags, await doGetSparkFeature(prefs_init.get_calendar_event), (prefs_init.connection_type === "chatgpt_web")); +let special_prompts_ids = getActiveSpecialPromptsIDs({ + addtags: prefs_init.add_tags, + get_calendar_event: await doGetSparkFeature(prefs_init.get_calendar_event), + get_task: await doGetSparkFeature(prefs_init.get_task), + is_chatgpt_web: (prefs_init.connection_type === "chatgpt_web") + }); browser.composeScripts.register({ js: [{file: "/js/mzta-compose-script.js"}] @@ -147,10 +152,15 @@ function preparePopupMenu(tab) { async function _reload_menus() { let prefs_reload = await browser.storage.sync.get({add_tags: prefs_default.add_tags, get_calendar_event: prefs_default.get_calendar_event, connection_type: prefs_default.connection_type}); - doGetSparkFeature(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); - }); + let getCalendarEvent = doGetSparkFeature(prefs_reload.get_calendar_event); + let getTask = doGetSparkFeature(prefs_reload.get_task); + const special_prompts_ids = getActiveSpecialPromptsIDs({ + addtags: prefs_reload.add_tags, + get_calendar_event: getCalendarEvent, + get_task: getTask, + is_chatgpt_web: (prefs_reload.connection_type === "chatgpt_web") + }); + menus.reload(special_prompts_ids); taLog.log("Reloading menus"); return true; } @@ -641,28 +651,43 @@ function setupStorageChangeListener() { // Process 'add_tags' changes if (changes.add_tags) { const newTags = changes.add_tags.newValue; - doGetSparkFeature(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); - }); + let getCalendarEvent = doGetSparkFeature(prefs_init.get_calendar_event); + let getTask = doGetSparkFeature(prefs_init.get_task); + const special_prompts_ids = getActiveSpecialPromptsIDs({ + addtags: newTags, + get_calendar_event: getCalendarEvent, + get_task: getTask, + is_chatgpt_web: (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; - doGetSparkFeature(newCalendarEvent).then(calendarEvent => { - const special_prompts_ids = getActiveSpecialPromptsIDs(prefs_init.add_tags, calendarEvent, (prefs_init.connection_type === "chatgpt_web")); - menus.reload(special_prompts_ids); - }); + let getCalendarEvent = doGetSparkFeature(newCalendarEvent); + let getTask = doGetSparkFeature(prefs_init.get_task); + const special_prompts_ids = getActiveSpecialPromptsIDs({ + addtags: prefs_init.add_tags, + get_calendar_event: getCalendarEvent, + get_task: getTask, + is_chatgpt_web: (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; - doGetSparkFeature(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); - }); + let getCalendarEvent = doGetSparkFeature(prefs_init.get_calendar_event); + let getTask = doGetSparkFeature(prefs_init.get_task); + const special_prompts_ids = getActiveSpecialPromptsIDs({ + addtags: prefs_init.add_tags, + get_calendar_event: getCalendarEvent, + get_task: getTask, + is_chatgpt_web: (newConnectionType === "chatgpt_web") + }); + menus.reload(special_prompts_ids); if(newConnectionType === "chatgpt_web"){ removeContextMenu(contextMenuID_AddTags); From e1ad9d9c5d25ebfab5ccd2165513cba2639c4247 Mon Sep 17 00:00:00 2001 From: Mic Date: Wed, 16 Apr 2025 23:59:00 +0200 Subject: [PATCH 038/127] Handle 'get_task' changes in setupStorageChangeListener to update special prompts IDs accordingly. see #333 --- mzta-background.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/mzta-background.js b/mzta-background.js index 023d362d..cd7238f7 100644 --- a/mzta-background.js +++ b/mzta-background.js @@ -676,6 +676,20 @@ function setupStorageChangeListener() { menus.reload(special_prompts_ids); } + // Process 'get_task' changes + if (changes.get_task) { + const newTask = changes.get_task.newValue; + let getCalendarEvent = doGetSparkFeature(prefs_init.get_calendar_event); + let getTask = doGetSparkFeature(newTask); + const special_prompts_ids = getActiveSpecialPromptsIDs({ + addtags: prefs_init.add_tags, + get_calendar_event: getCalendarEvent, + get_task: getTask, + is_chatgpt_web: (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; From 173cbf8ad030b8f2c64564974c02289d149948ff Mon Sep 17 00:00:00 2001 From: Mic Date: Wed, 16 Apr 2025 23:59:00 +0200 Subject: [PATCH 039/127] added a few logs lines --- js/mzta-prompts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/mzta-prompts.js b/js/mzta-prompts.js index 29bdd311..9ee7a1fa 100644 --- a/js/mzta-prompts.js +++ b/js/mzta-prompts.js @@ -408,7 +408,7 @@ export async function getSpecialPrompts(){ updatedPrompts.push(newPrompt); } }); - + // console.log(">>>>>>>>>>>>> getSpecialPrompts updatedPrompts: " + JSON.stringify(updatedPrompts)); if (updatedPrompts.length !== prefs._special_prompts.length) { await browser.storage.local.set({ _special_prompts: updatedPrompts }); } From 8b7b0efc002d2c54a64b75473fafa107f8c17cf7 Mon Sep 17 00:00:00 2001 From: Mic Date: Thu, 17 Apr 2025 00:04:00 +0200 Subject: [PATCH 040/127] adding get_task feature. work in progress. see #333 --- popup/mzta-popup.js | 51 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/popup/mzta-popup.js b/popup/mzta-popup.js index 08e98b8d..d2256335 100644 --- a/popup/mzta-popup.js +++ b/popup/mzta-popup.js @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +import { prefs_default } from "../options/mzta-options-default.js"; import { taLogger } from "../js/mzta-logger.js"; import { checkSparksPresence } from "../js/mzta-utils.js"; @@ -24,11 +25,12 @@ let taLog = console; let connection_type = 'chatgpt_web'; let add_tags = false; let get_calendar_event = false; +let get_task = false; let tabType; let num_special_menu_items = 0; document.addEventListener('DOMContentLoaded', async () => { - 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'}); + let prefs = await browser.storage.sync.get({do_debug: prefs_default.do_debug, dynamic_menu_force_enter: prefs_default.dynamic_menu_force_enter, add_tags: prefs_default.add_tags, get_calendar_event: prefs_default.get_calendar_event, get_task: prefs_default.get_task, connection_type: prefs_default.connection_type}); taLog = new taLogger("mzta-popup",prefs.do_debug); i18n.updateDocument(); let reponse = await browser.runtime.sendMessage({command: "popup_menu_ready"}); @@ -44,6 +46,7 @@ document.addEventListener('DOMContentLoaded', async () => { connection_type = prefs.connection_type; add_tags = prefs.add_tags; get_calendar_event = prefs.get_calendar_event; + get_task = prefs.get_task; searchPrompt(active_prompts, tabId, tabType); i18n.updateDocument(); @@ -116,12 +119,13 @@ async function searchPrompt(allPrompts, tabId, tabType){ let do_add_tags = checkDoAddTags(); let do_get_calendar_event = checkDoCalendarEvent(); + let do_get_task = checkDoTask(); // console.log(">>>>>>>>>>> do_add_tags: " + do_add_tags); // console.log(">>>>>>>>>>> do_get_calendar_event: " + do_get_calendar_event); // console.log(">>>>>>>>>>> filteredData: " + JSON.stringify(filteredData)); - num_special_menu_items = (do_add_tags ? 1 : 0) + (do_get_calendar_event ? 1 : 0); + num_special_menu_items = (do_add_tags ? 1 : 0) + (do_get_calendar_event ? 1 : 0) + (do_get_task ? 1 : 0); // console.log(">>>>>>>>>>>> num_special_menu_items: " + num_special_menu_items); if(num_special_menu_items > 0){ max_num_el -= num_special_menu_items; @@ -143,16 +147,16 @@ async function searchPrompt(allPrompts, tabId, tabType){ filteredData[gce_curr_pos].label = gce_curr_pos + '. ' + filteredData[gce_curr_pos].label; } } + if(do_get_task){ + filteredData = ensurePromptGetTaskFirst(filteredData, do_add_tags, do_get_calendar_event); + let gtask_curr_pos = (do_add_tags ? 1 : 0) + (do_get_calendar_event ? 1 : 0); + if (!filteredData[gtask_curr_pos].numberPrepended) { + filteredData[gtask_curr_pos].numberPrepended = 'true'; + filteredData[gtask_curr_pos].label = gtask_curr_pos + '. ' + filteredData[gtask_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) => { let number = (index + first_num_el).toString(); // Check if the number is already prepended to avoid duplication @@ -170,7 +174,7 @@ async function searchPrompt(allPrompts, tabId, tabType){ itemDiv.classList.add('mzta_autocomplete-item'); itemDiv.textContent = item.label; itemDiv.setAttribute('data-id', item.id); - if((item.id === 'prompt_add_tags')||(item.id === 'prompt_get_calendar_event')){ + if((item.id === 'prompt_add_tags')||(item.id === 'prompt_get_calendar_event')||(item.id === 'prompt_get_task')){ itemDiv.className += ' special_prompt'; } @@ -336,6 +340,10 @@ function checkDoCalendarEvent(){ return get_calendar_event && (connection_type !== "chatgpt_web" && tabType !== 'messageCompose') && (checkSparksPresence() == 1); } +function checkDoTask(){ + return get_task && (connection_type !== "chatgpt_web" && tabType !== 'messageCompose') && (checkSparksPresence() == 1); +} + function ensurePromptAddTagsFirst(arr) { // Find the index of the object with id "prompt_add_tags" const index = arr.findIndex(item => item.id === "prompt_add_tags"); @@ -365,5 +373,24 @@ function ensurePromptGetCalendarEventFirst(arr, do_add_tags) { arr.splice(targetPosition, 0, promptAddTags); } + return arr; +} + +function ensurePromptGetTaskFirst(arr, do_add_tags, do_get_calendar_event) { + // Find the index of the object with id "prompt_get_task" + const index = arr.findIndex(item => item.id === "prompt_get_task"); + + // If found and needs repositioning + if (index !== -1 && ((do_get_calendar_event && do_add_tags) ? index !== 2 : (do_get_calendar_event ? index !== 1 : index !== 0))) { + // Remove it from its current position + const [promptGetTask] = arr.splice(index, 1); + + // Determine the target position to insert "prompt_get_task" after calendar + const targetPosition = do_add_tags && do_get_calendar_event ? 2 : (do_get_calendar_event ? 1 : 0); + + // Add it to the specified position + arr.splice(targetPosition, 0, promptGetTask); + } + return arr; } \ No newline at end of file From ac98621d0cfe4699995319d9918895af65d0899b Mon Sep 17 00:00:00 2001 From: Mic Date: Mon, 21 Apr 2025 23:56:00 +0200 Subject: [PATCH 041/127] Refactor get_task and get_calendar_event handling to improve clarity and consistency; update _ok_sparks logic for better state management. see #333 --- mzta-background.js | 14 ++++++++------ popup/mzta-popup.js | 27 ++++++++++++++++++--------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/mzta-background.js b/mzta-background.js index cd7238f7..deb9c72f 100644 --- a/mzta-background.js +++ b/mzta-background.js @@ -45,6 +45,7 @@ var original_html = ''; var modified_html = ''; let _process_incoming = false; +let _sparks_presence = false; let prefs_init = {}; await reload_pref_init(); @@ -54,8 +55,8 @@ taWorkingStatus.taLog = taLog; let special_prompts_ids = getActiveSpecialPromptsIDs({ addtags: prefs_init.add_tags, - get_calendar_event: await doGetSparkFeature(prefs_init.get_calendar_event), - get_task: await doGetSparkFeature(prefs_init.get_task), + get_calendar_event: doGetSparkFeature(prefs_init.get_calendar_event), + get_task: doGetSparkFeature(prefs_init.get_task), is_chatgpt_web: (prefs_init.connection_type === "chatgpt_web") }); @@ -151,7 +152,7 @@ function preparePopupMenu(tab) { } async function _reload_menus() { - let prefs_reload = await browser.storage.sync.get({add_tags: prefs_default.add_tags, get_calendar_event: prefs_default.get_calendar_event, connection_type: prefs_default.connection_type}); + let prefs_reload = await browser.storage.sync.get({add_tags: prefs_default.add_tags, get_calendar_event: prefs_default.get_calendar_event, get_task: prefs_default.get_task, connection_type: prefs_default.connection_type}); let getCalendarEvent = doGetSparkFeature(prefs_reload.get_calendar_event); let getTask = doGetSparkFeature(prefs_reload.get_task); const special_prompts_ids = getActiveSpecialPromptsIDs({ @@ -629,17 +630,18 @@ function checkScreenDimensions(prefs){ return prefs; } -async function doGetSparkFeature(spark_feature_active) { +function doGetSparkFeature(spark_feature_active) { if(spark_feature_active) { - return (await checkSparksPresence() == 1); + return (_sparks_presence == 1); } else { return false; } } async function reload_pref_init(){ - prefs_init = await browser.storage.sync.get({do_debug: prefs_default.do_debug, add_tags: prefs_default.add_tags, get_calendar_event: prefs_default.get_calendar_event, connection_type: prefs_default.connection_type, add_tags_auto: prefs_default.add_tags_auto, add_tags_auto_force_existing: prefs_default.add_tags_auto_force_existing, add_tags_auto_only_inbox: prefs_default.add_tags_auto_only_inbox, spamfilter: prefs_default.spamfilter, spamfilter_threshold: prefs_default.spamfilter_threshold, dynamic_menu_force_enter: prefs_default.dynamic_menu_force_enter, add_tags_context_menu: prefs_default.add_tags_context_menu, spamfilter_context_menu: prefs_default.spamfilter_context_menu}); + prefs_init = await browser.storage.sync.get({do_debug: prefs_default.do_debug, add_tags: prefs_default.add_tags, get_calendar_event: prefs_default.get_calendar_event, get_task: prefs_default.get_task, connection_type: prefs_default.connection_type, add_tags_auto: prefs_default.add_tags_auto, add_tags_auto_force_existing: prefs_default.add_tags_auto_force_existing, add_tags_auto_only_inbox: prefs_default.add_tags_auto_only_inbox, spamfilter: prefs_default.spamfilter, spamfilter_threshold: prefs_default.spamfilter_threshold, dynamic_menu_force_enter: prefs_default.dynamic_menu_force_enter, add_tags_context_menu: prefs_default.add_tags_context_menu, spamfilter_context_menu: prefs_default.spamfilter_context_menu}); _process_incoming = prefs_init.add_tags_auto || prefs_init.spamfilter; + _sparks_presence = await checkSparksPresence(); } diff --git a/popup/mzta-popup.js b/popup/mzta-popup.js index d2256335..f605bd23 100644 --- a/popup/mzta-popup.js +++ b/popup/mzta-popup.js @@ -26,6 +26,7 @@ let connection_type = 'chatgpt_web'; let add_tags = false; let get_calendar_event = false; let get_task = false; +let _ok_sparks = false; let tabType; let num_special_menu_items = 0; @@ -47,6 +48,11 @@ document.addEventListener('DOMContentLoaded', async () => { add_tags = prefs.add_tags; get_calendar_event = prefs.get_calendar_event; get_task = prefs.get_task; + _ok_sparks = await checkSparksPresence() == 1; + console.log(">>>>>>>>>>>>>>>>> add_tags: " + add_tags); + console.log(">>>>>>>>>>>>>>>>> get_calendar_event: " + get_calendar_event); + console.log(">>>>>>>>>>>>>>>>> get_task: " + get_task); + console.log(">>>>>>>>>>>>>>>>> _ok_sparks: " + _ok_sparks); searchPrompt(active_prompts, tabId, tabType); i18n.updateDocument(); @@ -121,17 +127,18 @@ async function searchPrompt(allPrompts, tabId, tabType){ let do_get_calendar_event = checkDoCalendarEvent(); let do_get_task = checkDoTask(); - // console.log(">>>>>>>>>>> do_add_tags: " + do_add_tags); - // console.log(">>>>>>>>>>> do_get_calendar_event: " + do_get_calendar_event); - // console.log(">>>>>>>>>>> filteredData: " + JSON.stringify(filteredData)); + console.log(">>>>>>>>>>> do_add_tags: " + do_add_tags); + console.log(">>>>>>>>>>> do_get_calendar_event: " + do_get_calendar_event); + console.log(">>>>>>>>>>> do_get_task: " + do_get_task); + console.log(">>>>>>>>>>> filteredData: " + JSON.stringify(filteredData)); - num_special_menu_items = (do_add_tags ? 1 : 0) + (do_get_calendar_event ? 1 : 0) + (do_get_task ? 1 : 0); - // console.log(">>>>>>>>>>>> num_special_menu_items: " + num_special_menu_items); + num_special_menu_items = (do_add_tags ? 1 : 0) + (do_get_calendar_event ? 1 : 0) + (do_get_task ? 1 : 0); + // 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); + 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) { @@ -157,6 +164,8 @@ async function searchPrompt(allPrompts, tabId, tabType){ } } + console.log(">>>>>>>>>>> filteredData after special items check: " + JSON.stringify(filteredData)); + Array.from(filteredData).slice(first_num_el, max_num_el).forEach((item, index) => { let number = (index + first_num_el).toString(); // Check if the number is already prepended to avoid duplication @@ -337,11 +346,11 @@ function checkDoAddTags(){ } function checkDoCalendarEvent(){ - return get_calendar_event && (connection_type !== "chatgpt_web" && tabType !== 'messageCompose') && (checkSparksPresence() == 1); + return get_calendar_event && (connection_type !== "chatgpt_web" && tabType !== 'messageCompose') && _ok_sparks; } function checkDoTask(){ - return get_task && (connection_type !== "chatgpt_web" && tabType !== 'messageCompose') && (checkSparksPresence() == 1); + return get_task && (connection_type !== "chatgpt_web" && tabType !== 'messageCompose') && _ok_sparks; } function ensurePromptAddTagsFirst(arr) { From fca3333d5fb74b167b2716e70bd8669c02c8c56a Mon Sep 17 00:00:00 2001 From: Mic Date: Tue, 22 Apr 2025 00:01:00 +0200 Subject: [PATCH 042/127] Update prompt_get_task_full_text message to clarify handling of date information and remove unnecessary date fields if absent. see #333 --- _locales/en/messages.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index af6e4e97..5d6eaf4c 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -1004,7 +1004,7 @@ "description": "" }, "prompt_get_task_full_text": { - "message": "Extract all relevant details required to generate a task from the following text. The extracted information should include:\n- Due Date and Time (including timezone, if specified)\n- Task summary\n- Initial Date and Time (including timezone, if specified)\nEnsure the data is formatted clearly and consistently so that it can be directly used for creating a task.\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 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\"InitialDate\": \"YYYYMMDDTHHMMSS\",\n\"dueDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Task summary here\"\n}\nHere's the text:\"{%selected_text%}\"", + "message": "Extract all relevant details required to generate a task from the following text. The extracted information should include:\n- Due Date and Time (including timezone, if specified)\n- Task summary\n- Initial Date and Time (including timezone, if specified)\nEnsure the data is formatted clearly and consistently so that it can be directly used for creating a task.\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 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\"InitialDate\": \"YYYYMMDDTHHMMSS\",\n\"dueDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Task summary here\"\n}\nIf there are no information about the dates, remove them.\nHere's the text:\"{%selected_text%}\"", "description": "" }, "prefs_OptionText_get_calendar_event": { From 775882de239b132c694bcb1aeed385cd1c2e6e62 Mon Sep 17 00:00:00 2001 From: Mic Date: Tue, 22 Apr 2025 00:01:00 +0200 Subject: [PATCH 043/127] Update error messages to reflect valid data checks and improve user feedback in task and calendar dialogs. see #333 --- _locales/en/messages.json | 4 ++-- js/mzta-menus.js | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 5d6eaf4c..4eb596ab 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -1111,8 +1111,8 @@ "message": "Error opening the task dialog", "description": "" }, - "sparks_not_installed": { - "message": "ThunderAI Sparks not installed!", + "no_valid_data_received": { + "message": "No valid data recevied from the AI.", "description": "" }, "prefs_OptionText_add_tags_auto": { diff --git a/js/mzta-menus.js b/js/mzta-menus.js index 6e81aa85..e93d0327 100644 --- a/js/mzta-menus.js +++ b/js/mzta-menus.js @@ -260,7 +260,7 @@ export class mzta_Menus { } }catch(err){ console.error("[ThunderAI] Error opening calendar event dialog: ", err); - browser.tabs.sendMessage(tabs[0].id, { command: "sendAlert", curr_tab_type: tabs[0].type, message: browser.i18n.getMessage("calendar_opening_dialog_error") + ": " + browser.i18n.getMessage("sparks_not_installed") }); + browser.tabs.sendMessage(tabs[0].id, { command: "sendAlert", curr_tab_type: tabs[0].type, message: browser.i18n.getMessage("calendar_opening_dialog_error") + ": " + browser.i18n.getMessage("no_valid_data_received") }); taWorkingStatus.stopWorking(); return {ok:'0'}; } @@ -296,6 +296,12 @@ export class mzta_Menus { let task_data_obj = {}; try{ task_data_obj = extractJsonObject(task_data); + if (!task_data_obj.dueDate || isNaN(Date.parse(task_data_obj.dueDate)) || task_data_obj.dueDate == '' ) { + delete task_data_obj.dueDate; + } + if (!task_data_obj.InitialDate || isNaN(Date.parse(task_data_obj.InitialDate)) || task_data_obj.InitialDate == '' ) { + delete task_data_obj.InitialDate; + } }catch(err){ console.error("[ThunderAI] Error extracting JSON object from task data: ", err.message); browser.tabs.sendMessage(tabs[0].id, { command: "sendAlert", curr_tab_type: tabs[0].type, message: browser.i18n.getMessage("task_getting_data_error") + ": " + err.message }); @@ -328,7 +334,7 @@ export class mzta_Menus { } }catch(err){ console.error("[ThunderAI] Error opening task dialog: ", err); - browser.tabs.sendMessage(tabs[0].id, { command: "sendAlert", curr_tab_type: tabs[0].type, message: browser.i18n.getMessage("task_opening_dialog_error") + ": " + browser.i18n.getMessage("sparks_not_installed") }); + browser.tabs.sendMessage(tabs[0].id, { command: "sendAlert", curr_tab_type: tabs[0].type, message: browser.i18n.getMessage("task_opening_dialog_error") + ": " + browser.i18n.getMessage("no_valid_data_received") }); taWorkingStatus.stopWorking(); return {ok:'0'}; } From ce3d39262809ca8b5b16eb1ff947f46d47a39bd1 Mon Sep 17 00:00:00 2001 From: Mic Date: Tue, 22 Apr 2025 00:16:00 +0200 Subject: [PATCH 044/127] adding options to manage accounts for autotagging. see #327 --- _locales/en/messages.json | 8 ++++++ js/mzta-utils.js | 11 ++++++++ options/mzta-options-default.js | 1 + pages/addtags/mzta-add-tags.css | 11 +++++++- pages/addtags/mzta-add-tags.html | 7 +++++ pages/addtags/mzta-add-tags.js | 44 +++++++++++++++++++++++++++++++- 6 files changed, 80 insertions(+), 2 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 4eb596ab..7cb9e10a 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -1350,5 +1350,13 @@ "ask_chatgptweb_permission_ok": { "message": "Permission granted. You can click here to close this tab and return to the main window.", "description": "" + }, + "AccountSelector_AutoTags": { + "message": "Choose the accounts where auto-tagging is enabled", + "description": "" + }, + "AccountSelector_AutoTags_infoline": { + "message": "Each change is saved immediately.", + "description": "" } } \ No newline at end of file diff --git a/js/mzta-utils.js b/js/mzta-utils.js index e4514a18..b16099a0 100644 --- a/js/mzta-utils.js +++ b/js/mzta-utils.js @@ -43,6 +43,17 @@ function fixMsgHeader(msgHeader) { return msgHeader; } +export async function getAccountsList() { + let accounts = await browser.accounts.list(); + let accounts_array = []; + for (let account of accounts) { + let account_id = account.id; + let account_name = account.name; + accounts_array.push({id: account_id, name: account_name}); + } + return accounts_array; +} + export async function getCurrentIdentity(msgHeader, getFull = false) { let identities_array = []; let fallback_identity = ''; diff --git a/options/mzta-options-default.js b/options/mzta-options-default.js index c4674218..409264dd 100644 --- a/options/mzta-options-default.js +++ b/options/mzta-options-default.js @@ -51,6 +51,7 @@ export const prefs_default = { add_tags_auto_force_existing: false, add_tags_auto_only_inbox: true, add_tags_context_menu: true, + add_tags_enabled_accounts: [], get_calendar_event: true, get_task: true, calendar_enforce_timezone: false, diff --git a/pages/addtags/mzta-add-tags.css b/pages/addtags/mzta-add-tags.css index 2899916f..729bb1b5 100644 --- a/pages/addtags/mzta-add-tags.css +++ b/pages/addtags/mzta-add-tags.css @@ -12,7 +12,7 @@ font-style: italic; } -#addtags_excl_list_container{ +#addtags_excl_list_container, #account_selector_container{ width: 90%; margin: 40px auto; } @@ -21,6 +21,15 @@ width: 30em; } +#account_selector_checkboxes{ + padding: 10px; + border: 1px solid gray; + width: 24em; + margin-bottom: 10px; + margin-top: 10px;; +} + + .btn_div{ width: 100%; display: flex; diff --git a/pages/addtags/mzta-add-tags.html b/pages/addtags/mzta-add-tags.html index 9067132c..8b75083b 100644 --- a/pages/addtags/mzta-add-tags.html +++ b/pages/addtags/mzta-add-tags.html @@ -106,6 +106,13 @@
+
+
__MSG_AccountSelector_AutoTags__ +
__MSG_AccountSelector_AutoTags_infoline__
+
+ + +
diff --git a/pages/addtags/mzta-add-tags.js b/pages/addtags/mzta-add-tags.js index ba24ca7d..2944f775 100644 --- a/pages/addtags/mzta-add-tags.js +++ b/pages/addtags/mzta-add-tags.js @@ -22,7 +22,7 @@ import { getSpecialPrompts, setSpecialPrompts } from "../../js/mzta-prompts.js"; import { getPlaceholders } from "../../js/mzta-placeholders.js"; import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js"; import { addTags_getExclusionList, addTags_setExclusionList } from "../../js/mzta-addatags-exclusion-list.js"; - +import { getAccountsList } from "../../js/mzta-utils.js"; let autocompleteSuggestions = []; let taLog = new taLogger("mzta-addtags-page",true); @@ -118,6 +118,48 @@ document.addEventListener('DOMContentLoaded', async () => { document.getElementById('excl_list_unsaved').classList.add('hidden'); }); + //Accounts manager + let accounts = await getAccountsList(); + const accountsContainer = document.getElementById('account_selector_checkboxes'); + accounts.forEach(account => { + const accountLabel = document.createElement('label'); + const accountCheckbox = document.createElement('input'); + accountCheckbox.type = 'checkbox'; + accountCheckbox.classList.add('accountCheckbox'); + accountCheckbox.value = account.id; + accountLabel.appendChild(accountCheckbox); + accountLabel.appendChild(document.createTextNode(account.name)); + accountsContainer.appendChild(accountLabel); + accountsContainer.appendChild(document.createElement('br')); + }); + + let prefs_add_tags = await browser.storage.sync.get({ add_tags_enabled_accounts: [] }); + let add_tags_enabled_accounts = prefs_add_tags.add_tags_enabled_accounts; + document.querySelectorAll('.accountCheckbox').forEach(checkbox => { + if (add_tags_enabled_accounts.length === 0 || add_tags_enabled_accounts.includes(checkbox.value)) { + checkbox.checked = true; + } else { + checkbox.checked = false; + } + }); + + document.querySelectorAll('.accountCheckbox').forEach(checkbox => { + checkbox.addEventListener('change', () => { + let selectedAccounts = Array.from(document.querySelectorAll('.accountCheckbox:checked')).map(checkbox => checkbox.value); + browser.storage.sync.set({ add_tags_enabled_accounts: selectedAccounts }); + }); + }); + + document.getElementById('accounts_select_all').addEventListener('click', () => { + let checkboxes = document.querySelectorAll('.accountCheckbox'); + checkboxes.forEach(checkbox => checkbox.checked = true); + }); + + document.getElementById('accounts_deselect_all').addEventListener('click', () => { + let checkboxes = document.querySelectorAll('.accountCheckbox'); + checkboxes.forEach(checkbox => checkbox.checked = false); + }); + }); From 93d30b6a02cc4f5a976eb9c945f41959cf0f5643 Mon Sep 17 00:00:00 2001 From: Mic Date: Tue, 22 Apr 2025 00:21:00 +0200 Subject: [PATCH 045/127] saving an empty array if all accounts are selected for improved efficiency. see #327 --- pages/addtags/mzta-add-tags.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pages/addtags/mzta-add-tags.js b/pages/addtags/mzta-add-tags.js index 2944f775..e1782f2a 100644 --- a/pages/addtags/mzta-add-tags.js +++ b/pages/addtags/mzta-add-tags.js @@ -145,8 +145,12 @@ document.addEventListener('DOMContentLoaded', async () => { document.querySelectorAll('.accountCheckbox').forEach(checkbox => { checkbox.addEventListener('change', () => { - let selectedAccounts = Array.from(document.querySelectorAll('.accountCheckbox:checked')).map(checkbox => checkbox.value); + let selectedAccounts = Array.from(document.querySelectorAll('.accountCheckbox:checked')).map(checkbox => checkbox.value); + if (selectedAccounts.length === document.querySelectorAll('.accountCheckbox').length) { + browser.storage.sync.set({ add_tags_enabled_accounts: [] }); + } else { browser.storage.sync.set({ add_tags_enabled_accounts: selectedAccounts }); + } }); }); From d7afad3b71ec7ba7fc3eb14ebd273e4673bc8528 Mon Sep 17 00:00:00 2001 From: Mic Date: Tue, 22 Apr 2025 00:21:00 +0200 Subject: [PATCH 046/127] Add account selection info for autotagging feature and update visibility logic. see #327 --- _locales/en/messages.json | 4 ++++ pages/addtags/mzta-add-tags.css | 4 ++++ pages/addtags/mzta-add-tags.html | 3 ++- pages/addtags/mzta-add-tags.js | 6 ++++++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 7cb9e10a..d048d10f 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -1123,6 +1123,10 @@ "message": "If checked, the AI will automatically add tags to newly received emails.", "description": "" }, + "prefs_OptionText_add_tags_auto_Info2": { + "message": "Choose which account to activate this feature for at the bottom of this page.", + "description": "" + }, "prefs_OptionText_add_tags_auto_force_existing": { "message": "Force existing tags when autotagging", "description": "" diff --git a/pages/addtags/mzta-add-tags.css b/pages/addtags/mzta-add-tags.css index 729bb1b5..527593e7 100644 --- a/pages/addtags/mzta-add-tags.css +++ b/pages/addtags/mzta-add-tags.css @@ -21,6 +21,10 @@ width: 30em; } +#account_selector_container{ + display: none; +} + #account_selector_checkboxes{ padding: 10px; border: 1px solid gray; diff --git a/pages/addtags/mzta-add-tags.html b/pages/addtags/mzta-add-tags.html index 8b75083b..3d5ca558 100644 --- a/pages/addtags/mzta-add-tags.html +++ b/pages/addtags/mzta-add-tags.html @@ -50,7 +50,8 @@ - __MSG_prefs_OptionText_add_tags_auto__ + __MSG_prefs_OptionText_add_tags_auto__ +
__MSG_prefs_OptionText_add_tags_auto_Info2__
- + __MSG_prefs_OptionText_add_tags_auto__
__MSG_prefs_OptionText_add_tags_auto_Info2__
@@ -59,7 +59,7 @@ - + __MSG_prefs_OptionText_add_tags_auto_force_existing__ - + __MSG_prefs_OptionText_add_tags_auto_only_inbox__