commit
f3d82c53a9
38 changed files with 3524 additions and 270 deletions
14
CHANGELOG.md
14
CHANGELOG.md
|
|
@ -5,6 +5,20 @@
|
|||
|
||||
|
||||
|
||||
<h2>Version 3.0.0 - ??/??/2024</h2>
|
||||
<ul>
|
||||
<li><i>[ChatGPT API][Ollama API][OpenAI Comp API]</i> Added a special prompt to apply tag to emails [<a href="https://github.com/micz/ThunderAI/issues/183">#183</a>].</li>
|
||||
<li>Default prompts text has been translated [<a href="https://github.com/micz/ThunderAI/issues/185">#185</a>].</li>
|
||||
<li>Data placeholder <i>{%tags_full_list%}</i> for the full available tags list added [<a href="https://github.com/micz/ThunderAI/issues/197">#197</a>].</li>
|
||||
<li>Data placeholder <i>{%tags_current_email%}</i> for the single mail tags list added [<a href="https://github.com/micz/ThunderAI/issues/198">#198</a>].</li>
|
||||
<li>User <a href="https://forms.gle/1qK2wcbuhaRzhwyt9">survey link</a> added [<a href="https://github.com/micz/ThunderAI/issues/202">#202</a>].</li>
|
||||
<li><i>[OpenAI Comp API]</i> Added a button in the options page to manually insert the model [<a href="https://github.com/micz/ThunderAI/issues/205">#205</a>].</li>
|
||||
<li>Polish (pl) translation added, thanks to <a href="https://github.com/neexpl">neexpl</a>.</li>
|
||||
<li>The Custom Prompts tab has now an icon.</li>
|
||||
<li>The red border in the Custom Prompts configuration page that highlights a needed prompt configuration that is not selected is now removed when the corresponding placeholder is removed [<a href="https://github.com/micz/ThunderAI/issues/201">#201</a>].</li>
|
||||
<li>Minor bugs fixed.</li>
|
||||
<li>...</li>
|
||||
</ul>
|
||||
<h2>Version 2.3.4 - 06/12/2024</h2>
|
||||
<ul>
|
||||
<li><i>[ChatGPT API]</i> Correctly showwing an error message received from the ChatGPT API [<a href="https://github.com/micz/ThunderAI/issues/191">#191</a>].</li>
|
||||
|
|
|
|||
34
README.md
34
README.md
|
|
@ -14,11 +14,9 @@ It enables users to analyse, write, correct, and optimize their emails, facilita
|
|||
|
||||
ThunderAI is a tool for anyone looking to improve their email quality, both in content and grammar, making the writing process quicker and more intuitive.
|
||||
|
||||
You can also define, export and import your own **custom prompts**!
|
||||
[Find out how!](https://micz.it/thunderbird-addon-thunderai/custom-prompts/)
|
||||
You can also define, export and import your own **[custom prompts](https://micz.it/thunderbird-addon-thunderai/custom-prompts/)**!
|
||||
|
||||
In any custom prompt you can use additional **data placeholders**!
|
||||
[Find out how!](https://micz.it/thunderbird-addon-thunderai/data-placeholders/)
|
||||
In any custom prompt you can use additional **[data placeholders](https://micz.it/thunderbird-addon-thunderai/data-placeholders/)**!
|
||||
|
||||
|
||||
<br>
|
||||
|
|
@ -27,16 +25,16 @@ In any custom prompt you can use additional **data placeholders**!
|
|||
> [!TIP]
|
||||
> **Using ChatGPT**
|
||||
>
|
||||
> There is no need for an API key and is possibile to use this extension even with a free account, using the web interface!
|
||||
> There is no need for an API key and is possibile to use this extension even with a free account, using the **ChatGPT web interface**!
|
||||
>
|
||||
> Starting from version 2.0.0, if you want to connect with the OpenAI API integration, now you can use an API Key!
|
||||
> If you want to connect with the OpenAI API integration, instead, you can use an **API Key**!
|
||||
|
||||
<br>
|
||||
|
||||
> [!TIP]
|
||||
> **Using Ollama**
|
||||
>
|
||||
> From version 2.1.0 is possible to use a local Ollama server!
|
||||
> It's also possible to use a local Ollama server!
|
||||
>
|
||||
> Just remember to add `OLLAMA_ORIGINS = moz-extension://*` to the Ollama server environment variables.
|
||||
>
|
||||
|
|
@ -47,8 +45,9 @@ In any custom prompt you can use additional **data placeholders**!
|
|||
> [!TIP]
|
||||
> **Using an OpenAI Compatible API**
|
||||
>
|
||||
> From version 2.2.0 is possible to use a local OpenAI Compatible API server, like LM Studio!
|
||||
> There is also an option to remove the "v1" segment from the API url, if needed.
|
||||
> You can also use a local OpenAI Compatible API server, like LM Studio!
|
||||
>
|
||||
> There is also an option to remove the "v1" segment from the API url, if needed, and to manually set the model name if the server doesn't have a models list endpoint (like Gemini).
|
||||
|
||||
|
||||
<br>
|
||||
|
|
@ -83,16 +82,10 @@ Are you using this addon in your Thunderbird?
|
|||
- French (fr): Generated automatically
|
||||
- German (de): Generated automatically
|
||||
- Italian (it): [Mic](https://github.com/micz/)
|
||||
- Polski (pl): [neexpl](https://github.com/neexpl)
|
||||
- Português Brasileiro (pt-br): Bruno Pereira de Souza
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
### Miscellaneous
|
||||
- <a href="https://github.com/KudoAI/chatgpt.js">chatgpt.js</a> for providing methods to interact with the ChatGPT web frontend
|
||||
- <a href="https://github.com/ali-raheem/Aify">Aify</a> for inspiration
|
||||
- <a href="https://github.com/boxabirds">Julian Harris</a> for his project <a href="https://github.com/boxabirds/chatgpt-frontend-nobuild">chatgpt-frontend-nobuild</a>, that has been used as a starting point for the API Web Interface
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
|
|
@ -101,3 +94,12 @@ Are you using this addon in your Thunderbird?
|
|||
- <a href="https://loading.io">loading.io</a> for the dynamic menu loading SVG
|
||||
- [Fluent Design System](https://www.iconfinder.com/fluent-designsystem) for the Custom Prompts table sorting icons
|
||||
- [JessiGue](https://www.flaticon.com/authors/jessigue) for the show/hide icon for api key fields
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
### Miscellaneous
|
||||
- <a href="https://github.com/KudoAI/chatgpt.js">chatgpt.js</a> for providing methods to interact with the ChatGPT web frontend
|
||||
- <a href="https://github.com/boxabirds">Julian Harris</a> for his project <a href="https://github.com/boxabirds/chatgpt-frontend-nobuild">chatgpt-frontend-nobuild</a>, that has been used as a starting point for the API Web Interface
|
||||
- <a href="https://github.com/ali-raheem/Aify">Aify</a> for inspiration
|
||||
|
|
|
|||
|
|
@ -680,7 +680,11 @@
|
|||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_btnManagePrompts_infoline": {
|
||||
"message": "Sie können jetzt zusätzliche Datenplatzhalter verwenden!",
|
||||
"message": "Sie können zusätzliche Datenplatzhalter verwenden.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_btnManagePrompts_infoline2": {
|
||||
"message": "Sie können den Prompt nach Wunsch ändern, aber die Antwort der KI muss eine durch Kommas getrennte Liste von Tags sein!",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_openai_comp_use_v1": {
|
||||
|
|
@ -694,5 +698,201 @@
|
|||
"prefs_OptionText_owl_warning": {
|
||||
"message": "Es scheint, dass mindestens eines Ihrer Konten das Add-on Eule für Exchange verwendet. Es gibt ein bekanntes Problem zwischen Thunderbird und Eule, das derzeit behoben wird. Derzeit können Sie ThunderAI beim Verfassen von E-Mails verwenden, jedoch nicht beim Lesen.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatgpt_web_model_tooltip": {
|
||||
"message": "Klicken Sie auf einen Wert, um ihn festzulegen.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_reply_full_text": {
|
||||
"message": "Antworten Sie auf die folgende E-Mail. Antworten Sie nur mit dem benötigten Text und ohne zusätzliche Kommentare oder andere Texte.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_reply_additional_text": {
|
||||
"message": "Fügen Sie die Betreffzeile nicht zur Antwort hinzu.",
|
||||
"description": ""
|
||||
},
|
||||
"reply_same_lang": {
|
||||
"message": "Antworten Sie in derselben Sprache.",
|
||||
"description": ""
|
||||
},
|
||||
"sign_msg_as": {
|
||||
"message": "Unterzeichnen Sie die Nachricht als",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_reply_advanced_full_text": {
|
||||
"message": "Antworten Sie auf die folgende E-Mail \"{%selected_text%}\", unter Berücksichtigung, dass dies der vollständige E-Mail-Thread ist \"{%mail_html_body%}\". Antworten Sie nur mit dem benötigten Text und ohne zusätzliche Kommentare oder andere Texte.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_rewrite_full_text": {
|
||||
"message": "Schreiben Sie den folgenden Text höflicher um. Antworten Sie nur mit dem umgeschriebenen Text und ohne zusätzliche Kommentare oder andere Texte.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_rewrite_formal_full_text": {
|
||||
"message": "Schreiben Sie den folgenden Text formeller um. Antworten Sie nur mit dem umgeschriebenen Text und ohne zusätzliche Kommentare oder andere Texte.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_classify_full_text": {
|
||||
"message": "Klassifizieren Sie den folgenden Text nach Höflichkeit, Wärme, Formalität, Bestimmtheit und Anstößigkeit und geben Sie einen Prozentsatz für jede Kategorie an. Antworten Sie nur mit der Kategorie und der Punktzahl ohne zusätzliche Kommentare oder andere Texte.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_summarize_this_full_text": {
|
||||
"message": "Fassen Sie die folgende E-Mail in einer Liste mit Aufzählungspunkten zusammen.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_translate_this_full_text": {
|
||||
"message": "Übersetzen Sie die folgende E-Mail in",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_this_full_text": {
|
||||
"message": "Antworten Sie nur mit dem benötigten Text und ohne zusätzliche Kommentare oder andere Texte.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags": {
|
||||
"message": "Tags zu E-Mails hinzufügen",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_Info": {
|
||||
"message": "If checked, an item will be included in the menu to apply tags to emails.\nWenn aktiviert, wird ein Element im Menü hinzugefügt, um Tags auf E-Mails anzuwenden.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags": {
|
||||
"message": "Tags zu dieser E-Mail hinzufügen",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags_full_text": {
|
||||
"message": "Analysieren Sie den folgenden E-Mail-Text und erstellen Sie eine durch Kommas getrennte Liste von Tags, die den Inhalt zusammenfassen. Verwenden Sie Themen, Hauptthemen und relevante Beschreibungen als Tags. Stellen Sie sicher, dass die Tags prägnant und relevant für den Inhalt der E-Mail sind. E-Mail-Text: {%mail_text_body%} Berücksichtigen Sie die folgenden Details als Kontext: - Absender: {%author%} - Empfänger: {%recipients%} - CC-Liste: {%cc_list%} - E-Mail-Betreff: {%mail_subject%} Bitte basieren Sie Ihre Tags auf dem Text und Kontext der E-Mail und ignorieren Sie unnötige Informationen oder triviale Details. Die Ausgabe sollte nur eine Liste von durch Kommas getrennten Tags ohne zusätzlichen Kommentar oder Text sein.",
|
||||
"description": ""
|
||||
},
|
||||
"placeholder_tags_current_email": {
|
||||
"message": "E-Mail-Tags",
|
||||
"description": ""
|
||||
},
|
||||
"placeholder_tags_full_list": {
|
||||
"message": "Vorhandene Tags",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_maxnum": {
|
||||
"message": "Maximale Anzahl von Tags",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_maxnum_Info": {
|
||||
"message": "Die maximale Anzahl von Tags, die von der KI vorgeschlagen werden. Setzen Sie auf 0, wenn Sie die Anzahl der Tags nicht begrenzen möchten.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags_maxnum": {
|
||||
"message": "Die Anzahl der Tags begrenzen auf",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_hide_exclusions": {
|
||||
"message": "Ausgeschlossene Tags ausblenden",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_hide_exclusions_Info": {
|
||||
"message": "Wenn aktiviert, werden die Tags, die in der Ausschlussliste enthalten sind, im Bestätigungsdialog ausgeblendet.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_btnManageTagsInfo": {
|
||||
"message": "Tag-Einstellungen verwalten",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_PageTitle": {
|
||||
"message": "Tag-Einstellungen verwalten",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_info_default": {
|
||||
"message": "Auf dieser Seite können Sie den Standard-Prompt zum Hinzufügen von Tags zu E-Mails bearbeiten und die Ausschlussliste verwalten.",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_prompt_text_title": {
|
||||
"message": "Aktueller Prompt-Text",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_excl_list_title": {
|
||||
"message": "Ausschlussliste",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_excl_list_infoline": {
|
||||
"message": "Dies ist eine Liste von Tags, die nicht zu E-Mails hinzugefügt werden dürfen.",
|
||||
"description": ""
|
||||
},
|
||||
"save": {
|
||||
"message": "Speichern",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_info_additional_statements": {
|
||||
"message": "Diese Aussage wird am Ende des Prompts hinzugefügt:",
|
||||
"description": ""
|
||||
},
|
||||
"reset_default": {
|
||||
"message": "Auf Standard zurücksetzen",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_excl_list_infoline2": {
|
||||
"message": "Fügen Sie ein Wort pro Zeile oder durch ein Komma getrennt hinzu.",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_dialog_title": {
|
||||
"message": "Tags zur E-Mail hinzufügen",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_exclude_tag": {
|
||||
"message": "Tag ausschließen",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_no_tags_received": {
|
||||
"message": "Keine Tags von der KI erhalten.",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_no_valid_tags": {
|
||||
"message": "Nach der Filterung mit der Ausschlussliste wurden keine gültigen Tags gefunden.",
|
||||
"description": ""
|
||||
},
|
||||
"thunderai_error_title": {
|
||||
"message": "ThunderAI-Fehler",
|
||||
"description": ""
|
||||
},
|
||||
"thunderai_warning_title": {
|
||||
"message": "ThunderAI-Warnung",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_first_uppercase": {
|
||||
"message": "Erster Buchstabe groß",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_first_uppercase_Info": {
|
||||
"message": "Wenn aktiviert, wird die Tags-Beschriftung in Kleinbuchstaben mit nur dem ersten Buchstaben in Großbuchstaben gesetzt.",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_prompt_prefs_title": {
|
||||
"message": "Optionen zum Hinzufügen von Tags",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_SurveyLinkText": {
|
||||
"message": "Teilen Sie Ihr Feedback und helfen Sie uns, ThunderAI zu verbessern!",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_SurveyLinkText2": {
|
||||
"message": "Klicken Sie hier, es dauert nur eine Minute!",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OpenAIComp_ForceModel": {
|
||||
"message": "Modell manuell einfügen",
|
||||
"description": ""
|
||||
},
|
||||
"OpenAIComp_force_model_ask": {
|
||||
"message": "Fügen Sie hier den Namen des Modells ein, das Sie verwenden möchten.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_force_lang": {
|
||||
"message": "Sprache erzwingen",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_force_lang_Info": {
|
||||
"message": "Wenn aktiviert, wird die Sprache der Tags auf die in den ThunderAI Optionen definierte Sprache festgelegt, falls angegeben.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags_force_lang": {
|
||||
"message": "Die Tags müssen in geschrieben werden",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
|
|
@ -680,7 +680,11 @@
|
|||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_btnManagePrompts_infoline": {
|
||||
"message": "You can now use additional data placeholders!",
|
||||
"message": "You can use additional data placeholders.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_btnManagePrompts_infoline2": {
|
||||
"message": "You can change the prompt as you wish, but the response received from the AI must be a comma-separated list of tags!",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_openai_comp_use_v1" : {
|
||||
|
|
@ -698,5 +702,197 @@
|
|||
"prefs_OptionText_chatgpt_web_model_tooltip": {
|
||||
"message": "Click on a value to set it.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_reply_full_text": {
|
||||
"message": "Reply to the following email. Reply with only the needed text and with no extra comments or other text.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_reply_additional_text": {
|
||||
"message": "Do not add the subject line to the response.",
|
||||
"description": ""
|
||||
},
|
||||
"reply_same_lang": {
|
||||
"message": "Reply in the same language.",
|
||||
"description": ""
|
||||
},
|
||||
"sign_msg_as": {
|
||||
"message": "Sign the message as",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_reply_advanced_full_text": {
|
||||
"message": "Reply to the following email \"{%selected_text%}\", considering this is the full thread of emails \"{%mail_html_body%}\". Reply with only the needed text and with no extra comments or other text.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_rewrite_full_text": {
|
||||
"message": "Rewrite the following text to be more polite. Reply with only the re-written text and with no extra comments or other text.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_rewrite_formal_full_text": {
|
||||
"message": "Rewrite the following text to be more formal. Reply with only the re-written text and with no extra comments or other text.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_classify_full_text": {
|
||||
"message": "Classify the following text in terms of Politeness, Warmth, Formality, Assertiveness, Offensiveness giving a percentage for each category. Reply with only the category and score with no extra comments or other text.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_summarize_this_full_text": {
|
||||
"message": "Summarize the following email into a bullet point list.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_translate_this_full_text": {
|
||||
"message": "Translate the following email in",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_this_full_text": {
|
||||
"message": "Reply with only the needed text and with no extra comments or other text.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags": {
|
||||
"message": "Add tags to emails",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_Info": {
|
||||
"message": "If checked, an item will be included in the menu to apply tags to emails.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags": {
|
||||
"message": "Add tags to this email",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags_full_text": {
|
||||
"message": "Analyze the following email text and generate a comma-separated list of tags that summarize its content. Use themes, key topics, and relevant descriptors as tags. Ensure the tags are concise and relevant to the email's content.\nEmail text: {%mail_text_body%}\nConsider the following details for context:\n- Sender: {%author%}\n- Recipients: {%recipients%}\n- CC list: {%cc_list%}\n- Email subject: {%mail_subject%}\nPlease base your tags on the email's text and context, ignoring unnecessary information or trivial details. The output should be only a list of comma separated tags without any additional comment or text.",
|
||||
"description": ""
|
||||
},
|
||||
"placeholder_tags_current_email": {
|
||||
"message": "Mail tags",
|
||||
"description": ""
|
||||
},
|
||||
"placeholder_tags_full_list": {
|
||||
"message": "Existing tags",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_maxnum": {
|
||||
"message": "Maximum number of tags",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_maxnum_Info": {
|
||||
"message": "The maximum number of tags proposed by the AI. Set to 0 if you don't want to limit the number of tags.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags_maxnum": {
|
||||
"message": "Limit the number of tags to",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_hide_exclusions": {
|
||||
"message": "Hide excluded tags",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_hide_exclusions_Info": {
|
||||
"message": "If checked, the tags that are present in the exclusion list will be hidden in the confirm dialog.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_btnManageTagsInfo": {
|
||||
"message": "Manage tags settings",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_PageTitle": {
|
||||
"message": "Manage Tags Settings",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_info_default": {
|
||||
"message": "In this page you can modify the default prompt used to add tags to emails and manage the exclusion list.",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_prompt_text_title": {
|
||||
"message": "Current prompt text",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_excl_list_title": {
|
||||
"message": "Exclusion list",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_excl_list_infoline": {
|
||||
"message": "This is a list of tags that are not allowed to be added to emails.",
|
||||
"description": ""
|
||||
},
|
||||
"save": {
|
||||
"message": "Save",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_info_additional_statements": {
|
||||
"message": "This statement will be added at the end of the prompt:",
|
||||
"description": ""
|
||||
},
|
||||
"reset_default": {
|
||||
"message": "Reset to default",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_excl_list_infoline2": {
|
||||
"message": "Add a word per line, or separated by a comma.",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_dialog_title": {
|
||||
"message": "Add tags to the email",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_exclude_tag": {
|
||||
"message": "Exclude tag",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_no_tags_received": {
|
||||
"message": "No tags received from the AI.",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_no_valid_tags": {
|
||||
"message": "No valid tags found, after filtering with the exclusion list.",
|
||||
"description": ""
|
||||
},
|
||||
"thunderai_error_title": {
|
||||
"message": "ThunderAI Error",
|
||||
"description": ""
|
||||
},
|
||||
"thunderai_warning_title": {
|
||||
"message": "ThunderAI Warning",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_first_uppercase": {
|
||||
"message": "First letter uppercase",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_first_uppercase_Info": {
|
||||
"message": "If checked, the tags label will be set to lowercase letters with only the first letter uppercase.",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_prompt_prefs_title": {
|
||||
"message": "Add Tags Options",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_SurveyLinkText": {
|
||||
"message": "Share your feedback and help us improve ThunderAI!",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_SurveyLinkText2": {
|
||||
"message": "Click here, it only takes a minute!",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OpenAIComp_ForceModel": {
|
||||
"message": "Manually insert model",
|
||||
"description": ""
|
||||
},
|
||||
"OpenAIComp_force_model_ask": {
|
||||
"message": "Insert here the model name you want to use.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_force_lang": {
|
||||
"message": "Force language",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_force_lang_Info": {
|
||||
"message": "If checked, the tags language will be forced to match the language defined on the ThunderAI options page, if specified.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags_force_lang": {
|
||||
"message": "The tags must be written in",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
|
|
@ -680,7 +680,11 @@
|
|||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_btnManagePrompts_infoline": {
|
||||
"message": "Vous pouvez maintenant utiliser des espaces réservés de données supplémentaires !",
|
||||
"message": "Vous pouvez utiliser des espaces réservés pour des données supplémentaires.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_btnManagePrompts_infoline2": {
|
||||
"message": "Vous pouvez modifier l'invite comme vous le souhaitez, mais la réponse de l'IA doit être une liste de tags séparés par des virgules !",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_openai_comp_use_v1": {
|
||||
|
|
@ -694,5 +698,201 @@
|
|||
"prefs_OptionText_owl_warning": {
|
||||
"message": "Il semble qu'au moins un de vos comptes utilise le module complémentaire Chouette pour Exchange. Il existe un problème connu entre Thunderbird et Chouette, qui est en cours de résolution. Pour le moment, vous pouvez utiliser ThunderAI lors de la rédaction d'e-mails, mais pas lors de leur lecture.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatgpt_web_model_tooltip": {
|
||||
"message": "Cliquez sur une valeur pour la définir.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_reply_full_text": {
|
||||
"message": "Répondez au courriel suivant. Répondez uniquement avec le texte nécessaire, sans commentaires ou autre texte.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_reply_additional_text": {
|
||||
"message": "N'ajoutez pas la ligne d'objet à la réponse.",
|
||||
"description": ""
|
||||
},
|
||||
"reply_same_lang": {
|
||||
"message": "Répondez dans la même langue.",
|
||||
"description": ""
|
||||
},
|
||||
"sign_msg_as": {
|
||||
"message": "Signez le message comme",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_reply_advanced_full_text": {
|
||||
"message": "Répondez au courriel suivant \"{%selected_text%}\", en tenant compte qu'il s'agit de l'intégralité du fil de courriels \"{%mail_html_body%}\". Répondez uniquement avec le texte nécessaire, sans commentaires ou autre texte.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_rewrite_full_text": {
|
||||
"message": "Réécrivez le texte suivant pour le rendre plus poli. Répondez uniquement avec le texte réécrit, sans commentaires ou autre texte.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_rewrite_formal_full_text": {
|
||||
"message": "Réécrivez le texte suivant pour le rendre plus formel. Répondez uniquement avec le texte réécrit, sans commentaires ou autre texte.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_classify_full_text": {
|
||||
"message": "Classifiez le texte suivant en termes de politesse, chaleur, formalité, assertivité, caractère offensant en donnant un pourcentage pour chaque catégorie. Répondez uniquement avec la catégorie et le score, sans commentaires ou autre texte.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_summarize_this_full_text": {
|
||||
"message": "Résumez le courriel suivant sous forme de liste à puces.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_translate_this_full_text": {
|
||||
"message": "Traduisez le courriel suivant en",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_this_full_text": {
|
||||
"message": "Répondez uniquement avec le texte nécessaire, sans commentaires ou autre texte.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags": {
|
||||
"message": "Ajoutez des tags aux courriels",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_Info": {
|
||||
"message": "Si coché, un élément sera inclus dans le menu pour appliquer des tags aux courriels.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags": {
|
||||
"message": "Ajoutez des tags à ce courriel",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags_full_text": {
|
||||
"message": "Analysez le texte de courriel suivant et générez une liste de tags séparés par des virgules qui résument son contenu. Utilisez des thèmes, des sujets clés et des descripteurs pertinents comme tags. Assurez-vous que les tags soient concis et pertinents pour le contenu du courriel. Texte du courriel : {%mail_text_body%} Considérez les détails suivants pour le contexte : - Expéditeur : {%author%} - Destinataires : {%recipients%} - Liste CC : {%cc_list%} - Sujet du courriel : {%mail_subject%} Veuillez baser vos tags sur le texte et le contexte du courriel, en ignorant les informations inutiles ou triviales. La sortie doit être uniquement une liste de tags séparés par des virgules, sans aucun commentaire ou texte supplémentaire.",
|
||||
"description": ""
|
||||
},
|
||||
"placeholder_tags_current_email": {
|
||||
"message": "Tags de courriels",
|
||||
"description": ""
|
||||
},
|
||||
"placeholder_tags_full_list": {
|
||||
"message": "Tags existants",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_maxnum": {
|
||||
"message": "Nombre maximum de tags",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_maxnum_Info": {
|
||||
"message": "Le nombre maximum de tags proposés par l'IA. Réglez à 0 si vous ne voulez pas limiter le nombre de tags.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags_maxnum": {
|
||||
"message": "Limitez le nombre de tags à",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_hide_exclusions": {
|
||||
"message": "Masquer les tags exclus",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_hide_exclusions_Info": {
|
||||
"message": "Si coché, les tags présents dans la liste d'exclusion seront masqués dans la boîte de dialogue de confirmation.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_btnManageTagsInfo": {
|
||||
"message": "Gérez les paramètres des tags",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_PageTitle": {
|
||||
"message": "Gérez les paramètres des tags",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_info_default": {
|
||||
"message": "Sur cette page, vous pouvez modifier l'invite par défaut utilisée pour ajouter des tags aux courriels et gérer la liste d'exclusion.",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_prompt_text_title": {
|
||||
"message": "Texte de l'invite actuelle",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_excl_list_title": {
|
||||
"message": "Liste d'exclusion",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_excl_list_infoline": {
|
||||
"message": "Ceci est une liste de tags qui ne sont pas autorisés à être ajoutés aux courriels.",
|
||||
"description": ""
|
||||
},
|
||||
"save": {
|
||||
"message": "Enregistrer",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_info_additional_statements": {
|
||||
"message": "Cette déclaration sera ajoutée à la fin de l'invite :",
|
||||
"description": ""
|
||||
},
|
||||
"reset_default": {
|
||||
"message": "Réinitialiser aux valeurs par défaut",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_excl_list_infoline2": {
|
||||
"message": "Ajoutez un mot par ligne ou séparé par une virgule.",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_dialog_title": {
|
||||
"message": "Ajoutez des tags au courriel",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_exclude_tag": {
|
||||
"message": "Exclure un tag",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_no_tags_received": {
|
||||
"message": "Aucun tag reçu de l'IA.",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_no_valid_tags": {
|
||||
"message": "Aucun tag valide trouvé après filtrage avec la liste d'exclusion.",
|
||||
"description": ""
|
||||
},
|
||||
"thunderai_error_title": {
|
||||
"message": "Erreur ThunderAI",
|
||||
"description": ""
|
||||
},
|
||||
"thunderai_warning_title": {
|
||||
"message": "Avertissement ThunderAI",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_first_uppercase": {
|
||||
"message": "Première lettre en majuscule",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_first_uppercase_Info": {
|
||||
"message": "Si coché, l'étiquette des tags sera définie en minuscules avec seulement la première lettre en majuscule.",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_prompt_prefs_title": {
|
||||
"message": "Options d’ajout de tags",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_SurveyLinkText": {
|
||||
"message": "Partagez vos commentaires et aidez-nous à améliorer ThunderAI !",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_SurveyLinkText2": {
|
||||
"message": "Cliquez ici, cela ne prend qu'une minute !",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OpenAIComp_ForceModel": {
|
||||
"message": "Insérez manuellement le modèle",
|
||||
"description": ""
|
||||
},
|
||||
"OpenAIComp_force_model_ask": {
|
||||
"message": "Insérez ici le nom du modèle que vous souhaitez utiliser.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_force_lang": {
|
||||
"message": "Forcer la langue",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_force_lang_Info": {
|
||||
"message": "Si cette option est cochée, la langue des tags sera forcée pour correspondre à celle définie dans les options du ThunderAI, si spécifiée.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags_force_lang": {
|
||||
"message": "Les tags doivent être écrits en",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
|
|
@ -507,6 +507,10 @@
|
|||
"message": "La richiesta all'API Ollama è fallita",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_api_request_failed": {
|
||||
"message": "Richiesta all'API compatibile con OpenAI ChatGPT fallita",
|
||||
"description": ""
|
||||
},
|
||||
"WaitingServerReponse": {
|
||||
"message": "In attesa della risposta del server",
|
||||
"description": ""
|
||||
|
|
@ -543,10 +547,6 @@
|
|||
"message": "Richiesta all'API compatibile con OpenAI fallita",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_api_request_failed": {
|
||||
"message": "Richiesta all'API compatibile con OpenAI ChatGPT fallita",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OpenAIComp_ChatName": {
|
||||
"message": "Nome della chat",
|
||||
"description": ""
|
||||
|
|
@ -680,7 +680,11 @@
|
|||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_btnManagePrompts_infoline": {
|
||||
"message": "Ora puoi utilizzare segnaposti per i dati aggiuntivi!",
|
||||
"message": "Puoi utilizzare segnaposto per dati aggiuntivi.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_btnManagePrompts_infoline2": {
|
||||
"message": "Puoi modificare il prompt come preferisci, ma la risposta ricevuta dall'IA deve essere una lista di tag separati da virgole!",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_openai_comp_use_v1": {
|
||||
|
|
@ -694,5 +698,201 @@
|
|||
"prefs_OptionText_owl_warning": {
|
||||
"message": "Sembra che almeno uno dei tuoi account stia utilizzando il componente aggiuntivo Gufo per Exchange. Esiste un problema noto tra Thunderbird e Gufo, che è attualmente in fase di risoluzione. Al momento, puoi utilizzare ThunderAI durante la composizione delle email, ma non durante la loro lettura.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatgpt_web_model_tooltip": {
|
||||
"message": "Fai clic su un valore per impostarlo.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_reply_full_text": {
|
||||
"message": "Rispondi alla seguente email. Rispondi solo con il testo necessario, senza commenti o altro testo aggiuntivo.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_reply_additional_text": {
|
||||
"message": "Non aggiungere la riga dell'oggetto alla risposta.",
|
||||
"description": ""
|
||||
},
|
||||
"reply_same_lang": {
|
||||
"message": "Rispondi nella stessa lingua.",
|
||||
"description": ""
|
||||
},
|
||||
"sign_msg_as": {
|
||||
"message": "Firma il messaggio come",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_reply_advanced_full_text": {
|
||||
"message": "Rispondi alla seguente email \"{%selected_text%}\", considerando che questo è l'intero thread di email \"{%mail_html_body%}\". Rispondi solo con il testo necessario, senza commenti aggiuntivi o altro testo.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_rewrite_full_text": {
|
||||
"message": "Riformula il seguente testo per renderlo più cortese. Rispondi solo con il testo riformulato, senza commenti aggiuntivi o altro testo.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_rewrite_formal_full_text": {
|
||||
"message": "Riformula il seguente testo per renderlo più formale. Rispondi solo con il testo riformulato, senza commenti aggiuntivi o altro testo.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_classify_full_text": {
|
||||
"message": "Classifica il seguente testo in termini di Cortesia, Calore, Formalità, Assertività, Offensività, indicando una percentuale per ciascuna categoria. Rispondi solo con la categoria e il punteggio, senza commenti aggiuntivi o altro testo.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_summarize_this_full_text": {
|
||||
"message": "Riepiloga la seguente email in una lista con punti elenco.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_translate_this_full_text": {
|
||||
"message": "Traduci la seguente email in",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_this_full_text": {
|
||||
"message": "Rispondi solo con il testo necessario, senza commenti aggiuntivi o altro testo.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags": {
|
||||
"message": "Aggiungi tag alle email",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_Info": {
|
||||
"message": "Se selezionato, verrà incluso nel menu un elemento per applicare i tag alle email.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags": {
|
||||
"message": "Aggiungi tag a questa email",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags_full_text": {
|
||||
"message": "Analizza il seguente testo email e genera una lista di tag separati da virgole che ne riassumano il contenuto. Usa temi, argomenti principali e descrittori pertinenti come tag. Assicurati che i tag siano concisi e rilevanti per il contenuto dell'email. Testo email: {%mail_text_body%} Considera i seguenti dettagli come contesto: - Mittente: {%author%} - Destinatari: {%recipients%} - Lista CC: {%cc_list%} - Oggetto dell'email: {%mail_subject%} Basa i tuoi tag sul testo e sul contesto dell'email, ignorando informazioni superflue o dettagli banali. L'output dovrebbe essere solo un elenco di tag separati da virgole, senza alcun commento o testo aggiuntivo.",
|
||||
"description": ""
|
||||
},
|
||||
"placeholder_tags_current_email": {
|
||||
"message": "Tag delle email",
|
||||
"description": ""
|
||||
},
|
||||
"placeholder_tags_full_list": {
|
||||
"message": "Tag esistenti",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_maxnum": {
|
||||
"message": "Numero massimo di tag",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_maxnum_Info": {
|
||||
"message": "Il numero massimo di tag proposti dall'IA. Imposta a 0 se non vuoi limitare il numero di tag.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags_maxnum": {
|
||||
"message": "Limita il numero di tag a",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_hide_exclusions": {
|
||||
"message": "Nascondi i tag esclusi",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_hide_exclusions_Info": {
|
||||
"message": "Se selezionato, i tag presenti nella lista di esclusione saranno nascosti nella finestra di conferma.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_btnManageTagsInfo": {
|
||||
"message": "Gestisci le impostazioni dei tag",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_PageTitle": {
|
||||
"message": "Impostazioni dei Tag",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_info_default": {
|
||||
"message": "In questa pagina puoi modificare il prompt predefinito utilizzato per aggiungere tag alle email e gestire la lista di esclusione.",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_prompt_text_title": {
|
||||
"message": "Testo del prompt attuale",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_excl_list_title": {
|
||||
"message": "Lista di esclusione",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_excl_list_infoline": {
|
||||
"message": "Questa è una lista di tag che non possono essere aggiunti alle email.",
|
||||
"description": ""
|
||||
},
|
||||
"save": {
|
||||
"message": "Salva",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_info_additional_statements": {
|
||||
"message": "Questa frase verrà aggiunta alla fine del prompt:",
|
||||
"description": ""
|
||||
},
|
||||
"reset_default": {
|
||||
"message": "Ripristina impostazioni predefinite",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_excl_list_infoline2": {
|
||||
"message": "Aggiungi una parola per riga o separata da una virgola.",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_dialog_title": {
|
||||
"message": "Aggiungi tag all'email",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_exclude_tag": {
|
||||
"message": "Escludi il tag",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_no_tags_received": {
|
||||
"message": "Nessun tag ricevuto dall'IA.",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_no_valid_tags": {
|
||||
"message": "Nessun tag valido trovato dopo aver applicato il filtro della lista di esclusione.",
|
||||
"description": ""
|
||||
},
|
||||
"thunderai_error_title": {
|
||||
"message": "Errore ThunderAI",
|
||||
"description": ""
|
||||
},
|
||||
"thunderai_warning_title": {
|
||||
"message": "Avviso ThunderAI",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_first_uppercase": {
|
||||
"message": "Prima lettera maiuscola",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_first_uppercase_Info": {
|
||||
"message": "Se selezionato, l'etichetta dei tag sarà impostata in lettere minuscole con solo la prima lettera maiuscola.",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_prompt_prefs_title": {
|
||||
"message": "Opzioni per aggiungere tag",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_SurveyLinkText": {
|
||||
"message": "Condividi il tuo feedback e aiutaci a migliorare ThunderAI!",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_SurveyLinkText2": {
|
||||
"message": "Clicca qui, ci vuole solo un minuto!",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OpenAIComp_ForceModel": {
|
||||
"message": "Inserisci manualmente il modello",
|
||||
"description": ""
|
||||
},
|
||||
"OpenAIComp_force_model_ask": {
|
||||
"message": "Inserisci qui il nome del modello che vuoi utilizzare.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_force_lang": {
|
||||
"message": "Forza lingua",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_force_lang_Info": {
|
||||
"message": "Se selezionato, la lingua dei tag sarà forzata a corrispondere a quella definita nella pagina delle opzioni di ThunderAI, se specificata.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags_force_lang": {
|
||||
"message": "I tag devono essere scritti in",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
898
_locales/pl/messages.json
Normal file
898
_locales/pl/messages.json
Normal file
|
|
@ -0,0 +1,898 @@
|
|||
{
|
||||
"extensionDescription": {
|
||||
"message": "Używaj ChatGPT lub Ollama do ulepszania swoich e-maili!",
|
||||
"description": "Description of the extension."
|
||||
},
|
||||
"menu_title": {
|
||||
"message": "AI",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_lang": {
|
||||
"message": "Odpowiedz w ",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_reply": {
|
||||
"message": "Odpowiedz na ten e-mail",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_reply_advanced": {
|
||||
"message": "Odpowiedz na ten wątek",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_rewrite_polite": {
|
||||
"message": "Przepisz uprzejmie",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_rewrite_formal": {
|
||||
"message": "Przepisz formalnie",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_classify": {
|
||||
"message": "Klasyfikuj",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_summarize_this": {
|
||||
"message": "Podsumuj to",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_translate_this": {
|
||||
"message": "Przetłumacz to",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_this": {
|
||||
"message": "Zapytaj o to",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_selection_needed": {
|
||||
"message": "Aby kontynuować, musisz zaznaczyć tekst!",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_managePrompts": {
|
||||
"message": "Zarządzaj poleceniami",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_managePrompts_help": {
|
||||
"message": "Więcej informacji",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_managePrompts_info_default": {
|
||||
"message": "Domyślne polecenia nie są edytowalne. Możesz je wyłączyć, skopiować tekst polecenia i wkleić go do nowego, aby stworzyć zmodyfikowaną wersję.",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_managePrompts_info_default_2": {
|
||||
"message": "Możesz importować i eksportować polecenia. Istniejące polecenia o tym samym ID zostaną nadpisane. Polecenia z nowymi ID zostaną dodane.",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_managePrompts_info_default_3": {
|
||||
"message": "Jeśli wszystko jest poprawne, po imporcie kliknij przycisk 'Zapisz wszystko'.",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_start_saving": {
|
||||
"message": "Zapisywanie poleceń...",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_reindexing_list": {
|
||||
"message": "Ponowne indeksowanie listy...",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_filtering_prompts": {
|
||||
"message": "Filtrowanie polece<63><65>...",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_saving_default_prompts": {
|
||||
"message": "Zapisywanie domyślnych poleceń...",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_saving_custom_prompts": {
|
||||
"message": "Zapisywanie własnych poleceń...",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_reloading_menus": {
|
||||
"message": "Odświeżanie menu...",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_saved": {
|
||||
"message": "Polecenia zapisane!",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_form_label_ID": {
|
||||
"message": "ID",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_form_label_ID_rules": {
|
||||
"message": "Musi być unikalne, pisane małymi literami i bez spacji",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_form_label_Name": {
|
||||
"message": "Nazwa",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_form_label_Text": {
|
||||
"message": "Tekst polecenia",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_form_label_Action": {
|
||||
"message": "Akcja",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_form_label_need_selected": {
|
||||
"message": "Wymagane zaznaczenie tekstu",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_form_label_need_signature": {
|
||||
"message": "Zawsze dodawaj podpis",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_form_label_need_custom_text": {
|
||||
"message": "Poproś o dodatkowy tekst",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_form_label_enabled": {
|
||||
"message": "Włączone",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_form_required_fields": {
|
||||
"message": "Pola wymagane",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_btnEdit": {
|
||||
"message": "Edytuj",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_btnCancel": {
|
||||
"message": "Anuluj",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_btnOK": {
|
||||
"message": "OK",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_btnDelete": {
|
||||
"message": "Usuń",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_btnDelete_confirmText": {
|
||||
"message": "Czy na pewno chcesz usunąć ten element?",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_unsaved_changes": {
|
||||
"message": "Istnieją niezapisane zmiany!",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_btnSaveAll": {
|
||||
"message": "Zapisz wszystko",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_save_button": {
|
||||
"message": "Zapisz",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_btnNew": {
|
||||
"message": "Dodaj nowe",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_btnAddNewCommit": {
|
||||
"message": "Dodaj polecenie",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_add_to_menu": {
|
||||
"message": "Dodaj do menu",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_add_to_menu_always": {
|
||||
"message": "Zawsze",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_add_to_menu_reading": {
|
||||
"message": "Podczas czytania e-maila",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_add_to_menu_composing": {
|
||||
"message": "Podczas pisania e-maila",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_close_button": {
|
||||
"message": "Przycisk zamknięcia",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_do_reply": {
|
||||
"message": "Odpowiedz",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_substitute_text": {
|
||||
"message": "Zastąp tekst",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_win_working": {
|
||||
"message": "Praca w toku...",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_win_job_completed": {
|
||||
"message": "Zakończono!",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_win_job_completed_select": {
|
||||
"message": "Wybierz tekst, którego chcesz użyć i kliknij przycisk.",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_win_get_answer": {
|
||||
"message": "Użyj wybranej odpowiedzi",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_win_close": {
|
||||
"message": "Zamknij",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_textarea_not_found_error": {
|
||||
"message": "Wygląda na to, że strona ChatGPT ładuje się zbyt długo. Jeśli ładowanie zakończy się, kliknij przycisk po prawej stronie. Jeśli problem będzie się powtarzał, sprawdź status usługi.",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_btn_retry": {
|
||||
"message": "Spróbuj ponownie",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_sendbutton_not_found_error": {
|
||||
"message": "Kliknij przycisk wysyłania, aby przesłać zapytanie.",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_user_not_logged_in": {
|
||||
"message": "Nie jesteś zalogowany do ChatGPT. Zaloguj się swoimi danymi, zamknij okno ChatGPT, a następnie powtórz próbę. Po autoryzacji pozostaniesz zalogowany.",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_win_model_warning": {
|
||||
"message": "Ustawiłeś opcję używania określonego modelu, ale wygląda na to, że nie ładuje się on poprawnie. Sprawdź wartość i spróbuj ponownie. Na razie możesz nacisnąć niebieski przycisk, aby kontynuować.",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_win_custom_text": {
|
||||
"message": "Wstaw tutaj dodatkowy tekst dla zapytania.",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_win_send": {
|
||||
"message": "Wyślij",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_use_gpt35": {
|
||||
"message": "Użyj GPT3.5",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_force_completion": {
|
||||
"message": "wymuś zakończenie",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_force_completion_title": {
|
||||
"message": "Kliknij tutaj, aby wyświetlić przycisk 'Użyj ostatniej odpowiedzi', jeśli ChatGPT zakończył pracę, ale przycisk się nie pojawił.",
|
||||
"description": ""
|
||||
},
|
||||
"msg_prompt_too_long": {
|
||||
"message": "Podany tekst jest zbyt długi. Musisz go skrócić.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_release_notes": {
|
||||
"message": "Informacje o wydaniu",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_status_page": {
|
||||
"message": "status usługi",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatgpt_win_text": {
|
||||
"message": "Wymiary okna ChatGPT",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatgpt_win_height": {
|
||||
"message": "Wysokość",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatgpt_win_width": {
|
||||
"message": "Szerokość",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_default_sign_name": {
|
||||
"message": "Domyślna nazwa podpisu",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_default_chatgpt_lang": {
|
||||
"message": "Domyślny język odpowiedzi",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_reply_all": {
|
||||
"message": "Odpowiedz wszystkim",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_reply_sender": {
|
||||
"message": "Odpowiedz nadawcy",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_reply_type": {
|
||||
"message": "Typ odpowiedzi",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_btnManagePrompts": {
|
||||
"message": "Zarządzaj poleceniami",
|
||||
"description": ""
|
||||
},
|
||||
"prefsInfoTitle": {
|
||||
"message": "Ważne informacje",
|
||||
"description": ""
|
||||
},
|
||||
"prefsInfoDesc_1": {
|
||||
"message": "Może się zdarzyć, że interfejs ChatGPT zmieni się w sposób, który zakłóci działanie dodatku. Sprawdź stronę \"Status usługi\" połączoną na dole tej strony. Pamiętaj też, że przy pierwszym użyciu ThunderAI musisz zalogować się do ChatGPT.",
|
||||
"description": ""
|
||||
},
|
||||
"prefsInfoDesc_2": {
|
||||
"message": "Aby korzystać z API ChatGPT, potrzebujesz klucza API OpenAI ChatGPT i musisz wybrać model.",
|
||||
"description": ""
|
||||
},
|
||||
"prefsInfoDesc_3": {
|
||||
"message": "Aby korzystać z integracji z Ollama, musisz skonfigurować lokalny serwer Ollama. Po uruchomieniu serwera wprowadź jego adres w odpowiednim polu w aplikacji. Aby zapewnić prawidłową komunikację między ThunderAI a serwerem Ollama pamiętaj o ustawieniu OLLAMA_ORIGINS=moz-extension://*.",
|
||||
"description": ""
|
||||
},
|
||||
"prefsInfoDesc_4": {
|
||||
"message": "Aby korzystać z tej integracji, musisz skonfigurować lokalny serwer kompatybilny z API OpenAI, jak LM Studio. Po uruchomieniu serwera wprowadź jego adres w odpowiednim polu w aplikacji. Aby zapewnić prawidłową komunikację między ThunderAI a serwerem lokalnym pamiętaj o prawidłowym ustawieniu CORS.",
|
||||
"description": ""
|
||||
},
|
||||
"prefsInfoDesc_5": {
|
||||
"message": "Pamiętaj, że możesz otworzyć menu ThunderAI używając skrótu klawiszowego CTRL+ALT+A.",
|
||||
"description": ""
|
||||
},
|
||||
"prefsInfoDesc_6": {
|
||||
"message": "Możesz zmienić skrót klikając ikonę koła zębatego w prawym górnym rogu tej strony i wybierając \"Zarządzaj skrótami rozszerzenia\".",
|
||||
"description": ""
|
||||
},
|
||||
"prefsDonation_1": {
|
||||
"message": "Czy podoba Ci się ten dodatek?",
|
||||
"description": ""
|
||||
},
|
||||
"prefsDonation_2": {
|
||||
"message": "Rozważ wsparcie poprzez darowiznę!",
|
||||
"description": ""
|
||||
},
|
||||
"backToOptionsText": {
|
||||
"message": "Opcje",
|
||||
"description": ""
|
||||
},
|
||||
"TranslateText": {
|
||||
"message": "Czy chcesz pomóc w tłumaczeniu tego dodatku?",
|
||||
"description": ""
|
||||
},
|
||||
"TranslateLink": {
|
||||
"message": "Dowiedz się jak!",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_ExportAll": {
|
||||
"message": "Eksportuj wszystkie polecenia",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_Import": {
|
||||
"message": "Importuj nowe polecenia",
|
||||
"description": ""
|
||||
},
|
||||
"importPrompts_confirmText": {
|
||||
"message": "Zamierzasz zaimportować nowe polecenia.",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_start_import": {
|
||||
"message": "Rozpoczynanie importu własnych poleceń...",
|
||||
"description": ""
|
||||
},
|
||||
"customPrompts_import_completed": {
|
||||
"message": "Import własnych poleceń zakończony! Musisz kliknąć przycisk 'Zapisz wszystko', aby zapisać zmiany.",
|
||||
"description": ""
|
||||
},
|
||||
"importPrompts_invalidFile": {
|
||||
"message": "Plik, który próbujesz zaimportować, nie jest prawidłowym plikiem poleceń.",
|
||||
"description": ""
|
||||
},
|
||||
"importPrompts_invalidPrompts": {
|
||||
"message": "Plik, który próbujesz zaimportować, nie zawiera żadnych prawidłowych poleceń.",
|
||||
"description": ""
|
||||
},
|
||||
"currently_used_prompt": {
|
||||
"message": "Aktualnie używana nazwa polecenia",
|
||||
"description": ""
|
||||
},
|
||||
"customprompts_form_label_define_response_lang": {
|
||||
"message": "Określ język odpowiedzi w poleceniu",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_Connection_type": {
|
||||
"message": "Typ połączenia",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_Connection_type_ChatGPT_Web": {
|
||||
"message": "Interfejs webowy ChatGPT",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_Connection_type_ChatGPT_API": {
|
||||
"message": "API ChatGPT OpenAI",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_ChatGPT_API_Key": {
|
||||
"message": "Klucz API ChatGPT",
|
||||
"description": ""
|
||||
},
|
||||
"ChatGPT_Models": {
|
||||
"message": "Modele ChatGPT",
|
||||
"description": ""
|
||||
},
|
||||
"ChatGPT_Models_Fetch": {
|
||||
"message": "Zaktualizuj listę modeli ChatGPT",
|
||||
"description": ""
|
||||
},
|
||||
"ChatGPT_Models_Error_fetching": {
|
||||
"message": "Błąd podczas pobierania modeli ChatGPT",
|
||||
"description": ""
|
||||
},
|
||||
"Loading": {
|
||||
"message": "Ładowanie...",
|
||||
"description": ""
|
||||
},
|
||||
"error": {
|
||||
"message": "Błąd ThunderAI!",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_empty_apikey": {
|
||||
"message": "Nie dodałeś klucza API dla ChatGPT API. Proszę wprowadź go na stronie opcji.",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_empty_model": {
|
||||
"message": "Nie wybrałeś modelu dla ChatGPT API. Proszę wybierz jeden na stronie opcji.",
|
||||
"description": ""
|
||||
},
|
||||
"chagpt_api_send_button": {
|
||||
"message": "Używając modelu",
|
||||
"description": ""
|
||||
},
|
||||
"chagpt_api_connecting": {
|
||||
"message": "Próba połączenia z OpenAI ChatGPT przy użyciu podanego klucza API",
|
||||
"description": ""
|
||||
},
|
||||
"Debug": {
|
||||
"message": "Debugowanie",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_do_debug_info": {
|
||||
"message": "Aktywuj system debugowania",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_Connection_type_Ollama_API": {
|
||||
"message": "API Ollama (Lokalny LLM)",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_Connection_type_OpenAI_Comp_API": {
|
||||
"message": "API kompatybilne z OpenAI",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_API_Host": {
|
||||
"message": "Adres hosta",
|
||||
"description": ""
|
||||
},
|
||||
"Ollama_Models": {
|
||||
"message": "Modele Ollama",
|
||||
"description": ""
|
||||
},
|
||||
"Ollama_Models_Fetch": {
|
||||
"message": "Zaktualizuj listę modeli Ollama",
|
||||
"description": ""
|
||||
},
|
||||
"Ollama_Models_Error_fetching": {
|
||||
"message": "Błąd podczas pobierania modeli Ollama",
|
||||
"description": ""
|
||||
},
|
||||
"API_Models_Error_NoModels": {
|
||||
"message": "Nie znaleziono modeli",
|
||||
"description": ""
|
||||
},
|
||||
"ollama_empty_host": {
|
||||
"message": "Nie dodałeś adresu hosta dla API Ollama. Proszę wprowadź go na stronie opcji.",
|
||||
"description": ""
|
||||
},
|
||||
"ollama_empty_model": {
|
||||
"message": "Nie wybrałeś modelu dla API Ollama. Proszę wybierz jeden na stronie opcji.",
|
||||
"description": ""
|
||||
},
|
||||
"ollama_api_connecting": {
|
||||
"message": "Próba połączenia z lokalnym serwerem Ollama używając hosta",
|
||||
"description": ""
|
||||
},
|
||||
"andModel": {
|
||||
"message": "i modelu",
|
||||
"description": ""
|
||||
},
|
||||
"error_connection_interrupted": {
|
||||
"message": "Połączenie z serwerem zostało nieoczekiwanie przerwane",
|
||||
"description": ""
|
||||
},
|
||||
"ollama_api_request_failed": {
|
||||
"message": "Zapytanie do API Ollama nie powiodło się",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_api_request_failed": {
|
||||
"message": "Zapytanie do API OpenAI ChatGPT nie powiodło się",
|
||||
"description": ""
|
||||
},
|
||||
"WaitingServerReponse": {
|
||||
"message": "Oczekiwanie na odpowiedź serwera",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_API_Host_Info": {
|
||||
"message": "Taki jak",
|
||||
"description": ""
|
||||
},
|
||||
"OpenAIComp_Models": {
|
||||
"message": "Modele API kompatybilne z OpenAI",
|
||||
"description": ""
|
||||
},
|
||||
"OpenAIComp_Models_Fetch": {
|
||||
"message": "Zaktualizuj listę modeli API kompatybilnych z OpenAI",
|
||||
"description": ""
|
||||
},
|
||||
"OpenAIComp_Models_Error_fetching": {
|
||||
"message": "Błąd podczas pobierania modeli API kompatybilnych z OpenAI",
|
||||
"description": ""
|
||||
},
|
||||
"OpenAIComp_empty_host": {
|
||||
"message": "Nie dodałeś adresu hosta dla API kompatybilnego z OpenAI. Proszę wprowadź go na stronie opcji.",
|
||||
"description": ""
|
||||
},
|
||||
"OpenAIComp_empty_model": {
|
||||
"message": "Nie wybrałeś modelu dla API kompatybilnego z OpenAI. Proszę wybierz jeden na stronie opcji.",
|
||||
"description": ""
|
||||
},
|
||||
"OpenAIComp_api_connecting": {
|
||||
"message": "Próba połączenia z lokalnym serwerem API kompatybilnym z OpenAI używając hosta",
|
||||
"description": ""
|
||||
},
|
||||
"OpenAIComp_api_request_failed": {
|
||||
"message": "Zapytanie do API kompatybilnego z OpenAI nie powiodło się",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OpenAIComp_ChatName": {
|
||||
"message": "Nazwa czatu",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OpenAIComp_ChatName_Info": {
|
||||
"message": "To jest nazwa, która będzie używana w czacie AI.",
|
||||
"description": ""
|
||||
},
|
||||
"StorageSpace": {
|
||||
"message": "Całkowita zajęta przestrzeń dyskowa",
|
||||
"description": ""
|
||||
},
|
||||
"SearchPrompt": {
|
||||
"message": "Szukaj poleceń",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_dynamic_menu_force_enter": {
|
||||
"message": "Menu: natychmiastowe wysyłanie polecenia",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_dynamic_menu_force_enter_info": {
|
||||
"message": "Jeśli zaznaczone, użycie skrótu klawiszowego CTRL+ALT+A automatycznie wyśle zaznaczone polecenie z menu. W przeciwnym razie nazwa polecenia zostanie wyświetlona użytkownikowi, wymagając kolejnego naciśnięcia klawisza Enter, aby je wysłać.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_dynamic_menu_order_alphabet": {
|
||||
"message": "Menu: sortuj alfabetycznie",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_dynamic_menu_order_alphabet_info": {
|
||||
"message": "Jeśli zaznaczone, polecenia w menu będą uporządkowane alfabetycznie.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatgpt_win_dims_info": {
|
||||
"message": "Ustaw na 0, jeśli nie chcesz określać rozmiaru okna.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OpenAIComp_API_Key": {
|
||||
"message": "Klucz API kompatybilny z OpenAI",
|
||||
"description": ""
|
||||
},
|
||||
"Optional": {
|
||||
"message": "Opcjonalne",
|
||||
"description": ""
|
||||
},
|
||||
"OpenChatGPTTab": {
|
||||
"message": "Otwórz kartę ChatGPT",
|
||||
"description": ""
|
||||
},
|
||||
"OpenChatGPTTab_Info": {
|
||||
"message": "W przypadku problemów z logowaniem w oknie ThunderAI, otwórz ChatGPT w nowej karcie używając przycisku po prawej stronie, zaloguj się, następnie zamknij kartę i kontynuuj korzystanie z ThunderAI.",
|
||||
"description": ""
|
||||
},
|
||||
"placeholder_mail_text_body": {
|
||||
"message": "Treść wiadomości",
|
||||
"description": ""
|
||||
},
|
||||
"placeholder_mail_html_body": {
|
||||
"message": "Treść wiadomości HTML",
|
||||
"description": ""
|
||||
},
|
||||
"placeholder_mail_subject": {
|
||||
"message": "Temat wiadomości",
|
||||
"description": ""
|
||||
},
|
||||
"placeholder_selected_text": {
|
||||
"message": "Zaznaczony tekst",
|
||||
"description": ""
|
||||
},
|
||||
"placeholder_additional_text": {
|
||||
"message": "Dodatkowy tekst",
|
||||
"description": ""
|
||||
},
|
||||
"placeholder_junk_score": {
|
||||
"message": "Wynik spam",
|
||||
"description": ""
|
||||
},
|
||||
"placeholder_recipients": {
|
||||
"message": "Odbiorcy",
|
||||
"description": ""
|
||||
},
|
||||
"placeholder_cc_list": {
|
||||
"message": "Lista DW",
|
||||
"description": ""
|
||||
},
|
||||
"placeholder_author": {
|
||||
"message": "Autor",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_placeholders_use_default_value": {
|
||||
"message": "Symbole zastępcze: użyj wartości domyślnej",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_placeholders_use_default_value_info": {
|
||||
"message": "Jeśli zaznaczone, symbole zastępcze zostaną wypełnione wartościami domyślnymi, gdy nie podano wartości. W przeciwnym razie symbole zastępcze pozostaną na miejscu.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_max_prompt_length": {
|
||||
"message": "Maksymalna długość polecenia",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_max_prompt_length_Info": {
|
||||
"message": "To jest maksymalna liczba znaków, która może być użyta w poleceniu. W przeciwnym razie zostanie wyświetlony komunikat o błędzie. Wartość nie jest edytowalna dla interfejsu webowego ChatGPT.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatgpt_web_model": {
|
||||
"message": "Model interfejsu webowego ChatGPT",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatgpt_web_model_info": {
|
||||
"message": "To jest model, który będzie wymuszony dla interfejsu webowego ChatGPT. Jeśli nie zostanie określony lub podano nieprawidłowy, domyślny model zostanie ustawiony przez ChatGPT na stronie.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatgpt_web_tempchat": {
|
||||
"message": "Tymczasowy czat w interfejsie webowym ChatGPT",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatgpt_web_tempchat_info": {
|
||||
"message": "Jeśli zaznaczone, w interfejsie webowym ChatGPT będzie używany tymczasowy czat.",
|
||||
"description": ""
|
||||
},
|
||||
"chatgpt_btn_model": {
|
||||
"message": "Użyj bieżącego modelu",
|
||||
"description": ""
|
||||
},
|
||||
"SendingPrompt": {
|
||||
"message": "Wysyłanie polecenia...",
|
||||
"description": ""
|
||||
},
|
||||
"AllowedValues": {
|
||||
"message": "Dozwolone wartości",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_btnManagePrompts_infoline": {
|
||||
"message": "Możesz użyć dodatkowych symboli zastępczych danych.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_btnManagePrompts_infoline2": {
|
||||
"message": "Możesz zmienić polecenie według własnego uznania, ale odpowiedź otrzymana od AI musi być listą tagów oddzielonych przecinkami!",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_openai_comp_use_v1": {
|
||||
"message": "Zachowaj kompatybilność z \"v1\"",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_openai_comp_use_v1_info": {
|
||||
"message": "Jeśli zaznaczone, segment \"v1\" w ścieżce wywołań API zostanie zachowany, np. \"http://localhost:1234/v1/chat/completions\".",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_owl_warning": {
|
||||
"message": "Wygląda na to, że przynajmniej jedno z Twoich kont używa dodatku Owl for Exchange. Istnieje znany problem między Thunderbirdem a Owl, który jest obecnie rozwiązywany. Na ten moment możesz używać ThunderAI podczas pisania e-maili, ale nie podczas ich czytania.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatgpt_web_model_tooltip": {
|
||||
"message": "Kliknij na wartość, aby ją ustawić.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_reply_full_text": {
|
||||
"message": "Odpowiedz na poniższy e-mail. Odpowiedz wyłącznie wymaganym tekstem, bez dodatkowych komentarzy ani innego tekstu.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_reply_additional_text": {
|
||||
"message": "Nie dodawaj tematu do odpowiedzi.",
|
||||
"description": ""
|
||||
},
|
||||
"reply_same_lang": {
|
||||
"message": "Odpowiedz w tym samym języku.",
|
||||
"description": ""
|
||||
},
|
||||
"sign_msg_as": {
|
||||
"message": "Podpisz wiadomość jako",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_reply_advanced_full_text": {
|
||||
"message": "Odpowiedz na poniższy e-mail \"{%selected_text%}\", biorąc pod uwagę, że jest to pełny wątek e-maili \"{%mail_html_body%}\". Odpowiedz wyłącznie wymaganym tekstem, bez dodatkowych komentarzy ani innego tekstu.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_rewrite_full_text": {
|
||||
"message": "Przepisz poniższy tekst, aby był bardziej uprzejmy. Odpowiedz wyłącznie przepisanym tekstem, bez dodatkowych komentarzy ani innego tekstu.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_rewrite_formal_full_text": {
|
||||
"message": "Przepisz poniższy tekst, aby był bardziej formalny. Odpowiedz wyłącznie przepisanym tekstem, bez dodatkowych komentarzy ani innego tekstu.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_classify_full_text": {
|
||||
"message": "Sklasyfikuj poniższy tekst pod względem uprzejmości, serdeczności, formalności, stanowczości, obraźliwości, podając procent dla każdej kategorii. Odpowiedz wyłącznie kategorią i wynikiem, bez dodatkowych komentarzy ani innego tekstu.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_summarize_this_full_text": {
|
||||
"message": "Podsumuj poniższy e-mail w formie listy punktowanej.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_translate_this_full_text": {
|
||||
"message": "Przetłumacz poniższy e-mail na",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_this_full_text": {
|
||||
"message": "Odpowiedz wyłącznie wymaganym tekstem, bez dodatkowych komentarzy ani innego tekstu.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags": {
|
||||
"message": "Dodaj tagi do e-maili",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_Info": {
|
||||
"message": "Jeśli zaznaczone, element zostanie uwzględniony w menu w celu zastosowania tagów do e-maili.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags": {
|
||||
"message": "Dodaj tagi do tego e-maila",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags_full_text": {
|
||||
"message": "Przeanalizuj poniższy tekst e-maila i wygeneruj listę tagów oddzielonych przecinkami, które podsumowują jego treść. Użyj tematów, kluczowych zagadnień i odpowiednich opisów jako tagów. Upewnij się, że tagi są zwięzłe i odpowiednie do treści e-maila. Tekst e-maila: {%mail_text_body%} Weź pod uwagę następujące szczegóły w kontekście: - Nadawca: {%author%} - Odbiorcy: {%recipients%} - Lista DW: {%cc_list%} - Temat e-maila: {%mail_subject%} Oprzyj swoje tagi na treści i kontekście e-maila, ignorując zbędne informacje lub nieistotne szczegóły. Wynik powinien być jedynie listą tagów oddzielonych przecinkami, bez żadnych dodatkowych komentarzy ani tekstu.",
|
||||
"description": ""
|
||||
},
|
||||
"placeholder_tags_current_email": {
|
||||
"message": "Tagi e-maila",
|
||||
"description": ""
|
||||
},
|
||||
"placeholder_tags_full_list": {
|
||||
"message": "Istniejące tagi",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_maxnum": {
|
||||
"message": "Maksymalna liczba tagów",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_maxnum_Info": {
|
||||
"message": "Maksymalna liczba tagów proponowanych przez AI. Ustaw na 0, jeśli nie chcesz ograniczać liczby tagów.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags_maxnum": {
|
||||
"message": "Ogranicz liczbę tagów do",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_hide_exclusions": {
|
||||
"message": "Ukryj wykluczone tagi",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_hide_exclusions_Info": {
|
||||
"message": "Jeśli zaznaczone, tagi znajdujące się na liście wykluczeń zostaną ukryte w oknie potwierdzenia.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_btnManageTagsInfo": {
|
||||
"message": "Zarządzaj ustawieniami tagów",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_PageTitle": {
|
||||
"message": "Zarządzaj Ustawieniami Tagów",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_info_default": {
|
||||
"message": "Na tej stronie możesz zmodyfikować domyślne polecenie używane do dodawania tagów do e-maili i zarządzać listą wykluczeń.",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_prompt_text_title": {
|
||||
"message": "Aktualny tekst polecenia",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_excl_list_title": {
|
||||
"message": "Lista wykluczeń",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_excl_list_infoline": {
|
||||
"message": "Jest to lista tagów, które nie mogą być dodane do e-maili.",
|
||||
"description": ""
|
||||
},
|
||||
"save": {
|
||||
"message": "Zapisz",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_info_additional_statements": {
|
||||
"message": "To stwierdzenie zostanie dodane na końcu polecenia:",
|
||||
"description": ""
|
||||
},
|
||||
"reset_default": {
|
||||
"message": "Przywróć domyślne",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_excl_list_infoline2": {
|
||||
"message": "Dodaj jedno słowo na linię lub oddzielone przecinkiem.",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_dialog_title": {
|
||||
"message": "Dodaj tagi do e-maila",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_exclude_tag": {
|
||||
"message": "Wyklucz tag",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_no_tags_received": {
|
||||
"message": "Nie otrzymano tagów od AI.",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_no_valid_tags": {
|
||||
"message": "Nie znaleziono poprawnych tagów po przefiltrowaniu z listą wykluczeń.",
|
||||
"description": ""
|
||||
},
|
||||
"thunderai_error_title": {
|
||||
"message": "Błąd ThunderAI",
|
||||
"description": ""
|
||||
},
|
||||
"thunderai_warning_title": {
|
||||
"message": "Ostrzeżenie ThunderAI",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_first_uppercase": {
|
||||
"message": "Pierwsza litera wielka",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_first_uppercase_Info": {
|
||||
"message": "Jeśli zaznaczone, etykieta tagów będzie ustawiona na małe litery z wyjątkiem pierwszej wielkiej litery.",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_prompt_prefs_title": {
|
||||
"message": "Opcje dodawania tagów",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_SurveyLinkText": {
|
||||
"message": "Podziel się swoją opinią i pomóż nam ulepszyć ThunderAI!",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_SurveyLinkText2": {
|
||||
"message": "Kliknij tutaj, to zajmuje tylko minutę!",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OpenAIComp_ForceModel": {
|
||||
"message": "Ręcznie wprowadź model",
|
||||
"description": ""
|
||||
},
|
||||
"OpenAIComp_force_model_ask": {
|
||||
"message": "Wprowadź tutaj nazwę modelu, którego chcesz użyć.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_force_lang": {
|
||||
"message": "Wymuś język",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_force_lang_Info": {
|
||||
"message": "Jeśli zaznaczone, język tagów zostanie wymuszony na zgodny z językiem określonym na stronie opcji ThunderAI, jeśli został zdefiniowany.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags_force_lang": {
|
||||
"message": "Tagi muszą być napisane w",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
|
|
@ -680,7 +680,11 @@
|
|||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_btnManagePrompts_infoline": {
|
||||
"message": "Agora você pode usar marcadores de posição adicionais!",
|
||||
"message": "Você pode usar espaços reservados para dados adicionais.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_btnManagePrompts_infoline2": {
|
||||
"message": "Você pode alterar o prompt como quiser, mas a resposta recebida da IA deve ser uma lista de tags separadas por vírgulas!",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_openai_comp_use_v1": {
|
||||
|
|
@ -694,5 +698,201 @@
|
|||
"prefs_OptionText_owl_warning": {
|
||||
"message": "Parece que pelo menos uma das suas contas está usando o complemento Coruja para Exchange. Existe um problema conhecido entre Thunderbird e Coruja, que está sendo resolvido no momento. Por enquanto, você pode usar o ThunderAI ao redigir e-mails, mas não ao lê-los.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_chatgpt_web_model_tooltip": {
|
||||
"message": "Clique em um valor para defini-lo.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_reply_full_text": {
|
||||
"message": "Responda ao e-mail a seguir. Responda apenas com o texto necessário e sem comentários adicionais ou outros textos.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_reply_additional_text": {
|
||||
"message": "Não adicione a linha de assunto à resposta.",
|
||||
"description": ""
|
||||
},
|
||||
"reply_same_lang": {
|
||||
"message": "Responda no mesmo idioma.",
|
||||
"description": ""
|
||||
},
|
||||
"sign_msg_as": {
|
||||
"message": "Assine a mensagem como",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_reply_advanced_full_text": {
|
||||
"message": "Responda ao seguinte e-mail \"{%selected_text%}\", considerando que este é o thread completo de e-mails \"{%mail_html_body%}\". Responda apenas com o texto necessário e sem comentários adicionais ou outros textos.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_rewrite_full_text": {
|
||||
"message": "Reescreva o texto a seguir de forma mais educada. Responda apenas com o texto reescrito e sem comentários adicionais ou outros textos.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_rewrite_formal_full_text": {
|
||||
"message": "Reescreva o texto a seguir de forma mais formal. Responda apenas com o texto reescrito e sem comentários adicionais ou outros textos.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_classify_full_text": {
|
||||
"message": "Classifique o texto a seguir em termos de Educação, Calor, Formalidade, Assertividade e Ofensividade, atribuindo uma porcentagem para cada categoria. Responda apenas com as categorias e as pontuações, sem comentários adicionais ou outros textos.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_summarize_this_full_text": {
|
||||
"message": "Resuma o e-mail a seguir em uma lista de tópicos.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_translate_this_full_text": {
|
||||
"message": "Traduza o e-mail a seguir para",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_this_full_text": {
|
||||
"message": "Responda apenas com o texto necessário e sem comentários adicionais ou outros textos.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags": {
|
||||
"message": "Adicione tags aos e-mails",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_Info": {
|
||||
"message": "Se marcado, um item será incluído no menu para aplicar tags aos e-mails.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags": {
|
||||
"message": "Adicione tags a este e-mail",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags_full_text": {
|
||||
"message": "Analise o seguinte texto do e-mail e gere uma lista de tags separadas por vírgulas que resumam seu conteúdo. Use temas, tópicos principais e descritores relevantes como tags. Certifique-se de que as tags sejam concisas e relevantes para o conteúdo do e-mail. Texto do e-mail: {%mail_text_body%} Considere os seguintes detalhes como contexto: - Remetente: {%author%} - Destinatários: {%recipients%} - Lista CC: {%cc_list%} - Assunto do e-mail: {%mail_subject%} Baseie suas tags no texto e contexto do e-mail, ignorando informações desnecessárias ou triviais. A saída deve ser apenas uma lista de tags separadas por vírgulas, sem nenhum comentário ou texto adicional.",
|
||||
"description": ""
|
||||
},
|
||||
"placeholder_tags_current_email": {
|
||||
"message": "Tags do e-mail",
|
||||
"description": ""
|
||||
},
|
||||
"placeholder_tags_full_list": {
|
||||
"message": "Tags existentes",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_maxnum": {
|
||||
"message": "Número máximo de tags",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_maxnum_Info": {
|
||||
"message": "O número máximo de tags proposto pela IA. Defina como 0 se você não quiser limitar o número de tags.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags_maxnum": {
|
||||
"message": "Limite o número de tags para",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_hide_exclusions": {
|
||||
"message": "Ocultar tags excluídas",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_hide_exclusions_Info": {
|
||||
"message": "Se marcado, as tags que estão na lista de exclusão serão ocultadas na caixa de diálogo de confirmação.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_btnManageTagsInfo": {
|
||||
"message": "Gerenciar configurações de tags",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_PageTitle": {
|
||||
"message": "Configurações de tags",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_info_default": {
|
||||
"message": "Nesta página, você pode modificar o prompt padrão usado para adicionar tags aos e-mails e gerenciar a lista de exclusão.",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_prompt_text_title": {
|
||||
"message": "Texto do prompt atual",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_excl_list_title": {
|
||||
"message": "Lista de exclusão",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_excl_list_infoline": {
|
||||
"message": "Esta é uma lista de tags que não podem ser adicionadas aos e-mails.",
|
||||
"description": ""
|
||||
},
|
||||
"save": {
|
||||
"message": "Salvar",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_info_additional_statements": {
|
||||
"message": "Esta declaração será adicionada ao final do prompt:",
|
||||
"description": ""
|
||||
},
|
||||
"reset_default": {
|
||||
"message": "Redefinir para o padrão",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_excl_list_infoline2": {
|
||||
"message": "Adicione uma palavra por linha ou separada por vírgula.",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_dialog_title": {
|
||||
"message": "Adicione tags ao e-mail",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_exclude_tag": {
|
||||
"message": "Excluir tag",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_no_tags_received": {
|
||||
"message": "Nenhuma tag recebida da IA.",
|
||||
"description": ""
|
||||
},
|
||||
"addtags_no_valid_tags": {
|
||||
"message": "Nenhuma tag válida encontrada após filtrar com a lista de exclusão.",
|
||||
"description": ""
|
||||
},
|
||||
"thunderai_error_title": {
|
||||
"message": "Erro do ThunderAI",
|
||||
"description": ""
|
||||
},
|
||||
"thunderai_warning_title": {
|
||||
"message": "Aviso do ThunderAI",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_first_uppercase": {
|
||||
"message": "Primeira letra em maiúscula",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_first_uppercase_Info": {
|
||||
"message": "Se marcado, o rótulo das tags será definido em letras minúsculas, com apenas a primeira letra em maiúscula.",
|
||||
"description": ""
|
||||
},
|
||||
"AddTags_prompt_prefs_title": {
|
||||
"message": "Opções de adição de tags",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_SurveyLinkText": {
|
||||
"message": "Compartilhe seu feedback e ajude-nos a melhorar o ThunderAI!",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_SurveyLinkText2": {
|
||||
"message": "Clique aqui, leva apenas um minuto!",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OpenAIComp_ForceModel": {
|
||||
"message": "Insira manualmente o modelo",
|
||||
"description": ""
|
||||
},
|
||||
"OpenAIComp_force_model_ask": {
|
||||
"message": "Insira aqui o nome do modelo que você deseja usar.",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_force_lang": {
|
||||
"message": "Forçar idioma",
|
||||
"description": ""
|
||||
},
|
||||
"prefs_OptionText_add_tags_force_lang_Info": {
|
||||
"message": "Se marcado, o idioma das tags será forçado a corresponder ao idioma definido na página de opções do ThunderAI, se especificado.",
|
||||
"description": ""
|
||||
},
|
||||
"prompt_add_tags_force_lang": {
|
||||
"message": "As tags devem ser escritas em",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
|
|
@ -45,13 +45,13 @@ let worker = null;
|
|||
|
||||
switch (llm) {
|
||||
case "chatgpt_api":
|
||||
worker = new Worker('model-worker-openai.js', { type: 'module' });
|
||||
worker = new Worker('../js/workers/model-worker-openai.js', { type: 'module' });
|
||||
break;
|
||||
case "ollama_api":
|
||||
worker = new Worker('model-worker-ollama.js', { type: 'module' });
|
||||
worker = new Worker('../js/workers/model-worker-ollama.js', { type: 'module' });
|
||||
break;
|
||||
case "openai_comp_api":
|
||||
worker = new Worker('model-worker-openai_comp.js', { type: 'module' });
|
||||
worker = new Worker('../js/workers/model-worker-openai_comp.js', { type: 'module' });
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
17
images/exclude-tag.svg
Normal file
17
images/exclude-tag.svg
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<svg width="128" height="128" style="enable-background:new 0 0 128 128;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g>
|
||||
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="64" x2="64" y1="18.6667" y2="124.8554">
|
||||
<stop offset="0" style="stop-color:#FF5252"/>
|
||||
<stop offset="0.324" style="stop-color:#F33B3B"/>
|
||||
<stop offset="1" style="stop-color:#D50000"/>
|
||||
</linearGradient>
|
||||
<circle cx="64" cy="64" r="60" style="fill:url(#SVGID_1_);"/>
|
||||
<g style="opacity:0.2;">
|
||||
<path d="M64,7c31.43,0,57,25.57,57,57s-25.57,57-57,57S7,95.43,7,64S32.57,7,64,7 M64,4 C30.86,4,4,30.86,4,64s26.86,60,60,60s60-26.86,60-60S97.14,4,64,4L64,4z" style="fill:#424242;"/>
|
||||
</g>
|
||||
<g style="opacity:0.2;">
|
||||
<path d="M104,56c2.21,0,4,1.79,4,4v8c0,2.21-1.79,4-4,4H24c-2.21,0-4-1.79-4-4v-8c0-2.21,1.79-4,4-4H104 M104,53H24c-3.86,0-7,3.14-7,7v8c0,3.86,3.14,7,7,7h80c3.86,0,7-3.14,7-7v-8C111,56.14,107.86,53,104,53L104,53z" style="fill:#424242;"/>
|
||||
</g>
|
||||
<path d="M104,72H24c-2.21,0-4-1.79-4-4v-8c0-2.21,1.79-4,4-4h80c2.21,0,4,1.79,4,4v8 C108,70.21,106.21,72,104,72z" style="fill:#FAFAFA;"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
28
js/mzta-addatags-exclusion-list.js
Normal file
28
js/mzta-addatags-exclusion-list.js
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* ThunderAI [https://micz.it/thunderbird-addon-thunderai/]
|
||||
* Copyright (C) 2024 Mic (m@micz.it)
|
||||
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// These methods are also defined in the file /js/mzta-compose-script.js
|
||||
|
||||
export async function addTags_getExclusionList() {
|
||||
let prefs_excluded_tags = await browser.storage.local.get({add_tags_exclusions: []});
|
||||
return prefs_excluded_tags.add_tags_exclusions;
|
||||
}
|
||||
|
||||
export function addTags_setExclusionList(add_tags_exclusions) {
|
||||
browser.storage.local.set({add_tags_exclusions: add_tags_exclusions});
|
||||
}
|
||||
|
|
@ -61,46 +61,12 @@ switch (message.command) {
|
|||
case 'sendAlert':
|
||||
//console.log(">>>>>> message.curr_tab_type: " + JSON.stringify(message.curr_tab_type));
|
||||
if(message.curr_tab_type == 'mail'){ // workaround for Thunderbird bug not showing the alert
|
||||
// Create dialog elements
|
||||
const dialog_sendAlert = window.document.createElement('dialog');
|
||||
dialog_sendAlert.classList.add('mzta_dialog');
|
||||
|
||||
const content_sendAlert = window.document.createElement('div');
|
||||
content_sendAlert.classList.add('mzta_dialog_content');
|
||||
|
||||
// Create close button
|
||||
const closeButton_sendAlert = window.document.createElement('button');
|
||||
closeButton_sendAlert.classList.add('mzta_dialog_close');
|
||||
closeButton_sendAlert.id = 'mzta_dialog_close';
|
||||
closeButton_sendAlert.textContent = 'Close';
|
||||
|
||||
// Create message element
|
||||
const message_sendAlert = window.document.createElement('div');
|
||||
message_sendAlert.classList.add('mzta_dialog_message');
|
||||
message_sendAlert.textContent = message.message;
|
||||
|
||||
// Append elements to the dialog
|
||||
content_sendAlert.appendChild(message_sendAlert);
|
||||
content_sendAlert.appendChild(closeButton_sendAlert);
|
||||
dialog_sendAlert.appendChild(content_sendAlert);
|
||||
window.document.body.appendChild(dialog_sendAlert);
|
||||
|
||||
// Show the dialog
|
||||
dialog_sendAlert.showModal();
|
||||
|
||||
// Close dialog on button click and remove elements from the DOM
|
||||
closeButton_sendAlert.onclick = () => {
|
||||
dialog_sendAlert.close();
|
||||
dialog_sendAlert.addEventListener('close', () => {
|
||||
dialog_sendAlert.remove();
|
||||
style.remove();
|
||||
});
|
||||
};
|
||||
|
||||
// CSS styles for Thunderbird with support for light and dark themes
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
.mzta_dialog {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
padding: 0;
|
||||
|
|
@ -118,18 +84,23 @@ switch (message.command) {
|
|||
|
||||
.mzta_dialog_content {
|
||||
position: relative;
|
||||
padding: 20px;
|
||||
padding: 10px;
|
||||
overflow-y: auto;
|
||||
overflow-x: clip;
|
||||
max-height: 80vh;
|
||||
flex: 1;
|
||||
margin-bottom: 34px;
|
||||
}
|
||||
|
||||
.mzta_dialog_close {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
bottom: 2px;
|
||||
right: 2px;
|
||||
background: #007bff;
|
||||
border: none;
|
||||
color: #ffffff;
|
||||
font-size: 14px;
|
||||
padding: 8px 12px;
|
||||
padding: 4px 6px;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
|
@ -140,10 +111,22 @@ switch (message.command) {
|
|||
|
||||
.mzta_dialog_message {
|
||||
margin-bottom: 40px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Theme support */
|
||||
h2.addtags{
|
||||
margin:0;
|
||||
font-size: 1.2em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.div_btns{
|
||||
width: 90%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
position: fixed;
|
||||
bottom: 4px;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dialog-bg-color: #ffffff;
|
||||
--dialog-text-color: #000000;
|
||||
|
|
@ -155,29 +138,366 @@ switch (message.command) {
|
|||
--dialog-text-color: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
/* Darker overlay for the page background */
|
||||
.mzta_dialog_overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
z-index: 1000;
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
|
||||
// Create dialog elements
|
||||
const dialog_sendAlert = window.document.createElement('dialog');
|
||||
dialog_sendAlert.classList.add('mzta_dialog');
|
||||
|
||||
const title = document.createElement('h2');
|
||||
title.className = 'addtags';
|
||||
if(message.is_error){
|
||||
title.textContent = browser.i18n.getMessage("thunderai_error_title");
|
||||
}else{
|
||||
title.textContent = browser.i18n.getMessage("thunderai_warning_title");
|
||||
}
|
||||
dialog_sendAlert.appendChild(title);
|
||||
|
||||
const content_sendAlert = window.document.createElement('div');
|
||||
content_sendAlert.classList.add('mzta_dialog_content');
|
||||
|
||||
// Add a div for buttons
|
||||
const buttonsDiv = document.createElement('div');
|
||||
buttonsDiv.className = 'div_btns';
|
||||
|
||||
// Create close button
|
||||
const closeButton_sendAlert = window.document.createElement('button');
|
||||
closeButton_sendAlert.classList.add('mzta_dialog_close');
|
||||
closeButton_sendAlert.id = 'mzta_dialog_close';
|
||||
closeButton_sendAlert.textContent = 'Close';
|
||||
buttonsDiv.appendChild(closeButton_sendAlert);
|
||||
|
||||
// Create message element
|
||||
const message_sendAlert = window.document.createElement('div');
|
||||
message_sendAlert.classList.add('mzta_dialog_message');
|
||||
message_sendAlert.textContent = message.message;
|
||||
|
||||
// Append elements to the dialog
|
||||
content_sendAlert.appendChild(message_sendAlert);
|
||||
dialog_sendAlert.appendChild(content_sendAlert);
|
||||
dialog_sendAlert.appendChild(buttonsDiv);
|
||||
window.document.body.appendChild(dialog_sendAlert);
|
||||
|
||||
// Show the dialog
|
||||
dialog_sendAlert.showModal();
|
||||
|
||||
// Close dialog on button click and remove elements from the DOM
|
||||
closeButton_sendAlert.onclick = () => {
|
||||
dialog_sendAlert.close();
|
||||
dialog_sendAlert.addEventListener('close', () => {
|
||||
dialog_sendAlert.remove();
|
||||
style.remove();
|
||||
});
|
||||
};
|
||||
|
||||
const iframeHeight = window.innerHeight;
|
||||
const iframeWidth = window.innerWidth;
|
||||
|
||||
const dialogRect = dialog_sendAlert.getBoundingClientRect();
|
||||
|
||||
const top = Math.max(0, (iframeHeight - dialogRect.height) / 2);
|
||||
const left = Math.max(0, (iframeWidth - dialogRect.width) / 2);
|
||||
|
||||
dialog_sendAlert.style.top = `${top}px`;
|
||||
dialog_sendAlert.style.left = `${left}px`;
|
||||
dialog_sendAlert.style.maxHeight = `${iframeHeight - 40}px`;
|
||||
|
||||
dialog_sendAlert.style.transform = 'translate(0, 0)';
|
||||
|
||||
}else{
|
||||
alert(message.message);
|
||||
}
|
||||
return Promise.resolve(true);
|
||||
break;
|
||||
|
||||
case "getTags":
|
||||
console.log(">>>>>>>>>>>>>> getTags: " + JSON.stringify(message.tags));
|
||||
|
||||
// ===== These methods are also defined in the file /js/mzta-addatags-exclusion-list.js
|
||||
async function addTags_getExclusionList() {
|
||||
let prefs_excluded_tags = await browser.storage.local.get({add_tags_exclusions: []});
|
||||
console.log(">>>>>>>>>>>>>>> addTags_getExclusionList prefs_excluded_tags: " + JSON.stringify(prefs_excluded_tags));
|
||||
return prefs_excluded_tags.add_tags_exclusions;
|
||||
}
|
||||
|
||||
function addTags_setExclusionList(add_tags_exclusions) {
|
||||
browser.storage.local.set({add_tags_exclusions: add_tags_exclusions});
|
||||
}
|
||||
// ===================================================================================
|
||||
|
||||
// Create and append the styles
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
.mzta_dialog {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
width: 300px;
|
||||
max-width: 90%;
|
||||
max-height: 90%;
|
||||
padding: 0.5em;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||
background-color: var(--dialog-bg-color, #fff);
|
||||
color: var(--dialog-text-color, #000);
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
.mzta_dialog_content {
|
||||
position: relative;
|
||||
padding: 0;
|
||||
overflow-y: auto;
|
||||
max-height: 80vh;
|
||||
flex: 1;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.mzta_dialog_btn {
|
||||
background: #007bff;
|
||||
border: none;
|
||||
color: #ffffff;
|
||||
font-size: 14px;
|
||||
padding: 4px 6px;
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.mzta_dialog_btn_margin{
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.mzta_dialog_btn:hover {
|
||||
background: #0056b3;
|
||||
}
|
||||
|
||||
.mzta_dialog_message {
|
||||
margin-bottom: 40px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.mzta_dialog_message2{
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
.div_btns{
|
||||
width: 90%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
position: fixed;
|
||||
bottom: 4px;
|
||||
}
|
||||
|
||||
.tag_excluded{
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
h2.addtags{
|
||||
margin:0;
|
||||
font-size: 1.2em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
img.exclude-tag-icon{
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-right: 2px;
|
||||
margin-left: 2px;
|
||||
position: relative;
|
||||
top: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--dialog-bg-color: #2e2e2e;
|
||||
--dialog-text-color: #ffffff;
|
||||
}
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
|
||||
async function createDialog(inputString, onSubmit) {
|
||||
// Create the dialog
|
||||
const tags_dialog = document.createElement('dialog');
|
||||
tags_dialog.className = 'mzta_dialog';
|
||||
|
||||
const title = document.createElement('h2');
|
||||
title.className = 'addtags';
|
||||
title.textContent = browser.i18n.getMessage("addtags_dialog_title");
|
||||
tags_dialog.appendChild(title);
|
||||
|
||||
// Create the content
|
||||
const content = document.createElement('div');
|
||||
content.className = 'mzta_dialog_content';
|
||||
|
||||
let no_submit = false;
|
||||
|
||||
// Parse the input string into labels
|
||||
const words = inputString.split(',').map(word => word.trim()).filter(word => word !== '');
|
||||
|
||||
console.log(">>>>>>>>>>>>> words: " + JSON.stringify(words));
|
||||
|
||||
if(words.length == 0){
|
||||
const message = document.createElement('div');
|
||||
message.className = 'mzta_dialog_message2';
|
||||
message.textContent = browser.i18n.getMessage("addtags_no_tags_received");
|
||||
content.appendChild(message);
|
||||
no_submit = true;
|
||||
}
|
||||
|
||||
let prefs_tags = await browser.storage.sync.get({add_tags_hide_exclusions: false});
|
||||
let add_tags_exclusions_list = await addTags_getExclusionList();
|
||||
|
||||
console.log(">>>>>>>>>>>>> add_tags_exclusions_list: " + JSON.stringify(add_tags_exclusions_list));
|
||||
|
||||
const words_final = words
|
||||
.filter(word => word !== '')
|
||||
.map(word => {
|
||||
const isExcluded = add_tags_exclusions_list.some(exclusion =>
|
||||
word.toLowerCase().includes(exclusion.toLowerCase())
|
||||
);
|
||||
|
||||
return {
|
||||
tag: word,
|
||||
excluded: isExcluded ? 1 : 0
|
||||
};
|
||||
});
|
||||
|
||||
console.log(">>>>>>>>>>>>> words_final: " + JSON.stringify(words_final));
|
||||
|
||||
// Create the form
|
||||
const form = document.createElement('form');
|
||||
|
||||
let tags_shown = 0;
|
||||
|
||||
words_final.forEach(word => {
|
||||
const label = document.createElement('label');
|
||||
label.style.display = 'block';
|
||||
const checkbox = document.createElement('input');
|
||||
checkbox.type = 'checkbox';
|
||||
checkbox.checked = true; // Checked by default
|
||||
checkbox.value = word.tag;
|
||||
// Add an image to the checkbox label
|
||||
const img = document.createElement('img');
|
||||
img.src = browser.runtime.getURL("/images/exclude-tag.svg");
|
||||
img.alt = browser.i18n.getMessage("addtags_exclude_tag");
|
||||
img.title = browser.i18n.getMessage("addtags_exclude_tag");
|
||||
img.className = 'exclude-tag-icon';
|
||||
img.addEventListener('click', () => {
|
||||
if (!label.classList.contains('tag_excluded')) {
|
||||
label.classList.add('tag_excluded');
|
||||
if (!add_tags_exclusions_list.includes(word.tag)) {
|
||||
add_tags_exclusions_list.push(word.tag);
|
||||
addTags_setExclusionList(add_tags_exclusions_list);
|
||||
}
|
||||
} else {
|
||||
label.classList.remove('tag_excluded');
|
||||
const idx = add_tags_exclusions_list.indexOf(word.tag);
|
||||
if (idx > -1) {
|
||||
add_tags_exclusions_list.splice(idx, 1);
|
||||
addTags_setExclusionList(add_tags_exclusions_list);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
label.appendChild(checkbox);
|
||||
label.appendChild(img);
|
||||
label.appendChild(document.createTextNode(` ${word.tag}`));
|
||||
if(!word.excluded || (word.excluded && !prefs_tags.add_tags_hide_exclusions)){
|
||||
tags_shown++;
|
||||
form.appendChild(label);
|
||||
}
|
||||
if(word.excluded){
|
||||
label.className = 'tag_excluded';
|
||||
checkbox.checked = false;
|
||||
}
|
||||
});
|
||||
|
||||
if((!no_submit) && (tags_shown == 0)){
|
||||
const message = document.createElement('div');
|
||||
message.className = 'mzta_dialog_message2';
|
||||
message.textContent = browser.i18n.getMessage("addtags_no_valid_tags");
|
||||
content.appendChild(message);
|
||||
no_submit = true;
|
||||
}
|
||||
|
||||
// Add a div for buttons
|
||||
const buttonsDiv = document.createElement('div');
|
||||
buttonsDiv.className = 'div_btns';
|
||||
|
||||
// Add the close button
|
||||
const closeButton = document.createElement('button');
|
||||
closeButton.type = 'button';
|
||||
closeButton.id = 'mzta_dialog_close';
|
||||
closeButton.textContent = 'Close';
|
||||
closeButton.className = 'mzta_dialog_btn mzta_dialog_btn_margin';
|
||||
closeButton.addEventListener('click', closeDialog);
|
||||
buttonsDiv.appendChild(closeButton);
|
||||
|
||||
if(!no_submit){
|
||||
// Add the submit button
|
||||
const submitButton = document.createElement('button');
|
||||
submitButton.type = 'button';
|
||||
submitButton.id = 'mzta_dialog_submit';
|
||||
submitButton.textContent = 'Submit';
|
||||
submitButton.className = 'mzta_dialog_btn';
|
||||
submitButton.addEventListener('click', () => {
|
||||
const selected = Array.from(form.querySelectorAll('input[type=checkbox]:checked')).map(cb => cb.value);
|
||||
onSubmit(selected);
|
||||
closeDialog();
|
||||
});
|
||||
buttonsDiv.appendChild(submitButton);
|
||||
}
|
||||
|
||||
content.appendChild(form);
|
||||
tags_dialog.appendChild(content);
|
||||
tags_dialog.appendChild(buttonsDiv);
|
||||
document.body.appendChild(tags_dialog);
|
||||
|
||||
function closeDialog() {
|
||||
tags_dialog.close();
|
||||
tags_dialog.addEventListener('close', () => {
|
||||
tags_dialog.remove();
|
||||
style.remove();
|
||||
});
|
||||
}
|
||||
|
||||
tags_dialog.showModal();
|
||||
|
||||
const iframeHeight = window.innerHeight;
|
||||
const iframeWidth = window.innerWidth;
|
||||
|
||||
const dialogRect = tags_dialog.getBoundingClientRect();
|
||||
|
||||
const top = Math.max(0, (iframeHeight - dialogRect.height) / 2);
|
||||
const left = Math.max(0, (iframeWidth - dialogRect.width) / 2);
|
||||
|
||||
tags_dialog.style.top = `${top}px`;
|
||||
tags_dialog.style.left = `${left}px`;
|
||||
tags_dialog.style.maxHeight = `${iframeHeight - 40}px`;
|
||||
|
||||
tags_dialog.style.transform = 'translate(0, 0)';
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return createDialog(message.tags, (selected) => {
|
||||
console.log('>>>>>>>>>>>> Selected tags:', selected);
|
||||
browser.runtime.sendMessage({ command: "assign_tags", tags: selected, messageId: message.messageId });
|
||||
});
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
// do nothing
|
||||
return Promise.resolve(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
102
js/mzta-menus.js
102
js/mzta-menus.js
|
|
@ -19,9 +19,10 @@
|
|||
// Some original methods are derived from https://github.com/ali-raheem/Aify/blob/cfadf52f576b7be3720b5b73af7c8d3129c054da/plugin/html/actions.js
|
||||
|
||||
import { getPrompts } from './mzta-prompts.js';
|
||||
import { getLanguageDisplayName, getMenuContextCompose, getMenuContextDisplay, i18nConditionalGet, getMailSubject } from './mzta-utils.js'
|
||||
import { getLanguageDisplayName, getMenuContextCompose, getMenuContextDisplay, i18nConditionalGet, getMailSubject, getTagsList, transformTagsLabels } from './mzta-utils.js'
|
||||
import { taLogger } from './mzta-logger.js';
|
||||
import { placeholdersUtils } from './mzta-placeholders.js';
|
||||
import { mzta_specialCommand_AddTags } from './special_commands/mzta-add-tags.js';
|
||||
|
||||
export class mzta_Menus {
|
||||
|
||||
|
|
@ -50,29 +51,30 @@ export class mzta_Menus {
|
|||
}
|
||||
|
||||
|
||||
async initialize() {
|
||||
async initialize(also_special = false) {
|
||||
this.allPrompts = [];
|
||||
this.rootMenu = [];
|
||||
this.shortcutMenu = [];
|
||||
this.menu_listeners = {};
|
||||
this.allPrompts = await getPrompts(true);
|
||||
this.allPrompts = await getPrompts(true,also_special);
|
||||
this.allPrompts.sort((a, b) => a.name.localeCompare(b.name));
|
||||
this.allPrompts.forEach((prompt) => {
|
||||
this.addAction(prompt)
|
||||
});
|
||||
}
|
||||
|
||||
async reload(){
|
||||
async reload(also_special = false) {
|
||||
await browser.menus.removeAll().catch(error => {
|
||||
console.error("[ThunderAI] ERROR removing the menus: ", error);
|
||||
});
|
||||
this.removeClickListener();
|
||||
this.loadMenus();
|
||||
this.loadMenus(also_special);
|
||||
}
|
||||
|
||||
addAction = (curr_prompt) => {
|
||||
|
||||
let curr_menu_entry = {id: curr_prompt.id, is_default: curr_prompt.is_default, name: curr_prompt.name};
|
||||
let curr_message = null;
|
||||
|
||||
const getMailBody = async (tabs) => {
|
||||
//const tabs = await browser.tabs.query({ active: true, currentWindow: true });
|
||||
|
|
@ -92,7 +94,7 @@ export class mzta_Menus {
|
|||
//A selection is needed, but nothing is selected!
|
||||
//alert(browser.i18n.getMessage('prompt_selection_needed'));
|
||||
browser.tabs.sendMessage(tabs[0].id, { command: "sendAlert", curr_tab_type: tabs[0].type, message : browser.i18n.getMessage('prompt_selection_needed') });
|
||||
return;
|
||||
return {ok:'0'};
|
||||
}
|
||||
|
||||
let body_text = '';
|
||||
|
|
@ -107,13 +109,31 @@ export class mzta_Menus {
|
|||
chatgpt_lang = prefs.default_chatgpt_lang;
|
||||
//console.log(" >>>>>>>>>>>> chatgpt_lang: " + chatgpt_lang);
|
||||
if(chatgpt_lang === ''){
|
||||
chatgpt_lang = 'Reply in the same language.';
|
||||
chatgpt_lang = browser.i18n.getMessage("reply_same_lang");
|
||||
}else{
|
||||
chatgpt_lang = browser.i18n.getMessage("prompt_lang") + " " + chatgpt_lang + ".";
|
||||
}
|
||||
}
|
||||
|
||||
let fullPrompt = '';
|
||||
let tags_full_list = await getTagsList();
|
||||
|
||||
let curr_messages = null;
|
||||
switch(tabs[0].type){
|
||||
case 'mail':
|
||||
curr_messages = await browser.mailTabs.getSelectedMessages();
|
||||
curr_message = curr_messages.messages[0];
|
||||
break;
|
||||
case 'messageDisplay':
|
||||
curr_messages = await messenger.messageDisplay.getDisplayedMessage(tabs[0].id);
|
||||
curr_message = curr_messages;
|
||||
break;
|
||||
case 'messageCompose':
|
||||
curr_messages = await browser.compose.getComposeDetails(tabs[0].id);
|
||||
curr_message = curr_messages;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!placeholdersUtils.hasPlaceholder(curr_prompt.text)){
|
||||
// no placeholders, do as usual
|
||||
fullPrompt = curr_prompt.text + (String(curr_prompt.need_signature) == "1" ? " " + await this.getDefaultSignature():"") + " " + chatgpt_lang + " \"" + (selection_text=='' ? body_text : selection_text) + "\" ";
|
||||
|
|
@ -122,8 +142,6 @@ export class mzta_Menus {
|
|||
let currPHs = await placeholdersUtils.extractPlaceholders(curr_prompt.text);
|
||||
// console.log(">>>>>>>>>> currPHs: " + JSON.stringify(currPHs));
|
||||
let finalSubs = {};
|
||||
let curr_messages = await browser.mailTabs.getSelectedMessages();
|
||||
let curr_message = curr_messages.messages[0];
|
||||
for(let currPH of currPHs){
|
||||
switch(currPH.id){
|
||||
case 'mail_text_body':
|
||||
|
|
@ -151,13 +169,20 @@ export class mzta_Menus {
|
|||
case 'junk_score':
|
||||
finalSubs['junk_score'] = curr_message.junkScore;
|
||||
break;
|
||||
case 'tags_current_email':
|
||||
let tags_current_email_array = await transformTagsLabels(curr_message.tags, tags_full_list[1]);
|
||||
finalSubs['tags_current_email'] = tags_current_email_array.join(", ");
|
||||
break;
|
||||
case 'tags_full_list':
|
||||
finalSubs['tags_full_list'] = tags_full_list[0];
|
||||
break;
|
||||
default: // TODO Manage custom placeholders https://github.com/micz/ThunderAI/issues/156
|
||||
break;
|
||||
}
|
||||
}
|
||||
// console.log(">>>>>>>>>> finalSubs: " + JSON.stringify(finalSubs));
|
||||
let prefs_ph = await browser.storage.sync.get({placeholders_use_default_value: false});
|
||||
fullPrompt = placeholdersUtils.replacePlaceholders(curr_prompt.text, finalSubs, prefs_ph.placeholders_use_default_value, true) + (String(curr_prompt.need_signature) == "1" ? " " + await this.getDefaultSignature():"") + " " + chatgpt_lang;
|
||||
fullPrompt = (placeholdersUtils.replacePlaceholders(curr_prompt.text, finalSubs, prefs_ph.placeholders_use_default_value, true) + (String(curr_prompt.need_signature) == "1" ? " " + await this.getDefaultSignature():"") + " " + chatgpt_lang).trim();
|
||||
}
|
||||
|
||||
switch(curr_prompt.id){
|
||||
|
|
@ -167,10 +192,10 @@ export class mzta_Menus {
|
|||
if(chatgpt_lang2 === ''){
|
||||
chatgpt_lang2 = getLanguageDisplayName(browser.i18n.getUILanguage());
|
||||
}
|
||||
fullPrompt = curr_prompt.text + chatgpt_lang2 + ". \"" + body_text + "\" ";
|
||||
fullPrompt = curr_prompt.text + " " + chatgpt_lang2 + ". \"" + body_text + "\" ";
|
||||
break;
|
||||
case 'prompt_reply':
|
||||
fullPrompt += "Do not add the subject line to the response."
|
||||
fullPrompt += browser.i18n.getMessage("prompt_reply_additional_text");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -179,7 +204,49 @@ export class mzta_Menus {
|
|||
// const tabs = await browser.tabs.query({ active: true, currentWindow: true });
|
||||
// add custom text if needed
|
||||
//browser.runtime.sendMessage({command: "chatgpt_open", prompt: fullPrompt, action: curr_prompt.action, tabId: tabs[0].id});
|
||||
this.openChatGPT(fullPrompt, curr_prompt.action, tabs[0].id, curr_prompt.name, curr_prompt.need_custom_text);
|
||||
if(curr_prompt.is_special == '1'){ // Special prompts
|
||||
switch(curr_prompt.id){
|
||||
case 'prompt_add_tags': // Add tags to the email
|
||||
let tags_current_email = '';
|
||||
let prefs_at = await browser.storage.sync.get({add_tags_maxnum: 3, connection_type: '', add_tags_force_lang: true, default_chatgpt_lang: ''});
|
||||
if((prefs_at.connection_type === '')||(prefs_at.connection_type === null)||(prefs_at.connection_type === undefined)||(prefs_at.connection_type === 'chatgpt_web')){
|
||||
console.error("[ThunderAI | AddTags] Invalid connection type: " + prefs_at.connection_type);
|
||||
return {ok:'0'};
|
||||
}
|
||||
let add_tags_maxnum = prefs_at.add_tags_maxnum;
|
||||
if(add_tags_maxnum > 0){
|
||||
fullPrompt += " " + browser.i18n.getMessage("prompt_add_tags_maxnum") + " " + add_tags_maxnum +".";
|
||||
}
|
||||
if(prefs_at.add_tags_force_lang && prefs_at.default_chatgpt_lang !== ''){
|
||||
fullPrompt += " " + browser.i18n.getMessage("prompt_add_tags_force_lang") + " " + prefs_at.default_chatgpt_lang + ".";
|
||||
}
|
||||
this.logger.log("fullPrompt: " + fullPrompt);
|
||||
// TODO: use the current API, abort if using chatgpt web
|
||||
// COMMENTED TO DO TESTS
|
||||
// tags_current_email = "recipients, TEST, home, work, CAR, light";
|
||||
let cmd_addTags = new mzta_specialCommand_AddTags(fullPrompt,prefs_at.connection_type,true);
|
||||
await cmd_addTags.initWorker();
|
||||
try{
|
||||
tags_current_email = await cmd_addTags.sendPrompt();
|
||||
// console.log(">>>>>>>>>>> tags_current_email: " + tags_current_email);
|
||||
}catch(err){
|
||||
console.error("[ThunderAI] Error getting tags: ", err);
|
||||
browser.tabs.sendMessage(tabs[0].id, { command: "sendAlert", curr_tab_type: tabs[0].type, message: "Error getting tags: " + err });
|
||||
return {ok:'0'};
|
||||
}
|
||||
this.logger.log("tags_current_email: " + tags_current_email);
|
||||
console.log(">>>>>>>>>>>> tags_full_list: " + JSON.stringify(tags_full_list));
|
||||
browser.tabs.sendMessage(tabs[0].id, {command: "getTags", tags: tags_current_email, messageId: curr_message.id});
|
||||
return {ok:'1'};
|
||||
break;
|
||||
default:
|
||||
console.error("[ThunderAI] Unknown special prompt id: " + curr_prompt.id);
|
||||
break;
|
||||
}
|
||||
}else{ // Classic prompts for the API webchat
|
||||
this.openChatGPT(fullPrompt, curr_prompt.action, tabs[0].id, curr_prompt.name, curr_prompt.need_custom_text);
|
||||
return {ok:'1'};
|
||||
}
|
||||
};
|
||||
this.rootMenu.push(curr_menu_entry);
|
||||
};
|
||||
|
|
@ -189,7 +256,7 @@ export class mzta_Menus {
|
|||
if(prefs.default_sign_name===''){
|
||||
return '';
|
||||
}else{
|
||||
return "Sign the message as " + prefs.default_sign_name + ".";
|
||||
return browser.i18n.getMessage("sign_msg_as") + " " + prefs.default_sign_name + ".";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -205,8 +272,8 @@ export class mzta_Menus {
|
|||
this.shortcutMenu.push(curr_menu_entry);
|
||||
}
|
||||
|
||||
async loadMenus() {
|
||||
await this.initialize();
|
||||
async loadMenus(also_special = false) {
|
||||
await this.initialize(also_special);
|
||||
await this.addMenu(this.rootMenu);
|
||||
this.addClickListener();
|
||||
this.loadShortcutMenu();
|
||||
|
|
@ -296,7 +363,7 @@ export class mzta_Menus {
|
|||
if (action) {
|
||||
try {
|
||||
// Execute the action callback
|
||||
await action();
|
||||
return await action();
|
||||
} catch (error) {
|
||||
// Log any errors that occur during execution
|
||||
console.error(`Error executing action for menu item ${id}:`, error);
|
||||
|
|
@ -305,6 +372,7 @@ export class mzta_Menus {
|
|||
// Warn if no action is found for the provided ID
|
||||
console.warn(`No action found for menu item ID: ${id}`);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
135
js/mzta-placeholders-autocomplete.js
Normal file
135
js/mzta-placeholders-autocomplete.js
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* ThunderAI [https://micz.it/thunderbird-addon-thunderai/]
|
||||
* Copyright (C) 2024 Mic (m@micz.it)
|
||||
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export function textareaAutocomplete(textarea, suggestions, type_value = -1) {
|
||||
const container = textarea.closest('.autocomplete-container');
|
||||
const autocompleteList = container.querySelector('.autocomplete-list');
|
||||
let activeIndex = -1;
|
||||
|
||||
textarea.addEventListener('input', () => {
|
||||
const cursorPosition = textarea.selectionStart;
|
||||
const text = textarea.value.substring(0, cursorPosition);
|
||||
const match = text.match(/{%[^\s]*$/);
|
||||
|
||||
if (match) {
|
||||
const lastWord = match[0];
|
||||
let type = type_value;
|
||||
if(type_value === -1) {
|
||||
const tr = textarea.parentNode.parentNode.parentNode;
|
||||
type = tr.querySelector('.type_output').value
|
||||
}
|
||||
// console.log(">>>>>>>>> type: " + type);
|
||||
// console.log(">>>>>>>>> suggestions: " + JSON.stringify(suggestions));
|
||||
// console.log(">>>>>>>>> lastWord: " + lastWord);
|
||||
const matches = suggestions.filter(s => s.command.startsWith(lastWord) && (String(s.type) == String(type) || String(s.type) == '0' )).map(s => s.command);
|
||||
// console.log(">>>>>>>>> matches: " + JSON.stringify(matches));
|
||||
showSuggestions(matches, autocompleteList);
|
||||
} else {
|
||||
hideSuggestions(autocompleteList);
|
||||
}
|
||||
});
|
||||
|
||||
textarea.addEventListener('keydown', (e) => {
|
||||
if (autocompleteList.classList.contains('hidden')) {
|
||||
return;
|
||||
}
|
||||
const items = autocompleteList.querySelectorAll('li');
|
||||
if (items.length > 0) {
|
||||
if (e.key === 'ArrowDown') {
|
||||
e.preventDefault();
|
||||
activeIndex = (activeIndex + 1) % items.length;
|
||||
updateActiveSuggestion(items, activeIndex);
|
||||
} else if (e.key === 'ArrowUp') {
|
||||
e.preventDefault();
|
||||
activeIndex = (activeIndex - 1 + items.length) % items.length;
|
||||
updateActiveSuggestion(items, activeIndex);
|
||||
} else if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
if(activeIndex === -1) activeIndex = 0;
|
||||
if (activeIndex >= 0 && activeIndex < items.length) {
|
||||
insertAutocomplete(items[activeIndex].textContent, textarea);
|
||||
hideSuggestions(autocompleteList);
|
||||
}
|
||||
} else if (e.key === 'Escape') {
|
||||
hideSuggestions(autocompleteList);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function showSuggestions(matches, autocompleteList) {
|
||||
autocompleteList.innerHTML = '';
|
||||
activeIndex = -1;
|
||||
if (matches.length === 0) {
|
||||
hideSuggestions(autocompleteList);
|
||||
return;
|
||||
}
|
||||
matches.forEach(match => {
|
||||
const li = document.createElement('li');
|
||||
li.textContent = match;
|
||||
li.addEventListener('click', () => {
|
||||
insertAutocomplete(match, textarea);
|
||||
hideSuggestions(autocompleteList);
|
||||
});
|
||||
autocompleteList.appendChild(li);
|
||||
});
|
||||
autocompleteList.classList.remove('hidden');
|
||||
}
|
||||
|
||||
function hideSuggestions(autocompleteList) {
|
||||
autocompleteList.classList.add('hidden');
|
||||
activeIndex = -1;
|
||||
}
|
||||
|
||||
function updateActiveSuggestion(items, activeIndex) {
|
||||
items.forEach((item, index) => {
|
||||
item.classList.remove('active');
|
||||
if (index === activeIndex) {
|
||||
item.classList.add('active');
|
||||
item.scrollIntoView({ block: 'nearest' });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function insertAutocomplete(suggestion, textarea) {
|
||||
const cursorPosition = textarea.selectionStart;
|
||||
const textBefore = textarea.value.substring(0, cursorPosition);
|
||||
const textAfter = textarea.value.substring(cursorPosition);
|
||||
const match = textBefore.match(/{%[^\s]*$/);
|
||||
if (match) {
|
||||
const lastWord = match[0];
|
||||
const completion = suggestion.substring(lastWord.length);
|
||||
const newText = textBefore + completion + textAfter;
|
||||
textarea.value = newText;
|
||||
const newCursorPosition = cursorPosition + completion.length;
|
||||
textarea.setSelectionRange(newCursorPosition, newCursorPosition);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('click', (e) => {
|
||||
// Check if the click was outside the textarea or suggestion list
|
||||
const isClickInsideTextarea = e.target.closest('.editor');
|
||||
const isClickInsideAutocompleteList = e.target.closest('.autocomplete-list');
|
||||
|
||||
if (!isClickInsideTextarea && !isClickInsideAutocompleteList) {
|
||||
const container = textarea.closest('.autocomplete-container');
|
||||
const autocompleteList = container.querySelector('.autocomplete-list');
|
||||
hideSuggestions(autocompleteList);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
|
@ -96,6 +96,20 @@ const defaultPlaceholders = [
|
|||
type: 0,
|
||||
is_default: "1",
|
||||
},
|
||||
{
|
||||
id: 'tags_current_email',
|
||||
name: "__MSG_placeholder_tags_current_email__",
|
||||
default_value: "",
|
||||
type: 0,
|
||||
is_default: "1",
|
||||
},
|
||||
{
|
||||
id: 'tags_full_list',
|
||||
name: "__MSG_placeholder_tags_full_list__",
|
||||
default_value: "",
|
||||
type: 0,
|
||||
is_default: "1",
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ const defaultPrompts = [
|
|||
{
|
||||
id: 'prompt_reply',
|
||||
name: "__MSG_prompt_reply__",
|
||||
text: "Reply to the following email. Reply with only the needed text and with no extra comments or other text.",
|
||||
text: "prompt_reply_full_text",
|
||||
type: "1",
|
||||
action: "1",
|
||||
need_selected: "0",
|
||||
|
|
@ -73,11 +73,12 @@ const defaultPrompts = [
|
|||
need_custom_text: "0",
|
||||
define_response_lang: "1",
|
||||
is_default: "1",
|
||||
is_special: "0",
|
||||
},
|
||||
{
|
||||
id: 'prompt_reply_advanced',
|
||||
name: "__MSG_prompt_reply_advanced__",
|
||||
text: "Reply to the following email \"{%selected_text%}\", considering this is the full thread of emails \"{%mail_html_body%}\". Reply with only the needed text and with no extra comments or other text.",
|
||||
text: "prompt_reply_advanced_full_text",
|
||||
type: "1",
|
||||
action: "1",
|
||||
need_selected: "1",
|
||||
|
|
@ -85,11 +86,12 @@ const defaultPrompts = [
|
|||
need_custom_text: "0",
|
||||
define_response_lang: "1",
|
||||
is_default: "1",
|
||||
is_special: "0",
|
||||
},
|
||||
{
|
||||
id: 'prompt_rewrite_polite',
|
||||
name: "__MSG_prompt_rewrite_polite__",
|
||||
text: "Rewrite the following text to be more polite. Reply with only the re-written text and with no extra comments or other text.",
|
||||
text: "prompt_rewrite_full_text",
|
||||
type: "2",
|
||||
action: "2",
|
||||
need_selected: "1",
|
||||
|
|
@ -97,11 +99,12 @@ const defaultPrompts = [
|
|||
need_custom_text: "0",
|
||||
define_response_lang: "1",
|
||||
is_default: "1",
|
||||
is_special: "0",
|
||||
},
|
||||
{
|
||||
id: 'prompt_rewrite_formal',
|
||||
name: "__MSG_prompt_rewrite_formal__",
|
||||
text: "Rewrite the following text to be more formal. Reply with only the re-written text and with no extra comments or other text.",
|
||||
text: "prompt_rewrite_formal_full_text",
|
||||
type: "2",
|
||||
action: "2",
|
||||
need_selected: "1",
|
||||
|
|
@ -109,11 +112,12 @@ const defaultPrompts = [
|
|||
need_custom_text: "0",
|
||||
define_response_lang: "1",
|
||||
is_default: "1",
|
||||
is_special: "0",
|
||||
},
|
||||
{
|
||||
id: 'prompt_classify',
|
||||
name: "__MSG_prompt_classify__",
|
||||
text: "Classify the following text in terms of Politeness, Warmth, Formality, Assertiveness, Offensiveness giving a percentage for each category. Reply with only the category and score with no extra comments or other text.",
|
||||
text: "prompt_classify_full_text",
|
||||
type: "0",
|
||||
action: "0",
|
||||
need_selected: "0",
|
||||
|
|
@ -121,11 +125,12 @@ const defaultPrompts = [
|
|||
need_custom_text: "0",
|
||||
define_response_lang: "1",
|
||||
is_default: "1",
|
||||
is_special: "0",
|
||||
},
|
||||
{
|
||||
id: 'prompt_summarize_this',
|
||||
name: "__MSG_prompt_summarize_this__",
|
||||
text: "Summarize the following email into a bullet point list.",
|
||||
text: "prompt_summarize_this_full_text",
|
||||
type: "0",
|
||||
action: "0",
|
||||
need_selected: "0",
|
||||
|
|
@ -133,11 +138,12 @@ const defaultPrompts = [
|
|||
need_custom_text: "0",
|
||||
define_response_lang: "1",
|
||||
is_default: "1",
|
||||
is_special: "0",
|
||||
},
|
||||
{
|
||||
id: 'prompt_translate_this',
|
||||
name: "__MSG_prompt_translate_this__",
|
||||
text: "Translate the following email in ",
|
||||
text: "prompt_translate_this_full_text",
|
||||
type: "0",
|
||||
action: "0",
|
||||
need_selected: "0",
|
||||
|
|
@ -145,11 +151,12 @@ const defaultPrompts = [
|
|||
need_custom_text: "0",
|
||||
define_response_lang: "0",
|
||||
is_default: "1",
|
||||
is_special: "0",
|
||||
},
|
||||
{
|
||||
id: 'prompt_this',
|
||||
name: "__MSG_prompt_this__",
|
||||
text: "Reply with only the needed text and with no extra comments or other text.",
|
||||
text: "prompt_this_full_text",
|
||||
type: "2",
|
||||
action: "2",
|
||||
need_selected: "1",
|
||||
|
|
@ -157,16 +164,37 @@ const defaultPrompts = [
|
|||
need_custom_text: "0",
|
||||
define_response_lang: "0",
|
||||
is_default: "1",
|
||||
is_special: "0",
|
||||
},
|
||||
];
|
||||
|
||||
const specialPrompts = [
|
||||
{
|
||||
id: 'prompt_add_tags',
|
||||
name: "__MSG_prompt_add_tags__",
|
||||
text: "prompt_add_tags_full_text",
|
||||
type: "1",
|
||||
action: "0",
|
||||
need_selected: "0",
|
||||
need_signature: "0",
|
||||
need_custom_text: "0",
|
||||
define_response_lang: "0",
|
||||
is_default: "1",
|
||||
is_special: "1",
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
export async function getPrompts(onlyEnabled = false){
|
||||
export async function getPrompts(onlyEnabled = false, includeSpecial = false){
|
||||
const _defaultPrompts = await getDefaultPrompts_withProps();
|
||||
// console.log('>>>>>>>>>>>> getPrompts _defaultPrompts: ' + JSON.stringify(_defaultPrompts));
|
||||
const customPrompts = await getCustomPrompts();
|
||||
// console.log('>>>>>>>>>>>> getPrompts customPrompts: ' + JSON.stringify(customPrompts));
|
||||
let output = _defaultPrompts.concat(customPrompts);
|
||||
const specialPrompts = await getSpecialPrompts();
|
||||
let output = specialPrompts.concat(_defaultPrompts).concat(customPrompts);
|
||||
if(!includeSpecial){
|
||||
output = output.filter(obj => obj.is_special != 1); // we do not want special prompts
|
||||
}
|
||||
if(onlyEnabled){
|
||||
output = output.filter(obj => obj.enabled != 0);
|
||||
}else{ // order only if we are not filtering, the filtering is for the menus and we are ordering there after i18n
|
||||
|
|
@ -223,6 +251,7 @@ async function getDefaultPrompts_withProps() {
|
|||
if(prefs._default_prompts_properties === null){ // no default prompts properties saved
|
||||
let pos = 1;
|
||||
defaultPrompts_prop.forEach((prompt) => {
|
||||
prompt.text = browser.i18n.getMessage(prompt.text);
|
||||
prompt.position_display = pos;
|
||||
prompt.position_compose = pos;
|
||||
prompt.enabled = 1;
|
||||
|
|
@ -232,6 +261,7 @@ async function getDefaultPrompts_withProps() {
|
|||
} else { // we have saved default prompts properties
|
||||
let pos = 1000;
|
||||
defaultPrompts_prop.forEach((prompt) => {
|
||||
prompt.text = browser.i18n.getMessage(prompt.text);
|
||||
if(prefs._default_prompts_properties?.[prompt.id]){
|
||||
prompt.position_compose = prefs._default_prompts_properties[prompt.id].position_compose;
|
||||
prompt.position_display = prefs._default_prompts_properties[prompt.id].position_display;
|
||||
|
|
@ -268,7 +298,24 @@ export async function setDefaultPromptsProperties(prompts) {
|
|||
await browser.storage.local.set({_default_prompts_properties: default_prompts_properties});
|
||||
}
|
||||
|
||||
|
||||
export async function setCustomPrompts(prompts) {
|
||||
await browser.storage.local.set({_custom_prompt: prompts});
|
||||
}
|
||||
|
||||
export async function getSpecialPrompts(){
|
||||
let prefs = await browser.storage.local.get({_special_prompts: null});
|
||||
if(prefs._special_prompts === null){
|
||||
let def_specPrompts = [...specialPrompts];
|
||||
def_specPrompts.forEach((prompt) => {
|
||||
prompt.text = browser.i18n.getMessage(prompt.text);
|
||||
})
|
||||
return def_specPrompts;
|
||||
} else {
|
||||
return prefs._special_prompts;
|
||||
}
|
||||
}
|
||||
|
||||
export async function setSpecialPrompts(prompts) {
|
||||
// console.log(">>>>>>>>>>>> setSpecialPrompts prompts: " + JSON.stringify(prompts));
|
||||
await browser.storage.local.set({_special_prompts: prompts});
|
||||
}
|
||||
|
|
@ -176,6 +176,92 @@ export function generateCallID(length = 10) {
|
|||
return result;
|
||||
}
|
||||
|
||||
export async function getTagsList(){
|
||||
let messageTags = {};
|
||||
if(await isThunderbird128OrGreater()) {
|
||||
messageTags = await browser.messages.tags.list();
|
||||
} else {
|
||||
messageTags = await browser.messages.listTags();
|
||||
}
|
||||
const output = messageTags.map(tag => tag.tag).join(', ');
|
||||
|
||||
const output2 = messageTags.reduce((acc, messageTag) => {
|
||||
acc[messageTag.key] = {
|
||||
tag: messageTag.tag,
|
||||
color: messageTag.color,
|
||||
key: messageTag.key,
|
||||
ordinal: messageTag.ordinal,
|
||||
};
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
return [output, output2]; // Return the list of tags and the list of tags objects as an array
|
||||
}
|
||||
|
||||
export async function createTag(tag) {
|
||||
let prefs_tag = await browser.storage.sync.get({add_tags_first_uppercase: true});
|
||||
if(prefs_tag.add_tags_first_uppercase) tag = tag.toLowerCase().charAt(0).toUpperCase() + tag.toLowerCase().slice(1);
|
||||
try {
|
||||
if(await isThunderbird128OrGreater()) {
|
||||
return browser.messages.tags.create('$ta-'+sanitizeString(tag), tag, generateHexColorForTag());
|
||||
}else{
|
||||
return browser.messages.createTag('$ta-'+sanitizeString(tag), tag, generateHexColorForTag());
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[ThunderAI] Error creating tag:', error);
|
||||
}
|
||||
}
|
||||
|
||||
export function checkIfTagExists(tag, tags_list) {
|
||||
return tags_list.hasOwnProperty("$ta-" + sanitizeString(tag));
|
||||
}
|
||||
|
||||
export async function assignTagsToMessage(messageId, tags) {
|
||||
tags = tags.map(tag => `$ta-${sanitizeString(tag)}`);
|
||||
let msg_prop = await browser.messages.get(messageId);
|
||||
tags = tags.concat(msg_prop.tags || []);
|
||||
try {
|
||||
return browser.messages.update(messageId, {tags: tags});
|
||||
} catch (error) {
|
||||
console.error('[ThunderAI] Error assigning tag [messageId: ', messageId, ' - tag: ', tag, ']:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function sanitizeString(input) {
|
||||
input = input.toLowerCase();
|
||||
// Define the regex to match valid characters
|
||||
const regex = /^[^ ()/{%*<>"]+$/;
|
||||
// Filter out invalid characters from the string
|
||||
let sanitized = '';
|
||||
for (const char of input) {
|
||||
// Check if the character is valid according to the regex
|
||||
if (regex.test(char)) {
|
||||
sanitized += char;
|
||||
}
|
||||
}
|
||||
|
||||
return sanitized;
|
||||
}
|
||||
|
||||
function generateHexColorForTag() {
|
||||
const red = Math.floor(Math.random() * 256);
|
||||
const green = Math.floor(Math.random() * 256);
|
||||
const blue = Math.floor(Math.random() * 256);
|
||||
|
||||
const hexColor = `#${red.toString(16).padStart(2, '0')}${green.toString(16).padStart(2, '0')}${blue.toString(16).padStart(2, '0')}`;
|
||||
|
||||
return hexColor;
|
||||
}
|
||||
|
||||
export async function transformTagsLabels(labels, tags_list) {
|
||||
console.log(">>>>>>>>> transformTagsLabels labels: " + labels);
|
||||
console.log(">>>>>>>>> transformTagsLabels tags_list: " + tags_list);
|
||||
let output = [];
|
||||
for(let label of labels) {
|
||||
output.push(tags_list[label].tag);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
// The following methods are a modified version derived from https://github.com/ali-raheem/Aify/blob/13ff87583bc520fb80f555ab90a90c5c9df797a7/plugin/content_scripts/compose.js
|
||||
|
|
|
|||
114
js/special_commands/mzta-add-tags.js
Normal file
114
js/special_commands/mzta-add-tags.js
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* ThunderAI [https://micz.it/thunderbird-addon-thunderai/]
|
||||
* Copyright (C) 2024 Mic (m@micz.it)
|
||||
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// Call the API to get the tags
|
||||
|
||||
import { taLogger } from '../mzta-logger.js';
|
||||
|
||||
|
||||
export class mzta_specialCommand_AddTags {
|
||||
|
||||
prompt = "";
|
||||
worker = null;
|
||||
llm = "";
|
||||
full_message = "";
|
||||
logger = null;
|
||||
do_debug = false;
|
||||
|
||||
constructor(prompt, llm, do_debug = false) {
|
||||
this.prompt = prompt;
|
||||
this.llm = llm;
|
||||
this.logger = new taLogger('mzta_specialCommand_AddTags', do_debug);
|
||||
this.do_debug = do_debug;
|
||||
switch (this.llm) {
|
||||
case "chatgpt_api":
|
||||
this.worker = new Worker(new URL('../workers/model-worker-openai.js', import.meta.url), { type: 'module' });
|
||||
break;
|
||||
case "ollama_api":
|
||||
this.worker = new Worker(new URL('../workers/model-worker-ollama.js', import.meta.url), { type: 'module' });
|
||||
break;
|
||||
case "openai_comp_api":
|
||||
this.worker = new Worker(new URL('../workers/model-worker-openai_comp.js', import.meta.url), { type: 'module' });
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
async initWorker() {
|
||||
switch (this.llm) {
|
||||
case "chatgpt_api":
|
||||
let prefs_api = await browser.storage.sync.get({chatgpt_api_key: '', chatgpt_model: ''});
|
||||
this.worker.postMessage({ type: 'init', chatgpt_api_key: prefs_api.chatgpt_api_key, chatgpt_model: prefs_api.chatgpt_model, do_debug: this.do_debug, i18nStrings: ''});
|
||||
break;
|
||||
case "ollama_api": {
|
||||
let prefs_api = await browser.storage.sync.get({ollama_host: '', ollama_model: ''});
|
||||
this.worker.postMessage({ type: 'init', ollama_host: prefs_api.ollama_host, ollama_model: prefs_api.ollama_model, do_debug: this.do_debug, i18nStrings: ''});
|
||||
break;
|
||||
}
|
||||
case "openai_comp_api": {
|
||||
let prefs_api = await browser.storage.sync.get({openai_comp_host: '', openai_comp_model: '', openai_comp_api_key: '', openai_comp_use_v1: true, openai_comp_chat_name: '', do_debug: false});
|
||||
console.log(">>>>>>>>>>>> [ThunderAI] prefs_api: " + JSON.stringify(prefs_api));
|
||||
this.worker.postMessage({ type: 'init', openai_comp_host: prefs_api.openai_comp_host, openai_comp_model: prefs_api.openai_comp_model, openai_comp_api_key: prefs_api.openai_comp_api_key, openai_comp_use_v1: prefs_api.openai_comp_use_v1, do_debug: this.do_debug, i18nStrings: ''});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sendPrompt(){
|
||||
return new Promise((resolve, reject) => {
|
||||
// Event listeners for worker messages
|
||||
this.worker.onmessage = (event) => {
|
||||
const { type, payload } = event.data;
|
||||
// console.log(`>>>>>>>>>>>> [Worker Message Received] type: ${type}`, payload);
|
||||
switch (type) {
|
||||
case 'messageSent':
|
||||
break;
|
||||
case 'newToken':
|
||||
this.full_message += payload.token;
|
||||
break;
|
||||
case 'tokensDone':
|
||||
console.log(">>>>>>>>>>>> [ThunderAI] tokensDone: " + this.full_message);
|
||||
resolve(this.full_message); // Resolve the promise with the full message
|
||||
break;
|
||||
case 'error':
|
||||
console.error('[ThunderAI] Error from API worker:', payload);
|
||||
reject(new Error(`[ThunderAI] Error from API worker: ${payload}`)); // Use a single error object
|
||||
break;
|
||||
default:
|
||||
console.error('[ThunderAI] Unknown event type from API worker:', type);
|
||||
}
|
||||
};
|
||||
|
||||
this.worker.onerror = (error) => {
|
||||
console.error('[ThunderAI] Worker Error Details:');
|
||||
console.error('Message:', error.message);
|
||||
console.error('Filename:', error.filename);
|
||||
console.error('Line Number:', error.lineno);
|
||||
console.error('Column Number:', error.colno);
|
||||
console.error('Event:', error);
|
||||
reject(error);
|
||||
};
|
||||
|
||||
try {
|
||||
// console.log('[ThunderAI] Sending prompt to worker:', this.prompt);
|
||||
this.worker.postMessage({ type: 'chatMessage', message: this.prompt });
|
||||
} catch (error) {
|
||||
console.error('[ThunderAI] Failed to send message to worker:', error);
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -20,8 +20,8 @@
|
|||
* The original code has been released under the Apache License, Version 2.0.
|
||||
*/
|
||||
|
||||
import { Ollama } from '../js/api/ollama.js';
|
||||
import { taLogger } from '../js/mzta-logger.js';
|
||||
import { Ollama } from '../api/ollama.js';
|
||||
import { taLogger } from '../mzta-logger.js';
|
||||
|
||||
let ollama_host = null;
|
||||
let ollama_model = '';
|
||||
|
|
@ -20,8 +20,8 @@
|
|||
* The original code has been released under the Apache License, Version 2.0.
|
||||
*/
|
||||
|
||||
import { OpenAI } from '../js/api/openai.js';
|
||||
import { taLogger } from '../js/mzta-logger.js';
|
||||
import { OpenAI } from '../api/openai.js';
|
||||
import { taLogger } from '../mzta-logger.js';
|
||||
|
||||
let chatgpt_api_key = null;
|
||||
let chatgpt_model = '';
|
||||
|
|
@ -20,8 +20,8 @@
|
|||
* The original code has been released under the Apache License, Version 2.0.
|
||||
*/
|
||||
|
||||
import { OpenAIComp } from '../js/api/openai_comp.js';
|
||||
import { taLogger } from '../js/mzta-logger.js';
|
||||
import { OpenAIComp } from '../api/openai_comp.js';
|
||||
import { taLogger } from '../mzta-logger.js';
|
||||
|
||||
let openai_comp_host = null;
|
||||
let openai_comp_model = '';
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
"manifest_version": 2,
|
||||
"name": "ThunderAI",
|
||||
"description": "__MSG_extensionDescription__",
|
||||
"version": "2.3.4",
|
||||
"version": "3.0.0pre3",
|
||||
"author": "Mic (m@micz.it)",
|
||||
"homepage_url": "https://micz.it/thunderbird-addon-thunderai/",
|
||||
"browser_specific_settings": {
|
||||
|
|
@ -31,6 +31,9 @@
|
|||
"activeTab",
|
||||
"accountsRead",
|
||||
"downloads",
|
||||
"messagesTagsList",
|
||||
"messagesTags",
|
||||
"messagesUpdate",
|
||||
"https://*.chatgpt.com/*"
|
||||
],
|
||||
"background": {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import { mzta_script } from './js/mzta-chatgpt.js';
|
|||
import { prefs_default } from './options/mzta-options-default.js';
|
||||
import { mzta_Menus } from './js/mzta-menus.js';
|
||||
import { taLogger } from './js/mzta-logger.js';
|
||||
import { getCurrentIdentity, getOriginalBody, replaceBody, setBody, i18nConditionalGet, generateCallID, migrateCustomPromptsStorage, migrateDefaultPromptsPropStorage, getGPTWebModelString } from './js/mzta-utils.js';
|
||||
import { getCurrentIdentity, getOriginalBody, replaceBody, setBody, i18nConditionalGet, generateCallID, migrateCustomPromptsStorage, migrateDefaultPromptsPropStorage, getGPTWebModelString, getTagsList, createTag, assignTagsToMessage, checkIfTagExists } from './js/mzta-utils.js';
|
||||
|
||||
await migrateCustomPromptsStorage();
|
||||
await migrateDefaultPromptsPropStorage();
|
||||
|
|
@ -28,8 +28,8 @@ await migrateDefaultPromptsPropStorage();
|
|||
var original_html = '';
|
||||
var modified_html = '';
|
||||
|
||||
let prefs_debug = await browser.storage.sync.get({do_debug: false});
|
||||
let taLog = new taLogger("mzta-background",prefs_debug.do_debug);
|
||||
let prefs_init = await browser.storage.sync.get({do_debug: false, add_tags: true, connection_type: 'chatgpt_web'});
|
||||
let taLog = new taLogger("mzta-background",prefs_init.do_debug);
|
||||
|
||||
browser.composeScripts.register({
|
||||
js: [{file: "/js/mzta-compose-script.js"}]
|
||||
|
|
@ -210,14 +210,17 @@ messenger.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|||
return _reloadBody(message.tabId);
|
||||
break;
|
||||
case 'reload_menus':
|
||||
menus.reload();
|
||||
taLog.log("Reloading menus");
|
||||
return Promise.resolve(true);
|
||||
async function _reload_menus() {
|
||||
let prefs_reload = await browser.storage.sync.get({add_tags: true, connection_type: 'chatgpt_web'});
|
||||
menus.reload(prefs_reload.add_tags && (prefs_reload.connection_type !== "chatgpt_web"));
|
||||
taLog.log("Reloading menus");
|
||||
return true;
|
||||
}
|
||||
return _reload_menus();
|
||||
break;
|
||||
case 'shortcut_do_prompt':
|
||||
taLog.log("Executing shortcut, promptId: " + message.promptId);
|
||||
menus.executeMenuAction(message.promptId);
|
||||
return Promise.resolve(true);
|
||||
return menus.executeMenuAction(message.promptId);
|
||||
break;
|
||||
case 'popup_menu_ready':
|
||||
async function _popup_menu_ready() {
|
||||
|
|
@ -230,6 +233,26 @@ messenger.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|||
}
|
||||
return _popup_menu_ready();
|
||||
break;
|
||||
case 'assign_tags':
|
||||
async function _assign_tags() {
|
||||
let all_tags_list = await getTagsList();
|
||||
all_tags_list = all_tags_list[1];
|
||||
console.log(">>>>>>>>>>>>>>> all_tags_list: " + JSON.stringify(all_tags_list));
|
||||
taLog.log("assign_tags data: " + JSON.stringify(message));
|
||||
let new_tags = [];
|
||||
for (const tag of message.tags) {
|
||||
console.log(">>>>>>>>>>>>>>> tag: " + tag);
|
||||
if (!checkIfTagExists(tag, all_tags_list)) {
|
||||
taLog.log("Creating tag: " + tag);
|
||||
await createTag(tag);
|
||||
}
|
||||
new_tags.push(tag);
|
||||
}
|
||||
await assignTagsToMessage(message.messageId, new_tags);
|
||||
taLog.log("Assigned tags: " + JSON.stringify(new_tags));
|
||||
}
|
||||
return _assign_tags();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -384,7 +407,7 @@ async function openChatGPT(promptText, action, curr_tabId, prompt_name = '', do_
|
|||
|
||||
let rand_call_id3 = '_ollama_' + generateCallID();
|
||||
|
||||
const listener3 = async (message, sender, sendResponse) => {
|
||||
const listener3 = (message, sender, sendResponse) => {
|
||||
|
||||
function handleOllamaApi(createdTab3) {
|
||||
taLog.log("Ollama API window ready.");
|
||||
|
|
@ -440,7 +463,7 @@ async function openChatGPT(promptText, action, curr_tabId, prompt_name = '', do_
|
|||
let rand_call_id4 = '_openai_comp_api_' + generateCallID();
|
||||
|
||||
|
||||
const listener4 = async (message, sender, sendResponse) => {
|
||||
const listener4 = (message, sender, sendResponse) => {
|
||||
|
||||
function handleOpenAICompApi(createdTab) {
|
||||
let mailMessageId4 = -1;
|
||||
|
|
@ -497,6 +520,23 @@ function checkScreenDimensions(prefs){
|
|||
return prefs;
|
||||
}
|
||||
|
||||
// Register the listener for storage changes
|
||||
browser.storage.onChanged.addListener((changes, areaName) => {
|
||||
// Check if the change happened in the 'sync' storage area
|
||||
if (areaName === 'sync') {
|
||||
// Check if 'add_tags' has changed
|
||||
//console.log(">>>>>>>>>>>>> changes: " + JSON.stringify(changes));
|
||||
if (changes.add_tags) {
|
||||
menus.reload(changes.add_tags.newValue && (prefs_init.connection_type !== "chatgpt_web"));
|
||||
}
|
||||
|
||||
// Check if 'connection_type' has changed
|
||||
if (changes.connection_type) {
|
||||
menus.reload(prefs_init.add_tags && (changes.connection_type.newValue !== "chatgpt_web"));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Menus handling
|
||||
const menus = new mzta_Menus(openChatGPT, prefs_debug.do_debug);
|
||||
menus.loadMenus();
|
||||
const menus = new mzta_Menus(openChatGPT, prefs_init.do_debug);
|
||||
menus.loadMenus(prefs_init.add_tags && (prefs_init.connection_type !== "chatgpt_web"));
|
||||
|
|
@ -37,4 +37,9 @@ export const prefs_default = {
|
|||
dynamic_menu_order_alphabet: true,
|
||||
placeholders_use_default_value: false,
|
||||
max_prompt_length: 30000, // max string length for prompt
|
||||
add_tags: true,
|
||||
add_tags_maxnum: 3,
|
||||
add_tags_hide_exclusions: false,
|
||||
add_tags_first_uppercase: true,
|
||||
add_tags_force_lang: true,
|
||||
}
|
||||
|
|
@ -166,10 +166,31 @@ input.option-input[type="text"]{
|
|||
border-radius: 4px;
|
||||
}
|
||||
|
||||
#mzta_top_msg div{
|
||||
color: white;
|
||||
font-style: italic;
|
||||
background-color: rgb(3, 0, 180);
|
||||
border-radius: 4px;
|
||||
padding: 3px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#mzta_top_msg div a{
|
||||
background-color: white;
|
||||
padding:0px 3px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.conntype_chatgpt_web_option{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn_small{
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background-color: rgb(35, 34, 43);
|
||||
|
|
@ -201,4 +222,8 @@ input.option-input[type="text"]{
|
|||
filter: invert(1);
|
||||
}
|
||||
|
||||
#mzta_top_msg div{
|
||||
background-color: rgb(2, 0, 100);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -8,6 +8,9 @@
|
|||
<div id="miczRelNotes"><a href="mzta-release-notes.html">__MSG_prefs_OptionText_release_notes__</a></div>
|
||||
<div id="miczStatusPage" class="conntype_chatgpt_web"><a href="https://micz.it/thunderbird-addon-thunderai/status/">__MSG_prefs_status_page__</a></div>
|
||||
<table id="miczPrefs">
|
||||
<tr id="mzta_top_msg">
|
||||
<td colspan="2"><div>__MSG_prefs_SurveyLinkText__<br><a href="https://forms.gle/1qK2wcbuhaRzhwyt9">__MSG_prefs_SurveyLinkText2__</a></div></td>
|
||||
</tr>
|
||||
<tr id="owl_warning">
|
||||
<td colspan="2"><div>__MSG_prefs_OptionText_owl_warning__ <a href="https://micz.it/thunderbird-addon-thunderai/owl/">__MSG_customPrompts_managePrompts_help__</a></div></td>
|
||||
</tr>
|
||||
|
|
@ -236,6 +239,7 @@
|
|||
<td>
|
||||
<label>
|
||||
<span>__MSG_OpenAIComp_Models__</span>
|
||||
<br><button id="btnOpenAICompForceModel" class="btn_small">__MSG_prefs_OpenAIComp_ForceModel__</button></td>
|
||||
</label>
|
||||
</td>
|
||||
<td>
|
||||
|
|
@ -266,6 +270,16 @@
|
|||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="add_tags_tr">
|
||||
<td><span>__MSG_prefs_OptionText_add_tags__</span>
|
||||
<br><button id="btnManageTagsInfo" class="btn_small">__MSG_prefs_OptionText_btnManageTagsInfo__</button></td>
|
||||
<td>
|
||||
<label>
|
||||
<input type="checkbox" id="add_tags" name="add_tags" class="option-input" />
|
||||
__MSG_prefs_OptionText_add_tags_Info__
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="width:20em"><label>
|
||||
<span>__MSG_Debug__</span>
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ async function restoreOptions() {
|
|||
|
||||
function showConnectionOptions() {
|
||||
disable_MaxPromptLength();
|
||||
disable_AddTags();
|
||||
let chatgpt_web_display = 'table-row';
|
||||
let chatgpt_api_display = 'none';
|
||||
let ollama_api_display = 'none';
|
||||
|
|
@ -212,6 +213,14 @@ function disable_MaxPromptLength(){
|
|||
maxPromptLength_tr.style.display = (maxPromptLength.disabled) ? 'none' : 'table-row';
|
||||
}
|
||||
|
||||
function disable_AddTags(){
|
||||
let add_tags = document.getElementById('add_tags');
|
||||
let add_tags_tr_elements = document.querySelectorAll('.add_tags_tr');
|
||||
add_tags_tr_elements.forEach(add_tags_tr => {
|
||||
add_tags_tr.style.display = (add_tags.disabled) ? 'none' : 'table-row';
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
await restoreOptions();
|
||||
|
||||
|
|
@ -233,20 +242,53 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||
el.dispatchEvent(new Event('change'), { bubbles: true });
|
||||
});
|
||||
});
|
||||
|
||||
let addtags_el = document.getElementById('add_tags');
|
||||
let addtags_info_btn = document.getElementById('btnManageTagsInfo');
|
||||
addtags_el.addEventListener('click', (event) => {
|
||||
addtags_info_btn.disabled = event.target.checked ? '' : 'disabled';
|
||||
});
|
||||
addtags_info_btn.disabled = addtags_el.checked ? '' : 'disabled';
|
||||
|
||||
document.getElementById('btnManagePrompts').addEventListener('click', () => {
|
||||
// check if the tab is already there
|
||||
browser.tabs.query({url: browser.runtime.getURL('../customprompts/mzta-custom-prompts.html')}).then((tabs) => {
|
||||
browser.tabs.query({url: browser.runtime.getURL('../pages/customprompts/mzta-custom-prompts.html')}).then((tabs) => {
|
||||
if (tabs.length > 0) {
|
||||
// if the tab is already there, focus it
|
||||
browser.tabs.update(tabs[0].id, {active: true});
|
||||
} else {
|
||||
// if the tab is not there, create it
|
||||
browser.tabs.create({url: browser.runtime.getURL('../customprompts/mzta-custom-prompts.html')});
|
||||
browser.tabs.create({url: browser.runtime.getURL('../pages/customprompts/mzta-custom-prompts.html')});
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
document.getElementById('btnManageTagsInfo').addEventListener('click', () => {
|
||||
// check if the tab is already there
|
||||
browser.tabs.query({url: browser.runtime.getURL('../pages/addtags/mzta-add-tags.html')}).then((tabs) => {
|
||||
if (tabs.length > 0) {
|
||||
// if the tab is already there, focus it
|
||||
browser.tabs.update(tabs[0].id, {active: true});
|
||||
} else {
|
||||
// if the tab is not there, create it
|
||||
browser.tabs.create({url: browser.runtime.getURL('../pages/addtags/mzta-add-tags.html')});
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
document.getElementById('btnOpenAICompForceModel').addEventListener('click', () => {
|
||||
let modelName = prompt(browser.i18n.getMessage('OpenAIComp_force_model_ask')).trim();
|
||||
if ((modelName !== null) && (modelName !== undefined) && (modelName !== '')) {
|
||||
let select_openai_comp_model = document.getElementById('openai_comp_model');
|
||||
let option = document.createElement('option');
|
||||
option.value = modelName;
|
||||
option.text = modelName;
|
||||
select_openai_comp_model.appendChild(option);
|
||||
select_openai_comp_model.value = modelName;
|
||||
select_openai_comp_model.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
}
|
||||
});
|
||||
|
||||
let conntype_select = document.getElementById("connection_type");
|
||||
conntype_select.addEventListener("change", showConnectionOptions);
|
||||
conntype_select.addEventListener("change", warn_ChatGPT_APIKeyEmpty);
|
||||
|
|
@ -401,6 +443,7 @@ select_openai_comp_model.addEventListener("change", warn_OpenAIComp_HostEmpty);
|
|||
warn_Ollama_HostEmpty();
|
||||
warn_OpenAIComp_HostEmpty();
|
||||
disable_MaxPromptLength();
|
||||
disable_AddTags();
|
||||
|
||||
const passwordField_chatgpt_api_key = document.getElementById('chatgpt_api_key');
|
||||
const toggleIcon_chatgpt_api_key = document.getElementById('toggle_chatgpt_api_key');
|
||||
|
|
|
|||
|
|
@ -7,6 +7,20 @@
|
|||
<body>
|
||||
<div id="miczBackPrefs"><a href="mzta-options.html">__MSG_backToOptionsText__</a></div>
|
||||
<div id="miczRelNotes"><h1>ThunderAI Release Notes</h1>
|
||||
<h2>Version 3.0.0 - ??/??/2024</h2>
|
||||
<ul>
|
||||
<li><i>[ChatGPT API][Ollama API][OpenAI Comp API]</i> Added a special prompt to apply tag to emails [<a href="https://github.com/micz/ThunderAI/issues/183">#183</a>].</li>
|
||||
<li>Default prompts text has been translated [<a href="https://github.com/micz/ThunderAI/issues/185">#185</a>].</li>
|
||||
<li>Data placeholder <i>{%tags_full_list%}</i> for the full available tags list added [<a href="https://github.com/micz/ThunderAI/issues/197">#197</a>].</li>
|
||||
<li>Data placeholder <i>{%tags_current_email%}</i> for the single mail tags list added [<a href="https://github.com/micz/ThunderAI/issues/198">#198</a>].</li>
|
||||
<li>User <a href="https://forms.gle/1qK2wcbuhaRzhwyt9">survey link</a> added [<a href="https://github.com/micz/ThunderAI/issues/202">#202</a>].</li>
|
||||
<li>Polish (pl) translation added, thanks to <a href="https://github.com/neexpl">neexpl</a>.</li>
|
||||
<li><i>[OpenAI Comp API]</i> Added a button in the options page to manually insert the model [<a href="https://github.com/micz/ThunderAI/issues/205">#205</a>].</li>
|
||||
<li>The Custom Prompts tab has now an icon.</li>
|
||||
<li>The red border in the Custom Prompts configuration page that highlights a needed prompt configuration that is not selected is now removed when the corresponding placeholder is removed [<a href="https://github.com/micz/ThunderAI/issues/201">#201</a>].</li>
|
||||
<li>Minor bugs fixed.</li>
|
||||
<li>...</li>
|
||||
</ul>
|
||||
<h2>Version 2.3.4 - 06/12/2024</h2>
|
||||
<ul>
|
||||
<li><i>[ChatGPT API]</i> Correctly showwing an error message received from the ChatGPT API [<a href="https://github.com/micz/ThunderAI/issues/191">#191</a>].</li>
|
||||
|
|
|
|||
132
pages/addtags/mzta-add-tags.css
Normal file
132
pages/addtags/mzta-add-tags.css
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
#addtags_prompt_container{
|
||||
width: 90%;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
#addtags_prompt_text{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.infoline{
|
||||
font-size: 0.8em;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
#addtags_excl_list_container{
|
||||
width: 90%;
|
||||
margin: 40px auto;
|
||||
}
|
||||
|
||||
#addtags_excl_list{
|
||||
width: 30em;
|
||||
}
|
||||
|
||||
.btn_div{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
#addtags_info_additional_statements{
|
||||
display: none;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
75
pages/addtags/mzta-add-tags.html
Normal file
75
pages/addtags/mzta-add-tags.html
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>ThunderAI - __MSG_AddTags_PageTitle__</title>
|
||||
<link rel="stylesheet" href="mzta-add-tags.css">
|
||||
<link rel="icon" href="../../images/icon-16px.png">
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<h1 class="page_title">__MSG_AddTags_PageTitle__</h1>
|
||||
<p>__MSG_AddTags_info_default__</p>
|
||||
</div>
|
||||
<div class="addtags_table_title section_title">__MSG_AddTags_prompt_prefs_title__</div>
|
||||
<table id="miczPrefs">
|
||||
<tr class="add_tags_tr">
|
||||
<td><span>__MSG_prefs_OptionText_add_tags_maxnum__</span></td>
|
||||
<td>
|
||||
<label>
|
||||
<input type="number" id="add_tags_maxnum" name="add_tags_maxnum" class="option-input" />
|
||||
<br>__MSG_prefs_OptionText_add_tags_maxnum_Info__
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="add_tags_tr">
|
||||
<td><span>__MSG_prefs_OptionText_add_tags_hide_exclusions__</span></td>
|
||||
<td>
|
||||
<label>
|
||||
<input type="checkbox" id="add_tags_hide_exclusions" name="add_tags_hide_exclusions" class="option-input" />
|
||||
__MSG_prefs_OptionText_add_tags_hide_exclusions_Info__
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="add_tags_tr">
|
||||
<td><span>__MSG_prefs_OptionText_add_tags_first_uppercase__</span></td>
|
||||
<td>
|
||||
<label>
|
||||
<input type="checkbox" id="add_tags_first_uppercase" name="add_tags_first_uppercase" class="option-input" />
|
||||
__MSG_prefs_OptionText_add_tags_first_uppercase_Info__
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="add_tags_tr">
|
||||
<td><span>__MSG_prefs_OptionText_add_tags_force_lang__</span></td>
|
||||
<td>
|
||||
<label>
|
||||
<input type="checkbox" id="add_tags_force_lang" name="add_tags_force_lang" class="option-input" />
|
||||
__MSG_prefs_OptionText_add_tags_force_lang_Info__
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div id="addtags_prompt_container">
|
||||
<span class="section_title">__MSG_AddTags_prompt_text_title__</span><span id="addtags_prompt_unsaved" class="unsaved hidden"> __MSG_customPrompts_unsaved_changes__</span>
|
||||
<br><span class="infoline">__MSG_prefs_OptionText_btnManagePrompts_infoline__ <a href="https://micz.it/thunderbird-addon-thunderai/data-placeholders/">__MSG_customPrompts_managePrompts_help__</a>
|
||||
<br><b>__MSG_prefs_OptionText_btnManagePrompts_infoline2__</b></span>
|
||||
<br>
|
||||
<div class="autocomplete-container">
|
||||
<textarea id="addtags_prompt_text" rows="15"></textarea>
|
||||
<ul class="autocomplete-list hidden"></ul>
|
||||
</div>
|
||||
<div id="addtags_info_additional_statements"></div>
|
||||
<div class="btn_div"><button id="btn_reset_prompt" disabled>__MSG_reset_default__</button><button id="btn_save_prompt" disabled>__MSG_save__</button></div>
|
||||
</div>
|
||||
<div id="addtags_excl_list_container">
|
||||
<span class="section_title">__MSG_AddTags_excl_list_title__</span><span id="excl_list_unsaved" class="unsaved hidden"> __MSG_customPrompts_unsaved_changes__</span>
|
||||
<br><span class="infoline">__MSG_AddTags_excl_list_infoline__
|
||||
<br>__MSG_AddTags_excl_list_infoline2__</span>
|
||||
<br><textarea id="addtags_excl_list" rows="15"></textarea>
|
||||
<div class="btn_div"><button id="btn_save_excl_list" disabled>__MSG_save__</button></div>
|
||||
</div>
|
||||
<script src="mzta-add-tags.js" type="module"></script>
|
||||
<script src="../../js/mzta-i18n.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
203
pages/addtags/mzta-add-tags.js
Normal file
203
pages/addtags/mzta-add-tags.js
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
* ThunderAI [https://micz.it/thunderbird-addon-thunderai/]
|
||||
* Copyright (C) 2024 Mic (m@micz.it)
|
||||
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { prefs_default } from '../../options/mzta-options-default.js';
|
||||
import { taLogger } from '../../js/mzta-logger.js';
|
||||
import { getSpecialPrompts, setSpecialPrompts } from "../../js/mzta-prompts.js";
|
||||
import { getPlaceholders } from "../../js/mzta-placeholders.js";
|
||||
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
||||
import { addTags_getExclusionList, addTags_setExclusionList } from "../../js/mzta-addatags-exclusion-list.js";
|
||||
|
||||
|
||||
let autocompleteSuggestions = [];
|
||||
let taLog = new taLogger("mzta-addtags-page",true);
|
||||
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
|
||||
i18n.updateDocument();
|
||||
await restoreOptions();
|
||||
|
||||
document.querySelectorAll(".option-input").forEach(element => {
|
||||
element.addEventListener("change", saveOptions);
|
||||
});
|
||||
|
||||
let addtags_textarea = document.getElementById('addtags_prompt_text');
|
||||
let addtags_save_btn = document.getElementById('btn_save_prompt');
|
||||
let addtags_reset_btn = document.getElementById('btn_reset_prompt');
|
||||
|
||||
let specialPrompts = await getSpecialPrompts();
|
||||
let addtags_prompt = specialPrompts.find(prompt => prompt.id === 'prompt_add_tags');
|
||||
|
||||
addtags_textarea.addEventListener('input', (event) => {
|
||||
addtags_reset_btn.disabled = (event.target.value === browser.i18n.getMessage('prompt_add_tags_full_text'));
|
||||
addtags_save_btn.disabled = (event.target.value === addtags_prompt.text);
|
||||
if(addtags_save_btn.disabled){
|
||||
document.getElementById('addtags_prompt_unsaved').classList.add('hidden');
|
||||
} else {
|
||||
document.getElementById('addtags_prompt_unsaved').classList.remove('hidden');
|
||||
}
|
||||
});
|
||||
|
||||
addtags_reset_btn.addEventListener('click', () => {
|
||||
addtags_textarea.value = browser.i18n.getMessage('prompt_add_tags_full_text');
|
||||
addtags_reset_btn.disabled = true;
|
||||
let event = new Event('input', { bubbles: true, cancelable: true });
|
||||
addtags_textarea.dispatchEvent(event);
|
||||
});
|
||||
|
||||
addtags_save_btn.addEventListener('click', () => {
|
||||
specialPrompts.find(prompt => prompt.id === 'prompt_add_tags').text = addtags_textarea.value;
|
||||
setSpecialPrompts(specialPrompts);
|
||||
addtags_save_btn.disabled = true;
|
||||
document.getElementById('addtags_prompt_unsaved').classList.add('hidden');
|
||||
browser.runtime.sendMessage({command: "reload_menus"});
|
||||
});
|
||||
|
||||
if(addtags_prompt.text === 'prompt_add_tags_full_text'){
|
||||
addtags_prompt.text = browser.i18n.getMessage(addtags_prompt.text);
|
||||
}
|
||||
addtags_textarea.value = addtags_prompt.text;
|
||||
addtags_reset_btn.disabled = (addtags_textarea.value === browser.i18n.getMessage('prompt_add_tags_full_text'));
|
||||
|
||||
document.getElementById('add_tags_maxnum').addEventListener('change', updateAdditionalPromptStatements);
|
||||
document.getElementById('add_tags_force_lang').addEventListener('change', updateAdditionalPromptStatements);
|
||||
|
||||
updateAdditionalPromptStatements();
|
||||
|
||||
autocompleteSuggestions = (await getPlaceholders(true)).filter(p => !(p.id === 'selected_text' || p.id === 'additional_text')).map(p => ({command: '{%'+p.id+'%}', type: p.type}));
|
||||
textareaAutocomplete(addtags_textarea, autocompleteSuggestions, 1); // type_value = 1, only when reading an email
|
||||
|
||||
let excl_list_textarea = document.getElementById('addtags_excl_list');
|
||||
let excl_list_save_btn = document.getElementById('btn_save_excl_list');
|
||||
|
||||
let excl_list_value = await addTags_getExclusionList();
|
||||
let excl_list_string = excl_list_value.join('\n');
|
||||
|
||||
excl_list_textarea.value = excl_list_string;
|
||||
|
||||
excl_list_textarea.addEventListener('input', (event) => {
|
||||
excl_list_save_btn.disabled = (event.target.value === excl_list_string);
|
||||
if(excl_list_save_btn.disabled){
|
||||
document.getElementById('excl_list_unsaved').classList.add('hidden');
|
||||
} else {
|
||||
document.getElementById('excl_list_unsaved').classList.remove('hidden');
|
||||
}
|
||||
});
|
||||
|
||||
excl_list_save_btn.addEventListener('click', () => {
|
||||
let excl_array_new = excl_list_textarea.value.split(/[\n,]+/);
|
||||
excl_array_new = Array.from(new Set(excl_array_new.map(item => item.trim().toLowerCase()))).sort();
|
||||
addTags_setExclusionList(excl_array_new);
|
||||
excl_list_save_btn.disabled = true;
|
||||
excl_list_textarea.value = excl_array_new.join('\n');
|
||||
document.getElementById('excl_list_unsaved').classList.add('hidden');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
async function updateAdditionalPromptStatements(){
|
||||
let prefs_ = await browser.storage.sync.get({add_tags_maxnum: 3, add_tags_force_lang: true, default_chatgpt_lang: ''});
|
||||
let el_tag_limit = document.getElementById('addtags_info_additional_statements');
|
||||
if((prefs_.add_tags_maxnum > 0)||(prefs_.add_tags_force_lang && prefs_.default_chatgpt_lang !== '')){
|
||||
el_tag_limit.textContent = browser.i18n.getMessage("addtags_info_additional_statements") + " \""
|
||||
if(prefs_.add_tags_maxnum > 0){
|
||||
el_tag_limit.textContent += browser.i18n.getMessage("prompt_add_tags_maxnum") + " " + prefs_.add_tags_maxnum +"."
|
||||
}
|
||||
if(prefs_.add_tags_force_lang && prefs_.default_chatgpt_lang !== ''){
|
||||
if(prefs_.add_tags_maxnum > 0){
|
||||
el_tag_limit.textContent += " "
|
||||
}
|
||||
el_tag_limit.textContent += browser.i18n.getMessage("prompt_add_tags_force_lang") + " " + prefs_.default_chatgpt_lang + "."
|
||||
}
|
||||
el_tag_limit.textContent += "\".";
|
||||
el_tag_limit.style.display = 'block';
|
||||
}else{
|
||||
el_tag_limit.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Methods to manage options, derived from: /options/mzta-options.js
|
||||
|
||||
function saveOptions(e) {
|
||||
e.preventDefault();
|
||||
let options = {};
|
||||
let element = e.target;
|
||||
|
||||
switch (element.type) {
|
||||
case 'checkbox':
|
||||
options[element.id] = element.checked;
|
||||
break;
|
||||
case 'number':
|
||||
options[element.id] = element.valueAsNumber;
|
||||
break;
|
||||
case 'text':
|
||||
case 'password':
|
||||
options[element.id] = element.value.trim();
|
||||
break;
|
||||
default:
|
||||
if (element.tagName === 'SELECT') {
|
||||
options[element.id] = element.value;
|
||||
}else{
|
||||
console.error("[ThunderAI] Unhandled input type:", element.type);
|
||||
}
|
||||
}
|
||||
|
||||
browser.storage.sync.set(options);
|
||||
}
|
||||
|
||||
async function restoreOptions() {
|
||||
function setCurrentChoice(result) {
|
||||
document.querySelectorAll(".option-input").forEach(element => {
|
||||
taLog.log("Options restoring " + element.id + " = " + (element.id=="chatgpt_api_key" || element.id=="openai_comp_api_key" ? "****************" : result[element.id]));
|
||||
switch (element.type) {
|
||||
case 'checkbox':
|
||||
element.checked = result[element.id] || false;
|
||||
break;
|
||||
case 'number':
|
||||
let default_number_value = 0;
|
||||
if(element.id == 'chatgpt_win_height') default_number_value = prefs_default.chatgpt_win_height;
|
||||
if(element.id == 'chatgpt_win_width') default_number_value = prefs_default.chatgpt_win_width;
|
||||
element.value = result[element.id] ?? default_number_value;
|
||||
break;
|
||||
case 'text':
|
||||
case 'password':
|
||||
let default_text_value = '';
|
||||
if(element.id == 'default_chatgpt_lang') default_text_value = prefs_default.default_chatgpt_lang;
|
||||
element.value = result[element.id] || default_text_value;
|
||||
break;
|
||||
default:
|
||||
if (element.tagName === 'SELECT') {
|
||||
let default_select_value = '';
|
||||
if(element.id == 'reply_type') default_select_value = 'reply_all';
|
||||
if(element.id == 'connection_type') default_select_value = 'chatgpt_web';
|
||||
element.value = result[element.id] || default_select_value;
|
||||
if (element.value === '') {
|
||||
element.selectedIndex = -1;
|
||||
}
|
||||
}else{
|
||||
console.error("[ThunderAI] Unhandled input type:", element.type);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let getting = await browser.storage.sync.get(prefs_default);
|
||||
setCurrentChoice(getting);
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
<meta charset="UTF-8">
|
||||
<title>ThunderAI - __MSG_customPrompts_managePrompts__</title>
|
||||
<link rel="stylesheet" href="mzta-custom-prompts.css">
|
||||
<link rel="icon" href="../../images/icon-16px.png">
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
|
|
@ -98,6 +99,6 @@
|
|||
<div class="storage_space">__MSG_StorageSpace__: <span id="storage_space"></span></div>
|
||||
<script src="list.js"></script>
|
||||
<script src="mzta-custom-prompts.js" type="module"></script>
|
||||
<script src="../js/mzta-i18n.js"></script>
|
||||
<script src="../../js/mzta-i18n.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -16,10 +16,11 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { getPrompts, setDefaultPromptsProperties, setCustomPrompts, preparePromptsForExport, preparePromptsForImport } from "../js/mzta-prompts.js";
|
||||
import { isThunderbird128OrGreater, getCustomPromptsUsedSpace, sanitizeHtml } from "../js/mzta-utils.js";
|
||||
import { taLogger } from "../js/mzta-logger.js";
|
||||
import { getPlaceholders } from "../js/mzta-placeholders.js";
|
||||
import { getPrompts, setDefaultPromptsProperties, setCustomPrompts, preparePromptsForExport, preparePromptsForImport } from "../../js/mzta-prompts.js";
|
||||
import { isThunderbird128OrGreater, getCustomPromptsUsedSpace, sanitizeHtml } from "../../js/mzta-utils.js";
|
||||
import { taLogger } from "../../js/mzta-logger.js";
|
||||
import { getPlaceholders } from "../../js/mzta-placeholders.js";
|
||||
import { textareaAutocomplete } from "../../js/mzta-placeholders-autocomplete.js";
|
||||
|
||||
var promptsList = null;
|
||||
var somethingChanged = false;
|
||||
|
|
@ -118,7 +119,15 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||
|
||||
// console.log('>>>>>>>>>>> suggestions: ' + JSON.stringify(suggestions));
|
||||
|
||||
textareas.forEach(textarea => textareaAutocomplete(textarea, autocompleteSuggestions));
|
||||
textareas.forEach(textarea => {
|
||||
textareaAutocomplete(textarea, autocompleteSuggestions);
|
||||
textareas.forEach(textarea => {
|
||||
textarea.addEventListener('input', (e) => {
|
||||
checkPromptsConfigForPlaceholders(e.target);
|
||||
});
|
||||
textareaAutocomplete(textarea, autocompleteSuggestions);
|
||||
});
|
||||
});
|
||||
|
||||
// document.addEventListener('click', (e) => {
|
||||
// // Check if the click was outside the textarea or suggestion list
|
||||
|
|
@ -680,141 +689,29 @@ if(await isThunderbird128OrGreater()){
|
|||
});
|
||||
}
|
||||
|
||||
function textareaAutocomplete(textarea, suggestions) {
|
||||
const container = textarea.closest('.autocomplete-container');
|
||||
const autocompleteList = container.querySelector('.autocomplete-list');
|
||||
let activeIndex = -1;
|
||||
|
||||
textarea.addEventListener('input', () => {
|
||||
const cursorPosition = textarea.selectionStart;
|
||||
const text = textarea.value.substring(0, cursorPosition);
|
||||
const match = text.match(/{%[^\s]*$/);
|
||||
|
||||
checkPromptsConfigForPlaceholders(textarea);
|
||||
|
||||
if (match) {
|
||||
const lastWord = match[0];
|
||||
const tr = textarea.parentNode.parentNode.parentNode;
|
||||
let type = tr.querySelector('.type_output').value
|
||||
// console.log(">>>>>>>>> type: " + type);
|
||||
// console.log(">>>>>>>>> suggestions: " + JSON.stringify(suggestions));
|
||||
// console.log(">>>>>>>>> lastWord: " + lastWord);
|
||||
const matches = suggestions.filter(s => s.command.startsWith(lastWord) && (String(s.type) == String(type) || String(s.type) == '0' )).map(s => s.command);
|
||||
// console.log(">>>>>>>>> matches: " + JSON.stringify(matches));
|
||||
showSuggestions(matches, autocompleteList);
|
||||
} else {
|
||||
hideSuggestions(autocompleteList);
|
||||
}
|
||||
});
|
||||
|
||||
textarea.addEventListener('keydown', (e) => {
|
||||
if (autocompleteList.classList.contains('hidden')) {
|
||||
return;
|
||||
}
|
||||
const items = autocompleteList.querySelectorAll('li');
|
||||
if (items.length > 0) {
|
||||
if (e.key === 'ArrowDown') {
|
||||
e.preventDefault();
|
||||
activeIndex = (activeIndex + 1) % items.length;
|
||||
updateActiveSuggestion(items, activeIndex);
|
||||
} else if (e.key === 'ArrowUp') {
|
||||
e.preventDefault();
|
||||
activeIndex = (activeIndex - 1 + items.length) % items.length;
|
||||
updateActiveSuggestion(items, activeIndex);
|
||||
} else if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
if(activeIndex === -1) activeIndex = 0;
|
||||
if (activeIndex >= 0 && activeIndex < items.length) {
|
||||
insertAutocomplete(items[activeIndex].textContent, textarea);
|
||||
hideSuggestions(autocompleteList);
|
||||
}
|
||||
} else if (e.key === 'Escape') {
|
||||
hideSuggestions(autocompleteList);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function showSuggestions(matches, autocompleteList) {
|
||||
autocompleteList.innerHTML = '';
|
||||
activeIndex = -1;
|
||||
if (matches.length === 0) {
|
||||
hideSuggestions(autocompleteList);
|
||||
return;
|
||||
}
|
||||
matches.forEach(match => {
|
||||
const li = document.createElement('li');
|
||||
li.textContent = match;
|
||||
li.addEventListener('click', () => {
|
||||
insertAutocomplete(match, textarea);
|
||||
hideSuggestions(autocompleteList);
|
||||
});
|
||||
autocompleteList.appendChild(li);
|
||||
});
|
||||
autocompleteList.classList.remove('hidden');
|
||||
}
|
||||
|
||||
function hideSuggestions(autocompleteList) {
|
||||
autocompleteList.classList.add('hidden');
|
||||
activeIndex = -1;
|
||||
}
|
||||
|
||||
function updateActiveSuggestion(items, activeIndex) {
|
||||
items.forEach((item, index) => {
|
||||
item.classList.remove('active');
|
||||
if (index === activeIndex) {
|
||||
item.classList.add('active');
|
||||
item.scrollIntoView({ block: 'nearest' });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function insertAutocomplete(suggestion, textarea) {
|
||||
const cursorPosition = textarea.selectionStart;
|
||||
const textBefore = textarea.value.substring(0, cursorPosition);
|
||||
const textAfter = textarea.value.substring(cursorPosition);
|
||||
const match = textBefore.match(/{%[^\s]*$/);
|
||||
if (match) {
|
||||
const lastWord = match[0];
|
||||
const completion = suggestion.substring(lastWord.length);
|
||||
const newText = textBefore + completion + textAfter;
|
||||
textarea.value = newText;
|
||||
const newCursorPosition = cursorPosition + completion.length;
|
||||
textarea.setSelectionRange(newCursorPosition, newCursorPosition);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('click', (e) => {
|
||||
// Check if the click was outside the textarea or suggestion list
|
||||
const isClickInsideTextarea = e.target.closest('.editor');
|
||||
const isClickInsideAutocompleteList = e.target.closest('.autocomplete-list');
|
||||
|
||||
if (!isClickInsideTextarea && !isClickInsideAutocompleteList) {
|
||||
const container = textarea.closest('.autocomplete-container');
|
||||
const autocompleteList = container.querySelector('.autocomplete-list');
|
||||
hideSuggestions(autocompleteList);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function checkPromptsConfigForPlaceholders(textarea){
|
||||
// check additional_text and selected_text placeholders presence and the corrispondent checkboxes
|
||||
let tr_ancestor = textarea.closest('tr');
|
||||
let need_custom_text_element = tr_ancestor.querySelector('.need_custom_text') || tr_ancestor.querySelector('.need_custom_text_new');
|
||||
if(String(textarea.value).indexOf('{%additional_text%}') != -1){
|
||||
let tr_ancestor = textarea.closest('tr');
|
||||
let need_custom_text_element = tr_ancestor.querySelector('.need_custom_text') || tr_ancestor.querySelector('.need_custom_text_new');
|
||||
if(!need_custom_text_element.checked){
|
||||
need_custom_text_element.closest('.need_custom_text_span').style.border = '2px solid red';
|
||||
}else{
|
||||
need_custom_text_element.closest('.need_custom_text_span').style.border = '';
|
||||
}
|
||||
}else{
|
||||
need_custom_text_element.closest('.need_custom_text_span').style.border = '';
|
||||
}
|
||||
|
||||
let tr_ancestor2 = textarea.closest('tr');
|
||||
let selected_text_element = tr_ancestor2.querySelector('.need_selected') || tr_ancestor2.querySelector('.need_selected_new');
|
||||
if(String(textarea.value).indexOf('{%selected_text%}') != -1){
|
||||
let tr_ancestor = textarea.closest('tr');
|
||||
let selected_text_element = tr_ancestor.querySelector('.need_selected') || tr_ancestor.querySelector('.need_selected_new');
|
||||
if(!selected_text_element.checked){
|
||||
selected_text_element.closest('.need_selected_span').style.border = '2px solid red';
|
||||
}else{
|
||||
selected_text_element.closest('.need_selected_span').style.border = '';
|
||||
}
|
||||
}else{
|
||||
selected_text_element.closest('.need_selected_span').style.border = '';
|
||||
}
|
||||
}
|
||||
|
|
@ -44,6 +44,7 @@ body {
|
|||
overflow-y: auto;
|
||||
padding: 0;
|
||||
overflow-x: hidden;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mzta_sending_prompt{
|
||||
|
|
@ -62,6 +63,10 @@ body {
|
|||
.mzta_autocomplete-item-active {
|
||||
background-color: #e9e9e9;
|
||||
}
|
||||
|
||||
.prompt_add_tags{
|
||||
background-color: #cfe9ff;
|
||||
}
|
||||
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
|
@ -96,4 +101,8 @@ body {
|
|||
.mzta_autocomplete-item-active {
|
||||
background-color: #444444;
|
||||
}
|
||||
|
||||
.prompt_add_tags{
|
||||
background-color: #353542;
|
||||
}
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
<div id="mzta_sending_prompt"><img src="mzta-loading.svg" title="__MSG_SendingPrompt__"></div>
|
||||
<input type="text" id="mzta_search_input" placeholder="__MSG_SearchPrompt__">
|
||||
<div id="mzta_autocomplete-items-loading"><img src="mzta-loading.svg" title="__MSG_Loading__"></div>
|
||||
<div id="mzta_autocomplete-items" style="display: none;"></div>
|
||||
<div id="mzta_autocomplete-items"></div>
|
||||
</div>
|
||||
<script src="mzta-popup.js" type="module"></script>
|
||||
<script src="../js/mzta-i18n.js"></script>
|
||||
|
|
|
|||
|
|
@ -16,26 +16,30 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { taStore } from "../js/mzta-store.js";
|
||||
import { taLogger } from "../js/mzta-logger.js";
|
||||
|
||||
let menuSendImmediately = false;
|
||||
let taLog = console;
|
||||
let connection_type = 'chatgpt_web';
|
||||
let add_tags = false;
|
||||
let tabType;
|
||||
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
let prefs = await browser.storage.sync.get({do_debug: false, dynamic_menu_force_enter: false});
|
||||
let prefs = await browser.storage.sync.get({do_debug: false, dynamic_menu_force_enter: false, add_tags: false, connection_type: 'chatgpt_web'});
|
||||
taLog = new taLogger("mzta-popup",prefs.do_debug);
|
||||
i18n.updateDocument();
|
||||
let reponse = await browser.runtime.sendMessage({command: "popup_menu_ready"});
|
||||
taLog.log("Preparing data to load the popup menu: " + JSON.stringify(reponse));
|
||||
let tabId = reponse.lastShortcutTabId;
|
||||
let tabType = reponse.lastShortcutTabType;
|
||||
tabType = reponse.lastShortcutTabType;
|
||||
let filtering = reponse.lastShortcutFiltering;
|
||||
let _prompts_data = reponse.lastShortcutPromptsData;
|
||||
taLog.log("_prompts_data: " + JSON.stringify(_prompts_data));
|
||||
let active_prompts = filterPromptsForTab(_prompts_data, filtering);
|
||||
taLog.log("active_prompts: " + JSON.stringify(active_prompts));
|
||||
menuSendImmediately = prefs.dynamic_menu_force_enter;
|
||||
connection_type = prefs.connection_type;
|
||||
add_tags = prefs.add_tags;
|
||||
searchPrompt(active_prompts, tabId, tabType);
|
||||
i18n.updateDocument();
|
||||
}, { once: true });
|
||||
|
|
@ -78,7 +82,7 @@ async function searchPrompt(allPrompts, tabId, tabType){
|
|||
*/
|
||||
|
||||
// Filter data based on the query
|
||||
const filteredData = allPrompts.filter(item =>
|
||||
let filteredData = allPrompts.filter(item =>
|
||||
item.label.toLowerCase().includes(query)
|
||||
);
|
||||
taLog.log("filteredData: " + JSON.stringify(filteredData));
|
||||
|
|
@ -89,9 +93,22 @@ async function searchPrompt(allPrompts, tabId, tabType){
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
// Prepend numbers to the first 10 items
|
||||
Array.from(filteredData).slice(0, 10).forEach((item, index) => {
|
||||
const number = (index < 9) ? (index + 1).toString() : '0';
|
||||
// If add_tags is true and connection_type is not 'chatgpt_web' reserve 0 position for prompt_add_tags
|
||||
let max_num_el = 10
|
||||
let first_num_el = 0;
|
||||
if(checkDoAddTags()){
|
||||
max_num_el = 9;
|
||||
first_num_el = 1;
|
||||
filteredData = ensurePromptAddTagsFirst(filteredData);
|
||||
if (!filteredData[0].numberPrepended) {
|
||||
filteredData[0].numberPrepended = 'true';
|
||||
filteredData[0].label = '0. ' + filteredData[0].label;
|
||||
}
|
||||
}
|
||||
Array.from(filteredData).slice(first_num_el, max_num_el).forEach((item, index) => {
|
||||
let number = (index < 9) ? (index + 1).toString() : '0';
|
||||
// Check if the number is already prepended to avoid duplication
|
||||
if (!item.numberPrepended) {
|
||||
item.label = `${number}. ${item.label}`;
|
||||
|
|
@ -101,12 +118,22 @@ async function searchPrompt(allPrompts, tabId, tabType){
|
|||
|
||||
// console.log(">>>>>>>>>>>>> filteredData: " + JSON.stringify(filteredData));
|
||||
|
||||
// add the prompt_add_tags if add_tags is true and connection_type is not 'chatgpt_web'
|
||||
// if(checkDoAddTags()){
|
||||
// let number = '0';
|
||||
// let item = {label: `${number}. ${browser.i18n.getMessage('prompt_add_tags')}`, id: 'prompt_add_tags', numberPrepended: 'true'};
|
||||
// filteredData.unshift(item);
|
||||
// }
|
||||
|
||||
// Create a div for each filtered result
|
||||
filteredData.forEach(item => {
|
||||
const itemDiv = document.createElement('div');
|
||||
itemDiv.classList.add('mzta_autocomplete-item');
|
||||
itemDiv.textContent = item.label;
|
||||
itemDiv.setAttribute('data-id', item.id);
|
||||
if(item.id === 'prompt_add_tags'){
|
||||
itemDiv.className += ' prompt_add_tags';
|
||||
}
|
||||
|
||||
// Add a mousedown event to select the item
|
||||
itemDiv.addEventListener('mousedown', function(e) { // Use mousedown instead of click
|
||||
|
|
@ -141,8 +168,8 @@ async function searchPrompt(allPrompts, tabId, tabType){
|
|||
});
|
||||
|
||||
// Add a keydown event listener to handle arrow navigation and selection
|
||||
input.addEventListener('keydown', function (e) {
|
||||
|
||||
input.addEventListener('keydown', async function (e) {
|
||||
|
||||
const items = autocompleteList.getElementsByClassName('mzta_autocomplete-item');
|
||||
if ((autocompleteList.style.display === 'none' || items.length === 0)
|
||||
&& (e.key !== 'Enter')
|
||||
|
|
@ -154,7 +181,11 @@ async function searchPrompt(allPrompts, tabId, tabType){
|
|||
// Handle number key presses (1-9,0) to select the corresponding item directly
|
||||
if (['1','2','3','4','5','6','7','8','9','0'].includes(e.key)) {
|
||||
// Map '1' to index 0, '2' to 1, ..., '9' to 8, '0' to 9
|
||||
const numIndex = (e.key === '0') ? 9 : parseInt(e.key, 10) - 1;
|
||||
let numIndex = (e.key === '0') ? 9 : parseInt(e.key, 10) - 1;
|
||||
if(checkDoAddTags()){
|
||||
numIndex = parseInt(e.key, 10);
|
||||
}
|
||||
|
||||
if (items[numIndex]) {
|
||||
e.preventDefault(); // Prevent any default behavior
|
||||
// Dispatch a select_prompt event to simulate a click/select action
|
||||
|
|
@ -226,11 +257,15 @@ document.body.insertBefore(banner, document.body.firstChild);
|
|||
}
|
||||
|
||||
|
||||
function sendPrompt(prompt_id, tabId){
|
||||
async function sendPrompt(prompt_id, tabId){
|
||||
taLog.log("sendPrompt: " + prompt_id);
|
||||
document.getElementById('mzta_search_input').style.display = 'none';
|
||||
document.getElementById('mzta_sending_prompt').style.display = 'block';
|
||||
browser.runtime.sendMessage({command: "shortcut_do_prompt", tabId: tabId, promptId: prompt_id});
|
||||
let response = await browser.runtime.sendMessage({command: "shortcut_do_prompt", tabId: tabId, promptId: prompt_id});
|
||||
console.log(">>>>>>>>>>>>>>>>> response: " + JSON.stringify(response));
|
||||
if(response.ok == '1'){
|
||||
window.close();
|
||||
}
|
||||
}
|
||||
|
||||
function filterPromptsForTab(prompts_data, filtering){
|
||||
|
|
@ -252,4 +287,23 @@ function filterPromptsForTab(prompts_data, filtering){
|
|||
|
||||
// Filter the array based on the allowed types
|
||||
return prompts_data.filter(prompt => allowedTypes.includes(prompt.type));
|
||||
}
|
||||
|
||||
function checkDoAddTags(){
|
||||
return add_tags && (connection_type !== "chatgpt_web" && tabType !== 'messageCompose');
|
||||
}
|
||||
|
||||
function ensurePromptAddTagsFirst(arr) {
|
||||
// Find the index of the object with id "prompt_add_tags"
|
||||
const index = arr.findIndex(item => item.id === "prompt_add_tags");
|
||||
|
||||
// If found and not already the first element
|
||||
if (index !== -1 && index !== 0) {
|
||||
// Remove it from its current position
|
||||
const [promptAddTags] = arr.splice(index, 1);
|
||||
// Add it to the beginning of the array
|
||||
arr.unshift(promptAddTags);
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
Loading…
Reference in a new issue