Merge branch 'v4.0.0' into main
This commit is contained in:
commit
fa10a68337
56 changed files with 6425 additions and 756 deletions
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
|
@ -36,7 +36,7 @@ body:
|
||||||
attributes:
|
attributes:
|
||||||
label: Which version of Thunderbird are you using?
|
label: Which version of Thunderbird are you using?
|
||||||
description: >
|
description: >
|
||||||
Thunderbird version like 115.14.0 or 128.1.
|
Thunderbird version like 140.0 or 147.0.1.
|
||||||
- type: input
|
- type: input
|
||||||
id: version
|
id: version
|
||||||
validations:
|
validations:
|
||||||
|
|
|
||||||
20
CHANGELOG.md
20
CHANGELOG.md
|
|
@ -4,6 +4,25 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2>Version 4.0.0 - ??/??/2026</h2>
|
||||||
|
<ul>
|
||||||
|
<li>ThunderAI is now compatible only with Thunderbird 140 and later [<a href="https://github.com/micz/ThunderAI/issues/616">#616</a>].</li>
|
||||||
|
<li><i>[All APIs]</i> It's now possibile to define a specific API integration for calendar and task recognition [<a href="https://github.com/micz/ThunderAI/issues/498">#498</a>].</li>
|
||||||
|
<li>Added a new model selector with a search functionality to dynamically filter the list [<a href="https://github.com/micz/ThunderAI/issues/603">#603</a>].</li>
|
||||||
|
<li><i>[All APIs]</i> Added a special prompt to summarize one or more emails, using a context menu command [<a href="https://github.com/micz/ThunderAI/issues/615">#615</a>]. Thanks to <a href="https://github.com/gdkrmr">Guido Kraemer</a> for his great work on this feature.</li>
|
||||||
|
<li><i>[All APIs]</i> "Analyze for spam" and "Add tags" context menu items are always shown when the corresponding feature is enabled [<a href="https://github.com/micz/ThunderAI/issues/609">#609</a>].</li>
|
||||||
|
<li><i>[OpenAI Comp API][Ollama API]</i> Asking for the single host for permission to avoid CORS errors, instead of <i>all_urls</i>, as requested by the Thunderbird Review Team [<a href="https://github.com/micz/ThunderAI/issues/524">#524</a>].</li>
|
||||||
|
<li>Fix: Using also the mail folder owner to search for the right identity to use when composing a reply [<a href="https://github.com/micz/ThunderAI/issues/627">#627</a>].</li>
|
||||||
|
<li>Context menu items are always ordered alfabetically [<a href="https://github.com/micz/ThunderAI/issues/630">#630</a>].</li>
|
||||||
|
<li>The prompt export now includes an option to incorporate specific API settings, when present [<a href="https://github.com/micz/ThunderAI/issues/624">#624</a>].</li>
|
||||||
|
<li>Added the <i>{%mail_text_body_or_selected%}</i> placeholder to retrieve the selected text or the full text body of the email if no selection is present [<a href="https://github.com/micz/ThunderAI/issues/641">#641</a>].</li>
|
||||||
|
<li>Added the <i>{%mail_html_body_or_selected%}</i> placeholder to retrieve the selected HTML or the full HTML body of the email if no selection is present [<a href="https://github.com/micz/ThunderAI/issues/641">#641</a>].</li>
|
||||||
|
<li><i>[All APIs]</i> Added an option to get a calendar event without selecting some text, but using the full text body of the email [<a href="https://github.com/micz/ThunderAI/issues/518">#518</a>].</li>
|
||||||
|
<li><i>[All APIs]</i> Added a new menu item to create a calendar event from the text saved in the clipboard [<a href="https://github.com/micz/ThunderAI/issues/362">#362</a>].</li>
|
||||||
|
<li>Added a button to copy a prompt in the Custom Prompts page [<a href="https://github.com/micz/ThunderAI/issues/598">#598</a>].</li>
|
||||||
|
<li><i>[All APIs]</i> Showing the spam filter info at the top of the message. The data is saved only for the session in which the message has been checked for spam [<a href="https://github.com/micz/ThunderAI/issues/506">#506</a>].</li>
|
||||||
|
<li>...</li>
|
||||||
|
</ul>
|
||||||
<h2>Version 3.8.4 - 10/02/2026</h2>
|
<h2>Version 3.8.4 - 10/02/2026</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li><i>[ChatGPT Web]</i> Fix: Correctly importing the selected text into the compose windows also when ChatGPT shows the advanced mail editor in the response [<a href="https://github.com/micz/ThunderAI/issues/646">#646</a>].</li>
|
<li><i>[ChatGPT Web]</i> Fix: Correctly importing the selected text into the compose windows also when ChatGPT shows the advanced mail editor in the response [<a href="https://github.com/micz/ThunderAI/issues/646">#646</a>].</li>
|
||||||
|
|
@ -79,6 +98,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li><i>[All APIs]</i> It's now possibile to define a list of tags to be used when autotagging received emails [<a href="https://github.com/micz/ThunderAI/issues/436">#436</a>]. The tags are are now shown in the information header in the AI API chat [<a href="https://github.com/micz/ThunderAI/issues/289">#289</a>].</li>
|
<li><i>[All APIs]</i> It's now possibile to define a list of tags to be used when autotagging received emails [<a href="https://github.com/micz/ThunderAI/issues/436">#436</a>]. The tags are are now shown in the information header in the AI API chat [<a href="https://github.com/micz/ThunderAI/issues/289">#289</a>].</li>
|
||||||
<li><i>[All APIs]</i> The prompt id and name are now shown in the information header in the AI API chat [<a href="https://github.com/micz/ThunderAI/issues/436">#436</a>].</li>
|
<li><i>[All APIs]</i> The prompt id and name are now shown in the information header in the AI API chat [<a href="https://github.com/micz/ThunderAI/issues/436">#436</a>].</li>
|
||||||
|
<li><i>[All APIs]</i> It's now possibile to define a specific API integration for spamfilter and auto tagging [<a href="https://github.com/micz/ThunderAI/issues/438">#438</a>].</li>
|
||||||
<li>Added the <i>{%mail_attachments_info%}</i> placeholder to retrieve the name, type and file size of the mail attachments [<a href="https://github.com/micz/ThunderAI/issues/446">#446</a>].</li>
|
<li>Added the <i>{%mail_attachments_info%}</i> placeholder to retrieve the name, type and file size of the mail attachments [<a href="https://github.com/micz/ThunderAI/issues/446">#446</a>].</li>
|
||||||
<li><i>[Google Gemini API]</i> Support for the thinkingBudget parameter has been added [<a href="https://github.com/micz/ThunderAI/issues/494">#494</a>].</li>
|
<li><i>[Google Gemini API]</i> Support for the thinkingBudget parameter has been added [<a href="https://github.com/micz/ThunderAI/issues/494">#494</a>].</li>
|
||||||
<li><i>[OpenAI Comp API]</i> Added DeepSeek configuration [<a href="https://github.com/micz/ThunderAI/issues/486">#486</a>].</li>
|
<li><i>[OpenAI Comp API]</i> Added DeepSeek configuration [<a href="https://github.com/micz/ThunderAI/issues/486">#486</a>].</li>
|
||||||
|
|
|
||||||
39
GEMINI.md
Normal file
39
GEMINI.md
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
# ThunderAI Project Agent Context
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
ThunderAI is a Mozilla Thunderbird add-on that integrates Large Language Models (LLMs) such as ChatGPT, Gemini, Claude, and Ollama for advanced email management. It allows users to analyze, draft, correct, tag, and create calendar events directly from the email client.
|
||||||
|
|
||||||
|
## Technical Stack
|
||||||
|
- **Languages:** JavaScript (ES6+), HTML5, CSS3.
|
||||||
|
- **Environment:** Thunderbird MailExtension API (based on WebExtensions).
|
||||||
|
- **Core Logic:** Primarily located in `background.js` and UI-specific scripts.
|
||||||
|
- **API Integrations:** Specific logic is contained within dedicated API provider files (e.g., `api_openai.js`, `api_google_gemini.js`).
|
||||||
|
|
||||||
|
## Development Rules & Style Guide
|
||||||
|
- **Code Style:** Use modern JavaScript. Prefer `async/await` over chained Promises.
|
||||||
|
- **Naming Conventions:** Use `camelCase` for variables and functions.
|
||||||
|
- **Security:** - Never hardcode API keys in the source code.
|
||||||
|
- Use `messenger.storage.local` for data persistence.
|
||||||
|
- Strictly adhere to CORS policies for external API calls.
|
||||||
|
- **i18n:**
|
||||||
|
- The project supports multiple languages via `_locales/`. When adding UI strings, always use `messenger.i18n.getMessage()`.
|
||||||
|
- When you need to modify language file, modify only the english version.
|
||||||
|
- **Logging:**
|
||||||
|
- When possibile use the taLog object to log errors, otherwise use the console.error(<msg>) method.
|
||||||
|
- If it's useful to log add debug logs using taLog.log(<msg>) method.
|
||||||
|
|
||||||
|
## Files & Directories Structure
|
||||||
|
- `manifest.json`: Extension entry point and permission definitions.
|
||||||
|
- `api_*.js`: Modules for integration with different AI providers.
|
||||||
|
- `options/`: Configuration and settings pages.
|
||||||
|
- `_locales/`: Translation files (JSON format).
|
||||||
|
- `graphics/`: Visual assets and icons.
|
||||||
|
|
||||||
|
## Important Commands & Workflow
|
||||||
|
- **Testing:** Since this is a Thunderbird add-on, testing is performed by loading the extension as a "Temporary Add-on" via Thunderbird's `Debug Add-ons` menu.
|
||||||
|
- **Build:** The project does not use complex build tools (no Webpack/Vite by default); it is a "pure" MailExtension.
|
||||||
|
|
||||||
|
## Agent Instructions
|
||||||
|
1. **Context Awareness:** When modifying API-related files, ensure compatibility with the existing placeholder system (e.g., `{%mail_body%}`, `{%additional_text%}`).
|
||||||
|
2. **Permission Review:** Before modifying `manifest.json`, verify that any new permissions requested are strictly necessary for the feature.
|
||||||
|
3. **Compatibility:** Ensure code is compatible with the latest Thunderbird ESR (Extended Support Release) versions.
|
||||||
|
|
@ -117,6 +117,7 @@ _The language status represents the percentage of translated strings in the late
|
||||||
- [JessiGue](https://www.flaticon.com/authors/jessigue) for the show/hide icon for api key fields
|
- [JessiGue](https://www.flaticon.com/authors/jessigue) for the show/hide icon for api key fields
|
||||||
- [Iconka.com](https://www.iconarchive.com/artist/iconka.html) for the autotag context menu icon
|
- [Iconka.com](https://www.iconarchive.com/artist/iconka.html) for the autotag context menu icon
|
||||||
- [Icojam](https://www.iconarchive.com/artist/icojam.html) for the spam filter context menu icon
|
- [Icojam](https://www.iconarchive.com/artist/icojam.html) for the spam filter context menu icon
|
||||||
|
- [Roundicons](https://www.flaticon.com/authors/roundicons) for the summarize context menu icon
|
||||||
|
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
file: pages\_lib\list.js
|
file: pages\_lib\list.js
|
||||||
source: https://raw.githubusercontent.com/javve/list.js/v2.3.1/dist/list.js
|
source: https://raw.githubusercontent.com/javve/list.js/v2.3.1/dist/list.js
|
||||||
|
|
||||||
|
file: pages\_lib\tom-select.base.js
|
||||||
|
source: https://cdn.jsdelivr.net/npm/tom-select@2.4.6/dist/js/tom-select.base.js
|
||||||
|
|
||||||
file: js\lib\diff.js
|
file: js\lib\diff.js
|
||||||
source: https://cdnjs.cloudflare.com/ajax/libs/jsdiff/7.0.0/diff.js
|
source: https://cdnjs.cloudflare.com/ajax/libs/jsdiff/7.0.0/diff.js
|
||||||
|
|
@ -296,9 +296,6 @@
|
||||||
"chatgpt_empty_model": {
|
"chatgpt_empty_model": {
|
||||||
"message": "Nevybrali jste model pro ChatGPT API. Vyberte jej prosím na stránce s možnostmi."
|
"message": "Nevybrali jste model pro ChatGPT API. Vyberte jej prosím na stránce s možnostmi."
|
||||||
},
|
},
|
||||||
"chagpt_api_connecting": {
|
|
||||||
"message": "Pokouším se připojit k OpenAI ChatGPT pomocí poskytnutého klíče API"
|
|
||||||
},
|
|
||||||
"chagpt_api_send_button": {
|
"chagpt_api_send_button": {
|
||||||
"message": "Používám model"
|
"message": "Používám model"
|
||||||
},
|
},
|
||||||
|
|
@ -335,12 +332,6 @@
|
||||||
"ollama_empty_model": {
|
"ollama_empty_model": {
|
||||||
"message": "Nevybrali jste model pro Ollama API. Prosím, vyberte jej na stránce s nastavením."
|
"message": "Nevybrali jste model pro Ollama API. Prosím, vyberte jej na stránce s nastavením."
|
||||||
},
|
},
|
||||||
"ollama_api_connecting": {
|
|
||||||
"message": "Pokouším se připojit k lokálnímu serveru Ollama pomocí hostitele"
|
|
||||||
},
|
|
||||||
"andModel": {
|
|
||||||
"message": "a model"
|
|
||||||
},
|
|
||||||
"error_connection_interrupted": {
|
"error_connection_interrupted": {
|
||||||
"message": "Spojení se serverem bylo neočekávaně přerušeno"
|
"message": "Spojení se serverem bylo neočekávaně přerušeno"
|
||||||
},
|
},
|
||||||
|
|
@ -368,9 +359,6 @@
|
||||||
"OpenAIComp_empty_model": {
|
"OpenAIComp_empty_model": {
|
||||||
"message": "Nevybrali jste model pro API kompatibilní s OpenAI. Prosím, vyberte jej na stránce s nastavením."
|
"message": "Nevybrali jste model pro API kompatibilní s OpenAI. Prosím, vyberte jej na stránce s nastavením."
|
||||||
},
|
},
|
||||||
"OpenAIComp_api_connecting": {
|
|
||||||
"message": "Pokouším se připojit k lokálnímu serveru API kompatibilního s OpenAI pomocí hostitele"
|
|
||||||
},
|
|
||||||
"OpenAIComp_api_request_failed": {
|
"OpenAIComp_api_request_failed": {
|
||||||
"message": "Požadavek na OpenAI Comp API selhal"
|
"message": "Požadavek na OpenAI Comp API selhal"
|
||||||
},
|
},
|
||||||
|
|
@ -479,7 +467,7 @@
|
||||||
"Spam_Value": {
|
"Spam_Value": {
|
||||||
"message": "Hodnota spamu"
|
"message": "Hodnota spamu"
|
||||||
},
|
},
|
||||||
"spamfilter_not_moved": {
|
"no_string": {
|
||||||
"message": "Ne"
|
"message": "Ne"
|
||||||
},
|
},
|
||||||
"prefsInfoDesc_4": {
|
"prefsInfoDesc_4": {
|
||||||
|
|
@ -539,7 +527,7 @@
|
||||||
"Date": {
|
"Date": {
|
||||||
"message": "Datum"
|
"message": "Datum"
|
||||||
},
|
},
|
||||||
"spamfilter_moved": {
|
"yes_string": {
|
||||||
"message": "Ano"
|
"message": "Ano"
|
||||||
},
|
},
|
||||||
"Report_Date": {
|
"Report_Date": {
|
||||||
|
|
@ -590,9 +578,6 @@
|
||||||
"GoogleGemini_Models_Fetch": {
|
"GoogleGemini_Models_Fetch": {
|
||||||
"message": "Aktualizovat seznam modelů Google Gemini"
|
"message": "Aktualizovat seznam modelů Google Gemini"
|
||||||
},
|
},
|
||||||
"google_gemini_api_connecting": {
|
|
||||||
"message": "Probíhá pokus o připojení ke Google Gemini pomocí zadaného API klíče"
|
|
||||||
},
|
|
||||||
"google_gemini_empty_apikey": {
|
"google_gemini_empty_apikey": {
|
||||||
"message": "Nezadali jste API klíč pro Google Gemini API. Vložte jej na stránce možností."
|
"message": "Nezadali jste API klíč pro Google Gemini API. Vložte jej na stránce možností."
|
||||||
},
|
},
|
||||||
|
|
@ -810,7 +795,7 @@
|
||||||
"message": "Spravovat nastavení štítků"
|
"message": "Spravovat nastavení štítků"
|
||||||
},
|
},
|
||||||
"prompt_get_calendar_event_full_text": {
|
"prompt_get_calendar_event_full_text": {
|
||||||
"message": "Z následujícího textu extrahuj všechny relevantní podrobnosti potřebné k vygenerování události kalendáře. Extrahované informace by měly zahrnovat:\n- Název události\n- Datum a čas zahájení (včetně časového pásma, pokud je uvedeno)\n- Datum a čas ukončení (včetně časového pásma, pokud je uvedeno)\n- Celý den (pokud je zmíněn)\n- Účastníci\nZajisti, aby byla data formátována jasně a konzistentně, aby je bylo možné přímo použít k vytvoření události kalendáře.\nPokud existují relativní časové odkazy, vezmi v úvahu, že datum a čas e-mailu jsou \"{%mail_datetime%}\". Vypočítej datum a čas zahájení na základě tohoto odkazu. Pokud jsou vypočítané datum a čas zahájení dřívější než \"{%current_datetime%}\", přepočti datum a čas zahájení pomocí \"{%current_datetime%}\" jako základu.\nPokud není zadána doba trvání, nastav ji na jednu hodinu.\nToto jsou účastníci: {%author%}, {%recipients%}, {%cc_list%}. Pokud je přítomna, nezahrnuj mou adresu: {%account_email_address%}.\nPokud nejsi schopen získat jednu nebo více požadovaných informací, odpověz prázdným řetězcem.\nVygeneruj odpověď pouze ve formátu JSON. Nezahrnuj žádný další text ani vysvětlení; poskytni pouze JSON. Zde je formát, který se má použít:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Zde je souhrn události kalendáře\",\n\"forceAllDay\": false,\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nZde je text:\"{%selected_text%}\""
|
"message": "Z následujícího textu extrahuj všechny relevantní podrobnosti potřebné k vygenerování události kalendáře. Extrahované informace by měly zahrnovat:\n- Název události\n- Datum a čas zahájení (včetně časového pásma, pokud je uvedeno)\n- Datum a čas ukončení (včetně časového pásma, pokud je uvedeno)\n- Celý den (pokud je zmíněn)\n- Účastníci\nZajisti, aby byla data formátována jasně a konzistentně, aby je bylo možné přímo použít k vytvoření události kalendáře.\nPokud existují relativní časové odkazy, vezmi v úvahu, že datum a čas e-mailu jsou \"{%mail_datetime%}\". Vypočítej datum a čas zahájení na základě tohoto odkazu. Pokud jsou vypočítané datum a čas zahájení dřívější než \"{%current_datetime%}\", přepočti datum a čas zahájení pomocí \"{%current_datetime%}\" jako základu.\nPokud není zadána doba trvání, nastav ji na jednu hodinu.\nToto jsou účastníci: {%author%}, {%recipients%}, {%cc_list%}. Pokud je přítomna, nezahrnuj mou adresu: {%account_email_address%}.\nPokud nejsi schopen získat jednu nebo více požadovaných informací, odpověz prázdným řetězcem.\nVygeneruj odpověď pouze ve formátu JSON. Nezahrnuj žádný další text ani vysvětlení; poskytni pouze JSON. Zde je formát, který se má použít:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Zde je souhrn události kalendáře\",\n\"forceAllDay\": false,\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nZde je text:\"{%mail_text_body_or_selected%}\""
|
||||||
},
|
},
|
||||||
"prefs_OptionText_get_calendar_event": {
|
"prefs_OptionText_get_calendar_event": {
|
||||||
"message": "Přidat novou událost do kalendáře z vybraného textu"
|
"message": "Přidat novou událost do kalendáře z vybraného textu"
|
||||||
|
|
@ -848,9 +833,6 @@
|
||||||
"calendar_opening_dialog_error": {
|
"calendar_opening_dialog_error": {
|
||||||
"message": "Chyba při otevírání dialogu události kalendáře"
|
"message": "Chyba při otevírání dialogu události kalendáře"
|
||||||
},
|
},
|
||||||
"sparks_not_installed": {
|
|
||||||
"message": "ThunderAI Sparks není nainstalován!"
|
|
||||||
},
|
|
||||||
"prefs_OptionText_add_tags_auto": {
|
"prefs_OptionText_add_tags_auto": {
|
||||||
"message": "Přidávat štítky automaticky"
|
"message": "Přidávat štítky automaticky"
|
||||||
},
|
},
|
||||||
|
|
@ -869,18 +851,6 @@
|
||||||
"context_menu_mzta-spamfilter": {
|
"context_menu_mzta-spamfilter": {
|
||||||
"message": "Analýza spamu"
|
"message": "Analýza spamu"
|
||||||
},
|
},
|
||||||
"prefs_OptionText_add_tags_context_menu": {
|
|
||||||
"message": "Zobrazit v nabídce položku „Přidat štítky“"
|
|
||||||
},
|
|
||||||
"prefs_OptionText_spamfilter_context_menu": {
|
|
||||||
"message": "Zobrazit v nabídce položku „Analýza spamu“"
|
|
||||||
},
|
|
||||||
"prefs_OptionText_spamfilter_context_menu_Info": {
|
|
||||||
"message": "Po zaškrtnutí bude po kliknutí pravým tlačítkem na e-mail v seznamu zpráv v kontextové nabídce zobrazena položka „Analýza spamu“."
|
|
||||||
},
|
|
||||||
"prefs_OptionText_add_tags_context_menu_Info": {
|
|
||||||
"message": "Po zaškrtnutí bude po kliknutí pravým tlačítkem na e-mail v seznamu zpráv v kontextové nabídce zobrazena položka „Přidat štítky“."
|
|
||||||
},
|
|
||||||
"get_calendar_event_prompt_prefs_title": {
|
"get_calendar_event_prompt_prefs_title": {
|
||||||
"message": "Možnosti události kalendáře"
|
"message": "Možnosti události kalendáře"
|
||||||
},
|
},
|
||||||
|
|
@ -1125,12 +1095,6 @@
|
||||||
"CORS_alternative_1": {
|
"CORS_alternative_1": {
|
||||||
"message": "Problémy s nastavením CORS?"
|
"message": "Problémy s nastavením CORS?"
|
||||||
},
|
},
|
||||||
"CORS_alternative_2": {
|
|
||||||
"message": "Stiskněte tlačítko níže a udělte oprávnění <all_urls>, abyste se vyhnuli jakýmkoli problémům s CORS."
|
|
||||||
},
|
|
||||||
"CORS_give_allurls_perm": {
|
|
||||||
"message": "Udělit oprávnění \"všechny URL\""
|
|
||||||
},
|
|
||||||
"maybe_CORS_openai_comp": {
|
"maybe_CORS_openai_comp": {
|
||||||
"message": "Používání API kompatibilního s OpenAI může vyžadovat nastavení CORS na serveru."
|
"message": "Používání API kompatibilního s OpenAI může vyžadovat nastavení CORS na serveru."
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -327,9 +327,6 @@
|
||||||
"chagpt_api_send_button": {
|
"chagpt_api_send_button": {
|
||||||
"message": "Modell wird verwendet"
|
"message": "Modell wird verwendet"
|
||||||
},
|
},
|
||||||
"chagpt_api_connecting": {
|
|
||||||
"message": "Versuch, eine Verbindung zu OpenAI ChatGPT mit dem bereitgestellten API-Schlüssel herzustellen"
|
|
||||||
},
|
|
||||||
"Debug": {
|
"Debug": {
|
||||||
"message": "Debuggen"
|
"message": "Debuggen"
|
||||||
},
|
},
|
||||||
|
|
@ -363,12 +360,6 @@
|
||||||
"ollama_empty_model": {
|
"ollama_empty_model": {
|
||||||
"message": "Sie haben kein Modell für die Ollama API ausgewählt. Bitte wählen Sie eines auf der Optionsseite aus."
|
"message": "Sie haben kein Modell für die Ollama API ausgewählt. Bitte wählen Sie eines auf der Optionsseite aus."
|
||||||
},
|
},
|
||||||
"ollama_api_connecting": {
|
|
||||||
"message": "Versuch, eine Verbindung zum Ollama-Lokalserver über den Host herzustellen"
|
|
||||||
},
|
|
||||||
"andModel": {
|
|
||||||
"message": "und Modell"
|
|
||||||
},
|
|
||||||
"error_connection_interrupted": {
|
"error_connection_interrupted": {
|
||||||
"message": "Die Verbindung zum Server wurde unerwartet unterbrochen"
|
"message": "Die Verbindung zum Server wurde unerwartet unterbrochen"
|
||||||
},
|
},
|
||||||
|
|
@ -399,9 +390,6 @@
|
||||||
"OpenAIComp_empty_model": {
|
"OpenAIComp_empty_model": {
|
||||||
"message": "Sie haben kein Modell für die OpenAI-kompatible API ausgewählt. Bitte wählen Sie eines auf der Optionsseite aus."
|
"message": "Sie haben kein Modell für die OpenAI-kompatible API ausgewählt. Bitte wählen Sie eines auf der Optionsseite aus."
|
||||||
},
|
},
|
||||||
"OpenAIComp_api_connecting": {
|
|
||||||
"message": "Versuche, eine Verbindung zum OpenAI-kompatiblen lokalen API-Server über den Host herzustellen"
|
|
||||||
},
|
|
||||||
"OpenAIComp_api_request_failed": {
|
"OpenAIComp_api_request_failed": {
|
||||||
"message": "OpenAI-kompatible API-Anfrage fehlgeschlagen"
|
"message": "OpenAI-kompatible API-Anfrage fehlgeschlagen"
|
||||||
},
|
},
|
||||||
|
|
@ -681,9 +669,6 @@
|
||||||
"google_gemini_api_request_failed": {
|
"google_gemini_api_request_failed": {
|
||||||
"message": "Google Gemini API-Anfrage fehlgeschlagen"
|
"message": "Google Gemini API-Anfrage fehlgeschlagen"
|
||||||
},
|
},
|
||||||
"google_gemini_api_connecting": {
|
|
||||||
"message": "Versuch, eine Verbindung zu Google Gemini mit dem bereitgestellten API-Schlüssel herzustellen"
|
|
||||||
},
|
|
||||||
"google_gemini_empty_apikey": {
|
"google_gemini_empty_apikey": {
|
||||||
"message": "Sie haben keinen API-Schlüssel für die Google Gemini API hinzugefügt. Bitte fügen Sie einen auf der Optionsseite ein."
|
"message": "Sie haben keinen API-Schlüssel für die Google Gemini API hinzugefügt. Bitte fügen Sie einen auf der Optionsseite ein."
|
||||||
},
|
},
|
||||||
|
|
@ -712,7 +697,7 @@
|
||||||
"message": "Ein neues Kalenderevent hinzufügen"
|
"message": "Ein neues Kalenderevent hinzufügen"
|
||||||
},
|
},
|
||||||
"prompt_get_calendar_event_full_text": {
|
"prompt_get_calendar_event_full_text": {
|
||||||
"message": "Extrahieren Sie alle relevanten Details, die erforderlich sind, um ein Kalenderevent aus dem folgenden Text zu erstellen. Die extrahierten Informationen sollten Folgendes enthalten:\n- Ereignistitel\n- Startdatum und -uhrzeit (einschließlich Zeitzone, falls angegeben)\n- Enddatum und -uhrzeit (einschließlich Zeitzone, falls angegeben)\n- Ganztägig (falls erwähnt)\n- Teilnehmer\nStellen Sie sicher, dass die Daten klar und konsistent formatiert sind, sodass sie direkt für die Erstellung eines Kalenderevents verwendet werden können.\nFalls relative Zeitangaben enthalten sind, beachten Sie, dass Datum und Uhrzeit der E-Mail \"{%mail_datetime%}\" sind. Berechnen Sie das Startdatum und die Startzeit basierend auf diesem Bezugspunkt. Falls das berechnete Startdatum und die Startzeit vor \"{%current_datetime%}\" liegen, berechnen Sie Startdatum und -zeit erneut, wobei Sie \"{%current_datetime%}\" als Grundlage verwenden.\nFalls keine Dauer angegeben ist, setzen Sie sie auf eine Stunde.\nDas sind die Teilnehmer: {%author%}, {%recipients%}, {%cc_list%}. Falls vorhanden, meine Adresse ausschließen: {%account_email_address%}.\nFalls Sie eine oder mehrere der erforderlichen Informationen nicht erhalten können, antworten Sie mit einem leeren String.\nErstellen Sie eine Antwort ausschließlich im JSON-Format. Fügen Sie keinen zusätzlichen Text oder Erklärungen hinzu; geben Sie nur das JSON an. Verwenden Sie folgendes Format:\n{\n \"startDate\": \"YYYYMMDDTHHMMSS\",\n \"endDate\": \"YYYYMMDDTHHMMSS\",\n \"summary\": \"Zusammenfassung des Kalenderevents hier\",\n \"forceAllDay\": false\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nHier ist der Text: \"{%selected_text%}\""
|
"message": "Extrahieren Sie alle relevanten Details, die erforderlich sind, um ein Kalenderevent aus dem folgenden Text zu erstellen. Die extrahierten Informationen sollten Folgendes enthalten:\n- Ereignistitel\n- Startdatum und -uhrzeit (einschließlich Zeitzone, falls angegeben)\n- Enddatum und -uhrzeit (einschließlich Zeitzone, falls angegeben)\n- Ganztägig (falls erwähnt)\n- Teilnehmer\nStellen Sie sicher, dass die Daten klar und konsistent formatiert sind, sodass sie direkt für die Erstellung eines Kalenderevents verwendet werden können.\nFalls relative Zeitangaben enthalten sind, beachten Sie, dass Datum und Uhrzeit der E-Mail \"{%mail_datetime%}\" sind. Berechnen Sie das Startdatum und die Startzeit basierend auf diesem Bezugspunkt. Falls das berechnete Startdatum und die Startzeit vor \"{%current_datetime%}\" liegen, berechnen Sie Startdatum und -zeit erneut, wobei Sie \"{%current_datetime%}\" als Grundlage verwenden.\nFalls keine Dauer angegeben ist, setzen Sie sie auf eine Stunde.\nDas sind die Teilnehmer: {%author%}, {%recipients%}, {%cc_list%}. Falls vorhanden, meine Adresse ausschließen: {%account_email_address%}.\nFalls Sie eine oder mehrere der erforderlichen Informationen nicht erhalten können, antworten Sie mit einem leeren String.\nErstellen Sie eine Antwort ausschließlich im JSON-Format. Fügen Sie keinen zusätzlichen Text oder Erklärungen hinzu; geben Sie nur das JSON an. Verwenden Sie folgendes Format:\n{\n \"startDate\": \"YYYYMMDDTHHMMSS\",\n \"endDate\": \"YYYYMMDDTHHMMSS\",\n \"summary\": \"Zusammenfassung des Kalenderevents hier\",\n \"forceAllDay\": false\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nHier ist der Text: \"{%mail_text_body_or_selected%}\""
|
||||||
},
|
},
|
||||||
"prefs_OptionText_get_calendar_event": {
|
"prefs_OptionText_get_calendar_event": {
|
||||||
"message": "Ein neues Kalenderevent aus ausgewähltem Text hinzufügen"
|
"message": "Ein neues Kalenderevent aus ausgewähltem Text hinzufügen"
|
||||||
|
|
@ -825,18 +810,15 @@
|
||||||
"Report_Date": {
|
"Report_Date": {
|
||||||
"message": "Berichtsdatum"
|
"message": "Berichtsdatum"
|
||||||
},
|
},
|
||||||
"spamfilter_moved": {
|
"yes_string": {
|
||||||
"message": "Ja"
|
"message": "Ja"
|
||||||
},
|
},
|
||||||
"spamfilter_not_moved": {
|
"no_string": {
|
||||||
"message": "Nein"
|
"message": "Nein"
|
||||||
},
|
},
|
||||||
"spamfilter_threshold_too_low": {
|
"spamfilter_threshold_too_low": {
|
||||||
"message": "Der Spam-Schwellenwert ist zu niedrig! Sie werden wahrscheinlich zu viele E-Mails als Spam markieren!"
|
"message": "Der Spam-Schwellenwert ist zu niedrig! Sie werden wahrscheinlich zu viele E-Mails als Spam markieren!"
|
||||||
},
|
},
|
||||||
"sparks_not_installed": {
|
|
||||||
"message": "ThunderAI Sparks nicht installiert!"
|
|
||||||
},
|
|
||||||
"prefs_OptionText_add_tags_auto_force_existing_Info": {
|
"prefs_OptionText_add_tags_auto_force_existing_Info": {
|
||||||
"message": "Wenn aktiviert, fügt die KI nur vorhandene Tags hinzu und erstellt keine neuen Tags."
|
"message": "Wenn aktiviert, fügt die KI nur vorhandene Tags hinzu und erstellt keine neuen Tags."
|
||||||
},
|
},
|
||||||
|
|
@ -855,12 +837,6 @@
|
||||||
"prefs_OptionText_openai_comp_info_remote": {
|
"prefs_OptionText_openai_comp_info_remote": {
|
||||||
"message": "Hier können Sie auch die Adresse eines entfernten Servers eingeben."
|
"message": "Hier können Sie auch die Adresse eines entfernten Servers eingeben."
|
||||||
},
|
},
|
||||||
"prefs_OptionText_add_tags_context_menu_Info": {
|
|
||||||
"message": "Wenn aktiviert, wird beim Rechtsklick auf eine E-Mail in der Nachrichtenliste der Eintrag \"Tags hinzufügen\" angezeigt."
|
|
||||||
},
|
|
||||||
"prefs_OptionText_spamfilter_context_menu_Info": {
|
|
||||||
"message": "Wenn aktiviert, wird beim Rechtsklick auf eine E-Mail in der Nachrichtenliste der Eintrag \"Auf Spam analysieren\" angezeigt."
|
|
||||||
},
|
|
||||||
"prefs_OptionText_calendar_enforce_timezone": {
|
"prefs_OptionText_calendar_enforce_timezone": {
|
||||||
"message": "Erzwinge die angegebene Zeitzone"
|
"message": "Erzwinge die angegebene Zeitzone"
|
||||||
},
|
},
|
||||||
|
|
@ -882,12 +858,6 @@
|
||||||
"prefs_OptionText_calendar_enforce_timezone_Info": {
|
"prefs_OptionText_calendar_enforce_timezone_Info": {
|
||||||
"message": "Wenn aktiviert, wird die angegebene Zeitzone für die Kalendereinträge und Aufgaben erzwungen."
|
"message": "Wenn aktiviert, wird die angegebene Zeitzone für die Kalendereinträge und Aufgaben erzwungen."
|
||||||
},
|
},
|
||||||
"prefs_OptionText_add_tags_context_menu": {
|
|
||||||
"message": "\"Tags hinzufügen\" im Kontextmenü anzeigen"
|
|
||||||
},
|
|
||||||
"prefs_OptionText_spamfilter_context_menu": {
|
|
||||||
"message": "\"Auf Spam analysieren\" im Kontextmenü anzeigen"
|
|
||||||
},
|
|
||||||
"apiwebchat_you": {
|
"apiwebchat_you": {
|
||||||
"message": "Du"
|
"message": "Du"
|
||||||
},
|
},
|
||||||
|
|
@ -930,12 +900,6 @@
|
||||||
"CORS_alternative_1": {
|
"CORS_alternative_1": {
|
||||||
"message": "Probleme beim Einrichten von CORS?"
|
"message": "Probleme beim Einrichten von CORS?"
|
||||||
},
|
},
|
||||||
"CORS_alternative_2": {
|
|
||||||
"message": "Drücke den Button unten, um die Berechtigung <all_urls> zu erteilen und CORS-Probleme zu vermeiden."
|
|
||||||
},
|
|
||||||
"CORS_give_allurls_perm": {
|
|
||||||
"message": "Gib die Berechtigung für \"alle URLs\""
|
|
||||||
},
|
|
||||||
"remember_CORS": {
|
"remember_CORS": {
|
||||||
"message": "Denk daran, du musst die CORS-Einstellungen auf dem Server konfigurieren!"
|
"message": "Denk daran, du musst die CORS-Einstellungen auf dem Server konfigurieren!"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -564,7 +564,7 @@
|
||||||
"message": "Προσθήκη νέου συμβάντος ημερολογίου"
|
"message": "Προσθήκη νέου συμβάντος ημερολογίου"
|
||||||
},
|
},
|
||||||
"prompt_get_calendar_event_full_text": {
|
"prompt_get_calendar_event_full_text": {
|
||||||
"message": "Εξαγάγετε όλες τις σχετικές λεπτομέρειες που απαιτούνται για τη δημιουργία ενός συμβάντος ημερολογίου από το ακόλουθο κείμενο. Οι εξαγόμενες πληροφορίες θα πρέπει να περιλαμβάνουν:\n- Τίτλο συμβάντος\n- Ημερομηνία και ώρα έναρξης (συμπεριλαμβανομένης της ζώνης ώρας, εάν καθορίζεται)\n- Ημερομηνία και ώρα λήξης (συμπεριλαμβανομένης της ζώνης ώρας, εάν καθορίζεται)\n- Ολόκληρη ημέρα (εάν αναφέρεται)\n- Συμμετέχοντες\nΒεβαιωθείτε ότι τα δεδομένα έχουν μορφοποιηθεί με σαφήνεια και συνέπεια, ώστε να μπορούν να χρησιμοποιηθούν άμεσα για τη δημιουργία ενός συμβάντος ημερολογίου.\nΕάν υπάρχουν σχετικές χρονικές αναφορές, λάβετε υπόψη ότι η ημερομηνία και η ώρα του email είναι \"{%mail_datetime%}\". Υπολογίστε την ημερομηνία και την ώρα έναρξης με βάση αυτήν την αναφορά. Εάν η υπολογισμένη ημερομηνία και ώρα έναρξης είναι προγενέστερες από το \"{%current_datetime%}\", υπολογίστε ξανά την ημερομηνία και την ώρα έναρξης χρησιμοποιώντας το \"{%current_datetime%}\" ως βάση.\nΕάν η διάρκεια δεν έχει καθοριστεί, ορίστε την σε μία ώρα.\nΑυτοί είναι οι συμμετέχοντες: {%author%}, {%recipients%}, {%cc_list%}. Εάν υπάρχει, εξαιρέστε τη διεύθυνσή μου: {%account_email_address%}.\nΕάν δεν μπορείτε να λάβετε μία ή περισσότερες από τις απαιτούμενες πληροφορίες, απαντήστε με μια κενή συμβολοσειρά.\nΔημιουργήστε μια απάντηση μόνο σε μορφή JSON. Μην συμπεριλάβετε κανένα επιπλέον κείμενο ή εξηγήσεις. Δώστε μόνο το JSON. Η μορφή που θα χρησιμοποιηθεί είναι η εξής:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Σύνοψη συμβάντος ημερολογίου εδώ\",\n\"forceAllDay\": false,\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nΤο κείμενο είναι: \"{%selected_text%}\""
|
"message": "Εξαγάγετε όλες τις σχετικές λεπτομέρειες που απαιτούνται για τη δημιουργία ενός συμβάντος ημερολογίου από το ακόλουθο κείμενο. Οι εξαγόμενες πληροφορίες θα πρέπει να περιλαμβάνουν:\n- Τίτλο συμβάντος\n- Ημερομηνία και ώρα έναρξης (συμπεριλαμβανομένης της ζώνης ώρας, εάν καθορίζεται)\n- Ημερομηνία και ώρα λήξης (συμπεριλαμβανομένης της ζώνης ώρας, εάν καθορίζεται)\n- Ολόκληρη ημέρα (εάν αναφέρεται)\n- Συμμετέχοντες\nΒεβαιωθείτε ότι τα δεδομένα έχουν μορφοποιηθεί με σαφήνεια και συνέπεια, ώστε να μπορούν να χρησιμοποιηθούν άμεσα για τη δημιουργία ενός συμβάντος ημερολογίου.\nΕάν υπάρχουν σχετικές χρονικές αναφορές, λάβετε υπόψη ότι η ημερομηνία και η ώρα του email είναι \"{%mail_datetime%}\". Υπολογίστε την ημερομηνία και την ώρα έναρξης με βάση αυτήν την αναφορά. Εάν η υπολογισμένη ημερομηνία και ώρα έναρξης είναι προγενέστερες από το \"{%current_datetime%}\", υπολογίστε ξανά την ημερομηνία και την ώρα έναρξης χρησιμοποιώντας το \"{%current_datetime%}\" ως βάση.\nΕάν η διάρκεια δεν έχει καθοριστεί, ορίστε την σε μία ώρα.\nΑυτοί είναι οι συμμετέχοντες: {%author%}, {%recipients%}, {%cc_list%}. Εάν υπάρχει, εξαιρέστε τη διεύθυνσή μου: {%account_email_address%}.\nΕάν δεν μπορείτε να λάβετε μία ή περισσότερες από τις απαιτούμενες πληροφορίες, απαντήστε με μια κενή συμβολοσειρά.\nΔημιουργήστε μια απάντηση μόνο σε μορφή JSON. Μην συμπεριλάβετε κανένα επιπλέον κείμενο ή εξηγήσεις. Δώστε μόνο το JSON. Η μορφή που θα χρησιμοποιηθεί είναι η εξής:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Σύνοψη συμβάντος ημερολογίου εδώ\",\n\"forceAllDay\": false,\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nΤο κείμενο είναι: \"{%mail_text_body_or_selected%}\""
|
||||||
},
|
},
|
||||||
"prompt_get_task": {
|
"prompt_get_task": {
|
||||||
"message": "Προσθήκη νέας εργασίας"
|
"message": "Προσθήκη νέας εργασίας"
|
||||||
|
|
@ -773,10 +773,10 @@
|
||||||
"Report_Date": {
|
"Report_Date": {
|
||||||
"message": "Ημερομηνία αναφοράς"
|
"message": "Ημερομηνία αναφοράς"
|
||||||
},
|
},
|
||||||
"spamfilter_moved": {
|
"yes_string": {
|
||||||
"message": "Ναί"
|
"message": "Ναί"
|
||||||
},
|
},
|
||||||
"spamfilter_not_moved": {
|
"no_string": {
|
||||||
"message": "Οχι"
|
"message": "Οχι"
|
||||||
},
|
},
|
||||||
"context_menu_mzta-add-tags": {
|
"context_menu_mzta-add-tags": {
|
||||||
|
|
@ -785,18 +785,6 @@
|
||||||
"context_menu_mzta-spamfilter": {
|
"context_menu_mzta-spamfilter": {
|
||||||
"message": "Ανάλυση για ανεπιθύμητα μηνύματα"
|
"message": "Ανάλυση για ανεπιθύμητα μηνύματα"
|
||||||
},
|
},
|
||||||
"prefs_OptionText_add_tags_context_menu": {
|
|
||||||
"message": "Εμφάνιση του στοιχείου μενού \"Προσθήκη ετικετών\""
|
|
||||||
},
|
|
||||||
"prefs_OptionText_add_tags_context_menu_Info": {
|
|
||||||
"message": "Εάν είναι επιλεγμένο, το στοιχείο μενού \"Προσθήκη ετικετών\" θα εμφανίζεται όταν κάνετε δεξί κλικ σε ένα μήνυμα ηλεκτρονικού ταχυδρομείου στη λίστα μηνυμάτων."
|
|
||||||
},
|
|
||||||
"prefs_OptionText_spamfilter_context_menu": {
|
|
||||||
"message": "Εμφάνιση του στοιχείου μενού \"Ανάλυση για ανεπιθύμητα μηνύματα\""
|
|
||||||
},
|
|
||||||
"prefs_OptionText_spamfilter_context_menu_Info": {
|
|
||||||
"message": "Εάν είναι επιλεγμένο, το στοιχείο μενού \"Ανάλυση για ανεπιθύμητα μηνύματα\" θα εμφανίζεται όταν κάνετε δεξί κλικ σε ένα μήνυμα ηλεκτρονικού ταχυδρομείου στη λίστα μηνυμάτων."
|
|
||||||
},
|
|
||||||
"noActiveCalendar": {
|
"noActiveCalendar": {
|
||||||
"message": "Δεν βρέθηκε επεξεργάσιμο ημερολόγιο!"
|
"message": "Δεν βρέθηκε επεξεργάσιμο ημερολόγιο!"
|
||||||
},
|
},
|
||||||
|
|
@ -836,12 +824,6 @@
|
||||||
"CORS_alternative_1": {
|
"CORS_alternative_1": {
|
||||||
"message": "Προβλήματα με τη ρύθμιση του CORS;"
|
"message": "Προβλήματα με τη ρύθμιση του CORS;"
|
||||||
},
|
},
|
||||||
"CORS_alternative_2": {
|
|
||||||
"message": "Πατήστε το παρακάτω κουμπί για να δώσετε στο <all_urls> την άδεια να αποφύγει οποιοδήποτε πρόβλημα CORS."
|
|
||||||
},
|
|
||||||
"CORS_give_allurls_perm": {
|
|
||||||
"message": "Δώστε άδεια σε \"όλες τις διευθύνσεις URL\""
|
|
||||||
},
|
|
||||||
"prefs_OptionText_composing_plain_text": {
|
"prefs_OptionText_composing_plain_text": {
|
||||||
"message": "Σύνταξη σε απλό κείμενο"
|
"message": "Σύνταξη σε απλό κείμενο"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -659,6 +659,14 @@
|
||||||
"message": "Account email address",
|
"message": "Account email address",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"placeholder_mail_text_body_or_selected": {
|
||||||
|
"message": "Mail body or selected text",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"placeholder_mail_html_body_or_selected": {
|
||||||
|
"message": "Mail body or selected HTML",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"prefs_OptionText_placeholders_use_default_value": {
|
"prefs_OptionText_placeholders_use_default_value": {
|
||||||
"message": "Placeholders: use default value",
|
"message": "Placeholders: use default value",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
|
@ -1000,7 +1008,63 @@
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
"prompt_get_calendar_event_full_text": {
|
"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)\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%}\"",
|
"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:\"{%mail_text_body_or_selected%}\"",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prompt_get_calendar_event_from_clipboard": {
|
||||||
|
"message": "Add calendar event from clipboard",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"clipboard_read_error": {
|
||||||
|
"message": "Could not read clipboard. Please check permissions.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"clipboard_empty_error": {
|
||||||
|
"message": "Clipboard is empty. Please copy some text first.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"clipboard_permission_denied": {
|
||||||
|
"message": "Clipboard permission was denied. Please enable the feature again in settings to grant permission.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"clipboard_permission_error": {
|
||||||
|
"message": "Error requesting clipboard permission. Please try again.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_get_calendar_event_from_clipboard": {
|
||||||
|
"message": "Get calendar event from clipboard",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_get_calendar_event_from_clipboard_Info": {
|
||||||
|
"message": "Show an additional menu item to create calendar events from clipboard text content.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"Summarize_prompt_prefs_title": {
|
||||||
|
"message": "Add Summarization Options",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prompt_summarize": {
|
||||||
|
"message": "Summarize this email or these emails",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prompt_summarize_full_text": {
|
||||||
|
"message": "You are an assistant that summarizes email conversations.\n\nGiven an email thread, produce a concise, accurate summary that captures:\n\n- The main topic or purpose of the conversation\n- Key decisions, conclusions, or agreements\n- Important questions, requests, or action items\n- Who is responsible for each action item (if stated)\n\nOmit greetings, signatures, quoted text, and redundant back-and-forth.\nDo not add assumptions or information not present in the emails.\n\nWrite the summary in clear, neutral language suitable for a busy professional.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prompt_summarize_email_template": {
|
||||||
|
"message": "Summarize email template",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prompt_summarize_email_template_full_text": {
|
||||||
|
"message": "From: {%author%}\nTo: {%recipients%}\nCC: {%cc_list%}\nSubject: {%mail_subject%}\nDate: {%mail_datetime%}\nAttachments:\n{%mail_attachments_info%}\n\nBody:\n{%mail_text_body%}",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prompt_summarize_email_separator": {
|
||||||
|
"message": "Email separator",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prompt_summarize_email_separator_full_text": {
|
||||||
|
"message": "\n\n---------- NEXT EMAIL ----------\n\n",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
"prompt_get_task": {
|
"prompt_get_task": {
|
||||||
|
|
@ -1067,6 +1131,22 @@
|
||||||
"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!",
|
"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": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"prefs_OptionText_Summarize_infoline2": {
|
||||||
|
"message": "You can change the prompt as you wish, the first field is the main prompt, the second field is the template for a single mail. The list of emails will be appended to the main prompt. Emails will be separated by the separator specified in the third field.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_Summarize_main_prompt": {
|
||||||
|
"message": "The main prompt describing the task to be performed on all selected emails:",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_Summarize_email_template": {
|
||||||
|
"message": "The template for a single email:",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_Summarize_email_separator": {
|
||||||
|
"message": "The separator between emails:",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"prefs_OptionText_get_calendar_event_Sparks_not_present": {
|
"prefs_OptionText_get_calendar_event_Sparks_not_present": {
|
||||||
"message": "To use the calendar event and task features, please install the ThunderAI Sparks addon.",
|
"message": "To use the calendar event and task features, please install the ThunderAI Sparks addon.",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
|
@ -1167,6 +1247,10 @@
|
||||||
"message": "If checked, the Model and API specified below will be used for adding tags to emails, regardless the one choosen in the ThunderAI options page.",
|
"message": "If checked, the Model and API specified below will be used for adding tags to emails, regardless the one choosen in the ThunderAI options page.",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"prefs_OptionText_get_calendar_event_use_specific_integration_Info": {
|
||||||
|
"message": "If checked, the Model and API specified below will be used for creating calendar events, regardless the one choosen in the ThunderAI options page.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"placeholder_thunderai_def_sign": {
|
"placeholder_thunderai_def_sign": {
|
||||||
"message": "Default signature as defined in ThunderAI options.",
|
"message": "Default signature as defined in ThunderAI options.",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
|
@ -1195,6 +1279,22 @@
|
||||||
"message": "Manage spam filter settings",
|
"message": "Manage spam filter settings",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"prefs_OptionText_summarize": {
|
||||||
|
"message": "Summarize mail",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_summarize_use_specific_integration_Info": {
|
||||||
|
"message": "If checked, the Model and API specified below will be used for summarizing email(s), regardless the one choosen in the ThunderAI options page.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_summarize_Info": {
|
||||||
|
"message": "If checked, adds an option to context menu to summarize mail.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_btnManageSummarizeInfo": {
|
||||||
|
"message": "Manage summarize settings",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"SpamFilter_PageTitle": {
|
"SpamFilter_PageTitle": {
|
||||||
"message": "Manage Spam Filter Settings",
|
"message": "Manage Spam Filter Settings",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
|
@ -1219,6 +1319,18 @@
|
||||||
"message": "Spam Filter Options",
|
"message": "Spam Filter Options",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"Summarize_PageTitle": {
|
||||||
|
"message": "Manage Summarize Settings",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"Summarize_info_default": {
|
||||||
|
"message": "In this page you can modify the default prompt used to summarize emails.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"Summarize_prompt_text_title": {
|
||||||
|
"message": "Current prompt text",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"prefs_OptionText_use_specific_integration": {
|
"prefs_OptionText_use_specific_integration": {
|
||||||
"message": "Use specific Model and API",
|
"message": "Use specific Model and API",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
|
@ -1235,6 +1347,14 @@
|
||||||
"message": "If the value returned by the AI is above this threshold, the email will be moved to the spam folder.",
|
"message": "If the value returned by the AI is above this threshold, the email will be moved to the spam folder.",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"prefs_OptionText_spamfilter_show_msg_panel": {
|
||||||
|
"message": "Show spam report panel",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_spamfilter_show_msg_panel_Info": {
|
||||||
|
"message": "If checked, a panel with the spam report will be shown on top of the message.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"spamfilter_threshold_too_low": {
|
"spamfilter_threshold_too_low": {
|
||||||
"message": "The spam threshold is too low! You will likely mark too much mails as spam!",
|
"message": "The spam threshold is too low! You will likely mark too much mails as spam!",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
|
@ -1251,6 +1371,10 @@
|
||||||
"message": "Spam Filter Reports",
|
"message": "Spam Filter Reports",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"SpamReport_infoline": {
|
||||||
|
"message": "This information is saved only for the current session.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"Date": {
|
"Date": {
|
||||||
"message": "Date",
|
"message": "Date",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
|
@ -1267,6 +1391,14 @@
|
||||||
"message": "Spam Value",
|
"message": "Spam Value",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
"Spam": {
|
||||||
|
"message": "Spam",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"Valid": {
|
||||||
|
"message": "Valid",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
"Moved_to_Spam": {
|
"Moved_to_Spam": {
|
||||||
"message": "Moved to Spam",
|
"message": "Moved to Spam",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
|
@ -1279,11 +1411,11 @@
|
||||||
"message": "Report Date",
|
"message": "Report Date",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
"spamfilter_moved": {
|
"yes_string": {
|
||||||
"message": "Yes",
|
"message": "Yes",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
"spamfilter_not_moved": {
|
"no_string": {
|
||||||
"message": "No",
|
"message": "No",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
|
|
@ -1295,20 +1427,8 @@
|
||||||
"message": "Analyze for spam",
|
"message": "Analyze for spam",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
"prefs_OptionText_add_tags_context_menu": {
|
"context_menu_mzta-summarize": {
|
||||||
"message": "Show the \"Add tags\" context menu item",
|
"message": "Summarize",
|
||||||
"description": ""
|
|
||||||
},
|
|
||||||
"prefs_OptionText_add_tags_context_menu_Info": {
|
|
||||||
"message": "If checked, the \"Add tags\" context menu item will be shown when right-clicking on an email in the messages list.",
|
|
||||||
"description": ""
|
|
||||||
},
|
|
||||||
"prefs_OptionText_spamfilter_context_menu": {
|
|
||||||
"message": "Show the \"Analyze for spam\" context menu item",
|
|
||||||
"description": ""
|
|
||||||
},
|
|
||||||
"prefs_OptionText_spamfilter_context_menu_Info": {
|
|
||||||
"message": "If checked, the \"Analyze for spam\" context menu item will be shown when right-clicking on an email in the messages list.",
|
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
"noActiveCalendar": {
|
"noActiveCalendar": {
|
||||||
|
|
@ -1363,12 +1483,16 @@
|
||||||
"message": "Problems setting CORS?",
|
"message": "Problems setting CORS?",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
"CORS_alternative_2": {
|
"CORS_alternative_2_new": {
|
||||||
"message": "Press the button below to give the <all_urls> permission to avoid any CORS problem.",
|
"message": "Press the button below to give the permission to the current host to avoid any CORS problem.",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
"CORS_give_allurls_perm": {
|
"CORS_give_host_perm": {
|
||||||
"message": "Give \"all URLs\" permission",
|
"message": "Give permission to the current host",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"CORS_localhost_warn": {
|
||||||
|
"message": "If you are using localhost or 127.0.0.1 because the AI server is hosted on your PC, the <all_urls> permission is required.",
|
||||||
"description": ""
|
"description": ""
|
||||||
},
|
},
|
||||||
"prefs_OptionText_composing_plain_text": {
|
"prefs_OptionText_composing_plain_text": {
|
||||||
|
|
@ -1736,5 +1860,25 @@
|
||||||
"Optional_Permission_Denied_Model_Fetching": {
|
"Optional_Permission_Denied_Model_Fetching": {
|
||||||
"message": "You have denied the optional permission needed to fetch models for this integration.",
|
"message": "You have denied the optional permission needed to fetch models for this integration.",
|
||||||
"description": ""
|
"description": ""
|
||||||
|
},
|
||||||
|
"customPrompts_export_include_api_settings": {
|
||||||
|
"message": "Do you want to include the API settings in the export? Be aware that also the API Key will be saved in the file!",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_calendar_no_selection": {
|
||||||
|
"message": "Do not ask to select text",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"prefs_OptionText_calendar_no_selection_Info": {
|
||||||
|
"message": "If checked there is no need to select some text. The full message body will be used to get the calendar event.",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"customPrompts_btnCopy": {
|
||||||
|
"message": "Copy",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"copy_text": {
|
||||||
|
"message": "copy",
|
||||||
|
"description": ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@
|
||||||
"From": {
|
"From": {
|
||||||
"message": "De"
|
"message": "De"
|
||||||
},
|
},
|
||||||
"spamfilter_not_moved": {
|
"no_string": {
|
||||||
"message": "Ne"
|
"message": "Ne"
|
||||||
},
|
},
|
||||||
"apiwebchat_stopping": {
|
"apiwebchat_stopping": {
|
||||||
|
|
@ -122,7 +122,7 @@
|
||||||
"Explanation": {
|
"Explanation": {
|
||||||
"message": "Klarigo"
|
"message": "Klarigo"
|
||||||
},
|
},
|
||||||
"spamfilter_moved": {
|
"yes_string": {
|
||||||
"message": "Jes"
|
"message": "Jes"
|
||||||
},
|
},
|
||||||
"apiwebchat_you": {
|
"apiwebchat_you": {
|
||||||
|
|
|
||||||
|
|
@ -744,7 +744,7 @@
|
||||||
"message": "Agregar un nuevo evento de calendario"
|
"message": "Agregar un nuevo evento de calendario"
|
||||||
},
|
},
|
||||||
"prompt_get_calendar_event_full_text": {
|
"prompt_get_calendar_event_full_text": {
|
||||||
"message": "Extrae todos los detalles relevantes necesarios para generar un evento de calendario a partir del siguiente texto. La información extraída debe incluir:\n- Título del evento\n- Fecha y hora de inicio (incluyendo zona horaria, si se especifica)\n- Fecha y hora de fin (incluyendo zona horaria, si se especifica)\n- Día completo (si se menciona)\n- Asistentes\nAsegúrate de que los datos estén formateados de manera clara y consistente para que puedan usarse directamente en la creación de un evento de calendario.\nSi hay referencias de tiempo relativas, considera que la fecha y hora del correo son \"{%mail_datetime%}\". Calcula la fecha y hora de inicio basándote en esta referencia. Si la fecha y hora de inicio calculadas son anteriores a \"{%current_datetime%}\", recalcula la fecha y hora de inicio usando \"{%current_datetime%}\" como base.\nSi la duración no se especifica, establécela en una hora.\nEstos son los asistentes: {%author%}, {%recipients%}, {%cc_list%}. Si están presentes, excluye mi dirección: {%account_email_address%}.\nSi no puedes obtener uno o más de los datos requeridos, responde con una cadena vacía.\nGenera una respuesta solo en formato JSON. No incluyas texto adicional ni explicaciones; proporciona únicamente el JSON. El formato a usar es:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Resumen del evento de calendario aquí\",\n\"forceAllDay\": false,\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nEste es el texto:\"{%selected_text%}\""
|
"message": "Extrae todos los detalles relevantes necesarios para generar un evento de calendario a partir del siguiente texto. La información extraída debe incluir:\n- Título del evento\n- Fecha y hora de inicio (incluyendo zona horaria, si se especifica)\n- Fecha y hora de fin (incluyendo zona horaria, si se especifica)\n- Día completo (si se menciona)\n- Asistentes\nAsegúrate de que los datos estén formateados de manera clara y consistente para que puedan usarse directamente en la creación de un evento de calendario.\nSi hay referencias de tiempo relativas, considera que la fecha y hora del correo son \"{%mail_datetime%}\". Calcula la fecha y hora de inicio basándote en esta referencia. Si la fecha y hora de inicio calculadas son anteriores a \"{%current_datetime%}\", recalcula la fecha y hora de inicio usando \"{%current_datetime%}\" como base.\nSi la duración no se especifica, establécela en una hora.\nEstos son los asistentes: {%author%}, {%recipients%}, {%cc_list%}. Si están presentes, excluye mi dirección: {%account_email_address%}.\nSi no puedes obtener uno o más de los datos requeridos, responde con una cadena vacía.\nGenera una respuesta solo en formato JSON. No incluyas texto adicional ni explicaciones; proporciona únicamente el JSON. El formato a usar es:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Resumen del evento de calendario aquí\",\n\"forceAllDay\": false,\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nEste es el texto:\"{%mail_text_body_or_selected%}\""
|
||||||
},
|
},
|
||||||
"prompt_get_task": {
|
"prompt_get_task": {
|
||||||
"message": "Agregar una nueva tarea"
|
"message": "Agregar una nueva tarea"
|
||||||
|
|
@ -956,10 +956,10 @@
|
||||||
"Report_Date": {
|
"Report_Date": {
|
||||||
"message": "Fecha del informe"
|
"message": "Fecha del informe"
|
||||||
},
|
},
|
||||||
"spamfilter_moved": {
|
"yes_string": {
|
||||||
"message": "Si"
|
"message": "Si"
|
||||||
},
|
},
|
||||||
"spamfilter_not_moved": {
|
"no_string": {
|
||||||
"message": "No"
|
"message": "No"
|
||||||
},
|
},
|
||||||
"context_menu_mzta-add-tags": {
|
"context_menu_mzta-add-tags": {
|
||||||
|
|
@ -968,18 +968,6 @@
|
||||||
"context_menu_mzta-spamfilter": {
|
"context_menu_mzta-spamfilter": {
|
||||||
"message": "Analizar el spam"
|
"message": "Analizar el spam"
|
||||||
},
|
},
|
||||||
"prefs_OptionText_add_tags_context_menu": {
|
|
||||||
"message": "Mostrar el elemento del menú contextual “Añadir etiquetas”"
|
|
||||||
},
|
|
||||||
"prefs_OptionText_add_tags_context_menu_Info": {
|
|
||||||
"message": "Si está marcado, el elemento del menú contextual “Añadir etiquetas” se mostrará al hacer clic derecho en un correo electrónico de la lista de mensajes."
|
|
||||||
},
|
|
||||||
"prefs_OptionText_spamfilter_context_menu": {
|
|
||||||
"message": "Mostrar el elemento del menú contextual “Analizar el spam”"
|
|
||||||
},
|
|
||||||
"prefs_OptionText_spamfilter_context_menu_Info": {
|
|
||||||
"message": "Si está marcado, el elemento del menú contextual “Analizar el spam” se mostrará al hacer clic derecho en un correo electrónico de la lista de mensajes."
|
|
||||||
},
|
|
||||||
"noActiveCalendar": {
|
"noActiveCalendar": {
|
||||||
"message": "¡No se encontró un calendario editable!"
|
"message": "¡No se encontró un calendario editable!"
|
||||||
},
|
},
|
||||||
|
|
@ -1019,12 +1007,6 @@
|
||||||
"CORS_alternative_1": {
|
"CORS_alternative_1": {
|
||||||
"message": "¿Problemas al configurar CORS?"
|
"message": "¿Problemas al configurar CORS?"
|
||||||
},
|
},
|
||||||
"CORS_alternative_2": {
|
|
||||||
"message": "Presiona el botón a continuación para otorgar el permiso <all_urls> y evitar cualquier problema de CORS."
|
|
||||||
},
|
|
||||||
"CORS_give_allurls_perm": {
|
|
||||||
"message": "Otorgar permiso “all URLs”"
|
|
||||||
},
|
|
||||||
"prefs_OptionText_composing_plain_text": {
|
"prefs_OptionText_composing_plain_text": {
|
||||||
"message": "Redactando en texto plano"
|
"message": "Redactando en texto plano"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -327,9 +327,6 @@
|
||||||
"chagpt_api_send_button": {
|
"chagpt_api_send_button": {
|
||||||
"message": "Utilisation du modèle"
|
"message": "Utilisation du modèle"
|
||||||
},
|
},
|
||||||
"chagpt_api_connecting": {
|
|
||||||
"message": "Tentative de connexion à OpenAI ChatGPT en utilisant la clé API fournie"
|
|
||||||
},
|
|
||||||
"Debug": {
|
"Debug": {
|
||||||
"message": "Debug"
|
"message": "Debug"
|
||||||
},
|
},
|
||||||
|
|
@ -363,12 +360,6 @@
|
||||||
"ollama_empty_model": {
|
"ollama_empty_model": {
|
||||||
"message": "Vous n'avez pas choisi de modèle pour l'API Ollama. Veuillez en choisir un sur la page des options."
|
"message": "Vous n'avez pas choisi de modèle pour l'API Ollama. Veuillez en choisir un sur la page des options."
|
||||||
},
|
},
|
||||||
"ollama_api_connecting": {
|
|
||||||
"message": "Tentative de connexion au serveur local Ollama en utilisant l'hôte"
|
|
||||||
},
|
|
||||||
"andModel": {
|
|
||||||
"message": "et le modèle"
|
|
||||||
},
|
|
||||||
"error_connection_interrupted": {
|
"error_connection_interrupted": {
|
||||||
"message": "La connexion au serveur a été interrompue de manière inattendue"
|
"message": "La connexion au serveur a été interrompue de manière inattendue"
|
||||||
},
|
},
|
||||||
|
|
@ -399,9 +390,6 @@
|
||||||
"OpenAIComp_empty_model": {
|
"OpenAIComp_empty_model": {
|
||||||
"message": "Vous n'avez pas choisi de modèle pour l'API compatible OpenAI. Veuillez en choisir un dans la page des options."
|
"message": "Vous n'avez pas choisi de modèle pour l'API compatible OpenAI. Veuillez en choisir un dans la page des options."
|
||||||
},
|
},
|
||||||
"OpenAIComp_api_connecting": {
|
|
||||||
"message": "Tentative de connexion au serveur local de l'API compatible OpenAI en utilisant l'hôte"
|
|
||||||
},
|
|
||||||
"OpenAIComp_api_request_failed": {
|
"OpenAIComp_api_request_failed": {
|
||||||
"message": "La requête de l'API compatible OpenAI a échoué"
|
"message": "La requête de l'API compatible OpenAI a échoué"
|
||||||
},
|
},
|
||||||
|
|
@ -681,9 +669,6 @@
|
||||||
"google_gemini_api_request_failed": {
|
"google_gemini_api_request_failed": {
|
||||||
"message": "La requête API Google Gemini a échoué"
|
"message": "La requête API Google Gemini a échoué"
|
||||||
},
|
},
|
||||||
"google_gemini_api_connecting": {
|
|
||||||
"message": "Tentative de connexion à Google Gemini en utilisant la clé API fournie"
|
|
||||||
},
|
|
||||||
"google_gemini_empty_apikey": {
|
"google_gemini_empty_apikey": {
|
||||||
"message": "Vous n'avez pas ajouté de clé API pour l'API Google Gemini. Veuillez en insérer une dans la page des options."
|
"message": "Vous n'avez pas ajouté de clé API pour l'API Google Gemini. Veuillez en insérer une dans la page des options."
|
||||||
},
|
},
|
||||||
|
|
@ -712,7 +697,7 @@
|
||||||
"message": "Ajouter un nouvel événement au calendrier"
|
"message": "Ajouter un nouvel événement au calendrier"
|
||||||
},
|
},
|
||||||
"prompt_get_calendar_event_full_text": {
|
"prompt_get_calendar_event_full_text": {
|
||||||
"message": "Extrayez tous les détails pertinents nécessaires pour générer un événement de calendrier à partir du texte suivant. Les informations extraites doivent inclure :\n- Titre de l'événement\n- Date et heure de début (y compris le fuseau horaire, si spécifié)\n- Date et heure de fin (y compris le fuseau horaire, si spécifié)\n- Journée entière (si mentionnée)\n- Participants\nAssurez-vous que les données sont formatées clairement et de manière cohérente afin qu'elles puissent être utilisées directement pour créer un événement de calendrier.\nS'il y a des références temporelles relatives, considérez que la date et l'heure de l'email sont \"{%mail_datetime%}\". Calculez la date et l'heure de début sur cette base. Si la date et l'heure de début calculées sont antérieures à \"{%current_datetime%}\", recalculez-les en utilisant \"{%current_datetime%}\" comme base.\nSi la durée n'est pas spécifiée, définissez-la sur une heure.\nVoici les participants : {%author%}, {%recipients%}, {%cc_list%}. Si elle est présente, exclure mon adresse : {%account_email_address%}.\nSi vous n'êtes pas en mesure d'obtenir une ou plusieurs des informations requises, répondez avec une chaîne vide.\nGénérez une réponse uniquement au format JSON. N'incluez aucun texte ou explication supplémentaire ; fournissez uniquement le JSON. Voici le format à utiliser :\n{\n\"startDate\" : \"YYYYMMDDTHHMMSS\",\n\"endDate\" : \"YYYYMMDDTHHMMSS\",\n\"summary\" : \"Résumé de l'événement du calendrier ici\",\n\"forceAllDay\" : false\n\"attendees\" : [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nVoici le texte : \"{%selected_text%}\""
|
"message": "Extrayez tous les détails pertinents nécessaires pour générer un événement de calendrier à partir du texte suivant. Les informations extraites doivent inclure :\n- Titre de l'événement\n- Date et heure de début (y compris le fuseau horaire, si spécifié)\n- Date et heure de fin (y compris le fuseau horaire, si spécifié)\n- Journée entière (si mentionnée)\n- Participants\nAssurez-vous que les données sont formatées clairement et de manière cohérente afin qu'elles puissent être utilisées directement pour créer un événement de calendrier.\nS'il y a des références temporelles relatives, considérez que la date et l'heure de l'email sont \"{%mail_datetime%}\". Calculez la date et l'heure de début sur cette base. Si la date et l'heure de début calculées sont antérieures à \"{%current_datetime%}\", recalculez-les en utilisant \"{%current_datetime%}\" comme base.\nSi la durée n'est pas spécifiée, définissez-la sur une heure.\nVoici les participants : {%author%}, {%recipients%}, {%cc_list%}. Si elle est présente, exclure mon adresse : {%account_email_address%}.\nSi vous n'êtes pas en mesure d'obtenir une ou plusieurs des informations requises, répondez avec une chaîne vide.\nGénérez une réponse uniquement au format JSON. N'incluez aucun texte ou explication supplémentaire ; fournissez uniquement le JSON. Voici le format à utiliser :\n{\n\"startDate\" : \"YYYYMMDDTHHMMSS\",\n\"endDate\" : \"YYYYMMDDTHHMMSS\",\n\"summary\" : \"Résumé de l'événement du calendrier ici\",\n\"forceAllDay\" : false\n\"attendees\" : [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nVoici le texte : \"{%mail_text_body_or_selected%}\""
|
||||||
},
|
},
|
||||||
"prefs_OptionText_get_calendar_event": {
|
"prefs_OptionText_get_calendar_event": {
|
||||||
"message": "Ajouter un nouvel événement au calendrier à partir du texte sélectionné"
|
"message": "Ajouter un nouvel événement au calendrier à partir du texte sélectionné"
|
||||||
|
|
@ -792,7 +777,7 @@
|
||||||
"Moved_to_Spam": {
|
"Moved_to_Spam": {
|
||||||
"message": "Déplacé dans le spam"
|
"message": "Déplacé dans le spam"
|
||||||
},
|
},
|
||||||
"spamfilter_not_moved": {
|
"no_string": {
|
||||||
"message": "Non"
|
"message": "Non"
|
||||||
},
|
},
|
||||||
"spamfilter_no_reports": {
|
"spamfilter_no_reports": {
|
||||||
|
|
@ -801,9 +786,6 @@
|
||||||
"SpamFilter_PageTitle": {
|
"SpamFilter_PageTitle": {
|
||||||
"message": "Gérer les paramètres du filtre anti-spam"
|
"message": "Gérer les paramètres du filtre anti-spam"
|
||||||
},
|
},
|
||||||
"sparks_not_installed": {
|
|
||||||
"message": "ThunderAI Sparks non installé !"
|
|
||||||
},
|
|
||||||
"SpamFilter_info_default": {
|
"SpamFilter_info_default": {
|
||||||
"message": "Sur cette page, vous pouvez modifier l'invite par défaut utilisée pour détecter les e-mails indésirables."
|
"message": "Sur cette page, vous pouvez modifier l'invite par défaut utilisée pour détecter les e-mails indésirables."
|
||||||
},
|
},
|
||||||
|
|
@ -816,7 +798,7 @@
|
||||||
"SpamReport_Title": {
|
"SpamReport_Title": {
|
||||||
"message": "Rapports du filtre anti-spam"
|
"message": "Rapports du filtre anti-spam"
|
||||||
},
|
},
|
||||||
"spamfilter_moved": {
|
"yes_string": {
|
||||||
"message": "Oui"
|
"message": "Oui"
|
||||||
},
|
},
|
||||||
"prefs_OptionText_add_tags_auto_Info": {
|
"prefs_OptionText_add_tags_auto_Info": {
|
||||||
|
|
@ -858,12 +840,6 @@
|
||||||
"context_menu_mzta-add-tags": {
|
"context_menu_mzta-add-tags": {
|
||||||
"message": "Ajouter des étiquettes"
|
"message": "Ajouter des étiquettes"
|
||||||
},
|
},
|
||||||
"prefs_OptionText_spamfilter_context_menu": {
|
|
||||||
"message": "Afficher l'option \"Analyser comme spam\" dans le menu contextuel"
|
|
||||||
},
|
|
||||||
"prefs_OptionText_spamfilter_context_menu_Info": {
|
|
||||||
"message": "Si coché, l'option \"Analyser comme spam\" apparaîtra lors d’un clic droit sur un e-mail dans la liste des messages."
|
|
||||||
},
|
|
||||||
"noActiveCalendar": {
|
"noActiveCalendar": {
|
||||||
"message": "Aucun calendrier modifiable trouvé !"
|
"message": "Aucun calendrier modifiable trouvé !"
|
||||||
},
|
},
|
||||||
|
|
@ -879,9 +855,6 @@
|
||||||
"prefs_OptionText_calendar_enforce_timezone": {
|
"prefs_OptionText_calendar_enforce_timezone": {
|
||||||
"message": "Forcer le fuseau horaire spécifié"
|
"message": "Forcer le fuseau horaire spécifié"
|
||||||
},
|
},
|
||||||
"prefs_OptionText_add_tags_context_menu_Info": {
|
|
||||||
"message": "Si coché, l'option \"Ajouter des étiquettes\" apparaîtra lors d’un clic droit sur un e-mail dans la liste des messages."
|
|
||||||
},
|
|
||||||
"chatgpt_win_diff_title": {
|
"chatgpt_win_diff_title": {
|
||||||
"message": "Différences entre le texte original et le texte modifié"
|
"message": "Différences entre le texte original et le texte modifié"
|
||||||
},
|
},
|
||||||
|
|
@ -897,9 +870,6 @@
|
||||||
"apiwebchat_error": {
|
"apiwebchat_error": {
|
||||||
"message": "Erreur"
|
"message": "Erreur"
|
||||||
},
|
},
|
||||||
"prefs_OptionText_add_tags_context_menu": {
|
|
||||||
"message": "Afficher l'option \"Ajouter des étiquettes\" dans le menu contextuel"
|
|
||||||
},
|
|
||||||
"apiwebchat_use_this_answer": {
|
"apiwebchat_use_this_answer": {
|
||||||
"message": "Utiliser cette réponse"
|
"message": "Utiliser cette réponse"
|
||||||
},
|
},
|
||||||
|
|
@ -930,12 +900,6 @@
|
||||||
"CORS_alternative_1": {
|
"CORS_alternative_1": {
|
||||||
"message": "Des problèmes pour configurer le CORS ?"
|
"message": "Des problèmes pour configurer le CORS ?"
|
||||||
},
|
},
|
||||||
"CORS_alternative_2": {
|
|
||||||
"message": "Appuie sur le bouton ci-dessous pour accorder la permission <all_urls> afin d'éviter tout problème lié au CORS."
|
|
||||||
},
|
|
||||||
"CORS_give_allurls_perm": {
|
|
||||||
"message": "Accorde la permission \"tous les URLs\""
|
|
||||||
},
|
|
||||||
"remember_CORS": {
|
"remember_CORS": {
|
||||||
"message": "N'oublie pas, tu dois configurer les paramètres CORS sur le serveur !"
|
"message": "N'oublie pas, tu dois configurer les paramètres CORS sur le serveur !"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -327,9 +327,6 @@
|
||||||
"chagpt_api_send_button": {
|
"chagpt_api_send_button": {
|
||||||
"message": "Korištenje modela"
|
"message": "Korištenje modela"
|
||||||
},
|
},
|
||||||
"chagpt_api_connecting": {
|
|
||||||
"message": "Pokušaj povezivanja na OpenAI ChatGPT pomoću dostavljenog API ključa"
|
|
||||||
},
|
|
||||||
"Debug": {
|
"Debug": {
|
||||||
"message": "Otklanjanje pogrešaka"
|
"message": "Otklanjanje pogrešaka"
|
||||||
},
|
},
|
||||||
|
|
@ -363,12 +360,6 @@
|
||||||
"ollama_empty_model": {
|
"ollama_empty_model": {
|
||||||
"message": "Niste odabrali model za Ollama API. Odaberite jedan na stranici s mogućnostima."
|
"message": "Niste odabrali model za Ollama API. Odaberite jedan na stranici s mogućnostima."
|
||||||
},
|
},
|
||||||
"ollama_api_connecting": {
|
|
||||||
"message": "Pokušaj povezivanja na Ollama lokalni poslužitelj pomoću glavnog računala"
|
|
||||||
},
|
|
||||||
"andModel": {
|
|
||||||
"message": "i model"
|
|
||||||
},
|
|
||||||
"error_connection_interrupted": {
|
"error_connection_interrupted": {
|
||||||
"message": "Veza s poslužiteljem je neočekivano prekinuta"
|
"message": "Veza s poslužiteljem je neočekivano prekinuta"
|
||||||
},
|
},
|
||||||
|
|
@ -399,9 +390,6 @@
|
||||||
"OpenAIComp_empty_model": {
|
"OpenAIComp_empty_model": {
|
||||||
"message": "Niste odabrali model za OpenAI kompatibilan API. Odaberite jedan na stranici s opcijama."
|
"message": "Niste odabrali model za OpenAI kompatibilan API. Odaberite jedan na stranici s opcijama."
|
||||||
},
|
},
|
||||||
"OpenAIComp_api_connecting": {
|
|
||||||
"message": "Pokušaj povezivanja s OpenAI kompatibilnim API lokalnim poslužiteljem pomoću glavnog računala"
|
|
||||||
},
|
|
||||||
"OpenAIComp_api_request_failed": {
|
"OpenAIComp_api_request_failed": {
|
||||||
"message": "OpenAI Comp API zahtjev nije uspio"
|
"message": "OpenAI Comp API zahtjev nije uspio"
|
||||||
},
|
},
|
||||||
|
|
@ -681,9 +669,6 @@
|
||||||
"google_gemini_api_request_failed": {
|
"google_gemini_api_request_failed": {
|
||||||
"message": "Google Gemini API zahtjev nije uspio"
|
"message": "Google Gemini API zahtjev nije uspio"
|
||||||
},
|
},
|
||||||
"google_gemini_api_connecting": {
|
|
||||||
"message": "Pokušaj povezivanja na Google Gemini pomoću dostavljenog API ključa"
|
|
||||||
},
|
|
||||||
"google_gemini_empty_apikey": {
|
"google_gemini_empty_apikey": {
|
||||||
"message": "Niste dodali API ključ za Google Gemini API. Unesite jedan na stranicu s mogućnostima."
|
"message": "Niste dodali API ključ za Google Gemini API. Unesite jedan na stranicu s mogućnostima."
|
||||||
},
|
},
|
||||||
|
|
@ -712,7 +697,7 @@
|
||||||
"message": "Dodaj novi kalendarski događaj"
|
"message": "Dodaj novi kalendarski događaj"
|
||||||
},
|
},
|
||||||
"prompt_get_calendar_event_full_text": {
|
"prompt_get_calendar_event_full_text": {
|
||||||
"message": "Izdvoji sve relevantne detalje potrebne za generiranje kalendarskog događaja iz sljedećeg teksta. Izdvojene informacije trebaju uključivati:\n- Naslov događaja\n- Datum i vrijeme početka (uključujući vremensku zonu, ako je navedeno)\n- Datum i vrijeme završetka (uključujući vremensku zonu, ako je navedeno)\n- Cijeli dan (ako je navedeno)\n- Sudionici\nOsiguraj da su podaci oblikovani jasno i dosljedno kako bi se mogli izravno koristiti za stvaranje kalendarskog događaja.\nAko postoje relativne vremenske napomene, smatraj da su datum i vrijeme e-poruke \"{%mail_datetime%}\". Izračunajte datum i vrijeme početka na temelju ove napomene. Ako su izračunati početni datum i vrijeme raniji od \"{%current_datetime%}\", ponovno izračunaj početni datum i vrijeme koristeći \"{%current_datetime%}\" kao osnovu.\nAko trajanje nije navedeno, postavi ga na jedan sat.\nOvo su sudionici: {%author%}, {%recipients%}, {%cc_list%}. Ako je prisutna, isključi moju adresu: {%account_email_address%}.\nAko ne možeš dobiti jednu ili više potrebnih informacija, odgovori praznim nizom.\nGeneriraj odgovor samo u JSON formatu. Nemoj uključivati nikakav dodatni tekst ili objašnjenja; pruži samo JSON. Ovo je format koji će se koristiti:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Sažetak kalendarskih događaja ovdje\",\n\"forceAllDay\": false\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nOvo je tekst:\"{%selected_text%}\""
|
"message": "Izdvoji sve relevantne detalje potrebne za generiranje kalendarskog događaja iz sljedećeg teksta. Izdvojene informacije trebaju uključivati:\n- Naslov događaja\n- Datum i vrijeme početka (uključujući vremensku zonu, ako je navedeno)\n- Datum i vrijeme završetka (uključujući vremensku zonu, ako je navedeno)\n- Cijeli dan (ako je navedeno)\n- Sudionici\nOsiguraj da su podaci oblikovani jasno i dosljedno kako bi se mogli izravno koristiti za stvaranje kalendarskog događaja.\nAko postoje relativne vremenske napomene, smatraj da su datum i vrijeme e-poruke \"{%mail_datetime%}\". Izračunajte datum i vrijeme početka na temelju ove napomene. Ako su izračunati početni datum i vrijeme raniji od \"{%current_datetime%}\", ponovno izračunaj početni datum i vrijeme koristeći \"{%current_datetime%}\" kao osnovu.\nAko trajanje nije navedeno, postavi ga na jedan sat.\nOvo su sudionici: {%author%}, {%recipients%}, {%cc_list%}. Ako je prisutna, isključi moju adresu: {%account_email_address%}.\nAko ne možeš dobiti jednu ili više potrebnih informacija, odgovori praznim nizom.\nGeneriraj odgovor samo u JSON formatu. Nemoj uključivati nikakav dodatni tekst ili objašnjenja; pruži samo JSON. Ovo je format koji će se koristiti:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Sažetak kalendarskih događaja ovdje\",\n\"forceAllDay\": false\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nOvo je tekst:\"{%mail_text_body_or_selected%}\""
|
||||||
},
|
},
|
||||||
"prefs_OptionText_get_calendar_event": {
|
"prefs_OptionText_get_calendar_event": {
|
||||||
"message": "Dodaj novi kalendarski događaj iz odabranog teksta"
|
"message": "Dodaj novi kalendarski događaj iz odabranog teksta"
|
||||||
|
|
@ -753,9 +738,6 @@
|
||||||
"calendar_opening_dialog_error": {
|
"calendar_opening_dialog_error": {
|
||||||
"message": "Pogreška pri otvaranju dijaloškog okvira kalendarskog događaja"
|
"message": "Pogreška pri otvaranju dijaloškog okvira kalendarskog događaja"
|
||||||
},
|
},
|
||||||
"sparks_not_installed": {
|
|
||||||
"message": "ThunderAI Sparks nije instaliran!"
|
|
||||||
},
|
|
||||||
"prefs_OptionText_add_tags_auto": {
|
"prefs_OptionText_add_tags_auto": {
|
||||||
"message": "Dodajte oznake automatski"
|
"message": "Dodajte oznake automatski"
|
||||||
},
|
},
|
||||||
|
|
@ -846,10 +828,10 @@
|
||||||
"Report_Date": {
|
"Report_Date": {
|
||||||
"message": "Datum izvješća"
|
"message": "Datum izvješća"
|
||||||
},
|
},
|
||||||
"spamfilter_moved": {
|
"yes_string": {
|
||||||
"message": "Da"
|
"message": "Da"
|
||||||
},
|
},
|
||||||
"spamfilter_not_moved": {
|
"no_string": {
|
||||||
"message": "Ne"
|
"message": "Ne"
|
||||||
},
|
},
|
||||||
"prefs_OptionText_openai_comp_info_remote": {
|
"prefs_OptionText_openai_comp_info_remote": {
|
||||||
|
|
|
||||||
|
|
@ -327,9 +327,6 @@
|
||||||
"chagpt_api_send_button": {
|
"chagpt_api_send_button": {
|
||||||
"message": "Modello utilizzato"
|
"message": "Modello utilizzato"
|
||||||
},
|
},
|
||||||
"chagpt_api_connecting": {
|
|
||||||
"message": "Tentativo di connessione a OpenAI ChatGPT utilizzando la chiave API fornita"
|
|
||||||
},
|
|
||||||
"Debug": {
|
"Debug": {
|
||||||
"message": "Debug"
|
"message": "Debug"
|
||||||
},
|
},
|
||||||
|
|
@ -363,12 +360,6 @@
|
||||||
"ollama_empty_model": {
|
"ollama_empty_model": {
|
||||||
"message": "Non hai scelto un modello per l'API Ollama. Per favore, scegline uno nella pagina delle opzioni."
|
"message": "Non hai scelto un modello per l'API Ollama. Per favore, scegline uno nella pagina delle opzioni."
|
||||||
},
|
},
|
||||||
"ollama_api_connecting": {
|
|
||||||
"message": "Tentativo di connettersi al server locale Ollama usando l'host"
|
|
||||||
},
|
|
||||||
"andModel": {
|
|
||||||
"message": "e il modello"
|
|
||||||
},
|
|
||||||
"error_connection_interrupted": {
|
"error_connection_interrupted": {
|
||||||
"message": "La connessione al server è stata interrotta inaspettatamente"
|
"message": "La connessione al server è stata interrotta inaspettatamente"
|
||||||
},
|
},
|
||||||
|
|
@ -399,9 +390,6 @@
|
||||||
"OpenAIComp_empty_model": {
|
"OpenAIComp_empty_model": {
|
||||||
"message": "Non hai scelto un modello per l'API compatibile con OpenAI. Scegline uno nella pagina delle opzioni."
|
"message": "Non hai scelto un modello per l'API compatibile con OpenAI. Scegline uno nella pagina delle opzioni."
|
||||||
},
|
},
|
||||||
"OpenAIComp_api_connecting": {
|
|
||||||
"message": "Tentativo di connessione al server locale dell'API compatibile con OpenAI utilizzando l'host"
|
|
||||||
},
|
|
||||||
"OpenAIComp_api_request_failed": {
|
"OpenAIComp_api_request_failed": {
|
||||||
"message": "Richiesta all'API compatibile con OpenAI fallita"
|
"message": "Richiesta all'API compatibile con OpenAI fallita"
|
||||||
},
|
},
|
||||||
|
|
@ -681,9 +669,6 @@
|
||||||
"google_gemini_api_request_failed": {
|
"google_gemini_api_request_failed": {
|
||||||
"message": "La richiesta all'API Google Gemini è fallita"
|
"message": "La richiesta all'API Google Gemini è fallita"
|
||||||
},
|
},
|
||||||
"google_gemini_api_connecting": {
|
|
||||||
"message": "Tentativo di connessione a Google Gemini utilizzando la chiave API fornita"
|
|
||||||
},
|
|
||||||
"google_gemini_empty_apikey": {
|
"google_gemini_empty_apikey": {
|
||||||
"message": "Non hai aggiunto una chiave API per l'API Google Gemini. Inseriscine una nella pagina delle opzioni."
|
"message": "Non hai aggiunto una chiave API per l'API Google Gemini. Inseriscine una nella pagina delle opzioni."
|
||||||
},
|
},
|
||||||
|
|
@ -712,7 +697,7 @@
|
||||||
"message": "Aggiungi un nuovo evento al calendario"
|
"message": "Aggiungi un nuovo evento al calendario"
|
||||||
},
|
},
|
||||||
"prompt_get_calendar_event_full_text": {
|
"prompt_get_calendar_event_full_text": {
|
||||||
"message": "Estrai tutti i dettagli rilevanti necessari per generare un evento del calendario dal seguente testo. Le informazioni estratte devono includere:\n- Titolo dell'evento\n- Data e ora di inizio (incluso il fuso orario, se specificato)\n- Data e ora di fine (incluso il fuso orario, se specificato)\n- Giornata intera (se menzionato)\n- I partecipanti\nAssicurati che i dati siano formattati in modo chiaro e coerente in modo che possano essere utilizzati direttamente per creare un evento del calendario.\nSe ci sono riferimenti temporali relativi, considera che la data e l'ora dell'email sono \"{%mail_datetime%}\". Calcola la data e l'ora di inizio in base a questo riferimento. Se la data e l'ora di inizio calcolate sono precedenti a \"{%current_datetime%}\", ricalcolale utilizzando \"{%current_datetime%}\" come base.\nSe la durata non è specificata, impostala a un'ora.\nQuesti sono i partecipanti: {%author%}, {%recipients%}, {%cc_list%}. Se presente, escludi il mio indirizzo: {%account_email_address%}.\nSe non riesci a ottenere una o più delle informazioni richieste, rispondi con una stringa vuota.\nGenera una risposta solo in formato JSON. Non includere testo o spiegazioni aggiuntive; fornisci solo il JSON. Ecco il formato da utilizzare:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Riassunto evento calendario qui\",\n\"forceAllDay\": false\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nEcco il testo: \"{%selected_text%}\""
|
"message": "Estrai tutti i dettagli rilevanti necessari per generare un evento del calendario dal seguente testo. Le informazioni estratte devono includere:\n- Titolo dell'evento\n- Data e ora di inizio (incluso il fuso orario, se specificato)\n- Data e ora di fine (incluso il fuso orario, se specificato)\n- Giornata intera (se menzionato)\n- I partecipanti\nAssicurati che i dati siano formattati in modo chiaro e coerente in modo che possano essere utilizzati direttamente per creare un evento del calendario.\nSe ci sono riferimenti temporali relativi, considera che la data e l'ora dell'email sono \"{%mail_datetime%}\". Calcola la data e l'ora di inizio in base a questo riferimento. Se la data e l'ora di inizio calcolate sono precedenti a \"{%current_datetime%}\", ricalcolale utilizzando \"{%current_datetime%}\" come base.\nSe la durata non è specificata, impostala a un'ora.\nQuesti sono i partecipanti: {%author%}, {%recipients%}, {%cc_list%}. Se presente, escludi il mio indirizzo: {%account_email_address%}.\nSe non riesci a ottenere una o più delle informazioni richieste, rispondi con una stringa vuota.\nGenera una risposta solo in formato JSON. Non includere testo o spiegazioni aggiuntive; fornisci solo il JSON. Ecco il formato da utilizzare:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Riassunto evento calendario qui\",\n\"forceAllDay\": false\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nEcco il testo: \"{%mail_text_body_or_selected%}\""
|
||||||
},
|
},
|
||||||
"prefs_OptionText_get_calendar_event": {
|
"prefs_OptionText_get_calendar_event": {
|
||||||
"message": "Aggiungi un nuovo evento al calendario dal testo selezionato"
|
"message": "Aggiungi un nuovo evento al calendario dal testo selezionato"
|
||||||
|
|
@ -753,9 +738,6 @@
|
||||||
"calendar_opening_dialog_error": {
|
"calendar_opening_dialog_error": {
|
||||||
"message": "Errore durante l'apertura della finestra di dialogo dell'evento del calendario"
|
"message": "Errore durante l'apertura della finestra di dialogo dell'evento del calendario"
|
||||||
},
|
},
|
||||||
"sparks_not_installed": {
|
|
||||||
"message": "ThunderAI Sparks non installato!"
|
|
||||||
},
|
|
||||||
"Subject": {
|
"Subject": {
|
||||||
"message": "Oggetto"
|
"message": "Oggetto"
|
||||||
},
|
},
|
||||||
|
|
@ -789,7 +771,7 @@
|
||||||
"Moved_to_Spam": {
|
"Moved_to_Spam": {
|
||||||
"message": "Spostato nello spam"
|
"message": "Spostato nello spam"
|
||||||
},
|
},
|
||||||
"spamfilter_not_moved": {
|
"no_string": {
|
||||||
"message": "No"
|
"message": "No"
|
||||||
},
|
},
|
||||||
"From": {
|
"From": {
|
||||||
|
|
@ -798,7 +780,7 @@
|
||||||
"prefs_OptionText_btnManageSpamFilterInfo": {
|
"prefs_OptionText_btnManageSpamFilterInfo": {
|
||||||
"message": "Gestisci le impostazioni del filtro antispam"
|
"message": "Gestisci le impostazioni del filtro antispam"
|
||||||
},
|
},
|
||||||
"spamfilter_moved": {
|
"yes_string": {
|
||||||
"message": "Sì"
|
"message": "Sì"
|
||||||
},
|
},
|
||||||
"SpamReport_Title": {
|
"SpamReport_Title": {
|
||||||
|
|
@ -879,9 +861,6 @@
|
||||||
"btn_show_differences": {
|
"btn_show_differences": {
|
||||||
"message": "Mostra le differenze"
|
"message": "Mostra le differenze"
|
||||||
},
|
},
|
||||||
"apiwebchat_show_differences": {
|
|
||||||
"message": "Mostra le differenze"
|
|
||||||
},
|
|
||||||
"apiwebchat_error": {
|
"apiwebchat_error": {
|
||||||
"message": "Errore"
|
"message": "Errore"
|
||||||
},
|
},
|
||||||
|
|
@ -894,21 +873,9 @@
|
||||||
"prefs_OptionText_calendar_enforce_timezone": {
|
"prefs_OptionText_calendar_enforce_timezone": {
|
||||||
"message": "Forza il fuso orario specificato"
|
"message": "Forza il fuso orario specificato"
|
||||||
},
|
},
|
||||||
"prefs_OptionText_add_tags_context_menu_Info": {
|
|
||||||
"message": "Se selezionato, la voce \"Aggiungi etichette\" verrà mostrata facendo clic con il pulsante destro del mouse su un'email nell'elenco dei messaggi."
|
|
||||||
},
|
|
||||||
"apiwebchat_use_this_answer": {
|
"apiwebchat_use_this_answer": {
|
||||||
"message": "Usa questa risposta"
|
"message": "Usa questa risposta"
|
||||||
},
|
},
|
||||||
"prefs_OptionText_spamfilter_context_menu_Info": {
|
|
||||||
"message": "Se selezionato, la voce \"Analizza come spam\" verrà mostrata facendo clic con il pulsante destro del mouse su un'email nell'elenco dei messaggi."
|
|
||||||
},
|
|
||||||
"prefs_OptionText_spamfilter_context_menu": {
|
|
||||||
"message": "Mostra la voce \"Analizza come spam\" nel menu contestuale"
|
|
||||||
},
|
|
||||||
"prefs_OptionText_add_tags_context_menu": {
|
|
||||||
"message": "Mostra la voce \"Aggiungi etichette\" nel menu contestuale"
|
|
||||||
},
|
|
||||||
"apiwebchat_info": {
|
"apiwebchat_info": {
|
||||||
"message": "Informazioni"
|
"message": "Informazioni"
|
||||||
},
|
},
|
||||||
|
|
@ -933,12 +900,6 @@
|
||||||
"CORS_alternative_1": {
|
"CORS_alternative_1": {
|
||||||
"message": "Problemi con la configurazione di CORS?"
|
"message": "Problemi con la configurazione di CORS?"
|
||||||
},
|
},
|
||||||
"CORS_alternative_2": {
|
|
||||||
"message": "Premi il pulsante qui sotto per concedere il permesso <all_urls> ed evitare qualsiasi problema legato a CORS."
|
|
||||||
},
|
|
||||||
"CORS_give_allurls_perm": {
|
|
||||||
"message": "Concedi il permesso \"tutti gli URL\""
|
|
||||||
},
|
|
||||||
"remember_CORS": {
|
"remember_CORS": {
|
||||||
"message": "Ricorda, devi configurare le impostazioni CORS sul server!"
|
"message": "Ricorda, devi configurare le impostazioni CORS sul server!"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -750,7 +750,7 @@
|
||||||
"message": "新しいカレンダーイベントを追加"
|
"message": "新しいカレンダーイベントを追加"
|
||||||
},
|
},
|
||||||
"prompt_get_calendar_event_full_text": {
|
"prompt_get_calendar_event_full_text": {
|
||||||
"message": "以下のテキストからカレンダーイベントを生成するために必要なすべての関連詳細を抽出してください。抽出情報には以下を含めてください:\n- イベントタイトル\n- 開始日時(指定されている場合はタイムゾーンを含む)\n- 終了日時(指定されている場合はタイムゾーンを含む)\n- 終日(言及されている場合)\n- 出席者\nデータはカレンダーイベントの作成に直接使用できるよう、明確かつ一貫した形式にしてください。\n相対的な時間参照がある場合、メールの日時は「{%mail_datetime%}」であることを考慮してください。この参照に基づいて開始日時を計算してください。計算された開始日時が「{%current_datetime%}」より前の場合、「{%current_datetime%}」を基準として開始日時を再計算してください。\n期間が指定されていない場合は、1時間に設定してください。\n出席者:{%author%}、{%recipients%}、{%cc_list%}。存在する場合、私のアドレス{%account_email_address%}を除外してください。\n必要な情報の1つ以上を取得できない場合は、空の文字列で応答してください。\nJSON形式のみで応答を生成してください。追加のテキストや説明は含めず、JSONのみを提供してください。使用する形式:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"カレンダーイベントの概要をここに\",\n\"forceAllDay\": false,\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nテキスト:「{%selected_text%}」"
|
"message": "以下のテキストからカレンダーイベントを生成するために必要なすべての関連詳細を抽出してください。抽出情報には以下を含めてください:\n- イベントタイトル\n- 開始日時(指定されている場合はタイムゾーンを含む)\n- 終了日時(指定されている場合はタイムゾーンを含む)\n- 終日(言及されている場合)\n- 出席者\nデータはカレンダーイベントの作成に直接使用できるよう、明確かつ一貫した形式にしてください。\n相対的な時間参照がある場合、メールの日時は「{%mail_datetime%}」であることを考慮してください。この参照に基づいて開始日時を計算してください。計算された開始日時が「{%current_datetime%}」より前の場合、「{%current_datetime%}」を基準として開始日時を再計算してください。\n期間が指定されていない場合は、1時間に設定してください。\n出席者:{%author%}、{%recipients%}、{%cc_list%}。存在する場合、私のアドレス{%account_email_address%}を除外してください。\n必要な情報の1つ以上を取得できない場合は、空の文字列で応答してください。\nJSON形式のみで応答を生成してください。追加のテキストや説明は含めず、JSONのみを提供してください。使用する形式:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"カレンダーイベントの概要をここに\",\n\"forceAllDay\": false,\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nテキスト:「{%mail_text_body_or_selected%}」"
|
||||||
},
|
},
|
||||||
"prompt_get_task": {
|
"prompt_get_task": {
|
||||||
"message": "新しいタスクを追加"
|
"message": "新しいタスクを追加"
|
||||||
|
|
@ -959,10 +959,10 @@
|
||||||
"Report_Date": {
|
"Report_Date": {
|
||||||
"message": "レポート日"
|
"message": "レポート日"
|
||||||
},
|
},
|
||||||
"spamfilter_moved": {
|
"yes_string": {
|
||||||
"message": "はい"
|
"message": "はい"
|
||||||
},
|
},
|
||||||
"spamfilter_not_moved": {
|
"no_string": {
|
||||||
"message": "いいえ"
|
"message": "いいえ"
|
||||||
},
|
},
|
||||||
"context_menu_mzta-add-tags": {
|
"context_menu_mzta-add-tags": {
|
||||||
|
|
@ -971,18 +971,6 @@
|
||||||
"context_menu_mzta-spamfilter": {
|
"context_menu_mzta-spamfilter": {
|
||||||
"message": "スパムを分析"
|
"message": "スパムを分析"
|
||||||
},
|
},
|
||||||
"prefs_OptionText_add_tags_context_menu": {
|
|
||||||
"message": "「タグを追加」コンテキストメニュー項目を表示"
|
|
||||||
},
|
|
||||||
"prefs_OptionText_add_tags_context_menu_Info": {
|
|
||||||
"message": "チェックすると、メッセージリストでメールを右クリックした際に「タグを追加」コンテキストメニュー項目が表示されます。"
|
|
||||||
},
|
|
||||||
"prefs_OptionText_spamfilter_context_menu": {
|
|
||||||
"message": "「スパムを分析」コンテキストメニュー項目を表示"
|
|
||||||
},
|
|
||||||
"prefs_OptionText_spamfilter_context_menu_Info": {
|
|
||||||
"message": "チェックすると、メッセージリストでメールを右クリックした際に「スパムを分析」コンテキストメニュー項目が表示されます。"
|
|
||||||
},
|
|
||||||
"noActiveCalendar": {
|
"noActiveCalendar": {
|
||||||
"message": "編集可能なカレンダーが見つかりません!"
|
"message": "編集可能なカレンダーが見つかりません!"
|
||||||
},
|
},
|
||||||
|
|
@ -1022,12 +1010,6 @@
|
||||||
"CORS_alternative_1": {
|
"CORS_alternative_1": {
|
||||||
"message": "CORS設定に問題がありますか?"
|
"message": "CORS設定に問題がありますか?"
|
||||||
},
|
},
|
||||||
"CORS_alternative_2": {
|
|
||||||
"message": "下のボタンを押して<all_urls>権限を付与し、CORSの問題を回避してください。"
|
|
||||||
},
|
|
||||||
"CORS_give_allurls_perm": {
|
|
||||||
"message": "「すべてのURL」権限を付与"
|
|
||||||
},
|
|
||||||
"prefs_OptionText_composing_plain_text": {
|
"prefs_OptionText_composing_plain_text": {
|
||||||
"message": "プレーンテキストで作成"
|
"message": "プレーンテキストで作成"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -327,9 +327,6 @@
|
||||||
"chagpt_api_send_button": {
|
"chagpt_api_send_button": {
|
||||||
"message": "Używając modelu"
|
"message": "Używając modelu"
|
||||||
},
|
},
|
||||||
"chagpt_api_connecting": {
|
|
||||||
"message": "Próba połączenia z OpenAI ChatGPT przy użyciu podanego klucza API"
|
|
||||||
},
|
|
||||||
"Debug": {
|
"Debug": {
|
||||||
"message": "Debugowanie"
|
"message": "Debugowanie"
|
||||||
},
|
},
|
||||||
|
|
@ -363,12 +360,6 @@
|
||||||
"ollama_empty_model": {
|
"ollama_empty_model": {
|
||||||
"message": "Nie wybrałeś modelu dla API Ollama. Proszę wybierz jeden na stronie opcji."
|
"message": "Nie wybrałeś modelu dla API Ollama. Proszę wybierz jeden na stronie opcji."
|
||||||
},
|
},
|
||||||
"ollama_api_connecting": {
|
|
||||||
"message": "Próba połączenia z lokalnym serwerem Ollama używając hosta"
|
|
||||||
},
|
|
||||||
"andModel": {
|
|
||||||
"message": "i modelu"
|
|
||||||
},
|
|
||||||
"error_connection_interrupted": {
|
"error_connection_interrupted": {
|
||||||
"message": "Połączenie z serwerem zostało nieoczekiwanie przerwane"
|
"message": "Połączenie z serwerem zostało nieoczekiwanie przerwane"
|
||||||
},
|
},
|
||||||
|
|
@ -399,9 +390,6 @@
|
||||||
"OpenAIComp_empty_model": {
|
"OpenAIComp_empty_model": {
|
||||||
"message": "Nie wybrałeś modelu dla API kompatybilnego z OpenAI. Proszę wybierz jeden na stronie opcji."
|
"message": "Nie wybrałeś modelu dla API kompatybilnego z OpenAI. Proszę wybierz jeden na stronie opcji."
|
||||||
},
|
},
|
||||||
"OpenAIComp_api_connecting": {
|
|
||||||
"message": "Próba połączenia z lokalnym serwerem API kompatybilnym z OpenAI używając hosta"
|
|
||||||
},
|
|
||||||
"OpenAIComp_api_request_failed": {
|
"OpenAIComp_api_request_failed": {
|
||||||
"message": "Zapytanie do API kompatybilnego z OpenAI nie powiodło się"
|
"message": "Zapytanie do API kompatybilnego z OpenAI nie powiodło się"
|
||||||
},
|
},
|
||||||
|
|
@ -672,9 +660,6 @@
|
||||||
"google_gemini_api_request_failed": {
|
"google_gemini_api_request_failed": {
|
||||||
"message": "Połączenie do interfejsu API Google Gemini nie powiodło się"
|
"message": "Połączenie do interfejsu API Google Gemini nie powiodło się"
|
||||||
},
|
},
|
||||||
"google_gemini_api_connecting": {
|
|
||||||
"message": "Próba połączenia z Google Gemini przy użyciu dostarczonego klucza API"
|
|
||||||
},
|
|
||||||
"google_gemini_empty_apikey": {
|
"google_gemini_empty_apikey": {
|
||||||
"message": "Nie dodałeś klucza API dla API Google Gemini. Wstaw go na stronie opcji."
|
"message": "Nie dodałeś klucza API dla API Google Gemini. Wstaw go na stronie opcji."
|
||||||
},
|
},
|
||||||
|
|
@ -703,7 +688,7 @@
|
||||||
"message": "Dodaj nowe wydarzenie w kalendarzu"
|
"message": "Dodaj nowe wydarzenie w kalendarzu"
|
||||||
},
|
},
|
||||||
"prompt_get_calendar_event_full_text": {
|
"prompt_get_calendar_event_full_text": {
|
||||||
"message": "Wyodrębnij wszystkie istotne szczegóły wymagane do wygenerowania wydarzenia w kalendarzu z poniższego tekstu. Wyodrębnione informacje powinny obejmować:\n- Tytuł wydarzenia\n- Datę i godzinę rozpoczęcia (w tym strefę czasową, jeśli została określona)\n- Datę i godzinę zakończenia (w tym strefę czasową, jeśli została określona)\n- Cały dzień (jeśli jest podany)\n- Uczestnicy\nUpewnij się, że dane są sformatowane w sposób jasny i spójny, tak aby można go bezpośrednio wykorzystać do utworzenia wydarzenia w kalendarzu.\nJeśli istnieją odniesienia do czasu względnego, pamiętaj, że data i godzina wysłania wiadomości e-mail to „{%mail_datetime%}”. Oblicz datę i godzinę rozpoczęcia na podstawie tego odniesienia. Jeśli obliczona data i godzina rozpoczęcia są wcześniejsze niż „{%current_datetime%}”, oblicz ponownie datę i godzinę rozpoczęcia, stosując jako podstawę „{%current_datetime%}”.\nJeśli czas trwania nie jest określony, ustaw go na jedną godzinę.\nOto uczestnicy: {%author%}, {%recipients%}, {%cc_list%}. Jeśli jest obecny, wyklucz mój adres: {%account_email_address%}.\nJeśli nie możesz uzyskać co najmniej jednej z wymaganych informacji, w odpowiedzi wpisz pusty ciąg znaków.\nWygeneruj odpowiedź tylko w formacie JSON. Nie dołączaj żadnego dodatkowego tekstu ani wyjaśnień; podaj tylko JSON. Oto format, którego należy użyć:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Tutaj podsumowanie wydarzenia w kalendarzu\",\n\"forceAllDay\": false\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nOto tekst:\"{%selected_text %}\""
|
"message": "Wyodrębnij wszystkie istotne szczegóły wymagane do wygenerowania wydarzenia w kalendarzu z poniższego tekstu. Wyodrębnione informacje powinny obejmować:\n- Tytuł wydarzenia\n- Datę i godzinę rozpoczęcia (w tym strefę czasową, jeśli została określona)\n- Datę i godzinę zakończenia (w tym strefę czasową, jeśli została określona)\n- Cały dzień (jeśli jest podany)\n- Uczestnicy\nUpewnij się, że dane są sformatowane w sposób jasny i spójny, tak aby można go bezpośrednio wykorzystać do utworzenia wydarzenia w kalendarzu.\nJeśli istnieją odniesienia do czasu względnego, pamiętaj, że data i godzina wysłania wiadomości e-mail to „{%mail_datetime%}”. Oblicz datę i godzinę rozpoczęcia na podstawie tego odniesienia. Jeśli obliczona data i godzina rozpoczęcia są wcześniejsze niż „{%current_datetime%}”, oblicz ponownie datę i godzinę rozpoczęcia, stosując jako podstawę „{%current_datetime%}”.\nJeśli czas trwania nie jest określony, ustaw go na jedną godzinę.\nOto uczestnicy: {%author%}, {%recipients%}, {%cc_list%}. Jeśli jest obecny, wyklucz mój adres: {%account_email_address%}.\nJeśli nie możesz uzyskać co najmniej jednej z wymaganych informacji, w odpowiedzi wpisz pusty ciąg znaków.\nWygeneruj odpowiedź tylko w formacie JSON. Nie dołączaj żadnego dodatkowego tekstu ani wyjaśnień; podaj tylko JSON. Oto format, którego należy użyć:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Tutaj podsumowanie wydarzenia w kalendarzu\",\n\"forceAllDay\": false\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nOto tekst:\"{%mail_text_body_or_selected%}\""
|
||||||
},
|
},
|
||||||
"prefs_OptionText_get_calendar_event": {
|
"prefs_OptionText_get_calendar_event": {
|
||||||
"message": "Dodaj nowe wydarzenie w kalendarzu z zaznaczonego tekstu"
|
"message": "Dodaj nowe wydarzenie w kalendarzu z zaznaczonego tekstu"
|
||||||
|
|
@ -792,15 +777,12 @@
|
||||||
"Moved_to_Spam": {
|
"Moved_to_Spam": {
|
||||||
"message": "Przeniesiono do spamu"
|
"message": "Przeniesiono do spamu"
|
||||||
},
|
},
|
||||||
"spamfilter_not_moved": {
|
"no_string": {
|
||||||
"message": "Nie"
|
"message": "Nie"
|
||||||
},
|
},
|
||||||
"prefs_OptionText_add_tags_auto_force_existing_Info": {
|
"prefs_OptionText_add_tags_auto_force_existing_Info": {
|
||||||
"message": "Jeśli zaznaczone, AI doda tylko istniejące tagi do nowo odebranych e-maili i nie utworzy nowych."
|
"message": "Jeśli zaznaczone, AI doda tylko istniejące tagi do nowo odebranych e-maili i nie utworzy nowych."
|
||||||
},
|
},
|
||||||
"sparks_not_installed": {
|
|
||||||
"message": "ThunderAI Sparks nie zainstalowany!"
|
|
||||||
},
|
|
||||||
"SpamFilter_info_default": {
|
"SpamFilter_info_default": {
|
||||||
"message": "Na tej stronie możesz edytować domyślny prompt używany do wykrywania e-maili spamowych."
|
"message": "Na tej stronie możesz edytować domyślny prompt używany do wykrywania e-maili spamowych."
|
||||||
},
|
},
|
||||||
|
|
@ -813,7 +795,7 @@
|
||||||
"prefs_OptionText_btnManageSpamFilterInfo": {
|
"prefs_OptionText_btnManageSpamFilterInfo": {
|
||||||
"message": "Zarządzaj ustawieniami filtra spamu"
|
"message": "Zarządzaj ustawieniami filtra spamu"
|
||||||
},
|
},
|
||||||
"spamfilter_moved": {
|
"yes_string": {
|
||||||
"message": "Tak"
|
"message": "Tak"
|
||||||
},
|
},
|
||||||
"prefs_OptionText_spamfilter": {
|
"prefs_OptionText_spamfilter": {
|
||||||
|
|
|
||||||
|
|
@ -327,9 +327,6 @@
|
||||||
"chagpt_api_send_button": {
|
"chagpt_api_send_button": {
|
||||||
"message": "Usando modelo"
|
"message": "Usando modelo"
|
||||||
},
|
},
|
||||||
"chagpt_api_connecting": {
|
|
||||||
"message": "Tentando conectar ao OpenAI ChatGPT usando a chave de API fornecida"
|
|
||||||
},
|
|
||||||
"Debug": {
|
"Debug": {
|
||||||
"message": "Depurar"
|
"message": "Depurar"
|
||||||
},
|
},
|
||||||
|
|
@ -363,12 +360,6 @@
|
||||||
"ollama_empty_model": {
|
"ollama_empty_model": {
|
||||||
"message": "Você não escolheu um modelo para a API do Ollama. Por favor, escolha um na página de opções."
|
"message": "Você não escolheu um modelo para a API do Ollama. Por favor, escolha um na página de opções."
|
||||||
},
|
},
|
||||||
"ollama_api_connecting": {
|
|
||||||
"message": "Tentando conectar ao servidor local do Ollama usando o host"
|
|
||||||
},
|
|
||||||
"andModel": {
|
|
||||||
"message": "e modelo"
|
|
||||||
},
|
|
||||||
"error_connection_interrupted": {
|
"error_connection_interrupted": {
|
||||||
"message": "A conexão com o servidor foi interrompida inesperadamente"
|
"message": "A conexão com o servidor foi interrompida inesperadamente"
|
||||||
},
|
},
|
||||||
|
|
@ -399,9 +390,6 @@
|
||||||
"OpenAIComp_empty_model": {
|
"OpenAIComp_empty_model": {
|
||||||
"message": "Você não escolheu um modelo para a API Compatível com OpenAI. Por favor, escolha um na página de opções."
|
"message": "Você não escolheu um modelo para a API Compatível com OpenAI. Por favor, escolha um na página de opções."
|
||||||
},
|
},
|
||||||
"OpenAIComp_api_connecting": {
|
|
||||||
"message": "Tentando conectar ao Servidor Local da API Compatível com OpenAI usando o host"
|
|
||||||
},
|
|
||||||
"OpenAIComp_api_request_failed": {
|
"OpenAIComp_api_request_failed": {
|
||||||
"message": "Solicitação da API Comp do OpenAI falhou"
|
"message": "Solicitação da API Comp do OpenAI falhou"
|
||||||
},
|
},
|
||||||
|
|
@ -681,9 +669,6 @@
|
||||||
"google_gemini_api_request_failed": {
|
"google_gemini_api_request_failed": {
|
||||||
"message": "A solicitação para a API Google Gemini falhou"
|
"message": "A solicitação para a API Google Gemini falhou"
|
||||||
},
|
},
|
||||||
"google_gemini_api_connecting": {
|
|
||||||
"message": "Tentando conectar ao Google Gemini usando a chave API fornecida"
|
|
||||||
},
|
|
||||||
"google_gemini_empty_apikey": {
|
"google_gemini_empty_apikey": {
|
||||||
"message": "Você não adicionou uma chave API para a API Google Gemini. Por favor, insira uma na página de opções."
|
"message": "Você não adicionou uma chave API para a API Google Gemini. Por favor, insira uma na página de opções."
|
||||||
},
|
},
|
||||||
|
|
@ -712,7 +697,7 @@
|
||||||
"message": "Adicionar um novo evento ao calendário"
|
"message": "Adicionar um novo evento ao calendário"
|
||||||
},
|
},
|
||||||
"prompt_get_calendar_event_full_text": {
|
"prompt_get_calendar_event_full_text": {
|
||||||
"message": "Extraia todos os detalhes relevantes necessários para gerar um evento de calendário a partir do texto a seguir. As informações extraídas devem incluir:\n- Título do evento\n- Data e hora de início (incluindo fuso horário, se especificado)\n- Data e hora de término (incluindo fuso horário, se especificado)\n- Dia inteiro (se mencionado)\n- Participantes\nCertifique-se de que os dados estejam formatados de maneira clara e consistente para que possam ser usados diretamente para criar um evento de calendário.\nSe houver referências de tempo relativas, considere que a data e a hora do e-mail são \"{%mail_datetime%}\". Calcule a data e a hora de início com base nessa referência. Se a data e a hora de início calculadas forem anteriores a \"{%current_datetime%}\", recalcule a data e a hora de início usando \"{%current_datetime%}\" como base.\nSe a duração não for especificada, defina-a como uma hora.\nEstes são os participantes: {%author%}, {%recipients%}, {%cc_list%}. Se estiver presente, exclua meu endereço: {%account_email_address%}.\nSe você não conseguir obter uma ou mais informações necessárias, responda com uma string vazia.\nGere uma resposta apenas no formato JSON. Não inclua texto ou explicações adicionais; forneça apenas o JSON. Aqui está o formato a ser usado:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Resumo do evento do calendário aqui\",\n\"forceAllDay\": false\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nAqui está o texto: \"{%selected_text%}\""
|
"message": "Extraia todos os detalhes relevantes necessários para gerar um evento de calendário a partir do texto a seguir. As informações extraídas devem incluir:\n- Título do evento\n- Data e hora de início (incluindo fuso horário, se especificado)\n- Data e hora de término (incluindo fuso horário, se especificado)\n- Dia inteiro (se mencionado)\n- Participantes\nCertifique-se de que os dados estejam formatados de maneira clara e consistente para que possam ser usados diretamente para criar um evento de calendário.\nSe houver referências de tempo relativas, considere que a data e a hora do e-mail são \"{%mail_datetime%}\". Calcule a data e a hora de início com base nessa referência. Se a data e a hora de início calculadas forem anteriores a \"{%current_datetime%}\", recalcule a data e a hora de início usando \"{%current_datetime%}\" como base.\nSe a duração não for especificada, defina-a como uma hora.\nEstes são os participantes: {%author%}, {%recipients%}, {%cc_list%}. Se estiver presente, exclua meu endereço: {%account_email_address%}.\nSe você não conseguir obter uma ou mais informações necessárias, responda com uma string vazia.\nGere uma resposta apenas no formato JSON. Não inclua texto ou explicações adicionais; forneça apenas o JSON. Aqui está o formato a ser usado:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"Resumo do evento do calendário aqui\",\n\"forceAllDay\": false\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nAqui está o texto: \"{%mail_text_body_or_selected%}\""
|
||||||
},
|
},
|
||||||
"prefs_OptionText_get_calendar_event": {
|
"prefs_OptionText_get_calendar_event": {
|
||||||
"message": "Adicionar um novo evento ao calendário a partir do texto selecionado"
|
"message": "Adicionar um novo evento ao calendário a partir do texto selecionado"
|
||||||
|
|
@ -795,12 +780,9 @@
|
||||||
"Moved_to_Spam": {
|
"Moved_to_Spam": {
|
||||||
"message": "Movido para spam"
|
"message": "Movido para spam"
|
||||||
},
|
},
|
||||||
"spamfilter_not_moved": {
|
"no_string": {
|
||||||
"message": "Não"
|
"message": "Não"
|
||||||
},
|
},
|
||||||
"sparks_not_installed": {
|
|
||||||
"message": "ThunderAI Sparks não instalado!"
|
|
||||||
},
|
|
||||||
"prefs_OptionText_btnManageSpamFilterInfo": {
|
"prefs_OptionText_btnManageSpamFilterInfo": {
|
||||||
"message": "Gerenciar configurações do filtro de spam"
|
"message": "Gerenciar configurações do filtro de spam"
|
||||||
},
|
},
|
||||||
|
|
@ -810,7 +792,7 @@
|
||||||
"prefs_OptionText_spamfilter_Info": {
|
"prefs_OptionText_spamfilter_Info": {
|
||||||
"message": "Se marcado, o ThunderAI moverá automaticamente e-mails de spam para a pasta de spam."
|
"message": "Se marcado, o ThunderAI moverá automaticamente e-mails de spam para a pasta de spam."
|
||||||
},
|
},
|
||||||
"spamfilter_moved": {
|
"yes_string": {
|
||||||
"message": "Sim"
|
"message": "Sim"
|
||||||
},
|
},
|
||||||
"SpamReport_Title": {
|
"SpamReport_Title": {
|
||||||
|
|
|
||||||
|
|
@ -735,7 +735,7 @@
|
||||||
"message": "Добавьте новое событие календаря"
|
"message": "Добавьте новое событие календаря"
|
||||||
},
|
},
|
||||||
"prompt_get_calendar_event_full_text": {
|
"prompt_get_calendar_event_full_text": {
|
||||||
"message": "Извлеките из следующего текста все необходимые сведения, необходимые для создания календарного события. Извлеченная информация должна включать:\n- Название события\n- Дата и время начала (включая часовой пояс, если он указан)\n- Дата и время окончания (включая часовой пояс, если он указан)\n- Полный день (если указано)\n- Участники\nУбедитесь, что данные отформатированы четко и последовательно, чтобы их можно было напрямую использовать для создания календарного события.\nЕсли есть относительные временные ссылки, считайте, что дата и время письма - это \"{%mail_datetime%}\". Рассчитайте дату и время начала на основе этой ссылки. Если вычисленные дата и время начала раньше, чем \"{%current_datetime%}\", пересчитайте дату и время начала, взяв за основу \"{%current_datetime%}\".\nЕсли продолжительность не указана, установите ее равной одному часу.\nК ним относятся: {%author%}, {%recipients%}, {%cc_list%}. Если присутствует, исключите мой адрес: {%account_email_address%}.\nЕсли вы не можете получить одну или несколько требуемых данных, ответьте пустой строкой.\nГенерируйте ответ только в формате JSON. Не включайте никаких дополнительных текстов или пояснений; предоставляйте только JSON. Вот формат, который следует использовать:\n{\n\"startDate\": \"ГГГГММДДДХММССС\",\n\"endDate\": \"ГГГГММДДДХММССС\",\n\"summary\": \"Здесь выводится краткое описание события календаря\",\n\"forceAllDay\": false,\n\"attendees\": [участник1@example.com,участник2@example.com,участник3@example.com]\n}\nВот текст: \"{%selected_text%}\""
|
"message": "Извлеките из следующего текста все необходимые сведения, необходимые для создания календарного события. Извлеченная информация должна включать:\n- Название события\n- Дата и время начала (включая часовой пояс, если он указан)\n- Дата и время окончания (включая часовой пояс, если он указан)\n- Полный день (если указано)\n- Участники\nУбедитесь, что данные отформатированы четко и последовательно, чтобы их можно было напрямую использовать для создания календарного события.\nЕсли есть относительные временные ссылки, считайте, что дата и время письма - это \"{%mail_datetime%}\". Рассчитайте дату и время начала на основе этой ссылки. Если вычисленные дата и время начала раньше, чем \"{%current_datetime%}\", пересчитайте дату и время начала, взяв за основу \"{%current_datetime%}\".\nЕсли продолжительность не указана, установите ее равной одному часу.\nК ним относятся: {%author%}, {%recipients%}, {%cc_list%}. Если присутствует, исключите мой адрес: {%account_email_address%}.\nЕсли вы не можете получить одну или несколько требуемых данных, ответьте пустой строкой.\nГенерируйте ответ только в формате JSON. Не включайте никаких дополнительных текстов или пояснений; предоставляйте только JSON. Вот формат, который следует использовать:\n{\n\"startDate\": \"ГГГГММДДДХММССС\",\n\"endDate\": \"ГГГГММДДДХММССС\",\n\"summary\": \"Здесь выводится краткое описание события календаря\",\n\"forceAllDay\": false,\n\"attendees\": [участник1@example.com,участник2@example.com,участник3@example.com]\n}\nВот текст: \"{%mail_text_body_or_selected%}\""
|
||||||
},
|
},
|
||||||
"prompt_get_task": {
|
"prompt_get_task": {
|
||||||
"message": "Добавить новую задачу"
|
"message": "Добавить новую задачу"
|
||||||
|
|
@ -920,10 +920,10 @@
|
||||||
"Report_Date": {
|
"Report_Date": {
|
||||||
"message": "Дата отчета"
|
"message": "Дата отчета"
|
||||||
},
|
},
|
||||||
"spamfilter_moved": {
|
"yes_string": {
|
||||||
"message": "Да"
|
"message": "Да"
|
||||||
},
|
},
|
||||||
"spamfilter_not_moved": {
|
"no_string": {
|
||||||
"message": "Нет"
|
"message": "Нет"
|
||||||
},
|
},
|
||||||
"context_menu_mzta-add-tags": {
|
"context_menu_mzta-add-tags": {
|
||||||
|
|
@ -932,18 +932,6 @@
|
||||||
"context_menu_mzta-spamfilter": {
|
"context_menu_mzta-spamfilter": {
|
||||||
"message": "Анализ на предмет спама"
|
"message": "Анализ на предмет спама"
|
||||||
},
|
},
|
||||||
"prefs_OptionText_add_tags_context_menu": {
|
|
||||||
"message": "Показать пункт меню \"Добавить теги\""
|
|
||||||
},
|
|
||||||
"prefs_OptionText_add_tags_context_menu_Info": {
|
|
||||||
"message": "Если флажок установлен, пункт контекстного меню \"Добавить теги\" будет отображаться при щелчке ПКМ на письме в списке сообщений."
|
|
||||||
},
|
|
||||||
"prefs_OptionText_spamfilter_context_menu": {
|
|
||||||
"message": "Показать пункт контекстного меню \"Анализировать на предмет спама\""
|
|
||||||
},
|
|
||||||
"prefs_OptionText_spamfilter_context_menu_Info": {
|
|
||||||
"message": "Если флажок установлен, пункт контекстного меню \"Анализировать на спам\" будет отображаться при щелчке ПКМ на письме в списке сообщений."
|
|
||||||
},
|
|
||||||
"noActiveCalendar": {
|
"noActiveCalendar": {
|
||||||
"message": "Редактируемый календарь не найден!"
|
"message": "Редактируемый календарь не найден!"
|
||||||
},
|
},
|
||||||
|
|
@ -983,12 +971,6 @@
|
||||||
"CORS_alternative_1": {
|
"CORS_alternative_1": {
|
||||||
"message": "Проблемы с настройкой CORS?"
|
"message": "Проблемы с настройкой CORS?"
|
||||||
},
|
},
|
||||||
"CORS_alternative_2": {
|
|
||||||
"message": "Нажмите кнопку ниже, чтобы дать разрешение <all_urls> во избежание проблем с CORS."
|
|
||||||
},
|
|
||||||
"CORS_give_allurls_perm": {
|
|
||||||
"message": "Дайте разрешение на \"все URL-адреса\""
|
|
||||||
},
|
|
||||||
"prefs_OptionText_composing_plain_text": {
|
"prefs_OptionText_composing_plain_text": {
|
||||||
"message": "Сочинение обычного текста"
|
"message": "Сочинение обычного текста"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -797,10 +797,10 @@
|
||||||
"Report_Date": {
|
"Report_Date": {
|
||||||
"message": "Rapportdatum"
|
"message": "Rapportdatum"
|
||||||
},
|
},
|
||||||
"spamfilter_moved": {
|
"yes_string": {
|
||||||
"message": "Ja"
|
"message": "Ja"
|
||||||
},
|
},
|
||||||
"spamfilter_not_moved": {
|
"no_string": {
|
||||||
"message": "Nej"
|
"message": "Nej"
|
||||||
},
|
},
|
||||||
"context_menu_mzta-add-tags": {
|
"context_menu_mzta-add-tags": {
|
||||||
|
|
@ -809,18 +809,6 @@
|
||||||
"context_menu_mzta-spamfilter": {
|
"context_menu_mzta-spamfilter": {
|
||||||
"message": "Analysera för skräppost"
|
"message": "Analysera för skräppost"
|
||||||
},
|
},
|
||||||
"prefs_OptionText_add_tags_context_menu": {
|
|
||||||
"message": "Visa snabbmenyn \"Lägg till taggar\""
|
|
||||||
},
|
|
||||||
"prefs_OptionText_add_tags_context_menu_Info": {
|
|
||||||
"message": "Om markerat visas snabbmenyn \"Lägg till taggar\" när du högerklickar på ett e-postmeddelande i meddelandelistan."
|
|
||||||
},
|
|
||||||
"prefs_OptionText_spamfilter_context_menu": {
|
|
||||||
"message": "Visa snabbmenyalternativet \"Analysera för skräppost\""
|
|
||||||
},
|
|
||||||
"prefs_OptionText_spamfilter_context_menu_Info": {
|
|
||||||
"message": "Om markerat visas snabbmenyn \"Analysera för skräppost\" när du högerklickar på ett e-postmeddelande i meddelandelistan."
|
|
||||||
},
|
|
||||||
"noActiveCalendar": {
|
"noActiveCalendar": {
|
||||||
"message": "Ingen redigerbar kalender hittades!"
|
"message": "Ingen redigerbar kalender hittades!"
|
||||||
},
|
},
|
||||||
|
|
@ -860,9 +848,6 @@
|
||||||
"CORS_alternative_1": {
|
"CORS_alternative_1": {
|
||||||
"message": "Problem med att ställa in CORS?"
|
"message": "Problem med att ställa in CORS?"
|
||||||
},
|
},
|
||||||
"CORS_alternative_2": {
|
|
||||||
"message": "Tryck på knappen nedan för att ge <all_urls> behörighet för att undvika eventuella CORS-problem."
|
|
||||||
},
|
|
||||||
"customPrompts_Properties": {
|
"customPrompts_Properties": {
|
||||||
"message": "Egenskaper"
|
"message": "Egenskaper"
|
||||||
},
|
},
|
||||||
|
|
@ -1294,7 +1279,7 @@
|
||||||
"message": "Citerad text i meddelandets brödtext"
|
"message": "Citerad text i meddelandets brödtext"
|
||||||
},
|
},
|
||||||
"prompt_get_calendar_event_full_text": {
|
"prompt_get_calendar_event_full_text": {
|
||||||
"message": "Extrahera all relevant information som krävs för att generera en kalenderhändelse från följande text. Den extraherade informationen bör innehålla:\n- Händelsetitel\n- Startdatum och tid (inklusive tidszon, om angiven)\n- Slutdatum och tid (inklusive tidszon, om angiven)\n- Heldag (om angiven)\n- Deltagare\nSe till att informationen är tydligt och konsekvent formaterad så att den kan användas direkt för att skapa en kalenderhändelse.\nOm det finns relativa tidsreferenser, tänk på att datum och tid för e-postmeddelandet är \"{%mail_datetime%}\". Beräkna startdatum och tid baserat på denna referens. Om det beräknade startdatumet och tiden är tidigare än \"{%current_datetime%}\", beräkna om startdatumet och tiden med \"{%current_datetime%}\" som bas.\nOm varaktigheten inte anges, sätt den till en timme.\nDessa är deltagarna: {%author%}, {%recipients%}, {%cc_list%}. Om det finns, exkludera min adress: {%account_email_address%}.\nOm du inte kan få en eller flera av de obligatoriska uppgifterna, vänligen svara med en tom sträng.\nGenerera ett svar endast i JSON-format. Inkludera inte ytterligare text eller förklaringar; ange endast JSON. Här är formatet som ska användas:\n{\n\"startDate\": \"ÅÅÅÅMMDDTHHMMSS\",\n\"endDate\": \"ÅÅÅÅMMDDTHHMMSS\",\n\"summary\": \"Sammanfattning av kalenderhändelse här\",\n\"forceAllDay\": false,\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nHär är texten: \"{%selected_text%}\""
|
"message": "Extrahera all relevant information som krävs för att generera en kalenderhändelse från följande text. Den extraherade informationen bör innehålla:\n- Händelsetitel\n- Startdatum och tid (inklusive tidszon, om angiven)\n- Slutdatum och tid (inklusive tidszon, om angiven)\n- Heldag (om angiven)\n- Deltagare\nSe till att informationen är tydligt och konsekvent formaterad så att den kan användas direkt för att skapa en kalenderhändelse.\nOm det finns relativa tidsreferenser, tänk på att datum och tid för e-postmeddelandet är \"{%mail_datetime%}\". Beräkna startdatum och tid baserat på denna referens. Om det beräknade startdatumet och tiden är tidigare än \"{%current_datetime%}\", beräkna om startdatumet och tiden med \"{%current_datetime%}\" som bas.\nOm varaktigheten inte anges, sätt den till en timme.\nDessa är deltagarna: {%author%}, {%recipients%}, {%cc_list%}. Om det finns, exkludera min adress: {%account_email_address%}.\nOm du inte kan få en eller flera av de obligatoriska uppgifterna, vänligen svara med en tom sträng.\nGenerera ett svar endast i JSON-format. Inkludera inte ytterligare text eller förklaringar; ange endast JSON. Här är formatet som ska användas:\n{\n\"startDate\": \"ÅÅÅÅMMDDTHHMMSS\",\n\"endDate\": \"ÅÅÅÅMMDDTHHMMSS\",\n\"summary\": \"Sammanfattning av kalenderhändelse här\",\n\"forceAllDay\": false,\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\nHär är texten: \"{%mail_text_body_or_selected%}\""
|
||||||
},
|
},
|
||||||
"prompt_get_task_full_text": {
|
"prompt_get_task_full_text": {
|
||||||
"message": "Extrahera alla relevanta detaljer som krävs för att generera en uppgift från följande text. Den extraherade informationen bör innehålla:\n- Förfallodatum och tid (inklusive tidszon, om angiven)\n- Uppgiftssammanfattning\n- Initialt datum och tid (inklusive tidszon, om angiven)\nSe till att informationen är tydligt och konsekvent formaterad så att den kan användas direkt för att skapa en uppgift.\nOm det finns relativa tidsreferenser, tänk på att datum och tid för e-postmeddelandet är \"{%mail_datetime%}\". Beräkna startdatum och tid baserat på denna referens. Om det beräknade startdatumet och tiden är tidigare än \"{%current_datetime%}\", beräkna om startdatumet och tiden med \"{%current_datetime%}\" som bas.\nOm du inte kan få en eller flera av de obligatoriska uppgifterna, vänligen svara med en tom sträng.\nGenerera ett svar endast i JSON-format. Inkludera inte ytterligare text eller förklaringar; ange endast JSON. Här är formatet som ska användas:\n{\n\"InitialDate\": \"ÅÅÅÅMMDDTHHMMSS\",\n\"dueDate\": \"ÅÅÅÅMMDDTHHMMSS\",\n\"summary\": \"Uppgiftssammanfattning här\"\n}\nOm det inte finns någon information om datumen, ta bort dem.\nHär är texten: \"{%selected_text%}\""
|
"message": "Extrahera alla relevanta detaljer som krävs för att generera en uppgift från följande text. Den extraherade informationen bör innehålla:\n- Förfallodatum och tid (inklusive tidszon, om angiven)\n- Uppgiftssammanfattning\n- Initialt datum och tid (inklusive tidszon, om angiven)\nSe till att informationen är tydligt och konsekvent formaterad så att den kan användas direkt för att skapa en uppgift.\nOm det finns relativa tidsreferenser, tänk på att datum och tid för e-postmeddelandet är \"{%mail_datetime%}\". Beräkna startdatum och tid baserat på denna referens. Om det beräknade startdatumet och tiden är tidigare än \"{%current_datetime%}\", beräkna om startdatumet och tiden med \"{%current_datetime%}\" som bas.\nOm du inte kan få en eller flera av de obligatoriska uppgifterna, vänligen svara med en tom sträng.\nGenerera ett svar endast i JSON-format. Inkludera inte ytterligare text eller förklaringar; ange endast JSON. Här är formatet som ska användas:\n{\n\"InitialDate\": \"ÅÅÅÅMMDDTHHMMSS\",\n\"dueDate\": \"ÅÅÅÅMMDDTHHMMSS\",\n\"summary\": \"Uppgiftssammanfattning här\"\n}\nOm det inte finns någon information om datumen, ta bort dem.\nHär är texten: \"{%selected_text%}\""
|
||||||
|
|
@ -1302,7 +1287,130 @@
|
||||||
"prompt_spamfilter_full_text": {
|
"prompt_spamfilter_full_text": {
|
||||||
"message": "Analysera följande e-postmeddelande och avgör om det är skräppost eller inte. Tänk på faktorer som misstänkta sökord, överdrivet reklamspråk, vilseledande ämnesrader, förfrågningar om personlig information och ovanliga avsändaradresser.\nAnge ett värde från 0 (inte skräppost) till 100 (skräppost) och en förklaring på högst 10 ord.\nOm meddelandedata saknas, sätt värdet till 0 (inte skräppost) och ange orsaken.\nGenerera ett svar endast i JSON-format. Inkludera inte ytterligare text eller förklaring; ange endast JSON. Här är formatet som ska användas:\n{\n\"spamValue\": <heltal från 0 till 100>,\n\"explanation\": \"Kort förklaring av ditt resonemang\"\n}\nHär är e-postinformationen:\nAvsändare: \"{%author%}\"\nÄmne: \"{%mail_subject%}\"\nHtml-text: \"{%mail_html_body%}\""
|
"message": "Analysera följande e-postmeddelande och avgör om det är skräppost eller inte. Tänk på faktorer som misstänkta sökord, överdrivet reklamspråk, vilseledande ämnesrader, förfrågningar om personlig information och ovanliga avsändaradresser.\nAnge ett värde från 0 (inte skräppost) till 100 (skräppost) och en förklaring på högst 10 ord.\nOm meddelandedata saknas, sätt värdet till 0 (inte skräppost) och ange orsaken.\nGenerera ett svar endast i JSON-format. Inkludera inte ytterligare text eller förklaring; ange endast JSON. Här är formatet som ska användas:\n{\n\"spamValue\": <heltal från 0 till 100>,\n\"explanation\": \"Kort förklaring av ditt resonemang\"\n}\nHär är e-postinformationen:\nAvsändare: \"{%author%}\"\nÄmne: \"{%mail_subject%}\"\nHtml-text: \"{%mail_html_body%}\""
|
||||||
},
|
},
|
||||||
"CORS_give_allurls_perm": {
|
"Summarize_prompt_prefs_title": {
|
||||||
"message": "Ge behörighet för \"alla webbadresser\""
|
"message": "Lägg till sammanfattningsalternativ"
|
||||||
|
},
|
||||||
|
"prompt_summarize": {
|
||||||
|
"message": "Sammanfatta det här e-postmeddelandet eller dessa e-postmeddelanden"
|
||||||
|
},
|
||||||
|
"prompt_summarize_full_text": {
|
||||||
|
"message": "Du är en assistent som sammanfattar e-postkonversationer.\n\nMed tanke på en e-posttråd, skapa en kortfattad och korrekt sammanfattning som fångar:\n\n- Konversationens huvudämne eller syfte\n- Viktiga beslut, slutsatser eller överenskommelser\n- Viktiga frågor, förfrågningar eller åtgärdspunkter\n- Vem som är ansvarig för varje åtgärdspunkt (om det anges)\n\nUteslut hälsningar, signaturer, citat och överflödig fram-och-tillbaka-text.\nLägg inte till antaganden eller information som inte finns i e-postmeddelandena.\n\nSkriv sammanfattningen på ett tydligt och neutralt språk som passar en upptagen yrkesperson."
|
||||||
|
},
|
||||||
|
"prompt_summarize_email_template": {
|
||||||
|
"message": "Sammanfattningsmall för e-post"
|
||||||
|
},
|
||||||
|
"prompt_summarize_email_template_full_text": {
|
||||||
|
"message": "Från: {%author%}\nTill: {%recipients%}\nCC: {%cc_list%}\nÄmne: {%mail_subject%}\nDatum: {%mail_datetime%}\nBilagor:\n{%mail_attachments_info%}\n\nBrödtext:\n{%mail_text_body%}"
|
||||||
|
},
|
||||||
|
"prompt_summarize_email_separator": {
|
||||||
|
"message": "E-postavgränsare"
|
||||||
|
},
|
||||||
|
"prompt_summarize_email_separator_full_text": {
|
||||||
|
"message": "\n\n---------- NÄSTA E-POST ----------\n\n"
|
||||||
|
},
|
||||||
|
"prefs_OptionText_Summarize_infoline2": {
|
||||||
|
"message": "Du kan ändra prompten som du vill, det första fältet är huvudprompten, det andra fältet är mallen för ett enskilt e-postmeddelande. Listan över e-postmeddelanden kommer att läggas till i huvudprompten. E-postmeddelanden kommer att separeras med avgränsaren som anges i det tredje fältet."
|
||||||
|
},
|
||||||
|
"prefs_OptionText_Summarize_main_prompt": {
|
||||||
|
"message": "Huvudprompten som beskriver uppgiften som ska utföras på alla valda e-postmeddelanden:"
|
||||||
|
},
|
||||||
|
"prefs_OptionText_Summarize_email_template": {
|
||||||
|
"message": "Mallen för ett enda e-postmeddelande:"
|
||||||
|
},
|
||||||
|
"prefs_OptionText_Summarize_email_separator": {
|
||||||
|
"message": "Avgränsaren mellan e-postmeddelanden:"
|
||||||
|
},
|
||||||
|
"prefs_OptionText_summarize": {
|
||||||
|
"message": "Sammanfatta e-postmeddelande"
|
||||||
|
},
|
||||||
|
"prefs_OptionText_summarize_use_specific_integration_Info": {
|
||||||
|
"message": "Om markerat kommer modellen och API:et som anges nedan att användas för att sammanfatta e-postmeddelanden, oavsett vilket som valts på ThunderAI-alternativsidan."
|
||||||
|
},
|
||||||
|
"prefs_OptionText_summarize_Info": {
|
||||||
|
"message": "Om markerad läggs ett alternativ till i snabbmenyn för att sammanfatta e-post."
|
||||||
|
},
|
||||||
|
"prefs_OptionText_btnManageSummarizeInfo": {
|
||||||
|
"message": "Hantera sammanfattningsinställningar"
|
||||||
|
},
|
||||||
|
"Summarize_PageTitle": {
|
||||||
|
"message": "Hantera sammanfattningsinställningar"
|
||||||
|
},
|
||||||
|
"Summarize_info_default": {
|
||||||
|
"message": "På den här sidan kan du ändra standardprompten som används för att sammanfatta e-postmeddelanden."
|
||||||
|
},
|
||||||
|
"Summarize_prompt_text_title": {
|
||||||
|
"message": "Aktuell prompttext"
|
||||||
|
},
|
||||||
|
"context_menu_mzta-summarize": {
|
||||||
|
"message": "Sammanfatta"
|
||||||
|
},
|
||||||
|
"CORS_alternative_2_new": {
|
||||||
|
"message": "Tryck på knappen nedan för att ge den aktuella värden behörighet att undvika CORS-problem."
|
||||||
|
},
|
||||||
|
"CORS_give_host_perm": {
|
||||||
|
"message": "Ge behörighet till den nuvarande värden"
|
||||||
|
},
|
||||||
|
"CORS_localhost_warn": {
|
||||||
|
"message": "Om du använder localhost eller 127.0.0.1 eftersom AI-servern finns på din dator krävs behörigheten <all_urls>."
|
||||||
|
},
|
||||||
|
"prefs_OptionText_get_calendar_event_use_specific_integration_Info": {
|
||||||
|
"message": "Om markerat kommer modellen och API:et som anges nedan att användas för att skapa kalenderhändelser, oavsett vilket som valts på ThunderAI-alternativsidan."
|
||||||
|
},
|
||||||
|
"customPrompts_export_include_api_settings": {
|
||||||
|
"message": "Vill du inkludera API-inställningar i exporten? Tänk på att även API-nyckeln kommer att sparas i filen!"
|
||||||
|
},
|
||||||
|
"prompt_get_calendar_event_from_clipboard": {
|
||||||
|
"message": "Lägg till kalenderhändelse från urklipp"
|
||||||
|
},
|
||||||
|
"clipboard_read_error": {
|
||||||
|
"message": "Kunde inte läsa urklipp. Kontrollera behörigheterna."
|
||||||
|
},
|
||||||
|
"clipboard_empty_error": {
|
||||||
|
"message": "Urklipp är tom. Kopiera lite text först."
|
||||||
|
},
|
||||||
|
"clipboard_permission_denied": {
|
||||||
|
"message": "Åtkomst till urklipp nekades. Aktivera funktionen igen i inställningarna för att ge behörighet."
|
||||||
|
},
|
||||||
|
"clipboard_permission_error": {
|
||||||
|
"message": "Fel vid begäran om behörighet för urklipp. Försök igen."
|
||||||
|
},
|
||||||
|
"prefs_OptionText_get_calendar_event_from_clipboard": {
|
||||||
|
"message": "Hämta kalenderhändelse från urklipp"
|
||||||
|
},
|
||||||
|
"prefs_OptionText_get_calendar_event_from_clipboard_Info": {
|
||||||
|
"message": "Visa ytterligare ett menyalternativ för att skapa kalenderhändelser från textinnehåll i urklipp."
|
||||||
|
},
|
||||||
|
"prefs_OptionText_calendar_no_selection": {
|
||||||
|
"message": "Fråga inte om att markera text"
|
||||||
|
},
|
||||||
|
"prefs_OptionText_calendar_no_selection_Info": {
|
||||||
|
"message": "Om markerad behöver du inte markera någon text. Hela meddelandets innehåll kommer att användas för att hämta kalenderhändelsen."
|
||||||
|
},
|
||||||
|
"customPrompts_btnCopy": {
|
||||||
|
"message": "Kopiera"
|
||||||
|
},
|
||||||
|
"copy_text": {
|
||||||
|
"message": "kopiera"
|
||||||
|
},
|
||||||
|
"placeholder_mail_text_body_or_selected": {
|
||||||
|
"message": "Mejltext eller markerad text"
|
||||||
|
},
|
||||||
|
"placeholder_mail_html_body_or_selected": {
|
||||||
|
"message": "Mejltext eller vald HTML"
|
||||||
|
},
|
||||||
|
"Spam": {
|
||||||
|
"message": "Skräppost"
|
||||||
|
},
|
||||||
|
"Valid": {
|
||||||
|
"message": "Giltig"
|
||||||
|
},
|
||||||
|
"prefs_OptionText_spamfilter_show_msg_panel": {
|
||||||
|
"message": "Visa panelen för skräppostrapportering"
|
||||||
|
},
|
||||||
|
"prefs_OptionText_spamfilter_show_msg_panel_Info": {
|
||||||
|
"message": "Om markerat visas en panel med skräppostrapportering högst upp av meddelandet."
|
||||||
|
},
|
||||||
|
"SpamReport_infoline": {
|
||||||
|
"message": "Denna information sparas endast för den aktuella sessionen."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
20
_locales/tr/messages.json
Normal file
20
_locales/tr/messages.json
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"extensionDescription": {
|
||||||
|
"message": "E-postalarınızı geliştirmek için ChatGPT, Google Gemini, Claude veya Ollama’yı kullanın!"
|
||||||
|
},
|
||||||
|
"menu_title": {
|
||||||
|
"message": "YZ"
|
||||||
|
},
|
||||||
|
"customPrompts_managePrompts_info_default": {
|
||||||
|
"message": "Varsayılan promptlar düzenlenemez. Bunları devre dışı bırakabilir, ardından prompt metnini kopyalayıp yeni bir prompta yapıştırarak düzenlenmiş bir sürüm oluşturabilirsiniz."
|
||||||
|
},
|
||||||
|
"customPrompts_managePrompts_info_default_2": {
|
||||||
|
"message": "Promptları içe ve dışa aktarabilirsiniz. Aynı kimliğe (ID) sahip mevcut istemlerin üzerine yazılır. Yeni kimliklere (ID) sahip promptlar eklenir."
|
||||||
|
},
|
||||||
|
"customPrompts_managePrompts_info_default_3": {
|
||||||
|
"message": "Her şey doğruysa, içe aktarma işleminden sonra ‘Tümünü Kaydet’ düğmesine tıklayın."
|
||||||
|
},
|
||||||
|
"customPrompts_start_saving": {
|
||||||
|
"message": "Promptlar kaydediliyor…"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -134,10 +134,10 @@
|
||||||
"SpamReport_Title": {
|
"SpamReport_Title": {
|
||||||
"message": "垃圾邮件过滤报告"
|
"message": "垃圾邮件过滤报告"
|
||||||
},
|
},
|
||||||
"spamfilter_not_moved": {
|
"no_string": {
|
||||||
"message": "否"
|
"message": "否"
|
||||||
},
|
},
|
||||||
"spamfilter_moved": {
|
"yes_string": {
|
||||||
"message": "是"
|
"message": "是"
|
||||||
},
|
},
|
||||||
"prompt_rewrite_polite": {
|
"prompt_rewrite_polite": {
|
||||||
|
|
@ -236,9 +236,6 @@
|
||||||
"prefs_OptionText_spamfilter_Info": {
|
"prefs_OptionText_spamfilter_Info": {
|
||||||
"message": "如果选中,ThunderAI将自动将垃圾邮件移至垃圾邮件文件夹。"
|
"message": "如果选中,ThunderAI将自动将垃圾邮件移至垃圾邮件文件夹。"
|
||||||
},
|
},
|
||||||
"sparks_not_installed": {
|
|
||||||
"message": "ThunderAI Sparks 未安装!"
|
|
||||||
},
|
|
||||||
"chatgpt_textarea_not_found_error": {
|
"chatgpt_textarea_not_found_error": {
|
||||||
"message": "看起来 ChatGPT 页面加载时间太长。如果加载完成,请点击右边的按钮。如果问题仍然存在,请检查服务状态。"
|
"message": "看起来 ChatGPT 页面加载时间太长。如果加载完成,请点击右边的按钮。如果问题仍然存在,请检查服务状态。"
|
||||||
},
|
},
|
||||||
|
|
@ -341,9 +338,6 @@
|
||||||
"prefs_ChatGPT_API_Key": {
|
"prefs_ChatGPT_API_Key": {
|
||||||
"message": "ChatGPT API 密钥"
|
"message": "ChatGPT API 密钥"
|
||||||
},
|
},
|
||||||
"chagpt_api_connecting": {
|
|
||||||
"message": "尝试使用提供的 API 密钥连接到 OpenAI ChatGPT"
|
|
||||||
},
|
|
||||||
"prefs_OptionText_release_notes": {
|
"prefs_OptionText_release_notes": {
|
||||||
"message": "发行说明"
|
"message": "发行说明"
|
||||||
},
|
},
|
||||||
|
|
@ -371,9 +365,6 @@
|
||||||
"OpenAIComp_empty_model": {
|
"OpenAIComp_empty_model": {
|
||||||
"message": "您尚未选择 OpenAI Compatible API 的模型。请在选项页面中选择一个。"
|
"message": "您尚未选择 OpenAI Compatible API 的模型。请在选项页面中选择一个。"
|
||||||
},
|
},
|
||||||
"OpenAIComp_api_connecting": {
|
|
||||||
"message": "尝试使用主机连接到 OpenAI 兼容 API 本地服务器"
|
|
||||||
},
|
|
||||||
"prefs_OpenAIComp_ChatName": {
|
"prefs_OpenAIComp_ChatName": {
|
||||||
"message": "对话名称"
|
"message": "对话名称"
|
||||||
},
|
},
|
||||||
|
|
@ -416,9 +407,6 @@
|
||||||
"importPrompts_invalidPrompts": {
|
"importPrompts_invalidPrompts": {
|
||||||
"message": "您尝试导入的文件不包含任何有效提示词。"
|
"message": "您尝试导入的文件不包含任何有效提示词。"
|
||||||
},
|
},
|
||||||
"andModel": {
|
|
||||||
"message": "和模型"
|
|
||||||
},
|
|
||||||
"ChatGPT_Models_Error_fetching": {
|
"ChatGPT_Models_Error_fetching": {
|
||||||
"message": "尝试获取 ChatGPT 模型时出错"
|
"message": "尝试获取 ChatGPT 模型时出错"
|
||||||
},
|
},
|
||||||
|
|
@ -581,9 +569,6 @@
|
||||||
"OpenAIComp_force_model_ask": {
|
"OpenAIComp_force_model_ask": {
|
||||||
"message": "在此处填入您想要使用的模型名称。"
|
"message": "在此处填入您想要使用的模型名称。"
|
||||||
},
|
},
|
||||||
"ollama_api_connecting": {
|
|
||||||
"message": "尝试使用主机连接到 Ollama 本地服务器"
|
|
||||||
},
|
|
||||||
"ollama_api_request_failed": {
|
"ollama_api_request_failed": {
|
||||||
"message": "Ollama API 请求失败"
|
"message": "Ollama API 请求失败"
|
||||||
},
|
},
|
||||||
|
|
@ -635,9 +620,6 @@
|
||||||
"thunderai_warning_title": {
|
"thunderai_warning_title": {
|
||||||
"message": "ThunderAI 警告"
|
"message": "ThunderAI 警告"
|
||||||
},
|
},
|
||||||
"google_gemini_api_connecting": {
|
|
||||||
"message": "尝试使用提供的 API 密钥连接到 Google Gemini"
|
|
||||||
},
|
|
||||||
"prefs_SurveyLinkText2": {
|
"prefs_SurveyLinkText2": {
|
||||||
"message": "单击此处,只需一分钟!"
|
"message": "单击此处,只需一分钟!"
|
||||||
},
|
},
|
||||||
|
|
@ -783,7 +765,7 @@
|
||||||
"message": "管理垃圾邮件过滤器设置"
|
"message": "管理垃圾邮件过滤器设置"
|
||||||
},
|
},
|
||||||
"prompt_get_calendar_event_full_text": {
|
"prompt_get_calendar_event_full_text": {
|
||||||
"message": "从以下文本中提取生成日历事件所需的所有相关细节。提取的信息应包括:\n- 事件标题\n- 开始日期和时间(如果指定时区,则包括时区)\n- 结束日期和时间(如果指定时区,则包括时区)\n- 全天事件(如果提及)\n- 参与者 \n确保数据格式清晰且一致,以便可以直接用于创建日历事件。\n如果存在相对时间的引用,请注意邮件的日期和时间为“{%mail_datetime%}”。基于此参考计算开始日期和时间。如果计算出的开始日期和时间早于“{%current_datetime%}”,则使用“{%current_datetime%}”作为基准重新计算开始日期和时间。\n如果未指定持续时间,请将其设置为一小时。\n以下是参与者:{%author%}, {%recipients%}, {%cc_list%}。如有,请排除我的地址:{%account_email_address%}。\n如果无法获取一个或多个所需信息,请以空字符串响应。\n仅以 JSON 格式生成响应。不要包含任何额外的文本或说明,仅提供 JSON。以下是使用的格式:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"日历事件摘要\",\n\"forceAllDay\": false\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\n以下是文本:“{%selected_text%}”"
|
"message": "从以下文本中提取生成日历事件所需的所有相关细节。提取的信息应包括:\n- 事件标题\n- 开始日期和时间(如果指定时区,则包括时区)\n- 结束日期和时间(如果指定时区,则包括时区)\n- 全天事件(如果提及)\n- 参与者 \n确保数据格式清晰且一致,以便可以直接用于创建日历事件。\n如果存在相对时间的引用,请注意邮件的日期和时间为“{%mail_datetime%}”。基于此参考计算开始日期和时间。如果计算出的开始日期和时间早于“{%current_datetime%}”,则使用“{%current_datetime%}”作为基准重新计算开始日期和时间。\n如果未指定持续时间,请将其设置为一小时。\n以下是参与者:{%author%}, {%recipients%}, {%cc_list%}。如有,请排除我的地址:{%account_email_address%}。\n如果无法获取一个或多个所需信息,请以空字符串响应。\n仅以 JSON 格式生成响应。不要包含任何额外的文本或说明,仅提供 JSON。以下是使用的格式:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"日历事件摘要\",\n\"forceAllDay\": false\n\"attendees\": [attendee1@example.com,attendee2@example.com,attendee3@example.com]\n}\n以下是文本:“{%mail_text_body_or_selected%}”"
|
||||||
},
|
},
|
||||||
"prefs_OptionText_get_calendar_event": {
|
"prefs_OptionText_get_calendar_event": {
|
||||||
"message": "从所选文本添加新日历事件"
|
"message": "从所选文本添加新日历事件"
|
||||||
|
|
@ -854,21 +836,9 @@
|
||||||
"context_menu_mzta-add-tags": {
|
"context_menu_mzta-add-tags": {
|
||||||
"message": "添加标签"
|
"message": "添加标签"
|
||||||
},
|
},
|
||||||
"prefs_OptionText_add_tags_context_menu": {
|
|
||||||
"message": "显示“添加标签”上下文菜单项"
|
|
||||||
},
|
|
||||||
"prefs_OptionText_spamfilter_context_menu": {
|
|
||||||
"message": "显示“分析垃圾邮件”上下文菜单项"
|
|
||||||
},
|
|
||||||
"prefs_OptionText_spamfilter_context_menu_Info": {
|
|
||||||
"message": "如果选中,则在邮件列表中右键单击电子邮件时,将显示“分析垃圾邮件”上下文菜单项。"
|
|
||||||
},
|
|
||||||
"context_menu_mzta-spamfilter": {
|
"context_menu_mzta-spamfilter": {
|
||||||
"message": "分析垃圾邮件"
|
"message": "分析垃圾邮件"
|
||||||
},
|
},
|
||||||
"prefs_OptionText_add_tags_context_menu_Info": {
|
|
||||||
"message": "如果选中,“添加标签”上下文菜单项将在消息列表中右键单击电子邮件时显示。"
|
|
||||||
},
|
|
||||||
"noActiveCalendar": {
|
"noActiveCalendar": {
|
||||||
"message": "未找到可编辑的日历!"
|
"message": "未找到可编辑的日历!"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -284,7 +284,7 @@
|
||||||
"Spam_Value": {
|
"Spam_Value": {
|
||||||
"message": "垃圾訊息評分"
|
"message": "垃圾訊息評分"
|
||||||
},
|
},
|
||||||
"spamfilter_not_moved": {
|
"no_string": {
|
||||||
"message": "否"
|
"message": "否"
|
||||||
},
|
},
|
||||||
"Report_Date": {
|
"Report_Date": {
|
||||||
|
|
@ -387,7 +387,7 @@
|
||||||
"Date": {
|
"Date": {
|
||||||
"message": "日期"
|
"message": "日期"
|
||||||
},
|
},
|
||||||
"spamfilter_moved": {
|
"yes_string": {
|
||||||
"message": "是"
|
"message": "是"
|
||||||
},
|
},
|
||||||
"Custom": {
|
"Custom": {
|
||||||
|
|
@ -533,9 +533,6 @@
|
||||||
"chatgpt_api_request_failed": {
|
"chatgpt_api_request_failed": {
|
||||||
"message": "OpenAI ChatGPT API 請求失敗"
|
"message": "OpenAI ChatGPT API 請求失敗"
|
||||||
},
|
},
|
||||||
"WaitingServerReponse": {
|
|
||||||
"message": "等待伺服器回應"
|
|
||||||
},
|
|
||||||
"error_connection_interrupted": {
|
"error_connection_interrupted": {
|
||||||
"message": "與伺服器的連線意外中斷"
|
"message": "與伺服器的連線意外中斷"
|
||||||
},
|
},
|
||||||
|
|
@ -635,9 +632,6 @@
|
||||||
"context_menu_mzta-spamfilter": {
|
"context_menu_mzta-spamfilter": {
|
||||||
"message": "檢測垃圾郵件"
|
"message": "檢測垃圾郵件"
|
||||||
},
|
},
|
||||||
"prefs_OptionText_spamfilter_context_menu_Info": {
|
|
||||||
"message": "如果勾選,則在訊息清單中點右鍵時,會出現「分析垃圾郵件」快顯功能選單項目。"
|
|
||||||
},
|
|
||||||
"apiwebchat_use_this_answer": {
|
"apiwebchat_use_this_answer": {
|
||||||
"message": "使用這個答案"
|
"message": "使用這個答案"
|
||||||
},
|
},
|
||||||
|
|
@ -802,9 +796,6 @@
|
||||||
"prefs_OptionText_spamfilter_threshold_Info": {
|
"prefs_OptionText_spamfilter_threshold_Info": {
|
||||||
"message": "如果 AI 傳回的值高於此閾值,則電子郵件將被移至垃圾郵件資料夾。"
|
"message": "如果 AI 傳回的值高於此閾值,則電子郵件將被移至垃圾郵件資料夾。"
|
||||||
},
|
},
|
||||||
"prefs_OptionText_add_tags_context_menu": {
|
|
||||||
"message": "顯示「新增標籤」在快顯功能選單"
|
|
||||||
},
|
|
||||||
"remember_CORS": {
|
"remember_CORS": {
|
||||||
"message": "記住,您需要在伺服器上設定 CORS 設定!"
|
"message": "記住,您需要在伺服器上設定 CORS 設定!"
|
||||||
},
|
},
|
||||||
|
|
@ -1005,9 +996,6 @@
|
||||||
"prefs_OptionText_btnManageSpamFilterInfo": {
|
"prefs_OptionText_btnManageSpamFilterInfo": {
|
||||||
"message": "管理垃圾郵件設定"
|
"message": "管理垃圾郵件設定"
|
||||||
},
|
},
|
||||||
"CORS_give_allurls_perm": {
|
|
||||||
"message": "授予「所有網址」權限"
|
|
||||||
},
|
|
||||||
"prefs_ollama_num_ctx": {
|
"prefs_ollama_num_ctx": {
|
||||||
"message": "情境 Token 數量"
|
"message": "情境 Token 數量"
|
||||||
},
|
},
|
||||||
|
|
@ -1087,7 +1075,7 @@
|
||||||
"message": "您尚未選擇 ChatGPT API 的模型。請在選項頁面中選擇一個。"
|
"message": "您尚未選擇 ChatGPT API 的模型。請在選項頁面中選擇一個。"
|
||||||
},
|
},
|
||||||
"prompt_get_calendar_event_full_text": {
|
"prompt_get_calendar_event_full_text": {
|
||||||
"message": "從以下文字中提取所有需要生成日曆事件的相關資訊。 提取的資訊應包含:\n- 事件名稱\n- 起始日期和時間(包含時區,如果指定)\n- 結束日期和時間(包含時間區,如果指定)\n- 整天事件(如果提及\n- 參與者\n確保數據以清晰一致的方式格式化,以便直接用於創建日曆事件。\n如果有相對時間參考,請考慮電子郵件的日期和時間是 「{%mail_datetime%}」。 計算基於此參考的起日期和時間。 如果計算出的起日期和時間早於「{%current_datetime%}」,則使用「{%current_datetime%}」作為基準重新計算起日期和時間。\n如果持續時間沒有指定,則設定為一小時。\n參與者:{%author%}, {%recipients%}, {%cc_list%}。如果存在,請排除我的地址:{%account_email_address%}。\n如果無法獲得其中一個或多個所需的資訊,請回覆一個空字串。\n請以 JSON 格式回覆,不要包含任何額外的文字或說明,提供僅 JSON。 以下是將要使用的格式:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"日曆事件摘要在此\",\n\"forceAllDay\": false,\n\"attendees\": [\"attendee1@example.com \",\"attendee2@example.com \",\"attendee3@example.com \"]\n}\n這裡是文字:「{%selected_text%}」"
|
"message": "從以下文字中提取所有需要生成日曆事件的相關資訊。 提取的資訊應包含:\n- 事件名稱\n- 起始日期和時間(包含時區,如果指定)\n- 結束日期和時間(包含時間區,如果指定)\n- 整天事件(如果提及\n- 參與者\n確保數據以清晰一致的方式格式化,以便直接用於創建日曆事件。\n如果有相對時間參考,請考慮電子郵件的日期和時間是 「{%mail_datetime%}」。 計算基於此參考的起日期和時間。 如果計算出的起日期和時間早於「{%current_datetime%}」,則使用「{%current_datetime%}」作為基準重新計算起日期和時間。\n如果持續時間沒有指定,則設定為一小時。\n參與者:{%author%}, {%recipients%}, {%cc_list%}。如果存在,請排除我的地址:{%account_email_address%}。\n如果無法獲得其中一個或多個所需的資訊,請回覆一個空字串。\n請以 JSON 格式回覆,不要包含任何額外的文字或說明,提供僅 JSON。 以下是將要使用的格式:\n{\n\"startDate\": \"YYYYMMDDTHHMMSS\",\n\"endDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"日曆事件摘要在此\",\n\"forceAllDay\": false,\n\"attendees\": [\"attendee1@example.com \",\"attendee2@example.com \",\"attendee3@example.com \"]\n}\n這裡是文字:「{%mail_text_body_or_selected%}」"
|
||||||
},
|
},
|
||||||
"TranslateText": {
|
"TranslateText": {
|
||||||
"message": "您願意幫忙翻譯這個附加元件嗎?"
|
"message": "您願意幫忙翻譯這個附加元件嗎?"
|
||||||
|
|
@ -1095,9 +1083,6 @@
|
||||||
"prompt_get_task_full_text": {
|
"prompt_get_task_full_text": {
|
||||||
"message": "從以下文字中提取所有需要生成任務的相關資訊。 提取的資訊應包含:\n- 截止日期和時間(包括時區,如果指定)\n- 任務總結\n- 初始日期和時間(包括時區,如果指定)\n確保數據以清晰一致的方式格式化,以便直接用於建立任務。\n如果有相對時間參考,請考慮電子郵件的日期和時間是 「{%mail_datetime%}」。 計算基於此參考的起日期和時間。如果計算出的起日期和時間早於「{%current_datetime%}」,則使用 「{%current_datetime%}」作為基準重新計算起日期和時間。\n如果無法獲得其中一個或多個所需的資訊,請回覆一個空字串。\n請以 JSON 格式回覆,不包含任何額外的文字或說明,提供僅 JSON。 以下是將要使用的格式:\n{\n\"InitialDate\": \"YYYYMMDDTHHMMSS\",\n\"dueDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"任務總結在此\"\n}\n如果沒有日期資訊,請刪除這些資訊。\n以下是文字:「{%selected_text%}」"
|
"message": "從以下文字中提取所有需要生成任務的相關資訊。 提取的資訊應包含:\n- 截止日期和時間(包括時區,如果指定)\n- 任務總結\n- 初始日期和時間(包括時區,如果指定)\n確保數據以清晰一致的方式格式化,以便直接用於建立任務。\n如果有相對時間參考,請考慮電子郵件的日期和時間是 「{%mail_datetime%}」。 計算基於此參考的起日期和時間。如果計算出的起日期和時間早於「{%current_datetime%}」,則使用 「{%current_datetime%}」作為基準重新計算起日期和時間。\n如果無法獲得其中一個或多個所需的資訊,請回覆一個空字串。\n請以 JSON 格式回覆,不包含任何額外的文字或說明,提供僅 JSON。 以下是將要使用的格式:\n{\n\"InitialDate\": \"YYYYMMDDTHHMMSS\",\n\"dueDate\": \"YYYYMMDDTHHMMSS\",\n\"summary\": \"任務總結在此\"\n}\n如果沒有日期資訊,請刪除這些資訊。\n以下是文字:「{%selected_text%}」"
|
||||||
},
|
},
|
||||||
"prefs_OptionText_spamfilter_context_menu": {
|
|
||||||
"message": "顯示「分析垃圾郵件」在快顯功能選單"
|
|
||||||
},
|
|
||||||
"sign_msg_as": {
|
"sign_msg_as": {
|
||||||
"message": "簽署訊息為"
|
"message": "簽署訊息為"
|
||||||
},
|
},
|
||||||
|
|
@ -1137,15 +1122,9 @@
|
||||||
"prompt_rewrite_formal_full_text": {
|
"prompt_rewrite_formal_full_text": {
|
||||||
"message": "請將以下文字重寫得更正式一些。僅回覆重寫的文字,不要提供任何額外的註解或其他文字。"
|
"message": "請將以下文字重寫得更正式一些。僅回覆重寫的文字,不要提供任何額外的註解或其他文字。"
|
||||||
},
|
},
|
||||||
"CORS_alternative_2": {
|
|
||||||
"message": "點擊下方按鈕,授予「所有網址」權限,以避免任何 CORS 問題。"
|
|
||||||
},
|
|
||||||
"GoogleGemini_SystemInstruction_Info": {
|
"GoogleGemini_SystemInstruction_Info": {
|
||||||
"message": "當您設定系統指示時,您會為模型提供額外情境來理解任務,提供更客製化的回應,並遵守將要發送的提示的特定指南。"
|
"message": "當您設定系統指示時,您會為模型提供額外情境來理解任務,提供更客製化的回應,並遵守將要發送的提示的特定指南。"
|
||||||
},
|
},
|
||||||
"prefs_OptionText_add_tags_context_menu_Info": {
|
|
||||||
"message": "如果勾選,則右鍵單擊訊息清單中的電子郵件時將顯示「新增標籤」在快顯功能選單。"
|
|
||||||
},
|
|
||||||
"prefs_OptionText_chatgpt_web_custom_gpt_info": {
|
"prefs_OptionText_chatgpt_web_custom_gpt_info": {
|
||||||
"message": "這是將針對 ChatGPT 網頁介面強制執行的自訂 GPT。"
|
"message": "這是將針對 ChatGPT 網頁介面強制執行的自訂 GPT。"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
BIN
images/summarize.png
Normal file
BIN
images/summarize.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
|
|
@ -617,9 +617,58 @@ switch (message.command) {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "showSpamReport":
|
||||||
|
const data = message.data;
|
||||||
|
if(document.getElementById('mzta-spam-report-banner')) return Promise.resolve(true);
|
||||||
|
|
||||||
|
const container = document.createElement('div');
|
||||||
|
container.id = 'mzta-spam-report-banner';
|
||||||
|
|
||||||
|
const isDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||||
|
|
||||||
|
let bgColor = '#f8f9fa';
|
||||||
|
let textColor = '#333';
|
||||||
|
let borderColor = '#ccc';
|
||||||
|
|
||||||
|
if (data.spamValue >= (data.SpamThreshold || 50)) {
|
||||||
|
bgColor = isDark ? '#5a1a1a' : '#ffe6e6';
|
||||||
|
textColor = isDark ? '#ffcccc' : '#cc0000';
|
||||||
|
borderColor = '#cc0000';
|
||||||
|
} else {
|
||||||
|
bgColor = isDark ? '#1a401a' : '#e6ffe6';
|
||||||
|
textColor = isDark ? '#ccffcc' : '#006600';
|
||||||
|
borderColor = '#006600';
|
||||||
|
}
|
||||||
|
|
||||||
|
container.style.cssText = `background-color: ${bgColor}; color: ${textColor}; border-bottom: 1px solid ${borderColor}; padding: 8px 12px; font-family: system-ui, -apple-system, sans-serif; font-size: 13px; display: flex; align-items: center; gap: 15px; width: 100%; box-sizing: border-box;`;
|
||||||
|
|
||||||
|
const scoreText = document.createElement('strong');
|
||||||
|
scoreText.textContent = ((data.spamValue >= (data.SpamThreshold || 50)) ? browser.i18n.getMessage("Spam") : browser.i18n.getMessage("Valid")) + " [" + data.spamValue + "/100]";
|
||||||
|
|
||||||
|
const reasonText = document.createElement('span');
|
||||||
|
reasonText.textContent = browser.i18n.getMessage("Explanation") + ": " + data.explanation;
|
||||||
|
|
||||||
|
const closeBtn = document.createElement('span');
|
||||||
|
closeBtn.textContent = '×';
|
||||||
|
closeBtn.style.cssText = 'margin-left: auto; cursor: pointer; font-weight: bold; font-size: 16px; padding: 0 5px;';
|
||||||
|
closeBtn.title = browser.i18n.getMessage("chatgpt_win_close");
|
||||||
|
closeBtn.onclick = function() {
|
||||||
|
container.remove();
|
||||||
|
browser.runtime.sendMessage({ command: "removeSpamReport", headerMessageId: data.headerMessageId });
|
||||||
|
};
|
||||||
|
|
||||||
|
container.appendChild(scoreText);
|
||||||
|
container.appendChild(reasonText);
|
||||||
|
container.appendChild(closeBtn);
|
||||||
|
|
||||||
|
document.body.insertBefore(container, document.body.firstChild);
|
||||||
|
return Promise.resolve(true);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// do nothing
|
// do nothing
|
||||||
return Promise.resolve(false);
|
return Promise.resolve(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
browser.runtime.sendMessage({ command: "checkSpamReport" });
|
||||||
|
|
@ -110,6 +110,25 @@ export class mzta_Menus {
|
||||||
taWorkingStatus.startWorking();
|
taWorkingStatus.startWorking();
|
||||||
const tabs = await browser.tabs.query({ active: true, currentWindow: true });
|
const tabs = await browser.tabs.query({ active: true, currentWindow: true });
|
||||||
const msg_text = await getMailBody(tabs, placeholdersUtils.hasPlaceholder(curr_prompt.text,'mail_typed_text'));
|
const msg_text = await getMailBody(tabs, placeholdersUtils.hasPlaceholder(curr_prompt.text,'mail_typed_text'));
|
||||||
|
|
||||||
|
if (curr_prompt.id === 'prompt_get_calendar_event_from_clipboard') {
|
||||||
|
try {
|
||||||
|
const clipboardText = await navigator.clipboard.readText();
|
||||||
|
if (!clipboardText) {
|
||||||
|
browser.tabs.sendMessage(tabs[0].id, { command: "sendAlert", curr_tab_type: tabs[0].type, message: browser.i18n.getMessage('clipboard_empty_error') });
|
||||||
|
taWorkingStatus.stopWorking();
|
||||||
|
return {ok:'0'};
|
||||||
|
}
|
||||||
|
msg_text.selection = clipboardText;
|
||||||
|
msg_text.text = clipboardText;
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Clipboard read error:", e);
|
||||||
|
browser.tabs.sendMessage(tabs[0].id, { command: "sendAlert", curr_tab_type: tabs[0].type, message: browser.i18n.getMessage('clipboard_read_error') });
|
||||||
|
taWorkingStatus.stopWorking();
|
||||||
|
return {ok:'0'};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// console.log(">>>>>>>>>>>>> msg_text: " + JSON.stringify(msg_text));
|
// console.log(">>>>>>>>>>>>> msg_text: " + JSON.stringify(msg_text));
|
||||||
//check if a selection is needed
|
//check if a selection is needed
|
||||||
if(String(curr_prompt.need_selected) == "1" && (msg_text.selection==='')){
|
if(String(curr_prompt.need_selected) == "1" && (msg_text.selection==='')){
|
||||||
|
|
@ -256,7 +275,8 @@ export class mzta_Menus {
|
||||||
return {ok:'1'};
|
return {ok:'1'};
|
||||||
break; // Add tags to the email - END
|
break; // Add tags to the email - END
|
||||||
}
|
}
|
||||||
case 'prompt_get_calendar_event': { // Get a calendar event info
|
case 'prompt_get_calendar_event': // Get a calendar event info
|
||||||
|
case 'prompt_get_calendar_event_from_clipboard': { // here from clipboard
|
||||||
let calendar_event_data = '';
|
let calendar_event_data = '';
|
||||||
let prefs_at = await browser.storage.sync.get({
|
let prefs_at = await browser.storage.sync.get({
|
||||||
connection_type: prefs_default.connection_type,
|
connection_type: prefs_default.connection_type,
|
||||||
|
|
|
||||||
|
|
@ -267,6 +267,24 @@ const defaultPlaceholders = [
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
is_dynamic: "0",
|
is_dynamic: "0",
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'mail_text_body_or_selected',
|
||||||
|
name: "__MSG_placeholder_mail_text_body_or_selected__",
|
||||||
|
default_value: "",
|
||||||
|
type: 0,
|
||||||
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
|
enabled: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'mail_html_body_or_selected',
|
||||||
|
name: "__MSG_placeholder_mail_html_body_or_selected__",
|
||||||
|
default_value: "",
|
||||||
|
type: 0,
|
||||||
|
is_default: "1",
|
||||||
|
is_dynamic: "0",
|
||||||
|
enabled: 1,
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
@ -517,6 +535,12 @@ export const placeholdersUtils = {
|
||||||
case 'selected_html':
|
case 'selected_html':
|
||||||
finalSubs['selected_html'] = placeholdersUtils.failSafePlaceholders(selection_html);
|
finalSubs['selected_html'] = placeholdersUtils.failSafePlaceholders(selection_html);
|
||||||
break;
|
break;
|
||||||
|
case 'mail_text_body_or_selected':
|
||||||
|
finalSubs['mail_text_body_or_selected'] = placeholdersUtils.failSafePlaceholders(selection_text || body_text);
|
||||||
|
break;
|
||||||
|
case 'mail_html_body_or_selected':
|
||||||
|
finalSubs['mail_html_body_or_selected'] = placeholdersUtils.failSafePlaceholders(selection_html || msg_text?.html);
|
||||||
|
break;
|
||||||
case 'author':
|
case 'author':
|
||||||
finalSubs['author'] = placeholdersUtils.failSafePlaceholders(curr_message.author);
|
finalSubs['author'] = placeholdersUtils.failSafePlaceholders(curr_message.author);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -294,6 +294,21 @@ const specialPrompts = [
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
is_special: "1",
|
is_special: "1",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'prompt_get_calendar_event_from_clipboard',
|
||||||
|
name: "__MSG_prompt_get_calendar_event_from_clipboard__",
|
||||||
|
text: "prompt_get_calendar_event_full_text",
|
||||||
|
type: "1",
|
||||||
|
action: "0",
|
||||||
|
need_selected: "0",
|
||||||
|
need_signature: "0",
|
||||||
|
need_custom_text: "0",
|
||||||
|
define_response_lang: "0",
|
||||||
|
use_diff_viewer: "0",
|
||||||
|
api_type: '',
|
||||||
|
is_default: "1",
|
||||||
|
is_special: "1",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'prompt_get_task',
|
id: 'prompt_get_task',
|
||||||
name: "__MSG_prompt_get_task__",
|
name: "__MSG_prompt_get_task__",
|
||||||
|
|
@ -324,6 +339,54 @@ const specialPrompts = [
|
||||||
is_default: "1",
|
is_default: "1",
|
||||||
is_special: "1",
|
is_special: "1",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'prompt_summarize',
|
||||||
|
name: "__MSG_prompt_summarize__",
|
||||||
|
text: "prompt_summarize_full_text",
|
||||||
|
type: "1",
|
||||||
|
action: "0",
|
||||||
|
need_selected: "0",
|
||||||
|
need_signature: "0",
|
||||||
|
need_custom_text: "0",
|
||||||
|
define_response_lang: "0",
|
||||||
|
use_diff_viewer: "0",
|
||||||
|
api_type: '',
|
||||||
|
api_model: '',
|
||||||
|
is_default: "1",
|
||||||
|
is_special: "1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'prompt_summarize_email_template',
|
||||||
|
name: "__MSG_prompt_summarize_email_template__",
|
||||||
|
text: "prompt_summarize_email_template_full_text",
|
||||||
|
type: "1",
|
||||||
|
action: "0",
|
||||||
|
need_selected: "0",
|
||||||
|
need_signature: "0",
|
||||||
|
need_custom_text: "0",
|
||||||
|
define_response_lang: "0",
|
||||||
|
use_diff_viewer: "0",
|
||||||
|
api_type: '',
|
||||||
|
api_model: '',
|
||||||
|
is_default: "1",
|
||||||
|
is_special: "1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'prompt_summarize_email_separator',
|
||||||
|
name: "__MSG_prompt_summarize_email_separator__",
|
||||||
|
text: "prompt_summarize_email_separator_full_text",
|
||||||
|
type: "1",
|
||||||
|
action: "0",
|
||||||
|
need_selected: "0",
|
||||||
|
need_signature: "0",
|
||||||
|
need_custom_text: "0",
|
||||||
|
define_response_lang: "0",
|
||||||
|
use_diff_viewer: "0",
|
||||||
|
api_type: '',
|
||||||
|
api_model: '',
|
||||||
|
is_default: "1",
|
||||||
|
is_special: "1",
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -362,18 +425,55 @@ export async function getPrompts(onlyEnabled = false, includeSpecial = [], allSp
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function preparePromptsForExport(prompts){
|
export function preparePromptsForExport(prompts, include_api_settings = false){
|
||||||
let output = [...prompts];
|
let output = JSON.parse(JSON.stringify(prompts));
|
||||||
output.forEach(prompt => {
|
output.forEach(prompt => {
|
||||||
|
|
||||||
|
if(!include_api_settings){
|
||||||
|
delete prompt.api_type;
|
||||||
|
for (const [integration, options] of Object.entries(integration_options_config)) {
|
||||||
|
for (const key of Object.keys(options)) {
|
||||||
|
delete prompt[`${integration}_${key}`];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(prompt.api_type && prompt.api_type !== ''){
|
||||||
|
const activeIntegration = prompt.api_type.replace('_api', '');
|
||||||
|
for (const [integration, options] of Object.entries(integration_options_config)) {
|
||||||
|
if(integration !== activeIntegration){
|
||||||
|
for (const key of Object.keys(options)) {
|
||||||
|
delete prompt[`${integration}_${key}`];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (const [integration, options] of Object.entries(integration_options_config)) {
|
||||||
|
for (const key of Object.keys(options)) {
|
||||||
|
delete prompt[`${integration}_${key}`];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(prompt.is_default == 1){
|
if(prompt.is_default == 1){
|
||||||
|
let allowedKeys = ['id', 'enabled', 'position_compose', 'position_display', 'need_custom_text'];
|
||||||
|
if(include_api_settings){
|
||||||
|
allowedKeys.push('api_type');
|
||||||
|
for (const [integration, options] of Object.entries(integration_options_config)) {
|
||||||
|
for (const key of Object.keys(options)) {
|
||||||
|
allowedKeys.push(`${integration}_${key}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Object.keys(prompt).forEach(key => {
|
Object.keys(prompt).forEach(key => {
|
||||||
if(!['id', 'enabled', 'position_compose', 'position_display', 'need_custom_text'].includes(key)){
|
if(!allowedKeys.includes(key)){
|
||||||
delete prompt[key];
|
delete prompt[key];
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}else{
|
}else{
|
||||||
delete prompt['idnum'];
|
delete prompt['idnum'];
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
@ -587,4 +687,4 @@ export async function clearPromptAPI(id){
|
||||||
}
|
}
|
||||||
// console.log(">>>>>>>>>>>>> clearPromptAPI _prompt AFTER: " + JSON.stringify(_prompt));
|
// console.log(">>>>>>>>>>>>> clearPromptAPI _prompt AFTER: " + JSON.stringify(_prompt));
|
||||||
await savePrompt(_prompt);
|
await savePrompt(_prompt);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,11 @@ export const taSpamReport = {
|
||||||
return output[key] || null;
|
return output[key] || null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async removeReportData(data_id) {
|
||||||
|
const key = this._data_prefix + data_id;
|
||||||
|
await browser.storage.session.remove(key);
|
||||||
|
},
|
||||||
|
|
||||||
async getAllReportData() {
|
async getAllReportData() {
|
||||||
let allData = await browser.storage.session.get(null);
|
let allData = await browser.storage.session.get(null);
|
||||||
let reportData = {};
|
let reportData = {};
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,11 @@ export const getMenuContextDisplay = () => 'message_display_action_menu';
|
||||||
|
|
||||||
export const contextMenuID_AddTags = 'mzta-add-tags';
|
export const contextMenuID_AddTags = 'mzta-add-tags';
|
||||||
export const contextMenuID_Spamfilter = 'mzta-spamfilter';
|
export const contextMenuID_Spamfilter = 'mzta-spamfilter';
|
||||||
|
export const contextMenuID_Summarize = 'mzta-summarize';
|
||||||
export const contextMenuIconsPath = {
|
export const contextMenuIconsPath = {
|
||||||
[contextMenuID_AddTags]: 'moz-extension:images/autotags.png',
|
[contextMenuID_AddTags]: 'moz-extension:images/autotags.png',
|
||||||
[contextMenuID_Spamfilter]: 'moz-extension:images/spamfilter.png',
|
[contextMenuID_Spamfilter]: 'moz-extension:images/spamfilter.png',
|
||||||
|
[contextMenuID_Summarize]: 'moz-extension:images/summarize.png',
|
||||||
};
|
};
|
||||||
|
|
||||||
export function getLanguageDisplayName(languageCode) {
|
export function getLanguageDisplayName(languageCode) {
|
||||||
|
|
@ -92,6 +94,17 @@ export async function getCurrentIdentity(msgHeader, getFull = false) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check the account that the folder of the message belongs to
|
||||||
|
if (msgHeader.folder && msgHeader.folder.accountId) {
|
||||||
|
const account = accounts.find(a => a.id === msgHeader.folder.accountId);
|
||||||
|
if (account && account.identities && account.identities.length > 0) {
|
||||||
|
// Just return the first identity of the account.
|
||||||
|
const identity = account.identities[0];
|
||||||
|
console.log(">>>>>>>>>> got from folder");
|
||||||
|
return getFull ? { id: identity.id, email: identity.email } : identity.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Fallback
|
// Fallback
|
||||||
return getFull ? fallbackIdentity : fallbackIdentity?.id || null;
|
return getFull ? fallbackIdentity : fallbackIdentity?.id || null;
|
||||||
}
|
}
|
||||||
|
|
@ -347,17 +360,6 @@ export function i18nConditionalGet(str) {
|
||||||
return str; // Return the original string if the conditions are not met
|
return str; // Return the original string if the conditions are not met
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function isThunderbird128OrGreater(){
|
|
||||||
try {
|
|
||||||
const info = await browser.runtime.getBrowserInfo();
|
|
||||||
const version = info.version;
|
|
||||||
return compareThunderbirdVersions(version, '128.0') >= 0;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('[ThunderAI] Error retrieving browser information:', error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function compareThunderbirdVersions(v1, v2) {
|
function compareThunderbirdVersions(v1, v2) {
|
||||||
const v1parts = v1.split('.').map(Number);
|
const v1parts = v1.split('.').map(Number);
|
||||||
const v2parts = v2.split('.').map(Number);
|
const v2parts = v2.split('.').map(Number);
|
||||||
|
|
@ -383,12 +385,9 @@ export function generateCallID(length = 10) {
|
||||||
|
|
||||||
export async function getTagsList(){
|
export async function getTagsList(){
|
||||||
let messageTags = [];
|
let messageTags = [];
|
||||||
if(await isThunderbird128OrGreater()) {
|
// without the tags related permissions, we can't get the tags list
|
||||||
// without the tags related permissions, we can't get the tags list
|
messageTags = await browser.messages.tags.list();
|
||||||
messageTags = await browser.messages.tags.list();
|
|
||||||
} else {
|
|
||||||
messageTags = await browser.messages.listTags();
|
|
||||||
}
|
|
||||||
const output = messageTags.map(tag => tag.tag).join(', ');
|
const output = messageTags.map(tag => tag.tag).join(', ');
|
||||||
|
|
||||||
const output2 = messageTags.reduce((acc, messageTag) => {
|
const output2 = messageTags.reduce((acc, messageTag) => {
|
||||||
|
|
@ -409,11 +408,7 @@ export async function createTag(tag) {
|
||||||
if(prefs_tag.add_tags_first_uppercase) tag = tag.toLowerCase().charAt(0).toUpperCase() + tag.toLowerCase().slice(1);
|
if(prefs_tag.add_tags_first_uppercase) tag = tag.toLowerCase().charAt(0).toUpperCase() + tag.toLowerCase().slice(1);
|
||||||
try {
|
try {
|
||||||
const tagKey = '$ta-' + generateCallID(16) + '-' + sanitizeString(tag); // Ensure uniqueness with a longer random ID
|
const tagKey = '$ta-' + generateCallID(16) + '-' + sanitizeString(tag); // Ensure uniqueness with a longer random ID
|
||||||
if(await isThunderbird128OrGreater()) {
|
return browser.messages.tags.create(tagKey, tag, generateHexColorForTag());
|
||||||
return browser.messages.tags.create(tagKey, tag, generateHexColorForTag());
|
|
||||||
}else{
|
|
||||||
return browser.messages.createTag(tagKey, tag, generateHexColorForTag());
|
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[ThunderAI] Error creating tag:', error);
|
console.error('[ThunderAI] Error creating tag:', error);
|
||||||
}
|
}
|
||||||
|
|
@ -515,6 +510,10 @@ export function normalizeStringList(list, returnType = 0) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function prepareOriginURL(url) {
|
||||||
|
return url.endsWith('/') ? `${url}*` : `${url}/*`;
|
||||||
|
}
|
||||||
|
|
||||||
function generateHexColorForTag() {
|
function generateHexColorForTag() {
|
||||||
const red = Math.floor(Math.random() * 256);
|
const red = Math.floor(Math.random() * 256);
|
||||||
const green = Math.floor(Math.random() * 256);
|
const green = Math.floor(Math.random() * 256);
|
||||||
|
|
@ -535,6 +534,14 @@ export async function transformTagsLabels(labels, tags_list) {
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setTomSelectBorder(el){
|
||||||
|
if (el.getValue() === "") {
|
||||||
|
el.control.style.border = '2px solid red';
|
||||||
|
} else {
|
||||||
|
el.control.style.border = '1px solid #d0d0d0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function getAPIsInitMessageString(args = {}) {
|
export function getAPIsInitMessageString(args = {}) {
|
||||||
const {
|
const {
|
||||||
api_string = '',
|
api_string = '',
|
||||||
|
|
@ -570,6 +577,7 @@ export function getActiveSpecialPromptsIDs(args = {}) {
|
||||||
addtags = false,
|
addtags = false,
|
||||||
addtags_api = false,
|
addtags_api = false,
|
||||||
get_calendar_event = false,
|
get_calendar_event = false,
|
||||||
|
get_calendar_event_from_clipboard = false,
|
||||||
get_task = false,
|
get_task = false,
|
||||||
is_chatgpt_web = false
|
is_chatgpt_web = false
|
||||||
} = args;
|
} = args;
|
||||||
|
|
@ -589,6 +597,9 @@ export function getActiveSpecialPromptsIDs(args = {}) {
|
||||||
if (get_calendar_event) {
|
if (get_calendar_event) {
|
||||||
output.push('prompt_get_calendar_event');
|
output.push('prompt_get_calendar_event');
|
||||||
}
|
}
|
||||||
|
if (get_calendar_event_from_clipboard) {
|
||||||
|
output.push('prompt_get_calendar_event_from_clipboard');
|
||||||
|
}
|
||||||
if (get_task) {
|
if (get_task) {
|
||||||
output.push('prompt_get_task');
|
output.push('prompt_get_task');
|
||||||
}
|
}
|
||||||
|
|
@ -685,6 +696,29 @@ export function validateCustomData_ChatGPTWeb(event) {
|
||||||
document.getElementById(event.target.id + '_info').style.color = is_valid ? '' : 'red';
|
document.getElementById(event.target.id + '_info').style.color = is_valid ? '' : 'red';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// From https://thunderbird.topicbox.com/groups/addons/Tafa58394231a18f8-M3e565a75287313ea4395ff5f
|
||||||
|
// Thanks to John Bieling
|
||||||
|
export async function requestSitePermission(url) {
|
||||||
|
// Normalize the origin to ensure it ends with /*
|
||||||
|
const origin = url.replace(/\/?\*?$/, '/*');
|
||||||
|
|
||||||
|
const hasPermission = await browser.permissions.contains({
|
||||||
|
origins: [origin],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasPermission) {
|
||||||
|
// Permission already granted — safe to save and use the URL.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const granted = await browser.permissions.request({
|
||||||
|
origins: [origin],
|
||||||
|
});
|
||||||
|
|
||||||
|
// If not granted, it's not safe to save or use the URL,
|
||||||
|
// since the user explicitly denied access.
|
||||||
|
return granted;
|
||||||
|
}
|
||||||
|
|
||||||
// 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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
/*
|
|
||||||
* ThunderAI [https://micz.it/thunderbird-addon-thunderai/]
|
|
||||||
* Copyright (C) 2024 - 2026 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/>.
|
|
||||||
*/
|
|
||||||
// Firefox 115 and, consequently, Thunderbird 115 are not compatible with Intl.Segmenter.
|
|
||||||
// ChatGPT is using Intl.Segmenter, so we have to do something about it or it won't work...
|
|
||||||
|
|
||||||
// console.log("[ThunderAI] Intl.Segmenter: " + Intl.Segmenter);
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
if('Segmenter' in Intl){
|
|
||||||
// console.log('[ThunderAI] TB128+ detected. Intl.Segmenter is already supported.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Creates a <script> element to inject polyfill.js into the page context
|
|
||||||
const script = document.createElement('script');
|
|
||||||
script.src = browser.runtime.getURL('js/tb115_segmenter/tb115_polyfill.js');
|
|
||||||
script.onload = function() {
|
|
||||||
// Remove the script once loaded for cleanup
|
|
||||||
this.remove();
|
|
||||||
};
|
|
||||||
script.onerror = function() {
|
|
||||||
console.error('[ThunderAI] Error loading Intl.Segmenter polyfill.');
|
|
||||||
};
|
|
||||||
(document.head || document.documentElement).appendChild(script);
|
|
||||||
})();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async function isThunderbird128OrGreater(){
|
|
||||||
try {
|
|
||||||
const info = await browser.runtime.getBrowserInfo();
|
|
||||||
const version = info.version;
|
|
||||||
return compareThunderbirdVersions(version, '128.0') >= 0;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('[ThunderAI] Error retrieving browser information:', error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function compareThunderbirdVersions(v1, v2) {
|
|
||||||
const v1parts = v1.split('.').map(Number);
|
|
||||||
const v2parts = v2.split('.').map(Number);
|
|
||||||
|
|
||||||
for (let i = 0; i < Math.max(v1parts.length, v2parts.length); i++) {
|
|
||||||
const v1part = v1parts[i] || 0;
|
|
||||||
const v2part = v2parts[i] || 0;
|
|
||||||
if (v1part > v2part) return 1;
|
|
||||||
if (v1part < v2part) return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
/*
|
|
||||||
* ThunderAI [https://micz.it/thunderbird-addon-thunderai/]
|
|
||||||
* Copyright (C) 2024 - 2026 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/>.
|
|
||||||
*/
|
|
||||||
// Firefox 115 and, consequently, Thunderbird 115 are not compatible with Intl.Segmenter.
|
|
||||||
// ChatGPT is using Intl.Segmenter, so we have to do something about it or it won't work...
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
if (!('Segmenter' in Intl)) {
|
|
||||||
class Segmenter {
|
|
||||||
constructor(locale = 'en', options = { granularity: 'grapheme' }) {
|
|
||||||
this.locale = locale;
|
|
||||||
this.granularity = options.granularity || 'grapheme';
|
|
||||||
}
|
|
||||||
|
|
||||||
segment(text) {
|
|
||||||
switch (this.granularity) {
|
|
||||||
case 'word':
|
|
||||||
return text.split(/\s+/).filter(word => word.length > 0).map(word => ({ segment: word }));
|
|
||||||
case 'grapheme':
|
|
||||||
return Array.from(text).map(char => ({ segment: char }));
|
|
||||||
case 'sentence':
|
|
||||||
return text.split(/(?<=[.!?])\s+/).map(sentence => ({ segment: sentence }));
|
|
||||||
default:
|
|
||||||
return [{ segment: text }];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Intl.Segmenter = Segmenter;
|
|
||||||
// console.log('Intl.Segmenter polyfill correctly loaded.');
|
|
||||||
}
|
|
||||||
// else {
|
|
||||||
// console.log('Intl.Segmenter is already supported.');
|
|
||||||
// }
|
|
||||||
})();
|
|
||||||
|
|
@ -2,13 +2,13 @@
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"name": "ThunderAI",
|
"name": "ThunderAI",
|
||||||
"description": "__MSG_extensionDescription__",
|
"description": "__MSG_extensionDescription__",
|
||||||
"version": "3.8.4",
|
"version": "4.0.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": {
|
||||||
"gecko": {
|
"gecko": {
|
||||||
"id": "thunderai@micz.it",
|
"id": "thunderai@micz.it",
|
||||||
"strict_min_version": "115.0"
|
"strict_min_version": "140.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"message_display_action": {
|
"message_display_action": {
|
||||||
|
|
@ -34,12 +34,15 @@
|
||||||
"messagesTagsList"
|
"messagesTagsList"
|
||||||
],
|
],
|
||||||
"optional_permissions": [
|
"optional_permissions": [
|
||||||
|
"clipboardRead",
|
||||||
"messagesTags",
|
"messagesTags",
|
||||||
"messagesUpdate",
|
"messagesUpdate",
|
||||||
"messagesMove",
|
"messagesMove",
|
||||||
"https://*.chatgpt.com/*",
|
"https://*.chatgpt.com/*",
|
||||||
"https://*.openai.com/*",
|
"https://*.openai.com/*",
|
||||||
"https://*.anthropic.com/*",
|
"https://*.anthropic.com/*",
|
||||||
|
"https://*/*",
|
||||||
|
"http://*/*",
|
||||||
"<all_urls>"
|
"<all_urls>"
|
||||||
],
|
],
|
||||||
"background": {
|
"background": {
|
||||||
|
|
@ -65,7 +68,7 @@
|
||||||
"content_scripts": [
|
"content_scripts": [
|
||||||
{
|
{
|
||||||
"matches": ["https://*.chatgpt.com/*"],
|
"matches": ["https://*.chatgpt.com/*"],
|
||||||
"js": ["js/tb115_segmenter/tb115_loader.js","js/lib/diff.js"],
|
"js": ["js/lib/diff.js"],
|
||||||
"all_frames": true,
|
"all_frames": true,
|
||||||
"run_at": "document_start"
|
"run_at": "document_start"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ import {
|
||||||
extractJsonObject,
|
extractJsonObject,
|
||||||
contextMenuID_AddTags,
|
contextMenuID_AddTags,
|
||||||
contextMenuID_Spamfilter,
|
contextMenuID_Spamfilter,
|
||||||
|
contextMenuID_Summarize,
|
||||||
contextMenuIconsPath,
|
contextMenuIconsPath,
|
||||||
sanitizeChatGPTModelData,
|
sanitizeChatGPTModelData,
|
||||||
sanitizeChatGPTWebCustomData,
|
sanitizeChatGPTWebCustomData,
|
||||||
|
|
@ -57,10 +58,16 @@ import {
|
||||||
} from './js/mzta-utils.js';
|
} from './js/mzta-utils.js';
|
||||||
import { taPromptUtils } from './js/mzta-utils-prompt.js';
|
import { taPromptUtils } from './js/mzta-utils-prompt.js';
|
||||||
import { mzta_specialCommand } from './js/mzta-special-commands.js';
|
import { mzta_specialCommand } from './js/mzta-special-commands.js';
|
||||||
import { getSpamFilterPrompt } from './js/mzta-prompts.js';
|
import {
|
||||||
|
getSpamFilterPrompt,
|
||||||
|
getSpecialPrompts
|
||||||
|
} from './js/mzta-prompts.js';
|
||||||
import { taSpamReport } from './js/mzta-spamreport.js';
|
import { taSpamReport } from './js/mzta-spamreport.js';
|
||||||
import { taWorkingStatus } from './js/mzta-working-status.js';
|
import { taWorkingStatus } from './js/mzta-working-status.js';
|
||||||
import { addTags_getExclusionList, checkExcludedTag } from './js/mzta-addatags-exclusion-list.js';
|
import {
|
||||||
|
addTags_getExclusionList,
|
||||||
|
checkExcludedTag
|
||||||
|
} from './js/mzta-addatags-exclusion-list.js';
|
||||||
|
|
||||||
browser.runtime.onInstalled.addListener(({ reason, previousVersion }) => {
|
browser.runtime.onInstalled.addListener(({ reason, previousVersion }) => {
|
||||||
// console.log(">>>>>>>>>>> onInstalled: " + JSON.stringify(reason) + ", previousVersion: " + previousVersion);
|
// console.log(">>>>>>>>>>> onInstalled: " + JSON.stringify(reason) + ", previousVersion: " + previousVersion);
|
||||||
|
|
@ -92,6 +99,7 @@ let special_prompts_ids = getActiveSpecialPromptsIDs({
|
||||||
addtags: prefs_init.add_tags,
|
addtags: prefs_init.add_tags,
|
||||||
addtags_api: hasSpecificIntegration(prefs_init.add_tags_use_specific_integration, prefs_init.add_tags_connection_type),
|
addtags_api: hasSpecificIntegration(prefs_init.add_tags_use_specific_integration, prefs_init.add_tags_connection_type),
|
||||||
get_calendar_event: doGetSparkFeature(prefs_init.get_calendar_event),
|
get_calendar_event: doGetSparkFeature(prefs_init.get_calendar_event),
|
||||||
|
get_calendar_event_from_clipboard: doGetSparkFeature(prefs_init.get_calendar_event_from_clipboard),
|
||||||
get_task: doGetSparkFeature(prefs_init.get_task),
|
get_task: doGetSparkFeature(prefs_init.get_task),
|
||||||
is_chatgpt_web: (prefs_init.connection_type === "chatgpt_web")
|
is_chatgpt_web: (prefs_init.connection_type === "chatgpt_web")
|
||||||
});
|
});
|
||||||
|
|
@ -176,13 +184,15 @@ function preparePopupMenu(tab) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function _reload_menus() {
|
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, get_task: prefs_default.get_task, 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_calendar_event_from_clipboard: prefs_default.get_calendar_event_from_clipboard, get_task: prefs_default.get_task, connection_type: prefs_default.connection_type});
|
||||||
let getCalendarEvent = doGetSparkFeature(prefs_reload.get_calendar_event);
|
let getCalendarEvent = doGetSparkFeature(prefs_reload.get_calendar_event);
|
||||||
|
let getCalendarEventFromClipboard = doGetSparkFeature(prefs_reload.get_calendar_event_from_clipboard);
|
||||||
let getTask = doGetSparkFeature(prefs_reload.get_task);
|
let getTask = doGetSparkFeature(prefs_reload.get_task);
|
||||||
const special_prompts_ids = getActiveSpecialPromptsIDs({
|
const special_prompts_ids = getActiveSpecialPromptsIDs({
|
||||||
addtags: prefs_reload.add_tags,
|
addtags: prefs_reload.add_tags,
|
||||||
addtags_api: hasSpecificIntegration(prefs_init.add_tags_use_specific_integration, prefs_init.add_tags_connection_type),
|
addtags_api: hasSpecificIntegration(prefs_init.add_tags_use_specific_integration, prefs_init.add_tags_connection_type),
|
||||||
get_calendar_event: getCalendarEvent,
|
get_calendar_event: getCalendarEvent,
|
||||||
|
get_calendar_event_from_clipboard: getCalendarEventFromClipboard,
|
||||||
get_task: getTask,
|
get_task: getTask,
|
||||||
is_chatgpt_web: (prefs_reload.connection_type === "chatgpt_web")
|
is_chatgpt_web: (prefs_reload.connection_type === "chatgpt_web")
|
||||||
});
|
});
|
||||||
|
|
@ -348,6 +358,29 @@ messenger.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||||
case 'api_send_custom_text':
|
case 'api_send_custom_text':
|
||||||
browser.tabs.sendMessage(message.tabId, { command: "api_send_custom_text", custom_text: message.custom_text });
|
browser.tabs.sendMessage(message.tabId, { command: "api_send_custom_text", custom_text: message.custom_text });
|
||||||
break;
|
break;
|
||||||
|
case 'checkSpamReport':
|
||||||
|
if(!prefs_init.spamfilter_show_msg_panel){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function _checkSpamReport(tabId) {
|
||||||
|
try {
|
||||||
|
if (sender.tab.type !== 'messageDisplay' && sender.tab.type !== 'mail') return;
|
||||||
|
let message = await browser.messageDisplay.getDisplayedMessage(tabId);
|
||||||
|
if (!message) return;
|
||||||
|
let report = await taSpamReport.loadReportData(message.headerMessageId);
|
||||||
|
if (report) {
|
||||||
|
browser.tabs.sendMessage(tabId, { command: "showSpamReport", data: report });
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
taLog.error("Error in checkSpamReport: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_checkSpamReport(sender.tab.id);
|
||||||
|
break;
|
||||||
|
case 'removeSpamReport':
|
||||||
|
taSpamReport.removeReportData(message.headerMessageId);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -796,16 +829,17 @@ async function reload_pref_init(){
|
||||||
do_debug: prefs_default.do_debug,
|
do_debug: prefs_default.do_debug,
|
||||||
add_tags: prefs_default.add_tags,
|
add_tags: prefs_default.add_tags,
|
||||||
get_calendar_event: prefs_default.get_calendar_event,
|
get_calendar_event: prefs_default.get_calendar_event,
|
||||||
|
get_calendar_event_from_clipboard: prefs_default.get_calendar_event_from_clipboard,
|
||||||
get_task: prefs_default.get_task,
|
get_task: prefs_default.get_task,
|
||||||
connection_type: prefs_default.connection_type,
|
connection_type: prefs_default.connection_type,
|
||||||
add_tags_auto: prefs_default.add_tags_auto,
|
add_tags_auto: prefs_default.add_tags_auto,
|
||||||
add_tags_auto_force_existing: prefs_default.add_tags_auto_force_existing,
|
add_tags_auto_force_existing: prefs_default.add_tags_auto_force_existing,
|
||||||
add_tags_auto_only_inbox: prefs_default.add_tags_auto_only_inbox,
|
add_tags_auto_only_inbox: prefs_default.add_tags_auto_only_inbox,
|
||||||
spamfilter: prefs_default.spamfilter,
|
spamfilter: prefs_default.spamfilter,
|
||||||
|
summarize: prefs_default.summarize,
|
||||||
spamfilter_threshold: prefs_default.spamfilter_threshold,
|
spamfilter_threshold: prefs_default.spamfilter_threshold,
|
||||||
|
spamfilter_show_msg_panel: prefs_default.spamfilter_show_msg_panel,
|
||||||
dynamic_menu_force_enter: prefs_default.dynamic_menu_force_enter,
|
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,
|
|
||||||
...getDynamicSettingsDefaults(['use_specific_integration', 'connection_type'])
|
...getDynamicSettingsDefaults(['use_specific_integration', 'connection_type'])
|
||||||
});
|
});
|
||||||
_process_incoming = prefs_init.add_tags_auto || prefs_init.spamfilter;
|
_process_incoming = prefs_init.add_tags_auto || prefs_init.spamfilter;
|
||||||
|
|
@ -822,11 +856,13 @@ function setupStorageChangeListener() {
|
||||||
if (changes.add_tags) {
|
if (changes.add_tags) {
|
||||||
const newTags = changes.add_tags.newValue;
|
const newTags = changes.add_tags.newValue;
|
||||||
let getCalendarEvent = doGetSparkFeature(prefs_init.get_calendar_event);
|
let getCalendarEvent = doGetSparkFeature(prefs_init.get_calendar_event);
|
||||||
|
let getCalendarEventFromClipboard = doGetSparkFeature(prefs_init.get_calendar_event_from_clipboard);
|
||||||
let getTask = doGetSparkFeature(prefs_init.get_task);
|
let getTask = doGetSparkFeature(prefs_init.get_task);
|
||||||
const special_prompts_ids = getActiveSpecialPromptsIDs({
|
const special_prompts_ids = getActiveSpecialPromptsIDs({
|
||||||
addtags: newTags,
|
addtags: newTags,
|
||||||
addtags_api: hasSpecificIntegration(prefs_init.add_tags_use_specific_integration, prefs_init.add_tags_connection_type),
|
addtags_api: hasSpecificIntegration(prefs_init.add_tags_use_specific_integration, prefs_init.add_tags_connection_type),
|
||||||
get_calendar_event: getCalendarEvent,
|
get_calendar_event: getCalendarEvent,
|
||||||
|
get_calendar_event_from_clipboard: getCalendarEventFromClipboard,
|
||||||
get_task: getTask,
|
get_task: getTask,
|
||||||
is_chatgpt_web: (prefs_init.connection_type === "chatgpt_web")
|
is_chatgpt_web: (prefs_init.connection_type === "chatgpt_web")
|
||||||
});
|
});
|
||||||
|
|
@ -837,11 +873,30 @@ function setupStorageChangeListener() {
|
||||||
if (changes.get_calendar_event) {
|
if (changes.get_calendar_event) {
|
||||||
const newCalendarEvent = changes.get_calendar_event.newValue;
|
const newCalendarEvent = changes.get_calendar_event.newValue;
|
||||||
let getCalendarEvent = doGetSparkFeature(newCalendarEvent);
|
let getCalendarEvent = doGetSparkFeature(newCalendarEvent);
|
||||||
|
let getCalendarEventFromClipboard = doGetSparkFeature(prefs_init.get_calendar_event_from_clipboard);
|
||||||
let getTask = doGetSparkFeature(prefs_init.get_task);
|
let getTask = doGetSparkFeature(prefs_init.get_task);
|
||||||
const special_prompts_ids = getActiveSpecialPromptsIDs({
|
const special_prompts_ids = getActiveSpecialPromptsIDs({
|
||||||
addtags: prefs_init.add_tags,
|
addtags: prefs_init.add_tags,
|
||||||
addtags_api: hasSpecificIntegration(prefs_init.add_tags_use_specific_integration, prefs_init.add_tags_connection_type),
|
addtags_api: hasSpecificIntegration(prefs_init.add_tags_use_specific_integration, prefs_init.add_tags_connection_type),
|
||||||
get_calendar_event: getCalendarEvent,
|
get_calendar_event: getCalendarEvent,
|
||||||
|
get_calendar_event_from_clipboard: getCalendarEventFromClipboard,
|
||||||
|
get_task: getTask,
|
||||||
|
is_chatgpt_web: (prefs_init.connection_type === "chatgpt_web")
|
||||||
|
});
|
||||||
|
menus.reload(special_prompts_ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process 'get_calendar_event_from_clipboard' changes
|
||||||
|
if (changes.get_calendar_event_from_clipboard) {
|
||||||
|
const newCalendarEventFromClipboard = changes.get_calendar_event_from_clipboard.newValue;
|
||||||
|
let getCalendarEvent = doGetSparkFeature(prefs_init.get_calendar_event);
|
||||||
|
let getCalendarEventFromClipboard = doGetSparkFeature(newCalendarEventFromClipboard);
|
||||||
|
let getTask = doGetSparkFeature(prefs_init.get_task);
|
||||||
|
const special_prompts_ids = getActiveSpecialPromptsIDs({
|
||||||
|
addtags: prefs_init.add_tags,
|
||||||
|
addtags_api: hasSpecificIntegration(prefs_init.add_tags_use_specific_integration, prefs_init.add_tags_connection_type),
|
||||||
|
get_calendar_event: getCalendarEvent,
|
||||||
|
get_calendar_event_from_clipboard: getCalendarEventFromClipboard,
|
||||||
get_task: getTask,
|
get_task: getTask,
|
||||||
is_chatgpt_web: (prefs_init.connection_type === "chatgpt_web")
|
is_chatgpt_web: (prefs_init.connection_type === "chatgpt_web")
|
||||||
});
|
});
|
||||||
|
|
@ -852,11 +907,13 @@ function setupStorageChangeListener() {
|
||||||
if (changes.get_task) {
|
if (changes.get_task) {
|
||||||
const newTask = changes.get_task.newValue;
|
const newTask = changes.get_task.newValue;
|
||||||
let getCalendarEvent = doGetSparkFeature(prefs_init.get_calendar_event);
|
let getCalendarEvent = doGetSparkFeature(prefs_init.get_calendar_event);
|
||||||
|
let getCalendarEventFromClipboard = doGetSparkFeature(prefs_init.get_calendar_event_from_clipboard);
|
||||||
let getTask = doGetSparkFeature(newTask);
|
let getTask = doGetSparkFeature(newTask);
|
||||||
const special_prompts_ids = getActiveSpecialPromptsIDs({
|
const special_prompts_ids = getActiveSpecialPromptsIDs({
|
||||||
addtags: prefs_init.add_tags,
|
addtags: prefs_init.add_tags,
|
||||||
addtags_api: hasSpecificIntegration(prefs_init.add_tags_use_specific_integration, prefs_init.add_tags_connection_type),
|
addtags_api: hasSpecificIntegration(prefs_init.add_tags_use_specific_integration, prefs_init.add_tags_connection_type),
|
||||||
get_calendar_event: getCalendarEvent,
|
get_calendar_event: getCalendarEvent,
|
||||||
|
get_calendar_event_from_clipboard: getCalendarEventFromClipboard,
|
||||||
get_task: getTask,
|
get_task: getTask,
|
||||||
is_chatgpt_web: (prefs_init.connection_type === "chatgpt_web")
|
is_chatgpt_web: (prefs_init.connection_type === "chatgpt_web")
|
||||||
});
|
});
|
||||||
|
|
@ -867,57 +924,22 @@ function setupStorageChangeListener() {
|
||||||
if (changes.connection_type) {
|
if (changes.connection_type) {
|
||||||
const newConnectionType = changes.connection_type.newValue;
|
const newConnectionType = changes.connection_type.newValue;
|
||||||
let getCalendarEvent = doGetSparkFeature(prefs_init.get_calendar_event);
|
let getCalendarEvent = doGetSparkFeature(prefs_init.get_calendar_event);
|
||||||
|
let getCalendarEventFromClipboard = doGetSparkFeature(prefs_init.get_calendar_event_from_clipboard);
|
||||||
let getTask = doGetSparkFeature(prefs_init.get_task);
|
let getTask = doGetSparkFeature(prefs_init.get_task);
|
||||||
const special_prompts_ids = getActiveSpecialPromptsIDs({
|
const special_prompts_ids = getActiveSpecialPromptsIDs({
|
||||||
addtags: prefs_init.add_tags,
|
addtags: prefs_init.add_tags,
|
||||||
addtags_api: hasSpecificIntegration(prefs_init.add_tags_use_specific_integration, prefs_init.add_tags_connection_type),
|
addtags_api: hasSpecificIntegration(prefs_init.add_tags_use_specific_integration, prefs_init.add_tags_connection_type),
|
||||||
get_calendar_event: getCalendarEvent,
|
get_calendar_event: getCalendarEvent,
|
||||||
|
get_calendar_event_from_clipboard: getCalendarEventFromClipboard,
|
||||||
get_task: getTask,
|
get_task: getTask,
|
||||||
is_chatgpt_web: (newConnectionType === "chatgpt_web")
|
is_chatgpt_web: (newConnectionType === "chatgpt_web")
|
||||||
});
|
});
|
||||||
menus.reload(special_prompts_ids);
|
menus.reload(special_prompts_ids);
|
||||||
|
}
|
||||||
|
|
||||||
if(newConnectionType === "chatgpt_web"){
|
reload_pref_init().then(() => {
|
||||||
removeContextMenu(contextMenuID_AddTags);
|
|
||||||
removeContextMenu(contextMenuID_Spamfilter);
|
|
||||||
}
|
|
||||||
addContextMenuItems();
|
addContextMenuItems();
|
||||||
}
|
});
|
||||||
|
|
||||||
// context menu changes for add_tags and spamfilter
|
|
||||||
if (changes.add_tags_context_menu) {
|
|
||||||
if(changes.add_tags_context_menu.newValue){
|
|
||||||
addContextMenu(contextMenuID_AddTags);
|
|
||||||
}else{
|
|
||||||
removeContextMenu(contextMenuID_AddTags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (changes.add_tags) {
|
|
||||||
if(changes.add_tags.newValue){
|
|
||||||
if(prefs_init.add_tags_context_menu){
|
|
||||||
addContextMenu(contextMenuID_AddTags);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
removeContextMenu(contextMenuID_AddTags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (changes.spamfilter_context_menu) {
|
|
||||||
if(changes.spamfilter_context_menu.newValue){
|
|
||||||
addContextMenu(contextMenuID_Spamfilter);
|
|
||||||
}else{
|
|
||||||
removeContextMenu(contextMenuID_Spamfilter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (changes.spamfilter) {
|
|
||||||
if(changes.spamfilter.newValue){
|
|
||||||
if(prefs_init.spamfilter_context_menu){
|
|
||||||
addContextMenu(contextMenuID_Spamfilter);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
removeContextMenu(contextMenuID_Spamfilter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reload_pref_init();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -968,15 +990,38 @@ function removeContextMenu(menu_id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function addContextMenuItems() {
|
function addContextMenuItems() {
|
||||||
|
let itemsToAdd = [];
|
||||||
|
|
||||||
// Add Context menu: Add tags
|
// Add Context menu: Add tags
|
||||||
if(prefs_init.add_tags && prefs_init.add_tags_context_menu && checkAPIIntegration(prefs_init.connection_type, prefs_init.add_tags_use_specific_integration,prefs_init.add_tags_connection_type)){
|
if(prefs_init.add_tags && checkAPIIntegration(prefs_init.connection_type, prefs_init.add_tags_use_specific_integration,prefs_init.add_tags_connection_type)){
|
||||||
addContextMenu(contextMenuID_AddTags);
|
itemsToAdd.push(contextMenuID_AddTags);
|
||||||
|
} else {
|
||||||
|
removeContextMenu(contextMenuID_AddTags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add Context menu: Spamfilter
|
// Add Context menu: Spamfilter
|
||||||
if(prefs_init.spamfilter && prefs_init.spamfilter_context_menu && checkAPIIntegration(prefs_init.connection_type, prefs_init.spamfilter_use_specific_integration,prefs_init.spamfilter_connection_type)){
|
if(prefs_init.spamfilter && checkAPIIntegration(prefs_init.connection_type, prefs_init.spamfilter_use_specific_integration,prefs_init.spamfilter_connection_type)){
|
||||||
addContextMenu(contextMenuID_Spamfilter);
|
itemsToAdd.push(contextMenuID_Spamfilter);
|
||||||
|
} else {
|
||||||
|
removeContextMenu(contextMenuID_Spamfilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add Context menu: Summarize
|
||||||
|
if(prefs_init.summarize && checkAPIIntegration(prefs_init.connection_type, prefs_init.summarize_use_specific_integration, prefs_init.summarize_connection_type)) {
|
||||||
|
itemsToAdd.push(contextMenuID_Summarize);
|
||||||
|
} else {
|
||||||
|
removeContextMenu(contextMenuID_Summarize);
|
||||||
|
}
|
||||||
|
|
||||||
|
itemsToAdd.sort((a, b) => {
|
||||||
|
let titleA = browser.i18n.getMessage("context_menu_" + a);
|
||||||
|
let titleB = browser.i18n.getMessage("context_menu_" + b);
|
||||||
|
return titleA.localeCompare(titleB);
|
||||||
|
});
|
||||||
|
|
||||||
|
itemsToAdd.forEach(menu_id => {
|
||||||
|
addContextMenu(menu_id);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addContextMenuItems();
|
addContextMenuItems();
|
||||||
|
|
@ -985,17 +1030,93 @@ addContextMenuItems();
|
||||||
browser.menus.onClicked.addListener( (info, tab) => {
|
browser.menus.onClicked.addListener( (info, tab) => {
|
||||||
let _add_tags = false
|
let _add_tags = false
|
||||||
let _spamfilter = false
|
let _spamfilter = false
|
||||||
|
let _summarize = false;
|
||||||
if(info.menuItemId === contextMenuID_AddTags){
|
if(info.menuItemId === contextMenuID_AddTags){
|
||||||
_add_tags = true;
|
_add_tags = true;
|
||||||
}
|
}
|
||||||
if(info.menuItemId === contextMenuID_Spamfilter){
|
if(info.menuItemId === contextMenuID_Spamfilter){
|
||||||
_spamfilter = true;
|
_spamfilter = true;
|
||||||
}
|
}
|
||||||
|
if(info.menuItemId === contextMenuID_Summarize) {
|
||||||
|
_summarize = true;
|
||||||
|
}
|
||||||
if(_add_tags || _spamfilter){
|
if(_add_tags || _spamfilter){
|
||||||
processEmails(getMessages(info.selectedMessages), _add_tags, _spamfilter);
|
processEmails(getMessages(info.selectedMessages), _add_tags, _spamfilter);
|
||||||
}
|
}
|
||||||
|
if(_summarize) {
|
||||||
|
// info.selectedMessages is of type MessageList
|
||||||
|
summarizeEmails(getMessages(info.selectedMessages));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function summarizeEmails(messages) {
|
||||||
|
taWorkingStatus.startWorking();
|
||||||
|
|
||||||
|
// we have three prompts, the actual assignment for the LLM, the email
|
||||||
|
// template prompt, and the email separator prompt
|
||||||
|
const specialPrompts = await getSpecialPrompts();
|
||||||
|
const prompt = specialPrompts.find((prompt) => prompt.id === 'prompt_summarize');
|
||||||
|
const prompt_email = specialPrompts.find((prompt) => prompt.id === 'prompt_summarize_email_template');
|
||||||
|
const prompt_email_separator = specialPrompts.find((prompt) => prompt.id === 'prompt_summarize_email_separator');
|
||||||
|
|
||||||
|
const tabs = await browser.tabs.query({ active: true, currentWindow: true });
|
||||||
|
const chatgpt_lang = await taPromptUtils.getDefaultLang(prompt);
|
||||||
|
|
||||||
|
// replace placeholders in the prompts the assignment prompt and email
|
||||||
|
// separator prompt do not have a message as context, so there is only
|
||||||
|
// limited things to replace
|
||||||
|
const prompt_string = await taPromptUtils.preparePrompt({
|
||||||
|
curr_prompt: prompt,
|
||||||
|
chatgpt_lang: chatgpt_lang,
|
||||||
|
});
|
||||||
|
const prompt_email_separator_string = await taPromptUtils.preparePrompt({
|
||||||
|
curr_prompt: prompt_email_separator,
|
||||||
|
chatgpt_lang: chatgpt_lang,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// assemble all email messages into one string and add the assignment prompt
|
||||||
|
const messages_list = [];
|
||||||
|
for await (let curr_message of messages) {
|
||||||
|
|
||||||
|
// extract body of current message as text
|
||||||
|
const curr_message_full = await browser.messages.getFull(curr_message.id);
|
||||||
|
const curr_body_full_html = getMailBody(curr_message_full);
|
||||||
|
const curr_body_full_text = htmlBodyToPlainText(curr_body_full_html.html);
|
||||||
|
if( curr_body_full_text.length === 0) {
|
||||||
|
taLog.log("No HTML found in the message body, using plain text...");
|
||||||
|
curr_body_full_text = curr_message_full.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
messages_list.push(await taPromptUtils.preparePrompt({
|
||||||
|
curr_prompt: prompt_email,
|
||||||
|
curr_message: curr_message,
|
||||||
|
chatgpt_lang: chatgpt_lang,
|
||||||
|
body_text: curr_body_full_text,
|
||||||
|
subject_text: curr_message_full.headers.subject,
|
||||||
|
msg_text: curr_body_full_html,
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
const messages_string = messages_list.join(prompt_email_separator_string);
|
||||||
|
|
||||||
|
const full_prompt = prompt_string + prompt_email_separator_string + messages_string;
|
||||||
|
|
||||||
|
// console.log(full_prompt);
|
||||||
|
|
||||||
|
// send the prompt to the chat interface
|
||||||
|
openChatGPT(
|
||||||
|
full_prompt,
|
||||||
|
prompt.action,
|
||||||
|
tabs[0].id,
|
||||||
|
prompt.name,
|
||||||
|
prompt.need_custom_text,
|
||||||
|
prompt
|
||||||
|
)
|
||||||
|
|
||||||
|
taWorkingStatus.stopWorking();
|
||||||
|
return {ok : '1'};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Listening for new received emails
|
// Listening for new received emails
|
||||||
const newEmailListener = (folder, messagesList) => {
|
const newEmailListener = (folder, messagesList) => {
|
||||||
|
|
@ -1170,16 +1291,21 @@ async function processEmails(messages, addTagsAuto, spamFilter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
taSpamReport.saveReportData(report_data, message.headerMessageId);
|
taSpamReport.saveReportData(report_data, message.headerMessageId);
|
||||||
|
|
||||||
|
// Check if the message is currently displayed and update the banner
|
||||||
|
if (prefs_init.spamfilter_show_msg_panel) {
|
||||||
|
let tabs = await browser.tabs.query({ active: true, currentWindow: true });
|
||||||
|
if (tabs.length > 0) {
|
||||||
|
let activeTab = tabs[0];
|
||||||
|
let displayedMessage = await browser.messageDisplay.getDisplayedMessage(activeTab.id);
|
||||||
|
if (displayedMessage && displayedMessage.id === message.id) {
|
||||||
|
browser.tabs.sendMessage(activeTab.id, { command: "showSpamReport", data: report_data });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
taWorkingStatus.stopWorking();
|
taWorkingStatus.stopWorking();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
browser.messages.onNewMailReceived.addListener(newEmailListener, !prefs_init.add_tags_auto_only_inbox);
|
||||||
|
|
||||||
try {
|
|
||||||
browser.messages.onNewMailReceived.addListener(newEmailListener, !prefs_init.add_tags_auto_only_inbox);
|
|
||||||
} catch (e) {
|
|
||||||
taLog.log("Using browser.messages.onNewMailReceived.addListener with one agrument for Thunderbird 115.");
|
|
||||||
browser.messages.onNewMailReceived.addListener(newEmailListener);
|
|
||||||
}
|
|
||||||
|
|
@ -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/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const special_prompts_with_integration = ['add_tags', 'spamfilter'];
|
const special_prompts_with_integration = ['add_tags', 'spamfilter', 'summarize', 'get_calendar_event', 'get_task'];
|
||||||
|
|
||||||
export const integration_options_config = {
|
export const integration_options_config = {
|
||||||
chatgpt: {
|
chatgpt: {
|
||||||
|
|
@ -123,15 +123,17 @@ export const prefs_default = {
|
||||||
add_tags_auto_only_inbox: true,
|
add_tags_auto_only_inbox: true,
|
||||||
add_tags_auto_uselist: false,
|
add_tags_auto_uselist: false,
|
||||||
add_tags_auto_uselist_list: '',
|
add_tags_auto_uselist_list: '',
|
||||||
add_tags_context_menu: true,
|
|
||||||
add_tags_enabled_accounts: [],
|
add_tags_enabled_accounts: [],
|
||||||
get_calendar_event: true,
|
get_calendar_event: true,
|
||||||
|
get_calendar_event_from_clipboard: false, // Enable calendar event from clipboard menu item
|
||||||
get_task: true,
|
get_task: true,
|
||||||
calendar_enforce_timezone: false,
|
calendar_enforce_timezone: false,
|
||||||
calendar_timezone: '',
|
calendar_timezone: '',
|
||||||
|
calendar_no_selection: false, // If true do not ask for selection, but use the full prompt
|
||||||
spamfilter: false,
|
spamfilter: false,
|
||||||
spamfilter_threshold: 70,
|
spamfilter_threshold: 70,
|
||||||
spamfilter_context_menu: true,
|
|
||||||
spamfilter_enabled_accounts: [],
|
spamfilter_enabled_accounts: [],
|
||||||
|
spamfilter_show_msg_panel: true,
|
||||||
|
summarize: false,
|
||||||
...generated_prefs
|
...generated_prefs
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -147,6 +147,17 @@
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr class="summarize_tr">
|
||||||
|
<td><span class="opt_title">__MSG_prefs_OptionText_summarize__</span>
|
||||||
|
<br><button id="btnManageSummarizeInfo" class="btn_small">__MSG_prefs_OptionText_btnManageSummarizeInfo__</button></td>
|
||||||
|
<td>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" id="summarize" name="summarize" class="option-input" />
|
||||||
|
__MSG_prefs_OptionText_summarize_Info__
|
||||||
|
<br><span class="warn_API_needed" id="summarize_warn_API_needed">__MSG_warn_API_needed__</span>
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr class="get_calendar_event_tr">
|
<tr class="get_calendar_event_tr">
|
||||||
<td><span class="opt_title">__MSG_prefs_OptionText_get_calendar_event__</span>
|
<td><span class="opt_title">__MSG_prefs_OptionText_get_calendar_event__</span>
|
||||||
<br><button id="btnManageCalendarEventInfo" class="btn_small">__MSG_prefs_OptionText_btnManageCalendarEventInfo__</button></td>
|
<br><button id="btnManageCalendarEventInfo" class="btn_small">__MSG_prefs_OptionText_btnManageCalendarEventInfo__</button></td>
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,11 @@ import { taLogger } from '../js/mzta-logger.js';
|
||||||
import {
|
import {
|
||||||
ChatGPTWeb_models,
|
ChatGPTWeb_models,
|
||||||
checkSparksPresence,
|
checkSparksPresence,
|
||||||
isThunderbird128OrGreater,
|
|
||||||
openTab,
|
openTab,
|
||||||
getChatGPTWebModelsList_HTML,
|
getChatGPTWebModelsList_HTML,
|
||||||
isAPIKeyValue,
|
isAPIKeyValue,
|
||||||
getConnectionType,
|
getConnectionType,
|
||||||
|
setTomSelectBorder
|
||||||
} from '../js/mzta-utils.js';
|
} from '../js/mzta-utils.js';
|
||||||
import {
|
import {
|
||||||
injectConnectionUI,
|
injectConnectionUI,
|
||||||
|
|
@ -35,7 +35,6 @@ import {
|
||||||
} from '../pages/_lib/connection-ui.js';
|
} from '../pages/_lib/connection-ui.js';
|
||||||
|
|
||||||
let taLog = new taLogger("mzta-options",true);
|
let taLog = new taLogger("mzta-options",true);
|
||||||
let _isThunderbird128OrGreater = true;
|
|
||||||
|
|
||||||
function saveOptions(e) {
|
function saveOptions(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
@ -77,6 +76,7 @@ function saveOptions(e) {
|
||||||
async function restoreOptions() {
|
async function restoreOptions() {
|
||||||
function setCurrentChoice(result) {
|
function setCurrentChoice(result) {
|
||||||
document.querySelectorAll(".option-input").forEach(element => {
|
document.querySelectorAll(".option-input").forEach(element => {
|
||||||
|
if(!element.id) return;
|
||||||
taLog.log("Options restoring " + element.id + " = " + (isAPIKeyValue(element.id) ? "****************" : result[element.id]));
|
taLog.log("Options restoring " + element.id + " = " + (isAPIKeyValue(element.id) ? "****************" : result[element.id]));
|
||||||
switch (element.type) {
|
switch (element.type) {
|
||||||
case 'checkbox':
|
case 'checkbox':
|
||||||
|
|
@ -102,6 +102,10 @@ async function restoreOptions() {
|
||||||
if (element.value === '') {
|
if (element.value === '') {
|
||||||
element.selectedIndex = -1;
|
element.selectedIndex = -1;
|
||||||
}
|
}
|
||||||
|
if (element.tomselect) {
|
||||||
|
element.tomselect.setValue(element.value, true);
|
||||||
|
setTomSelectBorder(element.tomselect);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'textarea':
|
case 'textarea':
|
||||||
element.value = result[element.id];
|
element.value = result[element.id];
|
||||||
|
|
@ -167,6 +171,27 @@ function disable_SpamFilter(prefs_opt){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function disable_Summarize(prefs_opt){
|
||||||
|
let summarize = document.getElementById('summarize');
|
||||||
|
let conntype_select = document.getElementById("connection_type");
|
||||||
|
const tempPrefs = {
|
||||||
|
connection_type: conntype_select.value,
|
||||||
|
...prefs_opt
|
||||||
|
};
|
||||||
|
let summarize_disabled = (getConnectionType(tempPrefs, null, 'summarize') === "chatgpt_web");
|
||||||
|
let summarize_checked_original = summarize.checked;
|
||||||
|
summarize.checked = summarize_disabled ? false : summarize.checked;
|
||||||
|
if(!summarize.checked){
|
||||||
|
let summarize_info_btn = document.getElementById('btnManageSummarizeInfo');
|
||||||
|
summarize_info_btn.disabled = 'disabled';
|
||||||
|
}
|
||||||
|
let summarize_warn_API_needed = document.getElementById('summarize_warn_API_needed');
|
||||||
|
summarize_warn_API_needed.style.display = (summarize_disabled) ? 'inline-block' : 'none';
|
||||||
|
if(summarize_checked_original != summarize.checked){
|
||||||
|
browser.storage.sync.set({summarize: summarize.checked});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function disable_GetCalendarEvent(){
|
async function disable_GetCalendarEvent(){
|
||||||
let get_calendar_event = document.getElementById('get_calendar_event');
|
let get_calendar_event = document.getElementById('get_calendar_event');
|
||||||
let get_task = document.getElementById('get_task');
|
let get_task = document.getElementById('get_task');
|
||||||
|
|
@ -207,8 +232,6 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
|
|
||||||
varConnectionUI.permission_all_urls = await messenger.permissions.contains({ origins: ["<all_urls>"] })
|
varConnectionUI.permission_all_urls = await messenger.permissions.contains({ origins: ["<all_urls>"] })
|
||||||
|
|
||||||
_isThunderbird128OrGreater = await isThunderbird128OrGreater();
|
|
||||||
|
|
||||||
// show Owl warning
|
// show Owl warning
|
||||||
const accountList = await messenger.accounts.list(false);
|
const accountList = await messenger.accounts.list(false);
|
||||||
if(accountList.some(account => account.type.toLowerCase().includes('owl'))) {
|
if(accountList.some(account => account.type.toLowerCase().includes('owl'))) {
|
||||||
|
|
@ -227,11 +250,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
async function _addtags_el_change() {
|
async function _addtags_el_change() {
|
||||||
if (event.target.checked) {
|
if (event.target.checked) {
|
||||||
let granted = false;
|
let granted = false;
|
||||||
if(_isThunderbird128OrGreater){
|
granted = await messenger.permissions.request({ permissions: ["messagesTags", "messagesUpdate"] });
|
||||||
granted = await messenger.permissions.request({ permissions: ["messagesTags", "messagesUpdate"] });
|
|
||||||
}else{
|
|
||||||
granted = await messenger.permissions.request({ permissions: ["messagesTags"] });
|
|
||||||
}
|
|
||||||
if (!granted) {
|
if (!granted) {
|
||||||
event.target.checked = false;
|
event.target.checked = false;
|
||||||
addtags_info_btn.disabled = 'disabled';
|
addtags_info_btn.disabled = 'disabled';
|
||||||
|
|
@ -262,6 +281,13 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
});
|
});
|
||||||
spamfilter_info_btn.disabled = spamfilter_el.checked ? '' : 'disabled';
|
spamfilter_info_btn.disabled = spamfilter_el.checked ? '' : 'disabled';
|
||||||
|
|
||||||
|
let summarize_el = document.getElementById('summarize');
|
||||||
|
let summarize_info_btn = document.getElementById('btnManageSummarizeInfo');
|
||||||
|
summarize_el.addEventListener('click', (event) => {
|
||||||
|
summarize_info_btn.disabled = event.target.checked ? '' : 'disabled';
|
||||||
|
});
|
||||||
|
summarize_info_btn.disabled = summarize_el.checked ? '' : 'disabled';
|
||||||
|
|
||||||
let get_calendar_event_el = document.getElementById('get_calendar_event');
|
let get_calendar_event_el = document.getElementById('get_calendar_event');
|
||||||
let get_calendar_event_info_btn = document.getElementById('btnManageCalendarEventInfo');
|
let get_calendar_event_info_btn = document.getElementById('btnManageCalendarEventInfo');
|
||||||
get_calendar_event_el.addEventListener('click', (event) => {
|
get_calendar_event_el.addEventListener('click', (event) => {
|
||||||
|
|
@ -291,6 +317,10 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
document.getElementById('btnManageSpamFilterInfo').addEventListener('click', () => {
|
document.getElementById('btnManageSpamFilterInfo').addEventListener('click', () => {
|
||||||
openTab('/pages/spamfilter/mzta-spamfilter.html');
|
openTab('/pages/spamfilter/mzta-spamfilter.html');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.getElementById('btnManageSummarizeInfo').addEventListener('click', () => {
|
||||||
|
openTab('/pages/summarize/mzta-summarize.html');
|
||||||
|
});
|
||||||
|
|
||||||
document.getElementById('btnManageCalendarEventInfo').addEventListener('click', () => {
|
document.getElementById('btnManageCalendarEventInfo').addEventListener('click', () => {
|
||||||
openTab('/pages/get-calendar-event/mzta-get-calendar-event.html');
|
openTab('/pages/get-calendar-event/mzta-get-calendar-event.html');
|
||||||
|
|
@ -317,12 +347,14 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
conntype_select.addEventListener("change", disable_MaxPromptLength);
|
conntype_select.addEventListener("change", disable_MaxPromptLength);
|
||||||
conntype_select.addEventListener("change", () => disable_AddTags(prefs_opt));
|
conntype_select.addEventListener("change", () => disable_AddTags(prefs_opt));
|
||||||
conntype_select.addEventListener("change", () => disable_SpamFilter(prefs_opt));
|
conntype_select.addEventListener("change", () => disable_SpamFilter(prefs_opt));
|
||||||
|
conntype_select.addEventListener("change", () => disable_Summarize(prefs_opt));
|
||||||
conntype_select.addEventListener("change", disable_GetCalendarEvent);
|
conntype_select.addEventListener("change", disable_GetCalendarEvent);
|
||||||
|
|
||||||
showConnectionOptions(conntype_select);
|
showConnectionOptions(conntype_select);
|
||||||
disable_MaxPromptLength();
|
disable_MaxPromptLength();
|
||||||
disable_AddTags(prefs_opt);
|
disable_AddTags(prefs_opt);
|
||||||
disable_SpamFilter(prefs_opt);
|
disable_SpamFilter(prefs_opt);
|
||||||
|
disable_Summarize(prefs_opt);
|
||||||
disable_GetCalendarEvent();
|
disable_GetCalendarEvent();
|
||||||
|
|
||||||
document.getElementById('reset_max_prompt_length').addEventListener('click', resetMaxPromptLength);
|
document.getElementById('reset_max_prompt_length').addEventListener('click', resetMaxPromptLength);
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,25 @@
|
||||||
<body>
|
<body>
|
||||||
<div id="miczBackPrefs"><a href="mzta-options.html">__MSG_backToOptionsText__</a></div>
|
<div id="miczBackPrefs"><a href="mzta-options.html">__MSG_backToOptionsText__</a></div>
|
||||||
<div id="miczRelNotes"><h1>ThunderAI Release Notes</h1>
|
<div id="miczRelNotes"><h1>ThunderAI Release Notes</h1>
|
||||||
|
<h2>Version 4.0.0 - ??/??/2026</h2>
|
||||||
|
<ul>
|
||||||
|
<li>ThunderAI is now compatible only with Thunderbird 140 and later [<a href="https://github.com/micz/ThunderAI/issues/616">#616</a>].</li>
|
||||||
|
<li><i>[All APIs]</i> It's now possibile to define a specific API integration for calendar and task recognition [<a href="https://github.com/micz/ThunderAI/issues/498">#498</a>].</li>
|
||||||
|
<li>Added a new model selector with a search functionality to dynamically filter the list [<a href="https://github.com/micz/ThunderAI/issues/603">#603</a>].</li>
|
||||||
|
<li><i>[All APIs]</i> Added a special prompt to summarize one or more emails, using a context menu command [<a href="https://github.com/micz/ThunderAI/issues/615">#615</a>]. Thanks to <a href="https://github.com/gdkrmr">Guido Kraemer</a> for his great work on this feature.</li>
|
||||||
|
<li><i>[All APIs]</i> "Analyze for spam" and "Add tags" context menu items are always shown when the corresponding feature is enabled [<a href="https://github.com/micz/ThunderAI/issues/609">#609</a>].</li>
|
||||||
|
<li><i>[OpenAI Comp API][Ollama API]</i> Asking for the single host for permission to avoid CORS errors, instead of <i>all_urls</i>, as requested by the Thunderbird Review Team [<a href="https://github.com/micz/ThunderAI/issues/524">#524</a>].</li>
|
||||||
|
<li>Fix: Using also the mail folder owner to search for the right identity to use when composing a reply [<a href="https://github.com/micz/ThunderAI/issues/627">#627</a>].</li>
|
||||||
|
<li>Context menu items are always ordered alfabetically [<a href="https://github.com/micz/ThunderAI/issues/630">#630</a>].</li>
|
||||||
|
<li>The prompt export now includes an option to incorporate specific API settings, when present [<a href="https://github.com/micz/ThunderAI/issues/624">#624</a>].</li>
|
||||||
|
<li>Added the <i>{%mail_text_body_or_selected%}</i> placeholder to retrieve the selected text or the full text body of the email if no selection is present [<a href="https://github.com/micz/ThunderAI/issues/641">#641</a>].</li>
|
||||||
|
<li>Added the <i>{%mail_html_body_or_selected%}</i> placeholder to retrieve the selected HTML or the full HTML body of the email if no selection is present [<a href="https://github.com/micz/ThunderAI/issues/641">#641</a>].</li>
|
||||||
|
<li><i>[All APIs]</i> Added an option to get a calendar event without selecting some text, but using the full text body of the email [<a href="https://github.com/micz/ThunderAI/issues/518">#518</a>].</li>
|
||||||
|
<li><i>[All APIs]</i> Added a new menu item to create a calendar event from the text saved in the clipboard [<a href="https://github.com/micz/ThunderAI/issues/362">#362</a>].</li>
|
||||||
|
<li>Added a button to copy a prompt in the Custom Prompts page [<a href="https://github.com/micz/ThunderAI/issues/598">#598</a>].</li>
|
||||||
|
<li><i>[All APIs]</i> Showing the spam filter info at the top of the message. The data is saved only for the session in which the message has been checked for spam [<a href="https://github.com/micz/ThunderAI/issues/506">#506</a>].</li>
|
||||||
|
<li>...</li>
|
||||||
|
</ul>
|
||||||
<h2>Version 3.8.4 - 10/02/2026</h2>
|
<h2>Version 3.8.4 - 10/02/2026</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li><i>[ChatGPT Web]</i> Fix: Correctly importing the selected text into the compose windows also when ChatGPT shows the advanced mail editor in the response [<a href="https://github.com/micz/ThunderAI/issues/646">#646</a>].</li>
|
<li><i>[ChatGPT Web]</i> Fix: Correctly importing the selected text into the compose windows also when ChatGPT shows the advanced mail editor in the response [<a href="https://github.com/micz/ThunderAI/issues/646">#646</a>].</li>
|
||||||
|
|
@ -82,6 +101,7 @@
|
||||||
<ul>
|
<ul>
|
||||||
<li><i>[All APIs]</i> It's now possibile to define a list of tags to be used when autotagging received emails [<a href="https://github.com/micz/ThunderAI/issues/436">#436</a>]. The tags are are now shown in the information header in the AI API chat [<a href="https://github.com/micz/ThunderAI/issues/289">#289</a>].</li>
|
<li><i>[All APIs]</i> It's now possibile to define a list of tags to be used when autotagging received emails [<a href="https://github.com/micz/ThunderAI/issues/436">#436</a>]. The tags are are now shown in the information header in the AI API chat [<a href="https://github.com/micz/ThunderAI/issues/289">#289</a>].</li>
|
||||||
<li><i>[All APIs]</i> The prompt id and name are now shown in the information header in the AI API chat [<a href="https://github.com/micz/ThunderAI/issues/436">#436</a>].</li>
|
<li><i>[All APIs]</i> The prompt id and name are now shown in the information header in the AI API chat [<a href="https://github.com/micz/ThunderAI/issues/436">#436</a>].</li>
|
||||||
|
<li><i>[All APIs]</i> It's now possibile to define a specific API integration for spamfilter and auto tagging [<a href="https://github.com/micz/ThunderAI/issues/438">#438</a>].</li>
|
||||||
<li>Added the <i>{%mail_attachments_info%}</i> placeholder to retrieve the name, type and file size of the mail attachments [<a href="https://github.com/micz/ThunderAI/issues/446">#446</a>].</li>
|
<li>Added the <i>{%mail_attachments_info%}</i> placeholder to retrieve the name, type and file size of the mail attachments [<a href="https://github.com/micz/ThunderAI/issues/446">#446</a>].</li>
|
||||||
<li><i>[Google Gemini API]</i> Support for the thinkingBudget parameter has been added [<a href="https://github.com/micz/ThunderAI/issues/494">#494</a>].</li>
|
<li><i>[Google Gemini API]</i> Support for the thinkingBudget parameter has been added [<a href="https://github.com/micz/ThunderAI/issues/494">#494</a>].</li>
|
||||||
<li><i>[OpenAI Comp API]</i> Added DeepSeek configuration [<a href="https://github.com/micz/ThunderAI/issues/486">#486</a>].</li>
|
<li><i>[OpenAI Comp API]</i> Added DeepSeek configuration [<a href="https://github.com/micz/ThunderAI/issues/486">#486</a>].</li>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
@import url("tom-select.default.min.css");
|
||||||
|
|
||||||
tr.conntype_chatgpt_api, tr.conntype_chatgpt_api2{
|
tr.conntype_chatgpt_api, tr.conntype_chatgpt_api2{
|
||||||
background-color: rgb(185, 220, 252) !important;
|
background-color: rgb(185, 220, 252) !important;
|
||||||
}
|
}
|
||||||
|
|
@ -91,6 +93,10 @@ span.opt_title{
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ts-control, .ts-dropdown{
|
||||||
|
font-size: 14.4px;
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
tr.conntype_chatgpt_api, tr.conntype_chatgpt_api2{
|
tr.conntype_chatgpt_api, tr.conntype_chatgpt_api2{
|
||||||
background-color: rgb(0, 0, 58) !important;
|
background-color: rgb(0, 0, 58) !important;
|
||||||
|
|
|
||||||
|
|
@ -16,6 +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/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import './tom-select.base.js';
|
||||||
import {
|
import {
|
||||||
prefs_default,
|
prefs_default,
|
||||||
integration_options_config
|
integration_options_config
|
||||||
|
|
@ -28,7 +29,9 @@ import { Anthropic } from '../../js/api/anthropic.js';
|
||||||
import {
|
import {
|
||||||
validateCustomData_ChatGPTWeb,
|
validateCustomData_ChatGPTWeb,
|
||||||
sanitizeChatGPTModelData,
|
sanitizeChatGPTModelData,
|
||||||
sanitizeChatGPTWebCustomData
|
sanitizeChatGPTWebCustomData,
|
||||||
|
prepareOriginURL,
|
||||||
|
setTomSelectBorder
|
||||||
} from '../../js/mzta-utils.js';
|
} from '../../js/mzta-utils.js';
|
||||||
import { openAICompConfigs } from '../../js/api/openai_comp_configs.js';
|
import { openAICompConfigs } from '../../js/api/openai_comp_configs.js';
|
||||||
import {
|
import {
|
||||||
|
|
@ -38,7 +41,9 @@ import {
|
||||||
} from '../../js/mzta-prompts.js';
|
} from '../../js/mzta-prompts.js';
|
||||||
|
|
||||||
export const varConnectionUI = {
|
export const varConnectionUI = {
|
||||||
permission_all_urls: false
|
permission_all_urls: false,
|
||||||
|
permission_ollama_host: false,
|
||||||
|
permission_openai_comp_host: false
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function injectConnectionUI({
|
export async function injectConnectionUI({
|
||||||
|
|
@ -300,8 +305,9 @@ export async function injectConnectionUI({
|
||||||
<td colspan="2" style="text-align:center;">
|
<td colspan="2" style="text-align:center;">
|
||||||
__MSG_remember_CORS__ [<a href="https://micz.it/thunderbird-addon-thunderai/ollama-cors-information/">__MSG_more_info_string__</a>]
|
__MSG_remember_CORS__ [<a href="https://micz.it/thunderbird-addon-thunderai/ollama-cors-information/">__MSG_more_info_string__</a>]
|
||||||
<br><br><b>__MSG_CORS_alternative_1__</b>
|
<br><br><b>__MSG_CORS_alternative_1__</b>
|
||||||
<br>__MSG_CORS_alternative_2__
|
<br>__MSG_CORS_alternative_2_new__
|
||||||
<br><br><button id="${modelId_prefix ? `${modelId_prefix}` : ''}btnGiveAllUrlsPermission_ollama_api">__MSG_CORS_give_allurls_perm__</button>
|
<br><br><button id="${modelId_prefix ? `${modelId_prefix}` : ''}btnGiveAllUrlsPermission_ollama_api">__MSG_CORS_give_host_perm__</button>
|
||||||
|
<br>__MSG_CORS_localhost_warn__
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="conntype_ollama_api${tr_class ? ` ${tr_class}` : ''}">
|
<tr class="conntype_ollama_api${tr_class ? ` ${tr_class}` : ''}">
|
||||||
|
|
@ -379,8 +385,9 @@ export async function injectConnectionUI({
|
||||||
<td colspan="2" style="text-align:center;">
|
<td colspan="2" style="text-align:center;">
|
||||||
__MSG_maybe_CORS_openai_comp__ [<a href="https://micz.it/thunderbird-addon-thunderai/ollama-cors-information/">__MSG_more_info_string__</a>]
|
__MSG_maybe_CORS_openai_comp__ [<a href="https://micz.it/thunderbird-addon-thunderai/ollama-cors-information/">__MSG_more_info_string__</a>]
|
||||||
<br><br><b>__MSG_CORS_alternative_1__</b>
|
<br><br><b>__MSG_CORS_alternative_1__</b>
|
||||||
<br>__MSG_CORS_alternative_2__
|
<br>__MSG_CORS_alternative_2_new__
|
||||||
<br><br><button id="${modelId_prefix ? `${modelId_prefix}` : ''}btnGiveAllUrlsPermission_openai_comp_api">__MSG_CORS_give_allurls_perm__</button>
|
<br><br><button id="${modelId_prefix ? `${modelId_prefix}` : ''}btnGiveAllUrlsPermission_openai_comp_api">__MSG_CORS_give_host_perm__</button>
|
||||||
|
<br>__MSG_CORS_localhost_warn__
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="conntype_openai_comp_api${tr_class ? ` ${tr_class}` : ''}">
|
<tr class="conntype_openai_comp_api${tr_class ? ` ${tr_class}` : ''}">
|
||||||
|
|
@ -664,6 +671,7 @@ export async function injectConnectionUI({
|
||||||
while (openaiCompModelSelect.options.length > 0) {
|
while (openaiCompModelSelect.options.length > 0) {
|
||||||
openaiCompModelSelect.remove(0);
|
openaiCompModelSelect.remove(0);
|
||||||
}
|
}
|
||||||
|
syncTomSelect(openaiCompModelSelect);
|
||||||
document.getElementById(getPrefixedId('openai_comp_use_v1')).checked = !!config.use_v1;
|
document.getElementById(getPrefixedId('openai_comp_use_v1')).checked = !!config.use_v1;
|
||||||
document.getElementById(getPrefixedId('openai_comp_chat_name')).value = config.chat_name || '';
|
document.getElementById(getPrefixedId('openai_comp_chat_name')).value = config.chat_name || '';
|
||||||
// Trigger change events if needed
|
// Trigger change events if needed
|
||||||
|
|
@ -674,7 +682,17 @@ export async function injectConnectionUI({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let prefs = await browser.storage.sync.get({chatgpt_web_model: '', chatgpt_model: '', ollama_model: '', openai_comp_model: '', google_gemini_model: '', anthropic_model: '', anthropic_version: '', chatgpt_win_height: 0, chatgpt_win_width: 0 });
|
let prefs = await browser.storage.sync.get({
|
||||||
|
chatgpt_web_model: '',
|
||||||
|
chatgpt_model: '',
|
||||||
|
ollama_model: '',
|
||||||
|
openai_comp_model: '',
|
||||||
|
google_gemini_model: '',
|
||||||
|
anthropic_model: '',
|
||||||
|
anthropic_version: '',
|
||||||
|
chatgpt_win_height: 0,
|
||||||
|
chatgpt_win_width: 0
|
||||||
|
});
|
||||||
|
|
||||||
// OpenAI API ChatGPT model fetching
|
// OpenAI API ChatGPT model fetching
|
||||||
let select_chatgpt_model = getModelEl('chatgpt_model', modelId_prefix);
|
let select_chatgpt_model = getModelEl('chatgpt_model', modelId_prefix);
|
||||||
|
|
@ -682,6 +700,7 @@ export async function injectConnectionUI({
|
||||||
chatgpt_option.value = prefs.chatgpt_model;
|
chatgpt_option.value = prefs.chatgpt_model;
|
||||||
chatgpt_option.text = prefs.chatgpt_model;
|
chatgpt_option.text = prefs.chatgpt_model;
|
||||||
select_chatgpt_model.appendChild(chatgpt_option);
|
select_chatgpt_model.appendChild(chatgpt_option);
|
||||||
|
select_chatgpt_model.value = prefs.chatgpt_model;
|
||||||
select_chatgpt_model.addEventListener("change", () => warn_ChatGPT_APIKeyEmpty(modelId_prefix));
|
select_chatgpt_model.addEventListener("change", () => warn_ChatGPT_APIKeyEmpty(modelId_prefix));
|
||||||
|
|
||||||
document.getElementById(getPrefixedId('btnUpdateChatGPTModels')).addEventListener('click', async () => {
|
document.getElementById(getPrefixedId('btnUpdateChatGPTModels')).addEventListener('click', async () => {
|
||||||
|
|
@ -719,6 +738,7 @@ export async function injectConnectionUI({
|
||||||
select_chatgpt_model.appendChild(option);
|
select_chatgpt_model.appendChild(option);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
syncTomSelect(select_chatgpt_model);
|
||||||
document.getElementById(getPrefixedId('chatgpt_model_fetch_loading')).style.display = 'none';
|
document.getElementById(getPrefixedId('chatgpt_model_fetch_loading')).style.display = 'none';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -731,6 +751,7 @@ export async function injectConnectionUI({
|
||||||
google_gemini_option.value = prefs.google_gemini_model;
|
google_gemini_option.value = prefs.google_gemini_model;
|
||||||
google_gemini_option.text = prefs.google_gemini_model;
|
google_gemini_option.text = prefs.google_gemini_model;
|
||||||
select_google_gemini_model.appendChild(google_gemini_option);
|
select_google_gemini_model.appendChild(google_gemini_option);
|
||||||
|
select_google_gemini_model.value = prefs.google_gemini_model;
|
||||||
select_google_gemini_model.addEventListener("change", () => warn_GoogleGemini_APIKeyEmpty(modelId_prefix));
|
select_google_gemini_model.addEventListener("change", () => warn_GoogleGemini_APIKeyEmpty(modelId_prefix));
|
||||||
|
|
||||||
document.getElementById(getPrefixedId('btnUpdateGoogleGeminiModels')).addEventListener('click', async () => {
|
document.getElementById(getPrefixedId('btnUpdateGoogleGeminiModels')).addEventListener('click', async () => {
|
||||||
|
|
@ -761,6 +782,7 @@ export async function injectConnectionUI({
|
||||||
select_google_gemini_model.appendChild(option);
|
select_google_gemini_model.appendChild(option);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
syncTomSelect(select_google_gemini_model);
|
||||||
document.getElementById(getPrefixedId('google_gemini_model_fetch_loading')).style.display = 'none';
|
document.getElementById(getPrefixedId('google_gemini_model_fetch_loading')).style.display = 'none';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -773,6 +795,7 @@ export async function injectConnectionUI({
|
||||||
ollama_option.value = prefs.ollama_model;
|
ollama_option.value = prefs.ollama_model;
|
||||||
ollama_option.text = prefs.ollama_model;
|
ollama_option.text = prefs.ollama_model;
|
||||||
select_ollama_model.appendChild(ollama_option);
|
select_ollama_model.appendChild(ollama_option);
|
||||||
|
select_ollama_model.value = prefs.ollama_model;
|
||||||
select_ollama_model.addEventListener("change", () => warn_Ollama_HostEmpty(modelId_prefix));
|
select_ollama_model.addEventListener("change", () => warn_Ollama_HostEmpty(modelId_prefix));
|
||||||
|
|
||||||
document.getElementById(getPrefixedId('btnUpdateOllamaModels')).addEventListener('click', async () => {
|
document.getElementById(getPrefixedId('btnUpdateOllamaModels')).addEventListener('click', async () => {
|
||||||
|
|
@ -816,6 +839,7 @@ export async function injectConnectionUI({
|
||||||
select_ollama_model.appendChild(option);
|
select_ollama_model.appendChild(option);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
syncTomSelect(select_ollama_model);
|
||||||
document.getElementById(getPrefixedId('ollama_model_fetch_loading')).style.display = 'none';
|
document.getElementById(getPrefixedId('ollama_model_fetch_loading')).style.display = 'none';
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
document.getElementById(getPrefixedId('ollama_model_fetch_loading')).style.display = 'none';
|
document.getElementById(getPrefixedId('ollama_model_fetch_loading')).style.display = 'none';
|
||||||
|
|
@ -832,6 +856,7 @@ export async function injectConnectionUI({
|
||||||
openai_comp_option.value = prefs.openai_comp_model;
|
openai_comp_option.value = prefs.openai_comp_model;
|
||||||
openai_comp_option.text = prefs.openai_comp_model;
|
openai_comp_option.text = prefs.openai_comp_model;
|
||||||
select_openai_comp_model.appendChild(openai_comp_option);
|
select_openai_comp_model.appendChild(openai_comp_option);
|
||||||
|
select_openai_comp_model.value = prefs.openai_comp_model;
|
||||||
select_openai_comp_model.addEventListener("change", () => warn_OpenAIComp_HostEmpty(modelId_prefix));
|
select_openai_comp_model.addEventListener("change", () => warn_OpenAIComp_HostEmpty(modelId_prefix));
|
||||||
|
|
||||||
document.getElementById(getPrefixedId('btnUpdateOpenAICompModels')).addEventListener('click', async () => {
|
document.getElementById(getPrefixedId('btnUpdateOpenAICompModels')).addEventListener('click', async () => {
|
||||||
|
|
@ -864,6 +889,7 @@ export async function injectConnectionUI({
|
||||||
select_openai_comp_model.appendChild(option);
|
select_openai_comp_model.appendChild(option);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
syncTomSelect(select_openai_comp_model);
|
||||||
document.getElementById(getPrefixedId('openai_comp_model_fetch_loading')).style.display = 'none';
|
document.getElementById(getPrefixedId('openai_comp_model_fetch_loading')).style.display = 'none';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -876,6 +902,7 @@ export async function injectConnectionUI({
|
||||||
anthropic_option.value = prefs.anthropic_model;
|
anthropic_option.value = prefs.anthropic_model;
|
||||||
anthropic_option.text = prefs.anthropic_model;
|
anthropic_option.text = prefs.anthropic_model;
|
||||||
select_anthropic_model.appendChild(anthropic_option);
|
select_anthropic_model.appendChild(anthropic_option);
|
||||||
|
select_anthropic_model.value = prefs.anthropic_model;
|
||||||
select_anthropic_model.addEventListener("change", () => warn_Anthropic_APIKeyEmpty(modelId_prefix));
|
select_anthropic_model.addEventListener("change", () => warn_Anthropic_APIKeyEmpty(modelId_prefix));
|
||||||
select_anthropic_model.addEventListener("change", () => warn_Anthropic_VersionEmpty(modelId_prefix));
|
select_anthropic_model.addEventListener("change", () => warn_Anthropic_VersionEmpty(modelId_prefix));
|
||||||
|
|
||||||
|
|
@ -918,6 +945,7 @@ export async function injectConnectionUI({
|
||||||
select_anthropic_model.appendChild(option);
|
select_anthropic_model.appendChild(option);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
syncTomSelect(select_anthropic_model);
|
||||||
document.getElementById(getPrefixedId('anthropic_model_fetch_loading')).style.display = 'none';
|
document.getElementById(getPrefixedId('anthropic_model_fetch_loading')).style.display = 'none';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -933,6 +961,7 @@ export async function injectConnectionUI({
|
||||||
option.text = modelName;
|
option.text = modelName;
|
||||||
select_openai_comp_model.appendChild(option);
|
select_openai_comp_model.appendChild(option);
|
||||||
select_openai_comp_model.value = modelName;
|
select_openai_comp_model.value = modelName;
|
||||||
|
syncTomSelect(select_openai_comp_model);
|
||||||
select_openai_comp_model.dispatchEvent(new Event('change', { bubbles: true }));
|
select_openai_comp_model.dispatchEvent(new Event('change', { bubbles: true }));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -946,15 +975,32 @@ export async function injectConnectionUI({
|
||||||
select_openai_comp_model.remove(0);
|
select_openai_comp_model.remove(0);
|
||||||
}
|
}
|
||||||
select_openai_comp_model.value = '';
|
select_openai_comp_model.value = '';
|
||||||
|
syncTomSelect(select_openai_comp_model);
|
||||||
select_openai_comp_model.dispatchEvent(new Event('change', { bubbles: true }));
|
select_openai_comp_model.dispatchEvent(new Event('change', { bubbles: true }));
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById(getPrefixedId('btnGiveAllUrlsPermission_ollama_api')).addEventListener('click', async () => {
|
document.getElementById(getPrefixedId('btnGiveAllUrlsPermission_ollama_api')).addEventListener('click', async () => {
|
||||||
varConnectionUI.permission_all_urls = await messenger.permissions.request({ origins: ["<all_urls>"] });
|
let ollama_host = document.getElementById(getPrefixedId("ollama_host")).value;
|
||||||
|
if(ollama_host != ''){
|
||||||
|
if (ollama_host.includes("localhost") || ollama_host.includes("127.0.0.1")) {
|
||||||
|
varConnectionUI.permission_all_urls = await messenger.permissions.request({ origins: ["<all_urls>"] });
|
||||||
|
}else{
|
||||||
|
varConnectionUI.permission_ollama_host = await messenger.permissions.request({ origins: [prepareOriginURL(ollama_host)] });
|
||||||
|
}
|
||||||
|
updateCORSWarnings(modelId_prefix);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById(getPrefixedId('btnGiveAllUrlsPermission_openai_comp_api')).addEventListener('click', async () => {
|
document.getElementById(getPrefixedId('btnGiveAllUrlsPermission_openai_comp_api')).addEventListener('click', async () => {
|
||||||
varConnectionUI.permission_all_urls = await messenger.permissions.request({ origins: ["<all_urls>"] });
|
let openai_comp_host = document.getElementById(getPrefixedId("openai_comp_host")).value;
|
||||||
|
if(openai_comp_host != ''){
|
||||||
|
if (openai_comp_host.includes("localhost") || openai_comp_host.includes("127.0.0.1")) {
|
||||||
|
varConnectionUI.permission_all_urls = await messenger.permissions.request({ origins: ["<all_urls>"] });
|
||||||
|
}else{
|
||||||
|
varConnectionUI.permission_openai_comp_host = await messenger.permissions.request({ origins: [prepareOriginURL(openai_comp_host)] });
|
||||||
|
}
|
||||||
|
updateCORSWarnings(modelId_prefix);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
document.querySelectorAll('.check-number').forEach(input => {
|
document.querySelectorAll('.check-number').forEach(input => {
|
||||||
|
|
@ -978,6 +1024,30 @@ export async function injectConnectionUI({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateCORSWarnings(modelId_prefix);
|
||||||
|
|
||||||
|
['chatgpt_model', 'google_gemini_model', 'ollama_model', 'openai_comp_model', 'anthropic_model'].forEach(id => {
|
||||||
|
const el = document.getElementById(getPrefixedId(id));
|
||||||
|
if (el && !el.tomselect) {
|
||||||
|
let ts = new TomSelect(el, {
|
||||||
|
create: false,
|
||||||
|
maxOptions: null,
|
||||||
|
maxItems: 1,
|
||||||
|
sortField: {
|
||||||
|
field: "text",
|
||||||
|
direction: "asc"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ts.on('change', function() {
|
||||||
|
setTomSelectBorder(this);
|
||||||
|
});
|
||||||
|
if (el.value) {
|
||||||
|
ts.setValue(el.value);
|
||||||
|
}
|
||||||
|
setTomSelectBorder(ts);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
select: conntype_select,
|
select: conntype_select,
|
||||||
onTypeChange: (fn) => { onTypeChange = fn; fn(conntype_select.value, { select: conntype_select }); }
|
onTypeChange: (fn) => { onTypeChange = fn; fn(conntype_select.value, { select: conntype_select }); }
|
||||||
|
|
@ -1090,6 +1160,7 @@ export async function initializeSpecificIntegrationUI({
|
||||||
updateWarnings(model_prefix);
|
updateWarnings(model_prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// From here there are exported functions
|
// From here there are exported functions
|
||||||
|
|
||||||
export function updateWarnings(modelId_prefix = '') {
|
export function updateWarnings(modelId_prefix = '') {
|
||||||
|
|
@ -1167,17 +1238,30 @@ export function showConnectionOptions(conntype_select, modelId_prefix = '') {
|
||||||
parent.parentElement.querySelectorAll(".conntype_anthropic_api").forEach(element => {
|
parent.parentElement.querySelectorAll(".conntype_anthropic_api").forEach(element => {
|
||||||
element.style.display = anthropic_api_display;
|
element.style.display = anthropic_api_display;
|
||||||
});
|
});
|
||||||
if (varConnectionUI.permission_all_urls) {
|
updateCORSWarnings(modelId_prefix);
|
||||||
const openaiCompWarning = document.getElementById((modelId_prefix ? modelId_prefix : '') + 'openai_comp_api_cors_warning');
|
|
||||||
if (openaiCompWarning) openaiCompWarning.style.display = 'none';
|
|
||||||
const ollamaWarning = document.getElementById((modelId_prefix ? modelId_prefix : '') + 'ollama_api_cors_warning');
|
|
||||||
if (ollamaWarning) ollamaWarning.style.display = 'none';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// From here there are internal functions
|
// From here there are internal functions
|
||||||
|
|
||||||
|
function syncTomSelect(element) {
|
||||||
|
if (element && element.tomselect) {
|
||||||
|
element.tomselect.sync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleTomSelectDisabled(element, disabled) {
|
||||||
|
element.disabled = disabled;
|
||||||
|
if (element.tomselect) {
|
||||||
|
if (disabled) {
|
||||||
|
element.tomselect.disable();
|
||||||
|
element.tomselect.clear();
|
||||||
|
} else {
|
||||||
|
element.tomselect.enable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getModelEl(model, modelId_prefix) {
|
function getModelEl(model, modelId_prefix) {
|
||||||
return document.getElementById((modelId_prefix ? modelId_prefix : '') + model);
|
return document.getElementById((modelId_prefix ? modelId_prefix : '') + model);
|
||||||
}
|
}
|
||||||
|
|
@ -1232,13 +1316,13 @@ function warn_ChatGPT_APIKeyEmpty(modelId_prefix) {
|
||||||
if(apiKeyInput.value === ''){
|
if(apiKeyInput.value === ''){
|
||||||
apiKeyInput.style.border = '2px solid red';
|
apiKeyInput.style.border = '2px solid red';
|
||||||
btnFetchChatGPTModels.disabled = true;
|
btnFetchChatGPTModels.disabled = true;
|
||||||
modelChatGPT.disabled = true;
|
toggleTomSelectDisabled(modelChatGPT, true);
|
||||||
modelChatGPT.selectedIndex = -1;
|
modelChatGPT.selectedIndex = -1;
|
||||||
modelChatGPT.style.border = '';
|
modelChatGPT.style.border = '';
|
||||||
}else{
|
}else{
|
||||||
apiKeyInput.style.border = '';
|
apiKeyInput.style.border = '';
|
||||||
btnFetchChatGPTModels.disabled = false;
|
btnFetchChatGPTModels.disabled = false;
|
||||||
modelChatGPT.disabled = false;
|
toggleTomSelectDisabled(modelChatGPT, false);
|
||||||
if((modelChatGPT.selectedIndex === -1)||(modelChatGPT.value === '')){
|
if((modelChatGPT.selectedIndex === -1)||(modelChatGPT.value === '')){
|
||||||
modelChatGPT.style.border = '2px solid red';
|
modelChatGPT.style.border = '2px solid red';
|
||||||
}else{
|
}else{
|
||||||
|
|
@ -1255,13 +1339,13 @@ function warn_GoogleGemini_APIKeyEmpty(modelId_prefix) {
|
||||||
if(apiKeyInput.value === ''){
|
if(apiKeyInput.value === ''){
|
||||||
apiKeyInput.style.border = '2px solid red';
|
apiKeyInput.style.border = '2px solid red';
|
||||||
btnFetchGoogleGeminiModels.disabled = true;
|
btnFetchGoogleGeminiModels.disabled = true;
|
||||||
modelGoogleGemini.disabled = true;
|
toggleTomSelectDisabled(modelGoogleGemini, true);
|
||||||
modelGoogleGemini.selectedIndex = -1;
|
modelGoogleGemini.selectedIndex = -1;
|
||||||
modelGoogleGemini.style.border = '';
|
modelGoogleGemini.style.border = '';
|
||||||
}else{
|
}else{
|
||||||
apiKeyInput.style.border = '';
|
apiKeyInput.style.border = '';
|
||||||
btnFetchGoogleGeminiModels.disabled = false;
|
btnFetchGoogleGeminiModels.disabled = false;
|
||||||
modelGoogleGemini.disabled = false;
|
toggleTomSelectDisabled(modelGoogleGemini, false);
|
||||||
if((modelGoogleGemini.selectedIndex === -1)||(modelGoogleGemini.value === '')){
|
if((modelGoogleGemini.selectedIndex === -1)||(modelGoogleGemini.value === '')){
|
||||||
modelGoogleGemini.style.border = '2px solid red';
|
modelGoogleGemini.style.border = '2px solid red';
|
||||||
}else{
|
}else{
|
||||||
|
|
@ -1274,22 +1358,25 @@ function warn_Ollama_HostEmpty(modelId_prefix) {
|
||||||
const getPrefixedId = (id) => `${modelId_prefix ? `${modelId_prefix}` : ''}${id}`;
|
const getPrefixedId = (id) => `${modelId_prefix ? `${modelId_prefix}` : ''}${id}`;
|
||||||
let hostInput = document.getElementById(getPrefixedId('ollama_host'));
|
let hostInput = document.getElementById(getPrefixedId('ollama_host'));
|
||||||
let btnFetchOllamaModels = document.getElementById(getPrefixedId('btnUpdateOllamaModels'));
|
let btnFetchOllamaModels = document.getElementById(getPrefixedId('btnUpdateOllamaModels'));
|
||||||
|
let btnGiveAllUrlsPermission_ollama_api = document.getElementById(getPrefixedId('btnGiveAllUrlsPermission_ollama_api'));
|
||||||
let modelOllama = getModelEl('ollama_model', modelId_prefix);
|
let modelOllama = getModelEl('ollama_model', modelId_prefix);
|
||||||
if(hostInput.value === ''){
|
if(hostInput.value === ''){
|
||||||
hostInput.style.border = '2px solid red';
|
hostInput.style.border = '2px solid red';
|
||||||
btnFetchOllamaModels.disabled = true;
|
btnFetchOllamaModels.disabled = true;
|
||||||
modelOllama.disabled = true;
|
toggleTomSelectDisabled(modelOllama, true);
|
||||||
modelOllama.selectedIndex = -1;
|
modelOllama.selectedIndex = -1;
|
||||||
modelOllama.style.border = '';
|
modelOllama.style.border = '';
|
||||||
|
btnGiveAllUrlsPermission_ollama_api.disabled = true;
|
||||||
}else{
|
}else{
|
||||||
hostInput.style.border = '';
|
hostInput.style.border = '';
|
||||||
btnFetchOllamaModels.disabled = false;
|
btnFetchOllamaModels.disabled = false;
|
||||||
modelOllama.disabled = false;
|
toggleTomSelectDisabled(modelOllama, false);
|
||||||
if((modelOllama.selectedIndex === -1)||(modelOllama.value === '')){
|
if((modelOllama.selectedIndex === -1)||(modelOllama.value === '')){
|
||||||
modelOllama.style.border = '2px solid red';
|
modelOllama.style.border = '2px solid red';
|
||||||
}else{
|
}else{
|
||||||
modelOllama.style.border = '';
|
modelOllama.style.border = '';
|
||||||
}
|
}
|
||||||
|
btnGiveAllUrlsPermission_ollama_api.disabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1297,22 +1384,25 @@ function warn_OpenAIComp_HostEmpty(modelId_prefix) {
|
||||||
const getPrefixedId = (id) => `${modelId_prefix ? `${modelId_prefix}` : ''}${id}`;
|
const getPrefixedId = (id) => `${modelId_prefix ? `${modelId_prefix}` : ''}${id}`;
|
||||||
let hostInput = document.getElementById(getPrefixedId('openai_comp_host'));
|
let hostInput = document.getElementById(getPrefixedId('openai_comp_host'));
|
||||||
let btnUpdateOpenAICompModels = document.getElementById(getPrefixedId('btnUpdateOpenAICompModels'));
|
let btnUpdateOpenAICompModels = document.getElementById(getPrefixedId('btnUpdateOpenAICompModels'));
|
||||||
|
let btnGiveAllUrlsPermission_openai_comp_api = document.getElementById(getPrefixedId('btnGiveAllUrlsPermission_openai_comp_api'));
|
||||||
let modelOpenAIComp = getModelEl('openai_comp_model', modelId_prefix);
|
let modelOpenAIComp = getModelEl('openai_comp_model', modelId_prefix);
|
||||||
if(hostInput.value === ''){
|
if(hostInput.value === ''){
|
||||||
hostInput.style.border = '2px solid red';
|
hostInput.style.border = '2px solid red';
|
||||||
btnUpdateOpenAICompModels.disabled = true;
|
btnUpdateOpenAICompModels.disabled = true;
|
||||||
modelOpenAIComp.disabled = true;
|
toggleTomSelectDisabled(modelOpenAIComp, true);
|
||||||
modelOpenAIComp.selectedIndex = -1;
|
modelOpenAIComp.selectedIndex = -1;
|
||||||
modelOpenAIComp.style.border = '';
|
modelOpenAIComp.style.border = '';
|
||||||
|
btnGiveAllUrlsPermission_openai_comp_api.disabled = true;
|
||||||
}else{
|
}else{
|
||||||
hostInput.style.border = '';
|
hostInput.style.border = '';
|
||||||
btnUpdateOpenAICompModels.disabled = false;
|
btnUpdateOpenAICompModels.disabled = false;
|
||||||
modelOpenAIComp.disabled = false;
|
toggleTomSelectDisabled(modelOpenAIComp, false);
|
||||||
if((modelOpenAIComp.selectedIndex === -1)||(modelOpenAIComp.value === '')){
|
if((modelOpenAIComp.selectedIndex === -1)||(modelOpenAIComp.value === '')){
|
||||||
modelOpenAIComp.style.border = '2px solid red';
|
modelOpenAIComp.style.border = '2px solid red';
|
||||||
}else{
|
}else{
|
||||||
modelOpenAIComp.style.border = '';
|
modelOpenAIComp.style.border = '';
|
||||||
}
|
}
|
||||||
|
btnGiveAllUrlsPermission_openai_comp_api.disabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1324,13 +1414,13 @@ function warn_Anthropic_APIKeyEmpty(modelId_prefix) {
|
||||||
if(apiKeyInput.value === ''){
|
if(apiKeyInput.value === ''){
|
||||||
apiKeyInput.style.border = '2px solid red';
|
apiKeyInput.style.border = '2px solid red';
|
||||||
btnFetchAnthropicModels.disabled = true;
|
btnFetchAnthropicModels.disabled = true;
|
||||||
modelAnthropic.disabled = true;
|
toggleTomSelectDisabled(modelAnthropic, true);
|
||||||
modelAnthropic.selectedIndex = -1;
|
modelAnthropic.selectedIndex = -1;
|
||||||
modelAnthropic.style.border = '';
|
modelAnthropic.style.border = '';
|
||||||
}else{
|
}else{
|
||||||
apiKeyInput.style.border = '';
|
apiKeyInput.style.border = '';
|
||||||
btnFetchAnthropicModels.disabled = false;
|
btnFetchAnthropicModels.disabled = false;
|
||||||
modelAnthropic.disabled = false;
|
toggleTomSelectDisabled(modelAnthropic, false);
|
||||||
if((modelAnthropic.selectedIndex === -1)||(modelAnthropic.value === '')){
|
if((modelAnthropic.selectedIndex === -1)||(modelAnthropic.value === '')){
|
||||||
modelAnthropic.style.border = '2px solid red';
|
modelAnthropic.style.border = '2px solid red';
|
||||||
}else{
|
}else{
|
||||||
|
|
@ -1347,13 +1437,13 @@ function warn_Anthropic_VersionEmpty(modelId_prefix) {
|
||||||
if(versionInput.value === ''){
|
if(versionInput.value === ''){
|
||||||
versionInput.style.border = '2px solid red';
|
versionInput.style.border = '2px solid red';
|
||||||
btnFetchAnthropicModels.disabled = true;
|
btnFetchAnthropicModels.disabled = true;
|
||||||
modelAnthropic.disabled = true;
|
toggleTomSelectDisabled(modelAnthropic, true);
|
||||||
modelAnthropic.selectedIndex = -1;
|
modelAnthropic.selectedIndex = -1;
|
||||||
modelAnthropic.style.border = '';
|
modelAnthropic.style.border = '';
|
||||||
}else{
|
}else{
|
||||||
versionInput.style.border = '';
|
versionInput.style.border = '';
|
||||||
btnFetchAnthropicModels.disabled = false;
|
btnFetchAnthropicModels.disabled = false;
|
||||||
modelAnthropic.disabled = false;
|
toggleTomSelectDisabled(modelAnthropic, false);
|
||||||
if((modelAnthropic.selectedIndex === -1)||(modelAnthropic.value === '')){
|
if((modelAnthropic.selectedIndex === -1)||(modelAnthropic.value === '')){
|
||||||
modelAnthropic.style.border = '2px solid red';
|
modelAnthropic.style.border = '2px solid red';
|
||||||
}else{
|
}else{
|
||||||
|
|
@ -1376,3 +1466,27 @@ function loadOpenAICompConfigs(modelId_prefix = ''){
|
||||||
select_openai_comp_model.appendChild(option);
|
select_openai_comp_model.appendChild(option);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function loadURLsPermissions(modelId_prefix = ''){
|
||||||
|
let ollama_host = document.getElementById((modelId_prefix ? modelId_prefix : '') + "ollama_host")?.value;
|
||||||
|
if((ollama_host) && (ollama_host != '')){
|
||||||
|
varConnectionUI.permission_ollama_host = await messenger.permissions.contains({ origins: [prepareOriginURL(ollama_host)] });
|
||||||
|
}
|
||||||
|
let openai_comp_host = document.getElementById((modelId_prefix ? modelId_prefix : '') + "openai_comp_host")?.value;
|
||||||
|
if((openai_comp_host) && (openai_comp_host != '')){
|
||||||
|
varConnectionUI.permission_openai_comp_host = await messenger.permissions.contains({ origins: [prepareOriginURL(openai_comp_host)] });
|
||||||
|
}
|
||||||
|
varConnectionUI.permission_all_urls = await messenger.permissions.contains({ origins: ["<all_urls>"] });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updateCORSWarnings(modelId_prefix = ''){
|
||||||
|
await loadURLsPermissions(modelId_prefix);
|
||||||
|
if (varConnectionUI.permission_all_urls || varConnectionUI.permission_ollama_host) {
|
||||||
|
const ollamaWarning = document.getElementById((modelId_prefix ? modelId_prefix : '') + 'ollama_api_cors_warning');
|
||||||
|
if (ollamaWarning) ollamaWarning.style.display = 'none';
|
||||||
|
}
|
||||||
|
if (varConnectionUI.permission_all_urls || varConnectionUI.permission_openai_comp_host) {
|
||||||
|
const openaiCompWarning = document.getElementById((modelId_prefix ? modelId_prefix : '') + 'openai_comp_api_cors_warning');
|
||||||
|
if (openaiCompWarning) openaiCompWarning.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
4145
pages/_lib/tom-select.base.js
Normal file
4145
pages/_lib/tom-select.base.js
Normal file
File diff suppressed because it is too large
Load diff
2
pages/_lib/tom-select.default.min.css
vendored
Normal file
2
pages/_lib/tom-select.default.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -101,15 +101,7 @@
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="add_tags_tr">
|
|
||||||
<td><span class="opt_title">__MSG_prefs_OptionText_add_tags_context_menu__</span></td>
|
|
||||||
<td>
|
|
||||||
<label>
|
|
||||||
<input type="checkbox" id="add_tags_context_menu" name="add_tags_context_menu" class="option-input" />
|
|
||||||
__MSG_prefs_OptionText_add_tags_context_menu_Info__
|
|
||||||
</label>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="add_tags_tr">
|
<tr class="add_tags_tr">
|
||||||
<td><span class="opt_title">__MSG_prefs_OptionText_add_tags_auto_force_existing__</span></td>
|
<td><span class="opt_title">__MSG_prefs_OptionText_add_tags_auto_force_existing__</span></td>
|
||||||
<td>
|
<td>
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,8 @@ import {
|
||||||
import {
|
import {
|
||||||
getAccountsList,
|
getAccountsList,
|
||||||
normalizeStringList,
|
normalizeStringList,
|
||||||
isAPIKeyValue
|
isAPIKeyValue,
|
||||||
|
setTomSelectBorder
|
||||||
} from "../../js/mzta-utils.js";
|
} from "../../js/mzta-utils.js";
|
||||||
import {
|
import {
|
||||||
initializeSpecificIntegrationUI
|
initializeSpecificIntegrationUI
|
||||||
|
|
@ -301,6 +302,7 @@ function saveOptions(e) {
|
||||||
async function restoreOptions() {
|
async function restoreOptions() {
|
||||||
function setCurrentChoice(result) {
|
function setCurrentChoice(result) {
|
||||||
document.querySelectorAll(".option-input").forEach(element => {
|
document.querySelectorAll(".option-input").forEach(element => {
|
||||||
|
if(!element.id) return;
|
||||||
taLog.log("Options restoring " + element.id + " = " + (isAPIKeyValue(element.id) ? "****************" : result[element.id]));
|
taLog.log("Options restoring " + element.id + " = " + (isAPIKeyValue(element.id) ? "****************" : result[element.id]));
|
||||||
switch (element.type) {
|
switch (element.type) {
|
||||||
case 'checkbox':
|
case 'checkbox':
|
||||||
|
|
@ -338,6 +340,10 @@ async function restoreOptions() {
|
||||||
if (element.value === '') {
|
if (element.value === '') {
|
||||||
element.selectedIndex = -1;
|
element.selectedIndex = -1;
|
||||||
}
|
}
|
||||||
|
if (element.tomselect) {
|
||||||
|
element.tomselect.setValue(element.value, true);
|
||||||
|
setTomSelectBorder(element.tomselect);
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
console.error("[ThunderAI] Unhandled input type:", element.type);
|
console.error("[ThunderAI] Unhandled input type:", element.type);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,20 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { prefs_default } from "../../options/mzta-options-default.js";
|
import { prefs_default } from "../../options/mzta-options-default.js";
|
||||||
import { getLocalStorageUsedSpace, sanitizeHtml, isThunderbird128OrGreater, openTab } from "../../js/mzta-utils.js";
|
import {
|
||||||
|
getLocalStorageUsedSpace,
|
||||||
|
sanitizeHtml,
|
||||||
|
openTab
|
||||||
|
} from "../../js/mzta-utils.js";
|
||||||
import { taLogger } from "../../js/mzta-logger.js";
|
import { taLogger } from "../../js/mzta-logger.js";
|
||||||
import { getPlaceholders, setCustomPlaceholders, getCustomPlaceholders, prepareCustomDataPHsForExport, prepareCustomDataPHsForImport, placeholdersUtils } from "../../js/mzta-placeholders.js";
|
import {
|
||||||
|
getPlaceholders,
|
||||||
|
setCustomPlaceholders,
|
||||||
|
getCustomPlaceholders,
|
||||||
|
prepareCustomDataPHsForExport,
|
||||||
|
prepareCustomDataPHsForImport,
|
||||||
|
placeholdersUtils
|
||||||
|
} from "../../js/mzta-placeholders.js";
|
||||||
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
||||||
|
|
||||||
let prefs = null;
|
let prefs = null;
|
||||||
|
|
@ -550,12 +561,8 @@ async function setStorageSpace() {
|
||||||
document.getElementById('storage_space').textContent = storage_space;
|
document.getElementById('storage_space').textContent = storage_space;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.addEventListener('beforeunload', function (event) {
|
||||||
if(await isThunderbird128OrGreater()){
|
if (somethingChanged) {
|
||||||
window.addEventListener('beforeunload', function (event) {
|
event.preventDefault();
|
||||||
// Check if any changes have been made (Only for Thunderbird 128+ see https://github.com/micz/ThunderAI/issues/88)
|
}
|
||||||
if (somethingChanged) {
|
});
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -330,6 +330,17 @@ label:has(input[type="checkbox"]) {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dialog.export{
|
||||||
|
padding: 20px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: var(--dialog-bg-color, #fff);
|
||||||
|
color: var(--dialog-text-color, #000);
|
||||||
|
max-width: 400px;
|
||||||
|
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||||||
|
font-family: system-ui, -apple-system, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
body {
|
body {
|
||||||
background-color: #1C1B22;
|
background-color: #1C1B22;
|
||||||
|
|
|
||||||
|
|
@ -34,12 +34,12 @@ import {
|
||||||
} from "../../pages/_lib/connection-ui.js";
|
} from "../../pages/_lib/connection-ui.js";
|
||||||
import {
|
import {
|
||||||
ChatGPTWeb_models,
|
ChatGPTWeb_models,
|
||||||
isThunderbird128OrGreater,
|
|
||||||
getLocalStorageUsedSpace,
|
getLocalStorageUsedSpace,
|
||||||
sanitizeHtml,
|
sanitizeHtml,
|
||||||
validateCustomData_ChatGPTWeb,
|
validateCustomData_ChatGPTWeb,
|
||||||
getChatGPTWebModelsList_HTML,
|
getChatGPTWebModelsList_HTML,
|
||||||
openTab
|
openTab,
|
||||||
|
setTomSelectBorder
|
||||||
} from "../../js/mzta-utils.js";
|
} from "../../js/mzta-utils.js";
|
||||||
import { taLogger } from "../../js/mzta-logger.js";
|
import { taLogger } from "../../js/mzta-logger.js";
|
||||||
import {
|
import {
|
||||||
|
|
@ -324,6 +324,8 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
let editBtn = document.querySelector(`tr[data-idnum="${curr_idnum}"] button.btnEditItem`);
|
let editBtn = document.querySelector(`tr[data-idnum="${curr_idnum}"] button.btnEditItem`);
|
||||||
//console.log(`>>>>>>>>>>>> tr[data-idnum="${curr_idnum}"] button.btnEditItem`);
|
//console.log(`>>>>>>>>>>>> tr[data-idnum="${curr_idnum}"] button.btnEditItem`);
|
||||||
editBtn.addEventListener('click', handleEditClick);
|
editBtn.addEventListener('click', handleEditClick);
|
||||||
|
let copyBtn = document.querySelector(`tr[data-idnum="${curr_idnum}"] button.btnCopyItem`);
|
||||||
|
copyBtn.addEventListener('click', handleCopyClick);
|
||||||
//console.log('>>>>>>>>>>>>> editBtn: ' + JSON.stringify(editBtn));
|
//console.log('>>>>>>>>>>>>> editBtn: ' + JSON.stringify(editBtn));
|
||||||
let deleteBtn = document.querySelector(`tr[data-idnum="${curr_idnum}"] button.btnDeleteItem`);
|
let deleteBtn = document.querySelector(`tr[data-idnum="${curr_idnum}"] button.btnDeleteItem`);
|
||||||
//console.log(`>>>>>>>>>>>> tr[data-idnum="${curr_idnum}"] button.btnDeleteItem`);
|
//console.log(`>>>>>>>>>>>> tr[data-idnum="${curr_idnum}"] button.btnDeleteItem`);
|
||||||
|
|
@ -354,7 +356,9 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
async function exportPrompts() {
|
async function exportPrompts() {
|
||||||
const manifest = browser.runtime.getManifest();
|
const manifest = browser.runtime.getManifest();
|
||||||
const addonVersion = manifest.version;
|
const addonVersion = manifest.version;
|
||||||
const outputPrompts = preparePromptsForExport(await getPrompts());
|
const include_api_settings = await showYesNoDialog(browser.i18n.getMessage("customPrompts_export_include_api_settings"));
|
||||||
|
if (include_api_settings === null) return;
|
||||||
|
const outputPrompts = preparePromptsForExport(await getPrompts(), include_api_settings);
|
||||||
let outputObj = {id: 'thunderai-prompts', addon_version: addonVersion, prompts: outputPrompts};
|
let outputObj = {id: 'thunderai-prompts', addon_version: addonVersion, prompts: outputPrompts};
|
||||||
const blob = new Blob([JSON.stringify(outputObj, null, 2)], {
|
const blob = new Blob([JSON.stringify(outputObj, null, 2)], {
|
||||||
type: "application/json",
|
type: "application/json",
|
||||||
|
|
@ -368,6 +372,82 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function showYesNoDialog(message) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const dialog = document.createElement('dialog');
|
||||||
|
dialog.className = 'export';
|
||||||
|
// dialog.style.cssText = `
|
||||||
|
// padding: 20px;
|
||||||
|
// border: none;
|
||||||
|
// border-radius: 8px;
|
||||||
|
// background-color: var(--dialog-bg-color, #fff);
|
||||||
|
// color: var(--dialog-text-color, #000);
|
||||||
|
// max-width: 400px;
|
||||||
|
// box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||||||
|
// font-family: system-ui, -apple-system, sans-serif;
|
||||||
|
// `;
|
||||||
|
|
||||||
|
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||||
|
dialog.style.backgroundColor = '#2e2e2e';
|
||||||
|
dialog.style.color = '#ffffff';
|
||||||
|
}
|
||||||
|
|
||||||
|
const text = document.createElement('p');
|
||||||
|
text.textContent = message;
|
||||||
|
text.style.marginBottom = '20px';
|
||||||
|
text.style.fontSize = '14px';
|
||||||
|
text.style.lineHeight = '1.5';
|
||||||
|
dialog.appendChild(text);
|
||||||
|
|
||||||
|
const btnContainer = document.createElement('div');
|
||||||
|
btnContainer.style.display = 'flex';
|
||||||
|
btnContainer.style.justifyContent = 'flex-end';
|
||||||
|
btnContainer.style.gap = '10px';
|
||||||
|
|
||||||
|
const createBtn = (text, bgColor) => {
|
||||||
|
const btn = document.createElement('button');
|
||||||
|
btn.textContent = text;
|
||||||
|
btn.style.padding = '8px 16px';
|
||||||
|
btn.style.borderRadius = '4px';
|
||||||
|
btn.style.border = 'none';
|
||||||
|
btn.style.cursor = 'pointer';
|
||||||
|
btn.style.fontSize = '14px';
|
||||||
|
btn.style.color = 'white';
|
||||||
|
btn.style.backgroundColor = bgColor;
|
||||||
|
return btn;
|
||||||
|
};
|
||||||
|
|
||||||
|
const cancelBtn = createBtn(browser.i18n.getMessage("customPrompts_btnCancel"), '#6c757d');
|
||||||
|
cancelBtn.onclick = () => {
|
||||||
|
dialog.close();
|
||||||
|
dialog.remove();
|
||||||
|
resolve(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
const noBtn = createBtn(browser.i18n.getMessage("no_string"), '#007bff');
|
||||||
|
noBtn.onclick = () => {
|
||||||
|
dialog.close();
|
||||||
|
dialog.remove();
|
||||||
|
resolve(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const yesBtn = createBtn(browser.i18n.getMessage("yes_string"), '#6c757d');
|
||||||
|
yesBtn.onclick = () => {
|
||||||
|
dialog.close();
|
||||||
|
dialog.remove();
|
||||||
|
resolve(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
btnContainer.appendChild(cancelBtn);
|
||||||
|
btnContainer.appendChild(noBtn);
|
||||||
|
btnContainer.appendChild(yesBtn);
|
||||||
|
dialog.appendChild(btnContainer);
|
||||||
|
|
||||||
|
document.body.appendChild(dialog);
|
||||||
|
dialog.showModal();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const btnImport = document.getElementById('btnImport');
|
const btnImport = document.getElementById('btnImport');
|
||||||
btnImport.addEventListener('click', (e) => {
|
btnImport.addEventListener('click', (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
@ -498,6 +578,7 @@ function handleEditClick(e) {
|
||||||
tr.querySelector('.btnConfirmItem').style.display = 'inline'; // Save btn
|
tr.querySelector('.btnConfirmItem').style.display = 'inline'; // Save btn
|
||||||
tr.querySelector('.btnCancelItem').style.display = 'inline'; // Cancel btn
|
tr.querySelector('.btnCancelItem').style.display = 'inline'; // Cancel btn
|
||||||
// tr.querySelector('.btnEditItem').style.display = 'none'; // Edit btn
|
// tr.querySelector('.btnEditItem').style.display = 'none'; // Edit btn
|
||||||
|
tr.querySelector('.btnCopyItem').style.display = 'none'; // Copy btn
|
||||||
tr.querySelector('.btnDeleteItem').style.display = 'none'; // Delete btn
|
tr.querySelector('.btnDeleteItem').style.display = 'none'; // Delete btn
|
||||||
showItemRowEditor(tr);
|
showItemRowEditor(tr);
|
||||||
toggleDiffviewer(e);
|
toggleDiffviewer(e);
|
||||||
|
|
@ -568,7 +649,24 @@ function populateConnectionUI(tr, id, prefix, selectId) {
|
||||||
val = prefs[propName];
|
val = prefs[propName];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inputEl.type === 'checkbox' ? inputEl.checked = (val === true || val === 'true') : inputEl.value = val || '';
|
if (inputEl.type === 'checkbox') {
|
||||||
|
inputEl.checked = (val === true || val === 'true');
|
||||||
|
} else {
|
||||||
|
if (inputEl.tomselect) {
|
||||||
|
const restoreValue = val || '';
|
||||||
|
let optionExists = Array.from(inputEl.options).some(opt => opt.value === restoreValue);
|
||||||
|
if (!optionExists && restoreValue !== '') {
|
||||||
|
let newOption = new Option(restoreValue, restoreValue);
|
||||||
|
inputEl.add(newOption);
|
||||||
|
}
|
||||||
|
inputEl.value = restoreValue;
|
||||||
|
inputEl.tomselect.sync();
|
||||||
|
inputEl.tomselect.setValue(restoreValue, true);
|
||||||
|
setTomSelectBorder(inputEl.tomselect);
|
||||||
|
} else {
|
||||||
|
inputEl.value = val || '';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -743,6 +841,7 @@ function handleCancelClick(e) {
|
||||||
tr.querySelector('.btnConfirmItem').style.display = 'none'; // Save btn
|
tr.querySelector('.btnConfirmItem').style.display = 'none'; // Save btn
|
||||||
// tr.querySelector('.btnCancelItem').style.display = 'none'; // Cancel btn
|
// tr.querySelector('.btnCancelItem').style.display = 'none'; // Cancel btn
|
||||||
tr.querySelector('.btnEditItem').style.display = 'inline'; // Edit btn
|
tr.querySelector('.btnEditItem').style.display = 'inline'; // Edit btn
|
||||||
|
tr.querySelector('.btnCopyItem').style.display = 'inline'; // Copy btn
|
||||||
tr.querySelector('.btnDeleteItem').style.display = 'inline'; // Delete btn
|
tr.querySelector('.btnDeleteItem').style.display = 'inline'; // Delete btn
|
||||||
tr.querySelector('.id_output').value = tr.querySelector('.id_show').innerText.toLocaleUpperCase();
|
tr.querySelector('.id_output').value = tr.querySelector('.id_show').innerText.toLocaleUpperCase();
|
||||||
tr.querySelector('.name_output').value = tr.querySelector('.name_show').innerText;
|
tr.querySelector('.name_output').value = tr.querySelector('.name_show').innerText;
|
||||||
|
|
@ -796,6 +895,7 @@ function handleConfirmClick(e) {
|
||||||
// tr.querySelector('.btnConfirmItem').style.display = 'none'; // Ok btn
|
// tr.querySelector('.btnConfirmItem').style.display = 'none'; // Ok btn
|
||||||
tr.querySelector('.btnCancelItem').style.display = 'none'; // Cancel btn
|
tr.querySelector('.btnCancelItem').style.display = 'none'; // Cancel btn
|
||||||
tr.querySelector('.btnEditItem').style.display = 'inline'; // Edit btn
|
tr.querySelector('.btnEditItem').style.display = 'inline'; // Edit btn
|
||||||
|
tr.querySelector('.btnCopyItem').style.display = 'inline'; // Copy btn
|
||||||
tr.querySelector('.btnDeleteItem').style.display = 'inline'; // Delete btn
|
tr.querySelector('.btnDeleteItem').style.display = 'inline'; // Delete btn
|
||||||
// Update item data
|
// Update item data
|
||||||
tr.querySelector('.type').innerText = tr.querySelector('.type_output').value;
|
tr.querySelector('.type').innerText = tr.querySelector('.type_output').value;
|
||||||
|
|
@ -847,6 +947,88 @@ function handleInputChange(e) {
|
||||||
setSomethingChanged();
|
setSomethingChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleCopyClick(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const tr = e.target.parentNode.parentNode;
|
||||||
|
|
||||||
|
let id = tr.querySelector('.id_output').value;
|
||||||
|
let name = tr.querySelector('.name_output').value;
|
||||||
|
let text = tr.querySelector('.text_output').value;
|
||||||
|
let type = tr.querySelector('.type_output').value;
|
||||||
|
let action = tr.querySelector('.action_output').value;
|
||||||
|
|
||||||
|
let need_selected = tr.querySelector('.need_selected').checked;
|
||||||
|
let need_signature = tr.querySelector('.need_signature').checked;
|
||||||
|
let need_custom_text = tr.querySelector('.need_custom_text').checked;
|
||||||
|
let define_response_lang = tr.querySelector('.define_response_lang').checked;
|
||||||
|
let use_diff_viewer = tr.querySelector('.use_diff_viewer').checked;
|
||||||
|
|
||||||
|
let chatgpt_web_model = tr.querySelector('.chatgpt_web_model_output').value;
|
||||||
|
let chatgpt_web_project = tr.querySelector('.chatgpt_web_project_output').value;
|
||||||
|
let chatgpt_web_custom_gpt = tr.querySelector('.chatgpt_web_custom_gpt_output').value;
|
||||||
|
|
||||||
|
const item = promptsList.get('id', id.toLowerCase())[0];
|
||||||
|
const itemValues = item.values();
|
||||||
|
|
||||||
|
// Populate new form
|
||||||
|
document.getElementById('txtIdNew').value = id + '_' + browser.i18n.getMessage("copy_text");
|
||||||
|
document.getElementById('txtNameNew').value = name + ' (' + browser.i18n.getMessage("copy_text") + ')';
|
||||||
|
document.getElementById('txtTextNew').value = text;
|
||||||
|
document.getElementById('selectTypeNew').value = type;
|
||||||
|
document.getElementById('selectActionNew').value = action;
|
||||||
|
|
||||||
|
document.getElementById('checkboxNeedSelectedNew').checked = need_selected;
|
||||||
|
document.getElementById('checkboxNeedSignatureNew').checked = need_signature;
|
||||||
|
document.getElementById('checkboxNeedCustomTextNew').checked = need_custom_text;
|
||||||
|
document.getElementById('checkboxDefineResponseLangNew').checked = define_response_lang;
|
||||||
|
|
||||||
|
let checkboxUseDiffViewerNew = document.getElementById('checkboxUseDiffViewerNew');
|
||||||
|
checkboxUseDiffViewerNew.checked = use_diff_viewer;
|
||||||
|
checkboxUseDiffViewerNew.disabled = (action !== "2");
|
||||||
|
|
||||||
|
document.getElementById('chatGPTWebModelNew').value = chatgpt_web_model;
|
||||||
|
document.getElementById('chatGPTWebProjectNew').value = chatgpt_web_project;
|
||||||
|
document.getElementById('chatGPTWebCustomGPTNew').value = chatgpt_web_custom_gpt;
|
||||||
|
|
||||||
|
const apiSelect = document.getElementById('new_prompt_api_type');
|
||||||
|
if (apiSelect) {
|
||||||
|
apiSelect.value = itemValues.api_type || '';
|
||||||
|
apiSelect.dispatchEvent(new Event('change'));
|
||||||
|
|
||||||
|
for (const [integration, options] of Object.entries(integration_options_config)) {
|
||||||
|
for (const key of Object.keys(options)) {
|
||||||
|
const propName = `${integration}_${key}`;
|
||||||
|
const inputEl = document.getElementById(propName);
|
||||||
|
if (inputEl) {
|
||||||
|
let val = itemValues[propName];
|
||||||
|
if (val === undefined) val = '';
|
||||||
|
|
||||||
|
if (inputEl.type === 'checkbox') {
|
||||||
|
inputEl.checked = (val === true || val === 'true');
|
||||||
|
} else {
|
||||||
|
if (inputEl.tomselect) {
|
||||||
|
inputEl.tomselect.setValue(val, true);
|
||||||
|
setTomSelectBorder(inputEl.tomselect);
|
||||||
|
} else {
|
||||||
|
inputEl.value = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show form
|
||||||
|
document.getElementById('formNew').style.display = 'block';
|
||||||
|
|
||||||
|
// Scroll to top
|
||||||
|
window.scrollTo({
|
||||||
|
top: 0,
|
||||||
|
behavior: 'smooth'
|
||||||
|
});
|
||||||
|
checkFields();
|
||||||
|
}
|
||||||
|
|
||||||
//========= handling an item in a row - END
|
//========= handling an item in a row - END
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -976,6 +1158,8 @@ function loadPromptsList(values){
|
||||||
<br><br>
|
<br><br>
|
||||||
<button class="btnConfirmItem hiddendata"` + ((values.is_default == 1) ? ' disabled':'') + `>__MSG_customPrompts_btnOK__</button>
|
<button class="btnConfirmItem hiddendata"` + ((values.is_default == 1) ? ' disabled':'') + `>__MSG_customPrompts_btnOK__</button>
|
||||||
<button class="btnDeleteItem"` + ((values.is_default == 1) ? ' disabled':'') + `>__MSG_customPrompts_btnDelete__</button>
|
<button class="btnDeleteItem"` + ((values.is_default == 1) ? ' disabled':'') + `>__MSG_customPrompts_btnDelete__</button>
|
||||||
|
<br><br>
|
||||||
|
<button class="btnCopyItem">__MSG_customPrompts_btnCopy__</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>`;
|
</tr>`;
|
||||||
//console.log('>>>>>>>> values.name: ' + JSON.stringify(values.name));
|
//console.log('>>>>>>>> values.name: ' + JSON.stringify(values.name));
|
||||||
|
|
@ -1016,6 +1200,11 @@ function loadPromptsList(values){
|
||||||
element.addEventListener('click', handleEditClick);
|
element.addEventListener('click', handleEditClick);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let btnCopyItem_elements = document.querySelectorAll(".btnCopyItem");
|
||||||
|
btnCopyItem_elements.forEach(element => {
|
||||||
|
element.addEventListener('click', handleCopyClick);
|
||||||
|
});
|
||||||
|
|
||||||
let btnDeleteItem_elements = document.querySelectorAll(".btnDeleteItem");
|
let btnDeleteItem_elements = document.querySelectorAll(".btnDeleteItem");
|
||||||
btnDeleteItem_elements.forEach(element => {
|
btnDeleteItem_elements.forEach(element => {
|
||||||
element.addEventListener('click', handleDeleteClick);
|
element.addEventListener('click', handleDeleteClick);
|
||||||
|
|
@ -1184,7 +1373,7 @@ async function saveAll() {
|
||||||
setMessage(browser.i18n.getMessage('customPrompts_saving_custom_prompts'));
|
setMessage(browser.i18n.getMessage('customPrompts_saving_custom_prompts'));
|
||||||
await setCustomPrompts(newCustomPrompts);
|
await setCustomPrompts(newCustomPrompts);
|
||||||
setMessage(browser.i18n.getMessage('customPrompts_reloading_menus'));
|
setMessage(browser.i18n.getMessage('customPrompts_reloading_menus'));
|
||||||
browser.runtime.sendMessage({command: "reload_menus"});
|
await browser.runtime.sendMessage({command: "reload_menus"});
|
||||||
setMessage(browser.i18n.getMessage('customPrompts_saved'),'green');
|
setMessage(browser.i18n.getMessage('customPrompts_saved'),'green');
|
||||||
msgTimeout = setTimeout(() => {
|
msgTimeout = setTimeout(() => {
|
||||||
clearMessage();
|
clearMessage();
|
||||||
|
|
@ -1214,14 +1403,11 @@ async function setStorageSpace() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(await isThunderbird128OrGreater()){
|
window.addEventListener('beforeunload', function (event) {
|
||||||
window.addEventListener('beforeunload', function (event) {
|
if (somethingChanged) {
|
||||||
// Check if any changes have been made (Only for Thunderbird 128+ see https://github.com/micz/ThunderAI/issues/88)
|
event.preventDefault();
|
||||||
if (somethingChanged) {
|
}
|
||||||
event.preventDefault();
|
});
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function checkPromptsConfigForPlaceholders(textarea){
|
async function checkPromptsConfigForPlaceholders(textarea){
|
||||||
let curr_text = textarea.value;
|
let curr_text = textarea.value;
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>ThunderAI - __MSG_GetCalendarEvent_PageTitle__</title>
|
<title>ThunderAI - __MSG_GetCalendarEvent_PageTitle__</title>
|
||||||
<link rel="stylesheet" href="mzta-get-calendar-event.css">
|
<link rel="stylesheet" href="mzta-get-calendar-event.css">
|
||||||
|
<link rel="stylesheet" href="../_lib/connection-ui.css">
|
||||||
<link rel="icon" href="../../images/icon-16px.png">
|
<link rel="icon" href="../../images/icon-16px.png">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
@ -13,8 +14,40 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="get_calendar_event_table_title section_title">__MSG_get_calendar_event_prompt_prefs_title__</div>
|
<div class="get_calendar_event_table_title section_title">__MSG_get_calendar_event_prompt_prefs_title__</div>
|
||||||
<table id="miczPrefs">
|
<table id="miczPrefs">
|
||||||
|
<tr class="get_calendar_event_tr specific_integration">
|
||||||
|
<td><span class="opt_title">__MSG_prefs_OptionText_use_specific_integration__</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" id="get_calendar_event_use_specific_integration" name="get_calendar_event_use_specific_integration" class="option-input" />
|
||||||
|
__MSG_prefs_OptionText_get_calendar_event_use_specific_integration_Info__
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr id="connection_ui_anchor"></tr>
|
||||||
|
<tr id="connection_ui_end"><td colspan="2"></td></tr>
|
||||||
<tr class="get_calendar_event_tr">
|
<tr class="get_calendar_event_tr">
|
||||||
<td><span>__MSG_prefs_OptionText_calendar_enforce_timezone__</span></td>
|
<td><span class="opt_title">__MSG_prefs_OptionText_calendar_no_selection__</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" id="calendar_no_selection" name="calendar_no_selection" class="option-input" />
|
||||||
|
__MSG_prefs_OptionText_calendar_no_selection_Info__
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="get_calendar_event_tr">
|
||||||
|
<td><span class="opt_title">__MSG_prefs_OptionText_get_calendar_event_from_clipboard__</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" id="get_calendar_event_from_clipboard" name="get_calendar_event_from_clipboard" class="option-input" />
|
||||||
|
__MSG_prefs_OptionText_get_calendar_event_from_clipboard_Info__
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="get_calendar_event_tr">
|
||||||
|
<td><span class="opt_title">__MSG_prefs_OptionText_calendar_enforce_timezone__</span></td>
|
||||||
<td>
|
<td>
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" id="calendar_enforce_timezone" name="calendar_enforce_timezone" class="option-input" /> __MSG_prefs_OptionText_calendar_enforce_timezone_Info__
|
<input type="checkbox" id="calendar_enforce_timezone" name="calendar_enforce_timezone" class="option-input" /> __MSG_prefs_OptionText_calendar_enforce_timezone_Info__
|
||||||
|
|
|
||||||
|
|
@ -16,23 +16,59 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { prefs_default } from '../../options/mzta-options-default.js';
|
import {
|
||||||
|
prefs_default,
|
||||||
|
integration_options_config
|
||||||
|
} from '../../options/mzta-options-default.js';
|
||||||
import { taLogger } from '../../js/mzta-logger.js';
|
import { taLogger } from '../../js/mzta-logger.js';
|
||||||
import { getSpecialPrompts, setSpecialPrompts } from "../../js/mzta-prompts.js";
|
import {
|
||||||
|
getSpecialPrompts,
|
||||||
|
setSpecialPrompts
|
||||||
|
} from "../../js/mzta-prompts.js";
|
||||||
import {
|
import {
|
||||||
getPlaceholders,
|
getPlaceholders,
|
||||||
mapPlaceholderToSuggestion
|
mapPlaceholderToSuggestion
|
||||||
} from "../../js/mzta-placeholders.js";
|
} from "../../js/mzta-placeholders.js";
|
||||||
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
||||||
import { isAPIKeyValue } from "../../js/mzta-utils.js";
|
import {
|
||||||
|
isAPIKeyValue,
|
||||||
|
setTomSelectBorder
|
||||||
|
} from "../../js/mzta-utils.js";
|
||||||
|
import {
|
||||||
|
initializeSpecificIntegrationUI
|
||||||
|
} from "../_lib/connection-ui.js";
|
||||||
|
|
||||||
let autocompleteSuggestions = [];
|
let autocompleteSuggestions = [];
|
||||||
let taLog = new taLogger("mzta-get-calendar-event-page",true);
|
let taLog = new taLogger("mzta-get-calendar-event-page",true);
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', async () => {
|
document.addEventListener('DOMContentLoaded', async () => {
|
||||||
|
|
||||||
|
let specialPrompts = await getSpecialPrompts();
|
||||||
|
let get_calendar_event_prompt = specialPrompts.find(prompt => prompt.id === 'prompt_get_calendar_event');
|
||||||
|
|
||||||
|
if (get_calendar_event_prompt && get_calendar_event_prompt.api_type && get_calendar_event_prompt.api_type !== '') {
|
||||||
|
let update_prefs = {};
|
||||||
|
update_prefs['get_calendar_event_connection_type'] = get_calendar_event_prompt.api_type;
|
||||||
|
|
||||||
|
let integration = get_calendar_event_prompt.api_type.replace('_api', '');
|
||||||
|
if (integration_options_config && integration_options_config[integration]) {
|
||||||
|
for (const key of Object.keys(integration_options_config[integration])) {
|
||||||
|
if (get_calendar_event_prompt[key] !== undefined) {
|
||||||
|
update_prefs[`get_calendar_event_${integration}_${key}`] = get_calendar_event_prompt[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await browser.storage.sync.set(update_prefs);
|
||||||
|
}
|
||||||
|
|
||||||
|
await initializeSpecificIntegrationUI({
|
||||||
|
prefix: 'get_calendar_event',
|
||||||
|
promptId: 'prompt_get_calendar_event',
|
||||||
|
taLog: taLog,
|
||||||
|
restoreOptionsCallback: restoreOptions
|
||||||
|
});
|
||||||
|
|
||||||
i18n.updateDocument();
|
i18n.updateDocument();
|
||||||
await restoreOptions();
|
|
||||||
|
|
||||||
document.querySelectorAll(".option-input").forEach(element => {
|
document.querySelectorAll(".option-input").forEach(element => {
|
||||||
element.addEventListener("change", saveOptions);
|
element.addEventListener("change", saveOptions);
|
||||||
|
|
@ -41,9 +77,9 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
let get_calendar_event_textarea = document.getElementById('get_calendar_event_prompt_text');
|
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_save_btn = document.getElementById('btn_save_prompt');
|
||||||
let get_calendar_event_reset_btn = document.getElementById('btn_reset_prompt');
|
let get_calendar_event_reset_btn = document.getElementById('btn_reset_prompt');
|
||||||
|
let get_calendar_event_use_specific_integration = document.getElementById('get_calendar_event_use_specific_integration');
|
||||||
let specialPrompts = await getSpecialPrompts();
|
let get_calendar_event_no_selection = document.getElementById('calendar_no_selection');
|
||||||
let get_calendar_event_prompt = specialPrompts.find(prompt => prompt.id === 'prompt_get_calendar_event');
|
let get_calendar_event_from_clipboard = document.getElementById('get_calendar_event_from_clipboard');
|
||||||
|
|
||||||
get_calendar_event_textarea.addEventListener('input', (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_reset_btn.disabled = (event.target.value === browser.i18n.getMessage('prompt_get_calendar_event_full_text'));
|
||||||
|
|
@ -55,6 +91,47 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
get_calendar_event_use_specific_integration.addEventListener('change', (event) => {
|
||||||
|
if (!event.target.checked) {
|
||||||
|
browser.storage.sync.set({ get_calendar_event_connection_type: '' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
get_calendar_event_no_selection.addEventListener('change', async (event) => {
|
||||||
|
specialPrompts.find(prompt => prompt.id === 'prompt_get_calendar_event').need_selected = event.target.checked ? '0' : '1';
|
||||||
|
await setSpecialPrompts(specialPrompts);
|
||||||
|
browser.runtime.sendMessage({command: "reload_menus"});
|
||||||
|
});
|
||||||
|
|
||||||
|
get_calendar_event_from_clipboard.addEventListener('change', async (event) => {
|
||||||
|
if (event.target.checked) {
|
||||||
|
// Request clipboardRead permission when enabling the feature
|
||||||
|
try {
|
||||||
|
const granted = await browser.permissions.request({
|
||||||
|
permissions: ["clipboardRead"]
|
||||||
|
});
|
||||||
|
|
||||||
|
if (granted) {
|
||||||
|
// Permission granted, enable the feature
|
||||||
|
await browser.storage.sync.set({ get_calendar_event_from_clipboard: true });
|
||||||
|
browser.runtime.sendMessage({command: "reload_menus"});
|
||||||
|
} else {
|
||||||
|
// Permission denied, uncheck the checkbox
|
||||||
|
event.target.checked = false;
|
||||||
|
alert(browser.i18n.getMessage("clipboard_permission_denied"));
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
taLog.error("Error requesting clipboard permission:", err);
|
||||||
|
event.target.checked = false;
|
||||||
|
alert(browser.i18n.getMessage("clipboard_permission_error"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Disabling the feature
|
||||||
|
await browser.storage.sync.set({ get_calendar_event_from_clipboard: false });
|
||||||
|
browser.runtime.sendMessage({command: "reload_menus"});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
get_calendar_event_reset_btn.addEventListener('click', () => {
|
get_calendar_event_reset_btn.addEventListener('click', () => {
|
||||||
get_calendar_event_textarea.value = browser.i18n.getMessage('prompt_get_calendar_event_full_text');
|
get_calendar_event_textarea.value = browser.i18n.getMessage('prompt_get_calendar_event_full_text');
|
||||||
get_calendar_event_reset_btn.disabled = true;
|
get_calendar_event_reset_btn.disabled = true;
|
||||||
|
|
@ -62,9 +139,10 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
get_calendar_event_textarea.dispatchEvent(event);
|
get_calendar_event_textarea.dispatchEvent(event);
|
||||||
});
|
});
|
||||||
|
|
||||||
get_calendar_event_save_btn.addEventListener('click', () => {
|
get_calendar_event_save_btn.addEventListener('click', async () => {
|
||||||
specialPrompts.find(prompt => prompt.id === 'prompt_get_calendar_event').text = get_calendar_event_textarea.value;
|
specialPrompts.find(prompt => prompt.id === 'prompt_get_calendar_event').text = get_calendar_event_textarea.value;
|
||||||
setSpecialPrompts(specialPrompts);
|
specialPrompts.find(prompt => prompt.id === 'prompt_get_calendar_event_from_clipboard').text = get_calendar_event_textarea.value;
|
||||||
|
await setSpecialPrompts(specialPrompts);
|
||||||
get_calendar_event_save_btn.disabled = true;
|
get_calendar_event_save_btn.disabled = true;
|
||||||
document.getElementById('get_calendar_event_prompt_unsaved').classList.add('hidden');
|
document.getElementById('get_calendar_event_prompt_unsaved').classList.add('hidden');
|
||||||
browser.runtime.sendMessage({command: "reload_menus"});
|
browser.runtime.sendMessage({command: "reload_menus"});
|
||||||
|
|
@ -97,8 +175,8 @@ function saveOptions(e) {
|
||||||
case 'number':
|
case 'number':
|
||||||
options[element.id] = element.valueAsNumber;
|
options[element.id] = element.valueAsNumber;
|
||||||
break;
|
break;
|
||||||
case 'text':
|
case 'text':
|
||||||
case 'password':
|
case 'password':
|
||||||
options[element.id] = element.value.trim();
|
options[element.id] = element.value.trim();
|
||||||
break;
|
break;
|
||||||
case 'select-one':
|
case 'select-one':
|
||||||
|
|
@ -114,6 +192,7 @@ function saveOptions(e) {
|
||||||
async function restoreOptions() {
|
async function restoreOptions() {
|
||||||
function setCurrentChoice(result) {
|
function setCurrentChoice(result) {
|
||||||
document.querySelectorAll(".option-input").forEach(element => {
|
document.querySelectorAll(".option-input").forEach(element => {
|
||||||
|
if(!element.id) return;
|
||||||
taLog.log("Options restoring " + element.id + " = " + (isAPIKeyValue(element.id) ? "****************" : result[element.id]));
|
taLog.log("Options restoring " + element.id + " = " + (isAPIKeyValue(element.id) ? "****************" : result[element.id]));
|
||||||
switch (element.type) {
|
switch (element.type) {
|
||||||
case 'checkbox':
|
case 'checkbox':
|
||||||
|
|
@ -131,15 +210,28 @@ async function restoreOptions() {
|
||||||
if(element.id == 'default_chatgpt_lang') default_text_value = prefs_default.default_chatgpt_lang;
|
if(element.id == 'default_chatgpt_lang') default_text_value = prefs_default.default_chatgpt_lang;
|
||||||
element.value = result[element.id] || default_text_value;
|
element.value = result[element.id] || default_text_value;
|
||||||
break;
|
break;
|
||||||
|
case 'textarea':
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (element.tagName === 'SELECT') {
|
if (element.tagName === 'SELECT') {
|
||||||
let default_select_value = '';
|
let default_select_value = '';
|
||||||
if(element.id == 'reply_type') default_select_value = 'reply_all';
|
const restoreValue = result[element.id] || default_select_value;
|
||||||
if(element.id == 'connection_type') default_select_value = 'chatgpt_web';
|
// Check if option exists
|
||||||
element.value = result[element.id] || default_select_value;
|
let optionExists = Array.from(element.options).some(opt => opt.value === restoreValue);
|
||||||
if (element.value === '') {
|
// If it doesn't exist and restoreValue is not empty, create it
|
||||||
element.selectedIndex = -1;
|
if (!optionExists && restoreValue !== '') {
|
||||||
}
|
let newOption = new Option(restoreValue, restoreValue);
|
||||||
|
element.add(newOption);
|
||||||
|
}
|
||||||
|
// Set value
|
||||||
|
element.value = restoreValue;
|
||||||
|
if (element.value === '') {
|
||||||
|
element.selectedIndex = -1;
|
||||||
|
}
|
||||||
|
if (element.tomselect) {
|
||||||
|
element.tomselect.setValue(element.value, true);
|
||||||
|
setTomSelectBorder(element.tomselect);
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
console.error("[ThunderAI] Unhandled input type:", element.type);
|
console.error("[ThunderAI] Unhandled input type:", element.type);
|
||||||
}
|
}
|
||||||
|
|
@ -148,5 +240,27 @@ async function restoreOptions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
let getting = await browser.storage.sync.get(prefs_default);
|
let getting = await browser.storage.sync.get(prefs_default);
|
||||||
|
|
||||||
|
let specialPrompts = await getSpecialPrompts();
|
||||||
|
let get_calendar_event_prompt = specialPrompts.find(prompt => prompt.id === 'prompt_get_calendar_event');
|
||||||
|
|
||||||
|
if (get_calendar_event_prompt) {
|
||||||
|
if (get_calendar_event_prompt.api_type && get_calendar_event_prompt.api_type !== '') {
|
||||||
|
getting['get_calendar_event_connection_type'] = get_calendar_event_prompt.api_type;
|
||||||
|
} else {
|
||||||
|
getting['get_calendar_event_connection_type'] = getting['connection_type'];
|
||||||
|
}
|
||||||
|
for (const [integration, options] of Object.entries(integration_options_config)) {
|
||||||
|
for (const key of Object.keys(options)) {
|
||||||
|
const propName = `${integration}_${key}`;
|
||||||
|
if (get_calendar_event_prompt[propName] !== undefined && get_calendar_event_prompt[propName] !== '') {
|
||||||
|
getting[`get_calendar_event_${propName}`] = get_calendar_event_prompt[propName];
|
||||||
|
} else {
|
||||||
|
getting[`get_calendar_event_${propName}`] = getting[propName];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setCurrentChoice(getting);
|
setCurrentChoice(getting);
|
||||||
}
|
}
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>ThunderAI - __MSG_GetTask_PageTitle__</title>
|
<title>ThunderAI - __MSG_GetTask_PageTitle__</title>
|
||||||
<link rel="stylesheet" href="mzta-get-task.css">
|
<link rel="stylesheet" href="mzta-get-task.css">
|
||||||
|
<link rel="stylesheet" href="../_lib/connection-ui.css">
|
||||||
<link rel="icon" href="../../images/icon-16px.png">
|
<link rel="icon" href="../../images/icon-16px.png">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
@ -11,10 +12,20 @@
|
||||||
<h1 class="page_title">__MSG_GetTask_PageTitle__</h1>
|
<h1 class="page_title">__MSG_GetTask_PageTitle__</h1>
|
||||||
<p>__MSG_GetTask_info_default__</p>
|
<p>__MSG_GetTask_info_default__</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="get_calendar_event_table_title section_title">__MSG_get_calendar_event_prompt_prefs_title__</div>
|
<div class="get_task_table_title section_title">__MSG_get_task_prompt_prefs_title__</div>
|
||||||
<table id="miczPrefs">
|
<table id="miczPrefs">
|
||||||
<tr class="get_calendar_event_tr">
|
<tr>
|
||||||
<td><span>__MSG_prefs_OptionText_calendar_enforce_timezone__</span></td>
|
<td><span class="opt_title">__MSG_prefs_OptionText_use_specific_integration__</span></td>
|
||||||
|
<td>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" id="get_task_use_specific_integration" name="get_task_use_specific_integration" class="option-input" /> __MSG_prefs_OptionText_get_calendar_event_use_specific_integration_Info__
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr id="connection_ui_anchor" style="display:none"></tr>
|
||||||
|
<tr id="connection_ui_end" style="display:none"></tr>
|
||||||
|
<tr class="get_task_tr">
|
||||||
|
<td><span class="opt_title">__MSG_prefs_OptionText_calendar_enforce_timezone__</span></td>
|
||||||
<td>
|
<td>
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" id="calendar_enforce_timezone" name="calendar_enforce_timezone" class="option-input" /> __MSG_prefs_OptionText_calendar_enforce_timezone_Info__
|
<input type="checkbox" id="calendar_enforce_timezone" name="calendar_enforce_timezone" class="option-input" /> __MSG_prefs_OptionText_calendar_enforce_timezone_Info__
|
||||||
|
|
|
||||||
|
|
@ -16,68 +16,108 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { prefs_default } from '../../options/mzta-options-default.js';
|
import {
|
||||||
|
prefs_default,
|
||||||
|
integration_options_config
|
||||||
|
} from '../../options/mzta-options-default.js';
|
||||||
import { taLogger } from '../../js/mzta-logger.js';
|
import { taLogger } from '../../js/mzta-logger.js';
|
||||||
import { getSpecialPrompts, setSpecialPrompts } from "../../js/mzta-prompts.js";
|
import {
|
||||||
|
getSpecialPrompts,
|
||||||
|
setSpecialPrompts
|
||||||
|
} from "../../js/mzta-prompts.js";
|
||||||
import {
|
import {
|
||||||
getPlaceholders,
|
getPlaceholders,
|
||||||
mapPlaceholderToSuggestion
|
mapPlaceholderToSuggestion
|
||||||
} from "../../js/mzta-placeholders.js";
|
} from "../../js/mzta-placeholders.js";
|
||||||
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
||||||
import { isAPIKeyValue } from "../../js/mzta-utils.js";
|
import {
|
||||||
|
isAPIKeyValue,
|
||||||
|
setTomSelectBorder
|
||||||
|
} from "../../js/mzta-utils.js";
|
||||||
|
import {
|
||||||
|
initializeSpecificIntegrationUI
|
||||||
|
} from "../_lib/connection-ui.js";
|
||||||
|
|
||||||
let autocompleteSuggestions = [];
|
let autocompleteSuggestions = [];
|
||||||
let taLog = new taLogger("mzta-get-calendar-event-page",true);
|
let taLog = new taLogger("mzta-get-task-page",true);
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', async () => {
|
document.addEventListener('DOMContentLoaded', async () => {
|
||||||
|
|
||||||
|
let specialPrompts = await getSpecialPrompts();
|
||||||
|
let get_task_prompt = specialPrompts.find(prompt => prompt.id === 'prompt_get_task');
|
||||||
|
|
||||||
|
if (get_task_prompt && get_task_prompt.api_type && get_task_prompt.api_type !== '') {
|
||||||
|
let update_prefs = {};
|
||||||
|
update_prefs['get_task_connection_type'] = get_task_prompt.api_type;
|
||||||
|
|
||||||
|
let integration = get_task_prompt.api_type.replace('_api', '');
|
||||||
|
if (integration_options_config && integration_options_config[integration]) {
|
||||||
|
for (const key of Object.keys(integration_options_config[integration])) {
|
||||||
|
if (get_task_prompt[key] !== undefined) {
|
||||||
|
update_prefs[`get_task_${integration}_${key}`] = get_task_prompt[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await browser.storage.sync.set(update_prefs);
|
||||||
|
}
|
||||||
|
|
||||||
|
await initializeSpecificIntegrationUI({
|
||||||
|
prefix: 'get_task',
|
||||||
|
promptId: 'prompt_get_task',
|
||||||
|
taLog: taLog,
|
||||||
|
restoreOptionsCallback: restoreOptions
|
||||||
|
});
|
||||||
|
|
||||||
i18n.updateDocument();
|
i18n.updateDocument();
|
||||||
await restoreOptions();
|
|
||||||
|
|
||||||
document.querySelectorAll(".option-input").forEach(element => {
|
document.querySelectorAll(".option-input").forEach(element => {
|
||||||
element.addEventListener("change", saveOptions);
|
element.addEventListener("change", saveOptions);
|
||||||
});
|
});
|
||||||
|
|
||||||
let get_calendar_event_textarea = document.getElementById('get_task_prompt_text');
|
let get_task_textarea = document.getElementById('get_task_prompt_text');
|
||||||
let get_calendar_event_save_btn = document.getElementById('btn_save_prompt');
|
let get_task_save_btn = document.getElementById('btn_save_prompt');
|
||||||
let get_calendar_event_reset_btn = document.getElementById('btn_reset_prompt');
|
let get_task_reset_btn = document.getElementById('btn_reset_prompt');
|
||||||
|
let get_task_use_specific_integration = document.getElementById('get_task_use_specific_integration');
|
||||||
|
|
||||||
let specialPrompts = await getSpecialPrompts();
|
get_task_textarea.addEventListener('input', (event) => {
|
||||||
let get_calendar_event_prompt = specialPrompts.find(prompt => prompt.id === 'prompt_get_task');
|
get_task_reset_btn.disabled = (event.target.value === browser.i18n.getMessage('prompt_get_task_full_text'));
|
||||||
|
get_task_save_btn.disabled = (event.target.value === get_task_prompt.text);
|
||||||
get_calendar_event_textarea.addEventListener('input', (event) => {
|
if(get_task_save_btn.disabled){
|
||||||
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');
|
document.getElementById('get_task_prompt_unsaved').classList.add('hidden');
|
||||||
} else {
|
} else {
|
||||||
document.getElementById('get_task_prompt_unsaved').classList.remove('hidden');
|
document.getElementById('get_task_prompt_unsaved').classList.remove('hidden');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
get_calendar_event_reset_btn.addEventListener('click', () => {
|
get_task_use_specific_integration.addEventListener('change', (event) => {
|
||||||
get_calendar_event_textarea.value = browser.i18n.getMessage('prompt_get_task_full_text');
|
if (!event.target.checked) {
|
||||||
get_calendar_event_reset_btn.disabled = true;
|
browser.storage.sync.set({ get_task_connection_type: '' });
|
||||||
let event = new Event('input', { bubbles: true, cancelable: true });
|
}
|
||||||
get_calendar_event_textarea.dispatchEvent(event);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
get_calendar_event_save_btn.addEventListener('click', () => {
|
get_task_reset_btn.addEventListener('click', () => {
|
||||||
specialPrompts.find(prompt => prompt.id === 'prompt_get_task').text = get_calendar_event_textarea.value;
|
get_task_textarea.value = browser.i18n.getMessage('prompt_get_task_full_text');
|
||||||
|
get_task_reset_btn.disabled = true;
|
||||||
|
let event = new Event('input', { bubbles: true, cancelable: true });
|
||||||
|
get_task_textarea.dispatchEvent(event);
|
||||||
|
});
|
||||||
|
|
||||||
|
get_task_save_btn.addEventListener('click', () => {
|
||||||
|
specialPrompts.find(prompt => prompt.id === 'prompt_get_task').text = get_task_textarea.value;
|
||||||
setSpecialPrompts(specialPrompts);
|
setSpecialPrompts(specialPrompts);
|
||||||
get_calendar_event_save_btn.disabled = true;
|
get_task_save_btn.disabled = true;
|
||||||
document.getElementById('get_task_prompt_unsaved').classList.add('hidden');
|
document.getElementById('get_task_prompt_unsaved').classList.add('hidden');
|
||||||
browser.runtime.sendMessage({command: "reload_menus"});
|
browser.runtime.sendMessage({command: "reload_menus"});
|
||||||
});
|
});
|
||||||
|
|
||||||
if(get_calendar_event_prompt.text === 'prompt_get_task_full_text'){
|
if(get_task_prompt.text === 'prompt_get_task_full_text'){
|
||||||
get_calendar_event_prompt.text = browser.i18n.getMessage(get_calendar_event_prompt.text);
|
get_task_prompt.text = browser.i18n.getMessage(get_task_prompt.text);
|
||||||
}
|
}
|
||||||
get_calendar_event_textarea.value = get_calendar_event_prompt.text;
|
get_task_textarea.value = get_task_prompt.text;
|
||||||
get_calendar_event_reset_btn.disabled = (get_calendar_event_textarea.value === browser.i18n.getMessage('prompt_get_task_full_text'));
|
get_task_reset_btn.disabled = (get_task_textarea.value === browser.i18n.getMessage('prompt_get_task_full_text'));
|
||||||
|
|
||||||
autocompleteSuggestions = (await getPlaceholders(true)).filter(p => !(p.id === 'additional_text')).map(mapPlaceholderToSuggestion);
|
autocompleteSuggestions = (await getPlaceholders(true)).filter(p => !(p.id === 'additional_text')).map(mapPlaceholderToSuggestion);
|
||||||
textareaAutocomplete(get_calendar_event_textarea, autocompleteSuggestions, 1); // type_value = 1, only when reading an email
|
textareaAutocomplete(get_task_textarea, autocompleteSuggestions, 1); // type_value = 1, only when reading an email
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -97,8 +137,8 @@ function saveOptions(e) {
|
||||||
case 'number':
|
case 'number':
|
||||||
options[element.id] = element.valueAsNumber;
|
options[element.id] = element.valueAsNumber;
|
||||||
break;
|
break;
|
||||||
case 'text':
|
case 'text':
|
||||||
case 'password':
|
case 'password':
|
||||||
options[element.id] = element.value.trim();
|
options[element.id] = element.value.trim();
|
||||||
break;
|
break;
|
||||||
case 'select-one':
|
case 'select-one':
|
||||||
|
|
@ -114,6 +154,7 @@ function saveOptions(e) {
|
||||||
async function restoreOptions() {
|
async function restoreOptions() {
|
||||||
function setCurrentChoice(result) {
|
function setCurrentChoice(result) {
|
||||||
document.querySelectorAll(".option-input").forEach(element => {
|
document.querySelectorAll(".option-input").forEach(element => {
|
||||||
|
if(!element.id) return;
|
||||||
taLog.log("Options restoring " + element.id + " = " + (isAPIKeyValue(element.id) ? "****************" : result[element.id]));
|
taLog.log("Options restoring " + element.id + " = " + (isAPIKeyValue(element.id) ? "****************" : result[element.id]));
|
||||||
switch (element.type) {
|
switch (element.type) {
|
||||||
case 'checkbox':
|
case 'checkbox':
|
||||||
|
|
@ -131,15 +172,28 @@ async function restoreOptions() {
|
||||||
if(element.id == 'default_chatgpt_lang') default_text_value = prefs_default.default_chatgpt_lang;
|
if(element.id == 'default_chatgpt_lang') default_text_value = prefs_default.default_chatgpt_lang;
|
||||||
element.value = result[element.id] || default_text_value;
|
element.value = result[element.id] || default_text_value;
|
||||||
break;
|
break;
|
||||||
|
case 'textarea':
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (element.tagName === 'SELECT') {
|
if (element.tagName === 'SELECT') {
|
||||||
let default_select_value = '';
|
let default_select_value = '';
|
||||||
if(element.id == 'reply_type') default_select_value = 'reply_all';
|
const restoreValue = result[element.id] || default_select_value;
|
||||||
if(element.id == 'connection_type') default_select_value = 'chatgpt_web';
|
// Check if option exists
|
||||||
element.value = result[element.id] || default_select_value;
|
let optionExists = Array.from(element.options).some(opt => opt.value === restoreValue);
|
||||||
if (element.value === '') {
|
// If it doesn't exist and restoreValue is not empty, create it
|
||||||
element.selectedIndex = -1;
|
if (!optionExists && restoreValue !== '') {
|
||||||
}
|
let newOption = new Option(restoreValue, restoreValue);
|
||||||
|
element.add(newOption);
|
||||||
|
}
|
||||||
|
// Set value
|
||||||
|
element.value = restoreValue;
|
||||||
|
if (element.value === '') {
|
||||||
|
element.selectedIndex = -1;
|
||||||
|
}
|
||||||
|
if (element.tomselect) {
|
||||||
|
element.tomselect.setValue(element.value, true);
|
||||||
|
setTomSelectBorder(element.tomselect);
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
console.error("[ThunderAI] Unhandled input type:", element.type);
|
console.error("[ThunderAI] Unhandled input type:", element.type);
|
||||||
}
|
}
|
||||||
|
|
@ -148,5 +202,27 @@ async function restoreOptions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
let getting = await browser.storage.sync.get(prefs_default);
|
let getting = await browser.storage.sync.get(prefs_default);
|
||||||
|
|
||||||
|
let specialPrompts = await getSpecialPrompts();
|
||||||
|
let get_task_prompt = specialPrompts.find(prompt => prompt.id === 'prompt_get_task');
|
||||||
|
|
||||||
|
if (get_task_prompt) {
|
||||||
|
if (get_task_prompt.api_type && get_task_prompt.api_type !== '') {
|
||||||
|
getting['get_task_connection_type'] = get_task_prompt.api_type;
|
||||||
|
} else {
|
||||||
|
getting['get_task_connection_type'] = getting['connection_type'];
|
||||||
|
}
|
||||||
|
for (const [integration, options] of Object.entries(integration_options_config)) {
|
||||||
|
for (const key of Object.keys(options)) {
|
||||||
|
const propName = `${integration}_${key}`;
|
||||||
|
if (get_task_prompt[propName] !== undefined && get_task_prompt[propName] !== '') {
|
||||||
|
getting[`get_task_${propName}`] = get_task_prompt[propName];
|
||||||
|
} else {
|
||||||
|
getting[`get_task_${propName}`] = getting[propName];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setCurrentChoice(getting);
|
setCurrentChoice(getting);
|
||||||
}
|
}
|
||||||
|
|
@ -36,14 +36,15 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="spamfilter_tr">
|
<tr class="spamfilter_tr">
|
||||||
<td><span class="opt_title">__MSG_prefs_OptionText_spamfilter_context_menu__</span></td>
|
<td><span class="opt_title">__MSG_prefs_OptionText_spamfilter_show_msg_panel__</span></td>
|
||||||
<td>
|
<td>
|
||||||
<label>
|
<label>
|
||||||
<input type="checkbox" id="spamfilter_context_menu" name="spamfilter_context_menu" class="option-input" />
|
<input type="checkbox" id="spamfilter_show_msg_panel" name="spamfilter_show_msg_panel" class="option-input" />
|
||||||
__MSG_prefs_OptionText_spamfilter_context_menu_Info__
|
__MSG_prefs_OptionText_spamfilter_show_msg_panel_Info__
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
</table>
|
</table>
|
||||||
<div id="spamfilter_container">
|
<div id="spamfilter_container">
|
||||||
<span class="section_title">__MSG_SpamFilter_prompt_text_title__</span><span id="spamfilter_prompt_unsaved" class="unsaved hidden"> __MSG_customPrompts_unsaved_changes__</span>
|
<span class="section_title">__MSG_SpamFilter_prompt_text_title__</span><span id="spamfilter_prompt_unsaved" class="unsaved hidden"> __MSG_customPrompts_unsaved_changes__</span>
|
||||||
|
|
@ -65,7 +66,8 @@
|
||||||
<button type="button" id="accounts_deselect_all">__MSG_DeselectAll__</button>
|
<button type="button" id="accounts_deselect_all">__MSG_DeselectAll__</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="spamfitler_reports_container">
|
<div id="spamfitler_reports_container">
|
||||||
<h2>__MSG_SpamReport_Title__</h2>
|
<div><span class="section_title">__MSG_SpamReport_Title__</span>
|
||||||
|
<br><span class="infoline">__MSG_SpamReport_infoline__</span></div>
|
||||||
<table id="report_data">
|
<table id="report_data">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,11 @@ import {
|
||||||
} from "../../js/mzta-placeholders.js";
|
} from "../../js/mzta-placeholders.js";
|
||||||
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
||||||
import { taSpamReport } from '../../js/mzta-spamreport.js';
|
import { taSpamReport } from '../../js/mzta-spamreport.js';
|
||||||
import { getAccountsList, isAPIKeyValue } from "../../js/mzta-utils.js";
|
import {
|
||||||
|
getAccountsList,
|
||||||
|
isAPIKeyValue,
|
||||||
|
setTomSelectBorder
|
||||||
|
} from "../../js/mzta-utils.js";
|
||||||
import {
|
import {
|
||||||
initializeSpecificIntegrationUI
|
initializeSpecificIntegrationUI
|
||||||
} from "../_lib/connection-ui.js";
|
} from "../_lib/connection-ui.js";
|
||||||
|
|
@ -240,7 +244,7 @@ async function loadSpamReport(){
|
||||||
row.appendChild(tdSpamValue);
|
row.appendChild(tdSpamValue);
|
||||||
|
|
||||||
const tdMoved = document.createElement("td");
|
const tdMoved = document.createElement("td");
|
||||||
tdMoved.textContent = (report.moved ? browser.i18n.getMessage("spamfilter_moved") : browser.i18n.getMessage("spamfilter_not_moved")) + ` (${report.SpamThreshold})`;
|
tdMoved.textContent = (report.moved ? browser.i18n.getMessage("yes_string") : browser.i18n.getMessage("no_string")) + ` (${report.SpamThreshold})`;
|
||||||
row.appendChild(tdMoved);
|
row.appendChild(tdMoved);
|
||||||
|
|
||||||
const tdExplanation = document.createElement("td");
|
const tdExplanation = document.createElement("td");
|
||||||
|
|
@ -290,6 +294,7 @@ function saveOptions(e) {
|
||||||
async function restoreOptions() {
|
async function restoreOptions() {
|
||||||
function setCurrentChoice(result) {
|
function setCurrentChoice(result) {
|
||||||
document.querySelectorAll(".option-input").forEach(element => {
|
document.querySelectorAll(".option-input").forEach(element => {
|
||||||
|
if(!element.id) return;
|
||||||
taLog.log("Options restoring " + element.id + " = " + (isAPIKeyValue(element.id) ? "****************" : result[element.id]));
|
taLog.log("Options restoring " + element.id + " = " + (isAPIKeyValue(element.id) ? "****************" : result[element.id]));
|
||||||
switch (element.type) {
|
switch (element.type) {
|
||||||
case 'checkbox':
|
case 'checkbox':
|
||||||
|
|
@ -325,6 +330,10 @@ async function restoreOptions() {
|
||||||
if (element.value === '') {
|
if (element.value === '') {
|
||||||
element.selectedIndex = -1;
|
element.selectedIndex = -1;
|
||||||
}
|
}
|
||||||
|
if (element.tomselect) {
|
||||||
|
element.tomselect.setValue(element.value, true);
|
||||||
|
setTomSelectBorder(element.tomselect);
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
console.error("[ThunderAI] Unhandled input type:", element.type);
|
console.error("[ThunderAI] Unhandled input type:", element.type);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
193
pages/summarize/mzta-summarize.css
Normal file
193
pages/summarize/mzta-summarize.css
Normal file
|
|
@ -0,0 +1,193 @@
|
||||||
|
#summarize_prompt_container {
|
||||||
|
width: 90%;
|
||||||
|
margin: 20px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#summarize_email_template_text {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#summarize_prompt_text {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#summarize_email_separator_text {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.infoline {
|
||||||
|
font-size: 0.8em;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
#account_selector_container{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#account_selector_checkboxes{
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid gray;
|
||||||
|
width: 24em;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specific_integration{
|
||||||
|
background-color: #dfeaff;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-collapse: separate;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group td {
|
||||||
|
border-top: none;
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specific_integration_sub td:first-child {
|
||||||
|
border-left: 10px solid #dfeaff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specific_integration_sub td:last-child {
|
||||||
|
border-right: 10px solid #dfeaff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#connection_ui_end td{
|
||||||
|
height: 6px;
|
||||||
|
background-color: #dfeaff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#connection_ui_end{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.addtags_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
label:has(input[type="checkbox"]) {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summarize_auto{
|
||||||
|
background-color: #415c35;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specific_integration{
|
||||||
|
background-color: #2E3A4F;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specific_integration_sub td:first-child {
|
||||||
|
border-left: 10px solid #2E3A4F;
|
||||||
|
}
|
||||||
|
|
||||||
|
.specific_integration_sub td:last-child {
|
||||||
|
border-right: 10px solid #2E3A4F;
|
||||||
|
}
|
||||||
|
|
||||||
|
#connection_ui_end td{
|
||||||
|
background-color: #2E3A4F;
|
||||||
|
}
|
||||||
|
}
|
||||||
123
pages/summarize/mzta-summarize.html
Normal file
123
pages/summarize/mzta-summarize.html
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>ThunderAI - __MSG_Summarize_PageTitle__</title>
|
||||||
|
<link rel="stylesheet" href="mzta-summarize.css" />
|
||||||
|
<link rel="stylesheet" href="../_lib/connection-ui.css">
|
||||||
|
<link rel="icon" href="../../images/icon-16px.png" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<h1 class="page_title">__MSG_Summarize_PageTitle__</h1>
|
||||||
|
<p>__MSG_Summarize_info_default__</p>
|
||||||
|
</div>
|
||||||
|
<div class="summarize_table_title section_title">__MSG_Summarize_prompt_prefs_title__</div>
|
||||||
|
<table id="miczPrefs">
|
||||||
|
<tr class="summarize_tr specific_integration">
|
||||||
|
<td><span class="opt_title">__MSG_prefs_OptionText_use_specific_integration__</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" id="summarize_use_specific_integration" name="summarize_use_specific_integration" class="option-input" />
|
||||||
|
__MSG_prefs_OptionText_summarize_use_specific_integration_Info__
|
||||||
|
</label>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr id="connection_ui_anchor"></tr>
|
||||||
|
<tr id="connection_ui_end"><td colspan="2"></td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- PROMPTS -->
|
||||||
|
<div id="summarize_prompt_container">
|
||||||
|
<!--title and description-->
|
||||||
|
<span class="section_title">
|
||||||
|
__MSG_Summarize_prompt_text_title__
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<span class="infoline">
|
||||||
|
__MSG_prefs_OptionText_btnManagePrompts_infoline__
|
||||||
|
<a href="https://micz.it/thunderbird-addon-thunderai/data-placeholders/">
|
||||||
|
__MSG_more_info_string__
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<b>__MSG_prefs_OptionText_Summarize_infoline2__</b>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<!--main prompt-->
|
||||||
|
<span class="infoline">
|
||||||
|
__MSG_prefs_OptionText_Summarize_main_prompt__
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<div class="autocomplete-container">
|
||||||
|
<textarea id="summarize_prompt_text" rows="15"></textarea>
|
||||||
|
<ul class="autocomplete-list hidden"></ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="summarize_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>
|
||||||
|
|
||||||
|
<!--email template-->
|
||||||
|
<span class="infoline">
|
||||||
|
__MSG_prefs_OptionText_Summarize_email_template__
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<div class="autocomplete-container">
|
||||||
|
<textarea id="summarize_email_template_text" rows="15"></textarea>
|
||||||
|
<ul class="autocomplete-list hidden"></ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="summarize_info_additional_statements"></div>
|
||||||
|
<div class="btn_div">
|
||||||
|
<button id="btn_reset_email_template" disabled>
|
||||||
|
__MSG_reset_default__
|
||||||
|
</button>
|
||||||
|
<button id="btn_save_email_template" disabled>
|
||||||
|
__MSG_save__
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- separator -->
|
||||||
|
<span class="infoline">
|
||||||
|
__MSG_prefs_OptionText_Summarize_email_separator__
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<div class="autocomplete-container">
|
||||||
|
<textarea id="summarize_email_separator_text" rows="7"></textarea>
|
||||||
|
<ul class="autocomplete-list hidden"></ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="summarize_info_additional_statements"></div>
|
||||||
|
<div class="btn_div">
|
||||||
|
<button id="btn_reset_email_separator" disabled>
|
||||||
|
__MSG_reset_default__
|
||||||
|
</button>
|
||||||
|
<button id="btn_save_email_separator" disabled>
|
||||||
|
__MSG_save__
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<script src="mzta-summarize.js" type="module"></script>
|
||||||
|
<script src="../../js/mzta-i18n.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
282
pages/summarize/mzta-summarize.js
Normal file
282
pages/summarize/mzta-summarize.js
Normal file
|
|
@ -0,0 +1,282 @@
|
||||||
|
/*
|
||||||
|
* 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, integration_options_config } from '../../options/mzta-options-default.js';
|
||||||
|
import { taLogger } from "../../js/mzta-logger.js";
|
||||||
|
import {
|
||||||
|
getSpecialPrompts,
|
||||||
|
setSpecialPrompts
|
||||||
|
} from "../../js/mzta-prompts.js";
|
||||||
|
import {
|
||||||
|
getPlaceholders,
|
||||||
|
mapPlaceholderToSuggestion
|
||||||
|
} from "../../js/mzta-placeholders.js";
|
||||||
|
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
||||||
|
import {
|
||||||
|
getAccountsList,
|
||||||
|
normalizeStringList,
|
||||||
|
isAPIKeyValue
|
||||||
|
} from "../../js/mzta-utils.js";
|
||||||
|
import {
|
||||||
|
initializeSpecificIntegrationUI
|
||||||
|
} from "../_lib/connection-ui.js";
|
||||||
|
|
||||||
|
let autocompleteSuggestions = [];
|
||||||
|
let taLog = new taLogger("mzta-summarize-page", true);
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", async () => {
|
||||||
|
|
||||||
|
let specialPrompts = await getSpecialPrompts();
|
||||||
|
let summarize_prompt = specialPrompts.find((prompt) => prompt.id === 'prompt_summarize');
|
||||||
|
let summarize_email_template = specialPrompts.find((prompt) => prompt.id === 'prompt_summarize_email_template');
|
||||||
|
let summarize_email_separator = specialPrompts.find((prompt) => prompt.id === 'prompt_summarize_email_separator');
|
||||||
|
|
||||||
|
if (summarize_prompt && summarize_prompt.api_type && summarize_prompt.api_type !== '') {
|
||||||
|
let update_prefs = {};
|
||||||
|
update_prefs['summarize_connection_type'] = summarize_prompt.api_type;
|
||||||
|
|
||||||
|
let integration = summarize_prompt.api_type.replace('_api', '');
|
||||||
|
if (integration_options_config && integration_options_config[integration]) {
|
||||||
|
for (const key of Object.keys(integration_options_config[integration])) {
|
||||||
|
if (summarize_prompt[key] !== undefined) {
|
||||||
|
update_prefs[`summarize_${integration}_${key}`] = summarize_prompt[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await browser.storage.sync.set(update_prefs);
|
||||||
|
}
|
||||||
|
|
||||||
|
await initializeSpecificIntegrationUI({
|
||||||
|
prefix: 'summarize',
|
||||||
|
promptId: 'prompt_summarize',
|
||||||
|
taLog: taLog,
|
||||||
|
restoreOptionsCallback: restoreOptions
|
||||||
|
});
|
||||||
|
|
||||||
|
i18n.updateDocument();
|
||||||
|
|
||||||
|
document.querySelectorAll(".option-input").forEach(element => {
|
||||||
|
element.addEventListener("change", saveOptions);
|
||||||
|
});
|
||||||
|
let prefs_summarize = await browser.storage.sync.get({ summarize_enabled_accounts: [], connection_type: 'chatgpt_web' });
|
||||||
|
|
||||||
|
let summarize_textarea = document.getElementById("summarize_prompt_text");
|
||||||
|
let summarize_save_btn = document.getElementById("btn_save_prompt");
|
||||||
|
let summarize_reset_btn = document.getElementById("btn_reset_prompt");
|
||||||
|
let summarize_textarea_email_template = document.getElementById("summarize_email_template_text");
|
||||||
|
let summarize_reset_email_template_btn = document.getElementById("btn_reset_email_template");
|
||||||
|
let summarize_save_email_template_btn = document.getElementById("btn_save_email_template");
|
||||||
|
let summarize_email_separator_textarea = document.getElementById("summarize_email_separator_text");
|
||||||
|
let summarize_email_separator_save_btn = document.getElementById("btn_save_email_separator");
|
||||||
|
let summarize_email_separator_reset_btn = document.getElementById("btn_reset_email_separator");
|
||||||
|
|
||||||
|
|
||||||
|
// on changing textareas
|
||||||
|
summarize_textarea.addEventListener("input", (event) => {
|
||||||
|
summarize_reset_btn.disabled = (event.target.value === browser.i18n.getMessage('prompt_summarize_full_text'));
|
||||||
|
summarize_save_btn.disabled = (event.target.value === summarize_prompt.text);
|
||||||
|
});
|
||||||
|
|
||||||
|
summarize_textarea_email_template.addEventListener("input", (event) => {
|
||||||
|
summarize_reset_email_template_btn.disabled = (event.target.value === browser.i18n.getMessage('prompt_summarize_email_template_full_text'));
|
||||||
|
summarize_save_email_template_btn.disabled = (event.target.value === summarize_email_template.text);
|
||||||
|
});
|
||||||
|
|
||||||
|
summarize_email_separator_textarea.addEventListener("input", (event) => {
|
||||||
|
summarize_email_separator_reset_btn.disabled = (event.target.value === browser.i18n.getMessage('prompt_summarize_email_separator_full_text'));
|
||||||
|
summarize_email_separator_save_btn.disabled = (event.target.value === summarize_email_separator.text);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// on clicking buttons, reset
|
||||||
|
summarize_reset_email_template_btn.addEventListener("click", () => {
|
||||||
|
summarize_textarea_email_template.value = browser.i18n.getMessage("prompt_summarize_email_template_full_text");
|
||||||
|
summarize_reset_email_template_btn.disabled = true;
|
||||||
|
let event = new Event("input", { bubbles: true, cancelable: true });
|
||||||
|
summarize_textarea_email_template.dispatchEvent(event);
|
||||||
|
});
|
||||||
|
|
||||||
|
summarize_reset_btn.addEventListener("click", () => {
|
||||||
|
summarize_textarea.value = browser.i18n.getMessage("prompt_summarize_full_text");
|
||||||
|
summarize_reset_btn.disabled = true;
|
||||||
|
let event = new Event("input", { bubbles: true, cancelable: true });
|
||||||
|
summarize_textarea.dispatchEvent(event);
|
||||||
|
});
|
||||||
|
|
||||||
|
summarize_email_separator_reset_btn.addEventListener("click", () => {
|
||||||
|
summarize_email_separator_textarea.value = browser.i18n.getMessage("prompt_summarize_email_separator_full_text");
|
||||||
|
summarize_email_separator_reset_btn.disabled = true;
|
||||||
|
let event = new Event("input", { bubbles: true, cancelable: true });
|
||||||
|
summarize_email_separator_textarea.dispatchEvent(event);
|
||||||
|
});
|
||||||
|
|
||||||
|
// on clicking buttons, save
|
||||||
|
summarize_save_email_template_btn.addEventListener("click", () => {
|
||||||
|
specialPrompts.find(prompt => prompt.id === 'prompt_summarize_email_template').text = summarize_textarea_email_template.value;
|
||||||
|
setSpecialPrompts(specialPrompts);
|
||||||
|
summarize_save_email_template_btn.disabled = true;
|
||||||
|
browser.runtime.sendMessage({ command: "reload_menus" });
|
||||||
|
});
|
||||||
|
|
||||||
|
summarize_save_btn.addEventListener("click", () => {
|
||||||
|
specialPrompts.find(prompt => prompt.id === 'prompt_summarize').text = summarize_textarea.value;
|
||||||
|
setSpecialPrompts(specialPrompts);
|
||||||
|
summarize_save_btn.disabled = true;
|
||||||
|
browser.runtime.sendMessage({ command: "reload_menus" });
|
||||||
|
});
|
||||||
|
|
||||||
|
summarize_email_separator_save_btn.addEventListener("click", () => {
|
||||||
|
specialPrompts.find(prompt => prompt.id === 'prompt_summarize_email_separator').text = summarize_email_separator_textarea.value;
|
||||||
|
setSpecialPrompts(specialPrompts);
|
||||||
|
summarize_email_separator_save_btn.disabled = true;
|
||||||
|
browser.runtime.sendMessage({ command: "reload_menus" });
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
if(summarize_prompt.text === 'prompt_summarize_full_text'){
|
||||||
|
summarize_prompt.text = browser.i18n.getMessage(summarize_prompt.text);
|
||||||
|
}
|
||||||
|
if(summarize_email_template.text === 'prompt_summarize_email_template_full_text'){
|
||||||
|
summarize_email_template.text = browser.i18n.getMessage(summarize_email_template.text);
|
||||||
|
}
|
||||||
|
if(summarize_email_separator.text === 'prompt_summarize_email_separator_full_text'){
|
||||||
|
summarize_email_separator.text = browser.i18n.getMessage(summarize_email_separator.text);
|
||||||
|
}
|
||||||
|
|
||||||
|
summarize_textarea_email_template.value = summarize_email_template.text;
|
||||||
|
summarize_reset_email_template_btn.disabled = (summarize_textarea_email_template.value === browser.i18n.getMessage("prompt_summarize_email_template_full_text"));
|
||||||
|
summarize_textarea.value = summarize_prompt.text;
|
||||||
|
summarize_reset_btn.disabled = (summarize_textarea.value === browser.i18n.getMessage("prompt_summarize_full_text"));
|
||||||
|
summarize_email_separator_textarea.value = summarize_email_separator.text;
|
||||||
|
summarize_email_separator_reset_btn.disabled = (summarize_email_separator_textarea.value === browser.i18n.getMessage("prompt_summarize_email_separator_full_text"));
|
||||||
|
|
||||||
|
autocompleteSuggestions = (await getPlaceholders(true))
|
||||||
|
.filter((p) => p.id !== "additional_text")
|
||||||
|
.map(mapPlaceholderToSuggestion);
|
||||||
|
|
||||||
|
textareaAutocomplete(summarize_textarea, autocompleteSuggestions, 1);
|
||||||
|
textareaAutocomplete(summarize_textarea_email_template, autocompleteSuggestions, 1);
|
||||||
|
textareaAutocomplete(summarize_email_separator_textarea, autocompleteSuggestions, 1);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// Methods to manage options, derived from: /options/mzta-options.js
|
||||||
|
|
||||||
|
function saveOptions(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
let options = {};
|
||||||
|
let element = e.target;
|
||||||
|
// console.log(">>>>>>>>>> Saving option: " + element.id + " = " + element.value);
|
||||||
|
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;
|
||||||
|
case 'select-one':
|
||||||
|
// console.log(">>>>>>>>>> Saving option [select-one]: " + element.id + " = " + element.value);
|
||||||
|
options[element.id] = element.value;
|
||||||
|
break;
|
||||||
|
case 'textarea':
|
||||||
|
options[element.id] = normalizeStringList(element.value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
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 => {
|
||||||
|
if(!element.id) return;
|
||||||
|
taLog.log("Options restoring " + element.id + " = " + (isAPIKeyValue(element.id) ? "****************" : 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 'textarea':
|
||||||
|
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 = '';
|
||||||
|
const restoreValue = result[element.id] || default_select_value;
|
||||||
|
// Check if option exists
|
||||||
|
let optionExists = Array.from(element.options).some(opt => opt.value === restoreValue);
|
||||||
|
// If it doesn't exist and restoreValue is not empty, create it
|
||||||
|
if (!optionExists && restoreValue !== '') {
|
||||||
|
let newOption = new Option(restoreValue, restoreValue);
|
||||||
|
element.add(newOption);
|
||||||
|
}
|
||||||
|
// Set value
|
||||||
|
element.value = restoreValue;
|
||||||
|
if (element.value === '') {
|
||||||
|
element.selectedIndex = -1;
|
||||||
|
}
|
||||||
|
if (element.tomselect) {
|
||||||
|
element.tomselect.setValue(element.value, true);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
console.error("[ThunderAI] Unhandled input type:", element.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let getting = await browser.storage.sync.get(prefs_default);
|
||||||
|
|
||||||
|
let specialPrompts = await getSpecialPrompts();
|
||||||
|
let addtags_prompt = specialPrompts.find(prompt => prompt.id === 'prompt_summarize');
|
||||||
|
|
||||||
|
if (addtags_prompt) {
|
||||||
|
if (addtags_prompt.api_type && addtags_prompt.api_type !== '') {
|
||||||
|
getting['summarize_connection_type'] = addtags_prompt.api_type;
|
||||||
|
} else {
|
||||||
|
getting['summarize_connection_type'] = getting['connection_type'];
|
||||||
|
}
|
||||||
|
for (const [integration, options] of Object.entries(integration_options_config)) {
|
||||||
|
for (const key of Object.keys(options)) {
|
||||||
|
const propName = `${integration}_${key}`;
|
||||||
|
if (addtags_prompt[propName] !== undefined && addtags_prompt[propName] !== '') {
|
||||||
|
getting[`summarize_${propName}`] = addtags_prompt[propName];
|
||||||
|
} else {
|
||||||
|
getting[`summarize_${propName}`] = getting[propName];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setCurrentChoice(getting);
|
||||||
|
}
|
||||||
|
|
@ -30,6 +30,7 @@ let add_tags = false;
|
||||||
let add_tags_use_specific_integration = false;
|
let add_tags_use_specific_integration = false;
|
||||||
let add_tags_connection_type = '';
|
let add_tags_connection_type = '';
|
||||||
let get_calendar_event = false;
|
let get_calendar_event = false;
|
||||||
|
let get_calendar_event_from_clipboard = false;
|
||||||
let get_task = false;
|
let get_task = false;
|
||||||
let _ok_sparks = false;
|
let _ok_sparks = false;
|
||||||
let tabType;
|
let tabType;
|
||||||
|
|
@ -43,6 +44,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
add_tags_use_specific_integration: prefs_default.add_tags_use_specific_integration,
|
add_tags_use_specific_integration: prefs_default.add_tags_use_specific_integration,
|
||||||
add_tags_connection_type: prefs_default.add_tags_connection_type,
|
add_tags_connection_type: prefs_default.add_tags_connection_type,
|
||||||
get_calendar_event: prefs_default.get_calendar_event,
|
get_calendar_event: prefs_default.get_calendar_event,
|
||||||
|
get_calendar_event_from_clipboard: prefs_default.get_calendar_event_from_clipboard,
|
||||||
get_task: prefs_default.get_task,
|
get_task: prefs_default.get_task,
|
||||||
connection_type: prefs_default.connection_type
|
connection_type: prefs_default.connection_type
|
||||||
});
|
});
|
||||||
|
|
@ -66,6 +68,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
add_tags_use_specific_integration = prefs.add_tags_use_specific_integration;
|
add_tags_use_specific_integration = prefs.add_tags_use_specific_integration;
|
||||||
add_tags_connection_type = prefs.add_tags_connection_type;
|
add_tags_connection_type = prefs.add_tags_connection_type;
|
||||||
get_calendar_event = prefs.get_calendar_event;
|
get_calendar_event = prefs.get_calendar_event;
|
||||||
|
get_calendar_event_from_clipboard = prefs.get_calendar_event_from_clipboard;
|
||||||
get_task = prefs.get_task;
|
get_task = prefs.get_task;
|
||||||
_ok_sparks = await checkSparksPresence() == 1;
|
_ok_sparks = await checkSparksPresence() == 1;
|
||||||
// console.log(">>>>>>>>>>>>>>>>> add_tags: " + add_tags);
|
// console.log(">>>>>>>>>>>>>>>>> add_tags: " + add_tags);
|
||||||
|
|
@ -164,6 +167,7 @@ async function searchPrompt(allPrompts, tabId, tabType){
|
||||||
|
|
||||||
let do_add_tags = checkDoAddTags();
|
let do_add_tags = checkDoAddTags();
|
||||||
let do_get_calendar_event = checkDoCalendarEvent();
|
let do_get_calendar_event = checkDoCalendarEvent();
|
||||||
|
let do_get_calendar_event_from_clipboard = checkDoCalendarEventFromClipboard();
|
||||||
let do_get_task = checkDoTask();
|
let do_get_task = checkDoTask();
|
||||||
|
|
||||||
// console.log(">>>>>>>>>>> do_add_tags: " + do_add_tags);
|
// console.log(">>>>>>>>>>> do_add_tags: " + do_add_tags);
|
||||||
|
|
@ -171,7 +175,7 @@ async function searchPrompt(allPrompts, tabId, tabType){
|
||||||
// console.log(">>>>>>>>>>> do_get_task: " + do_get_task);
|
// console.log(">>>>>>>>>>> do_get_task: " + do_get_task);
|
||||||
// console.log(">>>>>>>>>>> filteredData: " + JSON.stringify(filteredData));
|
// 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);
|
num_special_menu_items = (do_add_tags ? 1 : 0) + (do_get_calendar_event ? 1 : 0) + (do_get_calendar_event_from_clipboard ? 1 : 0) + (do_get_task ? 1 : 0);
|
||||||
// console.log(">>>>>>>>>>>> num_special_menu_items: " + num_special_menu_items);
|
// console.log(">>>>>>>>>>>> num_special_menu_items: " + num_special_menu_items);
|
||||||
if(num_special_menu_items > 0){
|
if(num_special_menu_items > 0){
|
||||||
max_num_el -= num_special_menu_items;
|
max_num_el -= num_special_menu_items;
|
||||||
|
|
@ -192,10 +196,18 @@ async function searchPrompt(allPrompts, tabId, tabType){
|
||||||
filteredData[gce_curr_pos].numberPrepended = 'true';
|
filteredData[gce_curr_pos].numberPrepended = 'true';
|
||||||
filteredData[gce_curr_pos].label = gce_curr_pos + '. ' + filteredData[gce_curr_pos].label;
|
filteredData[gce_curr_pos].label = gce_curr_pos + '. ' + filteredData[gce_curr_pos].label;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if(do_get_calendar_event_from_clipboard){
|
||||||
|
filteredData = ensurePromptGetCalendarEventFromClipboardFirst(filteredData, do_add_tags, do_get_calendar_event);
|
||||||
|
let gcefc_curr_pos = (do_add_tags ? 1 : 0) + (do_get_calendar_event ? 1 : 0);
|
||||||
|
if (!filteredData[gcefc_curr_pos].numberPrepended) {
|
||||||
|
filteredData[gcefc_curr_pos].numberPrepended = 'true';
|
||||||
|
filteredData[gcefc_curr_pos].label = gcefc_curr_pos + '. ' + filteredData[gcefc_curr_pos].label;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(do_get_task){
|
if(do_get_task){
|
||||||
filteredData = ensurePromptGetTaskFirst(filteredData, do_add_tags, do_get_calendar_event);
|
filteredData = ensurePromptGetTaskFirst(filteredData, do_add_tags, do_get_calendar_event, do_get_calendar_event_from_clipboard);
|
||||||
let gtask_curr_pos = (do_add_tags ? 1 : 0) + (do_get_calendar_event ? 1 : 0);
|
let gtask_curr_pos = (do_add_tags ? 1 : 0) + (do_get_calendar_event ? 1 : 0) + (do_get_calendar_event_from_clipboard ? 1 : 0);
|
||||||
if (!filteredData[gtask_curr_pos].numberPrepended) {
|
if (!filteredData[gtask_curr_pos].numberPrepended) {
|
||||||
filteredData[gtask_curr_pos].numberPrepended = 'true';
|
filteredData[gtask_curr_pos].numberPrepended = 'true';
|
||||||
filteredData[gtask_curr_pos].label = gtask_curr_pos + '. ' + filteredData[gtask_curr_pos].label;
|
filteredData[gtask_curr_pos].label = gtask_curr_pos + '. ' + filteredData[gtask_curr_pos].label;
|
||||||
|
|
@ -222,7 +234,7 @@ async function searchPrompt(allPrompts, tabId, tabType){
|
||||||
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')||(item.id === 'prompt_get_calendar_event')||(item.id === 'prompt_get_task')){
|
if((item.id === 'prompt_add_tags')||(item.id === 'prompt_get_calendar_event')||(item.id === 'prompt_get_calendar_event_from_clipboard')||(item.id === 'prompt_get_task')){
|
||||||
itemDiv.className += ' special_prompt';
|
itemDiv.className += ' special_prompt';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -388,6 +400,10 @@ function checkDoCalendarEvent(){
|
||||||
return get_calendar_event && (connection_type !== "chatgpt_web" && tabType !== 'messageCompose') && _ok_sparks;
|
return get_calendar_event && (connection_type !== "chatgpt_web" && tabType !== 'messageCompose') && _ok_sparks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkDoCalendarEventFromClipboard(){
|
||||||
|
return get_calendar_event_from_clipboard && (connection_type !== "chatgpt_web" && tabType !== 'messageCompose') && _ok_sparks;
|
||||||
|
}
|
||||||
|
|
||||||
function checkDoTask(){
|
function checkDoTask(){
|
||||||
return get_task && (connection_type !== "chatgpt_web" && tabType !== 'messageCompose') && _ok_sparks;
|
return get_task && (connection_type !== "chatgpt_web" && tabType !== 'messageCompose') && _ok_sparks;
|
||||||
}
|
}
|
||||||
|
|
@ -424,18 +440,36 @@ function ensurePromptGetCalendarEventFirst(arr, do_add_tags) {
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensurePromptGetTaskFirst(arr, do_add_tags, do_get_calendar_event) {
|
function ensurePromptGetCalendarEventFromClipboardFirst(arr, do_add_tags, do_get_calendar_event) {
|
||||||
|
// Find the index of the object with id "prompt_get_calendar_event_from_clipboard"
|
||||||
|
const index = arr.findIndex(item => item.id === "prompt_get_calendar_event_from_clipboard");
|
||||||
|
|
||||||
|
const targetPosition = (do_add_tags ? 1 : 0) + (do_get_calendar_event ? 1 : 0);
|
||||||
|
|
||||||
|
// If found and needs repositioning
|
||||||
|
if (index !== -1 && index !== targetPosition) {
|
||||||
|
// Remove it from its current position
|
||||||
|
const [promptAddTags] = arr.splice(index, 1);
|
||||||
|
|
||||||
|
// Add it to the specified position
|
||||||
|
arr.splice(targetPosition, 0, promptAddTags);
|
||||||
|
}
|
||||||
|
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ensurePromptGetTaskFirst(arr, do_add_tags, do_get_calendar_event, do_get_calendar_event_from_clipboard) {
|
||||||
// Find the index of the object with id "prompt_get_task"
|
// Find the index of the object with id "prompt_get_task"
|
||||||
const index = arr.findIndex(item => item.id === "prompt_get_task");
|
const index = arr.findIndex(item => item.id === "prompt_get_task");
|
||||||
|
|
||||||
|
// Determine the target position to insert "prompt_get_task" after calendar
|
||||||
|
const targetPosition = (do_add_tags ? 1 : 0) + (do_get_calendar_event ? 1 : 0) + (do_get_calendar_event_from_clipboard ? 1 : 0);
|
||||||
|
|
||||||
// If found and needs repositioning
|
// 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))) {
|
if (index !== -1 && index !== targetPosition) {
|
||||||
// Remove it from its current position
|
// Remove it from its current position
|
||||||
const [promptGetTask] = arr.splice(index, 1);
|
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
|
// Add it to the specified position
|
||||||
arr.splice(targetPosition, 0, promptGetTask);
|
arr.splice(targetPosition, 0, promptGetTask);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue