diff --git a/.github/workflows/tom-select-release-check.yml b/.github/workflows/tom-select-release-check.yml
new file mode 100644
index 00000000..eb51f281
--- /dev/null
+++ b/.github/workflows/tom-select-release-check.yml
@@ -0,0 +1,61 @@
+name: Check Tom-Select Latest Release
+
+on:
+ schedule:
+ - cron: '0 19 * * *' # Check every day at 19:00
+ workflow_dispatch: # Allows manual triggering for testing purposes
+
+permissions:
+ contents: read
+ issues: write
+
+jobs:
+ check-and-notify:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Get latest release from external repo
+ id: get_release
+ run: |
+ REPO_TARGET="orchidjs/tom-select"
+ LATEST_TAG=$(curl -s https://api.github.com/repos/$REPO_TARGET/releases/latest | jq -r .tag_name)
+
+ if [ "$LATEST_TAG" == "null" ] || [ -z "$LATEST_TAG" ]; then
+ echo "Error: unable to fetch tag or no release found."
+ exit 1
+ fi
+
+ echo "tag=$LATEST_TAG" >> $GITHUB_OUTPUT
+ echo "target=$REPO_TARGET" >> $GITHUB_OUTPUT
+
+ - name: Check if Issue already exists and create it
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const latestTag = "${{ steps.get_release.outputs.tag }}";
+ const targetRepo = "${{ steps.get_release.outputs.target }}";
+ const { owner, repo } = context.repo;
+ const issueTitle = `Update Tom Select to version ${latestTag}`;
+
+ // Search through issues (both open and closed for safety)
+ const response = await github.rest.search.issuesAndPullRequests({
+ q: `repo:${owner}/${repo} is:issue "${issueTitle}"`,
+ });
+
+ if (response.data.total_count > 0) {
+ core.info(`The issue for version ${latestTag} already exists. No action taken.`);
+ } else {
+ await github.rest.issues.create({
+ owner,
+ repo,
+ title: issueTitle,
+ labels: ['enhancement'],
+ body: `Update Tom Select to version **${latestTag}**.
+
+ https://cdn.jsdelivr.net/npm/tom-select@${latestTag}/dist/js/tom-select.base.js
+
+ https://cdn.jsdelivr.net/npm/tom-select@${latestTag}/dist/css/tom-select.default.min.css
+
+ Remember also to update the VENDORS.md file.`
+ });
+ core.info(`New issue created for version ${latestTag}.`);
+ }
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c3efc6fe..aadfab42 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -26,6 +26,10 @@
[ChatGPT Web] Added an option to define a custom time to wait for the page load. Sometimes, on slow PCs, the ChatGPT page loads slowly and ThunderAI inject its content too early. With this option you can adjust the waiting time [#634].
...
+Version 3.8.5 - 22/02/2026
+
+ - Fix: Correctly showing email addresses when using mail headers in data placeholders [#672].
+
Version 3.8.4 - 10/02/2026
- [ChatGPT Web] Fix: Correctly importing the selected text into the compose windows also when ChatGPT shows the advanced mail editor in the response [#646].
diff --git a/GEMINI.md b/CLAUDE.md
similarity index 100%
rename from GEMINI.md
rename to CLAUDE.md
diff --git a/VENDORS.md b/VENDORS.md
index f0c79411..cd5cd651 100644
--- a/VENDORS.md
+++ b/VENDORS.md
@@ -2,7 +2,7 @@ file: pages\_lib\list.js
source: https://raw.githubusercontent.com/javve/list.js/v2.3.1/dist/list.js
file: pages\_lib\tom-select.base.js
-source: https://cdn.jsdelivr.net/npm/tom-select@2.4.6/dist/js/tom-select.base.js
+source: https://cdn.jsdelivr.net/npm/tom-select@2.5.1/dist/js/tom-select.base.js
file: js\lib\diff.js
source: https://cdnjs.cloudflare.com/ajax/libs/jsdiff/7.0.0/diff.js
\ No newline at end of file
diff --git a/_locales/de/messages.json b/_locales/de/messages.json
index 7515b3a0..66367494 100644
--- a/_locales/de/messages.json
+++ b/_locales/de/messages.json
@@ -1302,5 +1302,152 @@
},
"prefs_anthropic_temperature_Info": {
"message": "Grad der Zufälligkeit in der Antwort. Der Standardwert ist 1,0. Der Bereich liegt zwischen 0,0 und 1,0. Verwenden Sie eine Temperatur näher an 0,0 für analytische Aufgaben oder Multiple-Choice-Fragen und näher an 1,0 für kreative und generative Aufgaben. Beachten Sie, dass die Ergebnisse selbst bei einer Temperatur von 0,0 nicht vollständig deterministisch sind."
+ },
+ "placeholder_mail_text_body_or_selected": {
+ "message": "E-Mail-Inhalt oder markierter Text"
+ },
+ "placeholder_mail_html_body_or_selected": {
+ "message": "E-Mail-Inhalt oder markiertes HTML"
+ },
+ "prefs_OptionText_chatgpt_web_load_wait_time": {
+ "message": "Wartezeit für das Laden der Seite"
+ },
+ "prefs_OptionText_chatgpt_web_load_wait_time_info": {
+ "message": "Wartezeit in Millisekunden, bis die ChatGPT-Seite geladen ist, bevor zusätzliche Inhalte geladen werden. Der Standardwert beträgt 1000 ms. Falls un Custom GPT oder ein Project definiert ist, werden diesem Wert zusätzliche 1000 ms hinzugefügt."
+ },
+ "prompt_get_calendar_event_from_clipboard": {
+ "message": "Termin aus Zwischenablage erstellen"
+ },
+ "clipboard_read_error": {
+ "message": "Zwischenablage konnte nicht gelesen werden. Bitte Berechtigungen prüfen."
+ },
+ "clipboard_empty_error": {
+ "message": "Zwischenablage leer. Bitte kopieren Sie zuerst einen Text."
+ },
+ "clipboard_permission_denied": {
+ "message": "Zugriff auf die Zwischenablage wurde verweigert. Bitte aktiviere die Funktion in den Einstellungen erneut, um die Berechtigung zu erteilen."
+ },
+ "clipboard_permission_error": {
+ "message": "Fehler bei der Berechtigungsanfrage. Bitte erneut versuchen."
+ },
+ "prefs_OptionText_get_calendar_event_from_clipboard": {
+ "message": "Termin aus Zwischenablage abrufen"
+ },
+ "prefs_OptionText_get_calendar_event_from_clipboard_Info": {
+ "message": "Zusätzlichen Menüpunkt einblenden: Kalendertermine aus Zwischenablagen-Text erstellen."
+ },
+ "Summarize_prompt_prefs_title": {
+ "message": "Zusammenfassungseinstellungen"
+ },
+ "prompt_summarize": {
+ "message": "Diese E-Mail o. E-Mails zusammenfassen"
+ },
+ "prompt_summarize_full_text": {
+ "message": "Du bist ein Assistent, der E-Mail-Konversationen zusammenfasst.\n\nErstelle aus einem E-Mail-Verlauf eine prägnante und präzise Zusammenfassung, die Folgendes enthält:\n\n- Das Hauptthema oder den Zweck der Konversation\n- Wichtige Entscheidungen, Schlussfolgerungen oder Vereinbarungen\n- Wichtige Fragen, Anfragen oder Aufgaben (Action Items)\n- Die verantwortliche Person für jede Aufgabe (falls angegeben)\n\nLasse Begrüßungen, Signaturen, zitierten Text und redundantes Hin- und Her weg.\nFüge keine Annahmen oder Informationen hinzu, die nicht in den E-Mails enthalten sind.\n\nVerfasse die Zusammenfassung in einer klaren, neutralen Sprache, die für vielbeschäftigte Fachkräfte geeignet ist."
+ },
+ "prompt_summarize_email_template": {
+ "message": "Vorlage für E-Mail-Zusammenfassung"
+ },
+ "prompt_summarize_email_template_full_text": {
+ "message": "Von: {%author%}\nAn: {%recipients%}\nCC: {%cc_list%}\nBetreff: {%mail_subject%}\nDatum: {%mail_datetime%}\nAnhänge:\n{%mail_attachments_info%}\n\nInhalt:\n{%mail_text_body%}"
+ },
+ "prompt_summarize_email_separator": {
+ "message": "E-Mail-Separator"
+ },
+ "prompt_summarize_email_separator_full_text": {
+ "message": "\n\n---------- NÄCHSTE E-MAIL ----------\n\n"
+ },
+ "prefs_OptionText_Summarize_infoline2": {
+ "message": "Sie können den Prompt nach Belieben anpassen: Das erste Feld ist der Haupt-Prompt, das zweite Feld ist die Vorlage für eine einzelne E-Mail. Die Liste der E-Mails wird an den Haupt-Prompt angehängt. Die E-Mails werden durch das im dritten Feld angegebene Trennzeichen voneinander getrennt."
+ },
+ "prefs_OptionText_Summarize_main_prompt": {
+ "message": "Der Haupt-Prompt, der die Aufgabe für alle ausgewählten E-Mails beschreibt:"
+ },
+ "prefs_OptionText_Summarize_email_template": {
+ "message": "Die Vorlage für eine einzelne E-Mail:"
+ },
+ "prefs_OptionText_Summarize_email_separator": {
+ "message": "Das Trennzeichen zwischen E-Mails:"
+ },
+ "prefs_OptionText_get_calendar_event_use_specific_integration_Info": {
+ "message": "Wenn aktiviert, werden das unten angegebene Modell und die API zum Erstellen von Kalenderereignissen verwendet, unabhängig von der Auswahl auf der ThunderAI-Optionsseite."
+ },
+ "prefs_OptionText_summarize": {
+ "message": "E-Mail zusammenfassen"
+ },
+ "prefs_OptionText_summarize_use_specific_integration_Info": {
+ "message": "Wenn aktiviert, werden das unten angegebene Modell und die API zum Zusammenfassen von E-Mails verwendet, unabhängig von der Auswahl auf der ThunderAI-Optionsseite."
+ },
+ "prefs_OptionText_summarize_Info": {
+ "message": "Wenn aktiviert, wird dem Kontextmenü eine Option zum Zusammenfassen von E-Mails hinzugefügt."
+ },
+ "prefs_OptionText_btnManageSummarizeInfo": {
+ "message": "Zusammenfassung verwalten"
+ },
+ "Summarize_PageTitle": {
+ "message": "Zusammenfassungseinstellungen verwalten"
+ },
+ "Summarize_info_default": {
+ "message": "Auf dieser Seite können Sie den Standard-Prompt für die Zusammenfassung von E-Mails bearbeiten."
+ },
+ "Summarize_prompt_text_title": {
+ "message": "Aktueller Prompt-Text"
+ },
+ "prefs_OptionText_spamfilter_show_msg_panel": {
+ "message": "Spam-Bericht-Panel anzeigen"
+ },
+ "prefs_OptionText_spamfilter_show_msg_panel_Info": {
+ "message": "Wenn aktiviert, wird oben über der Nachricht ein Panel mit dem Spam-Bericht angezeigt."
+ },
+ "SpamReport_infoline": {
+ "message": "Diese Informationen werden nur für die aktuelle Sitzung gespeichert."
+ },
+ "Spam": {
+ "message": "Spam"
+ },
+ "Valid": {
+ "message": "Zulässig"
+ },
+ "context_menu_mzta-summarize": {
+ "message": "Zusammenfassen"
+ },
+ "CORS_alternative_2_new": {
+ "message": "Klicken Sie auf die untenstehende Schaltfläche, um dem aktuellen Host die Berechtigung zu erteilen und CORS-Probleme zu vermeiden."
+ },
+ "CORS_give_host_perm": {
+ "message": "Berechtigung für den aktuellen Host erteilen"
+ },
+ "CORS_localhost_warn": {
+ "message": "Wenn Sie localhost oder 127.0.0.1 verwenden, da der KI-Server auf Ihrem PC gehostet wird, ist die Berechtigung erforderlich."
+ },
+ "customPrompts_export_include_api_settings": {
+ "message": "Möchten Sie die API-Einstellungen in den Export einbeziehen? Bitte beachten Sie, dass auch der API-Schlüssel in der Datei gespeichert wird!"
+ },
+ "prefs_OptionText_calendar_no_selection": {
+ "message": "Nicht zur Textauswahl auffordern"
+ },
+ "prefs_OptionText_calendar_no_selection_Info": {
+ "message": "Wenn aktiviert, ist keine Textauswahl erforderlich. Der gesamte Nachrichtentext wird verwendet, um das Kalenderereignis zu erstellen."
+ },
+ "customPrompts_btnCopy": {
+ "message": "Kopieren"
+ },
+ "copy_text": {
+ "message": "kopie"
+ },
+ "spam_check_in_progress": {
+ "message": "Spam-Prüfung läuft..."
+ },
+ "prefs_THStats_1": {
+ "message": "Möchtest du schöne Statistiken zu deinen E-Mails erhalten?"
+ },
+ "prefs_THStats_2": {
+ "message": "Hier klicken! Probiere ThunderStats aus!"
+ },
+ "prefs_OptionText_calendar_no_selection_missing_placeholder": {
+ "message": "Der Prompt muss den Platzhalter {%mail_text_body_or_selected%} oder {%mail_html_body_or_selected%} enthalten, um diese Option zu aktivieren. Bitte fügen Sie einen dieser Platzhalter zum Prompt hinzu oder setzen Sie ihn auf den Standardwert zurück."
+ },
+ "antispam_by": {
+ "message": "Antispam von"
}
}
diff --git a/_locales/en/messages.json b/_locales/en/messages.json
index 0396b7b5..e2abc0c0 100644
--- a/_locales/en/messages.json
+++ b/_locales/en/messages.json
@@ -1048,7 +1048,7 @@
"description": ""
},
"Summarize_prompt_prefs_title": {
- "message": "Add Summarization Options",
+ "message": "Summarization Options",
"description": ""
},
"prompt_summarize": {
@@ -1288,7 +1288,7 @@
"description": ""
},
"prefs_OptionText_summarize": {
- "message": "Summarize mail",
+ "message": "Summarize email",
"description": ""
},
"prefs_OptionText_summarize_use_specific_integration_Info": {
@@ -1296,7 +1296,7 @@
"description": ""
},
"prefs_OptionText_summarize_Info": {
- "message": "If checked, adds an option to context menu to summarize mail.",
+ "message": "If checked, adds an option to context menu to summarize email(s).",
"description": ""
},
"prefs_OptionText_btnManageSummarizeInfo": {
@@ -1899,6 +1899,10 @@
"message": "If checked there is no need to select some text. The full message body will be used to get the calendar event.",
"description": ""
},
+ "prefs_OptionText_calendar_no_selection_missing_placeholder": {
+ "message": "The prompt must contain the placeholder {%mail_text_body_or_selected%} or {%mail_html_body_or_selected%} to enable this option. Please add one of these placeholders to the prompt or reset it to the default.",
+ "description": ""
+ },
"customPrompts_btnCopy": {
"message": "Copy",
"description": ""
@@ -1954,5 +1958,17 @@
"summarize_refresh": {
"message": "Refresh summary",
"description": ""
- }
- }
+ },
+ "antispam_by": {
+ "message": "Antispam by",
+ "description": ""
+ },
+ "prefs_THStats_1": {
+ "message": "Do you want beautiful statistics about your emails?",
+ "description": ""
+ },
+ "prefs_THStats_2": {
+ "message": "Click here! Try ThunderStats!",
+ "description": ""
+ }
+}
\ No newline at end of file
diff --git a/_locales/fr/messages.json b/_locales/fr/messages.json
index 6a3ef008..dc41a8e9 100644
--- a/_locales/fr/messages.json
+++ b/_locales/fr/messages.json
@@ -1302,5 +1302,152 @@
},
"reset": {
"message": "Réinitialiser"
+ },
+ "placeholder_mail_text_body_or_selected": {
+ "message": "Corps de l'e-mail ou texte sélectionné"
+ },
+ "placeholder_mail_html_body_or_selected": {
+ "message": "Corps de l'e-mail ou HTML sélectionné"
+ },
+ "prefs_OptionText_chatgpt_web_load_wait_time": {
+ "message": "Délai d'attente pour le chargement de la page"
+ },
+ "prefs_OptionText_chatgpt_web_load_wait_time_info": {
+ "message": "Temps en millisecondes à attendre pour le chargement de la page ChatGPT avant de charger le contenu supplémentaire. La valeur par défaut est 1000ms. Si un GPT personnalisé ou un Projet est défini, 1000ms supplémentaires seront ajoutés à cette valeur."
+ },
+ "prompt_get_calendar_event_from_clipboard": {
+ "message": "Ajouter un événement de calendrier depuis le presse-papiers"
+ },
+ "clipboard_read_error": {
+ "message": "Impossible de lire le presse-papiers. Veuillez vérifier les autorisations."
+ },
+ "clipboard_empty_error": {
+ "message": "Le presse-papiers est vide. Veuillez d'abord copier du texte."
+ },
+ "clipboard_permission_denied": {
+ "message": "L'autorisation d'accès au presse-papiers a été refusée. Veuillez réactiver la fonctionnalité dans les paramètres per accorder l'autorisation."
+ },
+ "clipboard_permission_error": {
+ "message": "Erreur lors de la demande d'autorisation du presse-papiers. Veuillez réessayer."
+ },
+ "prefs_OptionText_get_calendar_event_from_clipboard": {
+ "message": "Obtenir l'événement de calendrier depuis le presse-papiers"
+ },
+ "prefs_OptionText_get_calendar_event_from_clipboard_Info": {
+ "message": "Afficher un élément de menu supplémentaire pour créer des événements de calendrier à partir du contenu textuel du presse-papiers."
+ },
+ "Summarize_prompt_prefs_title": {
+ "message": "Options de résumé"
+ },
+ "prompt_summarize": {
+ "message": "Résumer cet e-mail ou ces e-mails"
+ },
+ "prompt_summarize_full_text": {
+ "message": "Vous êtes un assistant qui résume les conversations par e-mail.\n\nÀ partir d'un fil de discussion, produisez un résumé concis et précis qui capture :\n\n- Le sujet principal ou l'objet de la conversation.\n- Les décisions clés, conclusions ou accords.\n- Les questions importantes, requêtes ou points à traiter.\n- Le responsable de chaque action à entreprendre (si précisé).\n\nOmettez les salutations, les signatures, le texte cité et les échanges redondants.\nN'ajoutez pas d'hypothèses ou d'informations non présentes dans les e-mails.\n\nRédigez le résumé dans un langage clair et neutre, adapté à un professionnel occupé."
+ },
+ "prompt_summarize_email_template": {
+ "message": "Résumé du modèle d'e-mail"
+ },
+ "prompt_summarize_email_template_full_text": {
+ "message": "De : {%author%}\nÀ : {%recipients%}\nCopie : {%cc_list%}\nObjet : {%mail_subject%}\nDate : {%mail_datetime%}\nPièces jointes :\n{%mail_attachments_info%}\n\nCorps du message :\n{%mail_text_body%}"
+ },
+ "prompt_summarize_email_separator": {
+ "message": "Séparateur d'e-mail"
+ },
+ "prompt_summarize_email_separator_full_text": {
+ "message": "\n\n---------- E-MAIL SUIVANTE ----------\n\n"
+ },
+ "prefs_OptionText_Summarize_infoline2": {
+ "message": "Vous pouvez modifier l’instruction (prompt) comme vous le souhaitez : le premier champ est l’instruction principale, le deuxième est le modèle pour un e-mail individuel. La liste des e-mails sera ajoutée à la suite de l’instruction principale. Les e-mails seront séparés par le séparateur spécifié dans le troisième champ."
+ },
+ "prefs_OptionText_Summarize_main_prompt": {
+ "message": "L'instruction principale décrivant la tâche à effectuer sur tous les e-mails sélectionnés :"
+ },
+ "prefs_OptionText_Summarize_email_template": {
+ "message": "Le modèle pour un e-mail unique :"
+ },
+ "prefs_OptionText_Summarize_email_separator": {
+ "message": "Le séparateur entre les e-mails :"
+ },
+ "prefs_OptionText_get_calendar_event_use_specific_integration_Info": {
+ "message": "Si coché, le Modèle et l'API spécifiés ci-dessous seront utilisés pour créer des événements de calendrier, quel que soit celui choisi dans la page des options de ThunderAI."
+ },
+ "prefs_OptionText_summarize": {
+ "message": "Résumer l'e-mail"
+ },
+ "prefs_OptionText_summarize_use_specific_integration_Info": {
+ "message": "Si coché, le Modèle et l'API spécifiés ci-dessous seront utilisés pour résumer les e-mails, quel que soit celui choisi dans la page des options de ThunderAI."
+ },
+ "prefs_OptionText_summarize_Info": {
+ "message": "Si coché, ajoute une option au menu contextuel pour résumer l'e-mail."
+ },
+ "prefs_OptionText_btnManageSummarizeInfo": {
+ "message": "Gérer les paramètres de résumé"
+ },
+ "Summarize_PageTitle": {
+ "message": "Gestion des paramètres de résumé"
+ },
+ "Summarize_info_default": {
+ "message": "Sur cette page, vous pouvez modifier le prompt par défaut utilisé pour résumer les e-mails."
+ },
+ "Summarize_prompt_text_title": {
+ "message": "Texte actuel du prompt"
+ },
+ "prefs_OptionText_spamfilter_show_msg_panel": {
+ "message": "Afficher le panneau de rapport de spam"
+ },
+ "prefs_OptionText_spamfilter_show_msg_panel_Info": {
+ "message": "Si coché, un panneau avec le rapport de spam s'affichera au-dessus du message."
+ },
+ "SpamReport_infoline": {
+ "message": "Ces informations ne sont enregistrées que pour la session en cours."
+ },
+ "Spam": {
+ "message": "Indésirables"
+ },
+ "Valid": {
+ "message": "Valide"
+ },
+ "context_menu_mzta-summarize": {
+ "message": "Résumer"
+ },
+ "CORS_alternative_2_new": {
+ "message": "Appuyez sur le bouton ci-dessous pour donner l'autorisation à l'hôte actuel afin d'éviter tout problème CORS."
+ },
+ "CORS_give_host_perm": {
+ "message": "Donner l'autorisation à l'hôte actuel"
+ },
+ "CORS_localhost_warn": {
+ "message": "Si vous utilisez localhost ou 127.0.0.1 parce que le serveur d'IA est hébergé sur votre PC, l'autorisation est requise."
+ },
+ "customPrompts_export_include_api_settings": {
+ "message": "Voulez-vous inclure les paramètres API dans l'exportation ? Attention, la clé API sera également enregistrée dans le fichier !"
+ },
+ "prefs_OptionText_calendar_no_selection": {
+ "message": "Ne pas demander de sélectionner du texte"
+ },
+ "prefs_OptionText_calendar_no_selection_Info": {
+ "message": "Si coché, il n'est pas nécessaire de sélectionner du texte. Le corps complet du message sera utilisé pour créer l'événement de calendrier."
+ },
+ "spam_check_in_progress": {
+ "message": "Analyse antispam en cours..."
+ },
+ "customPrompts_btnCopy": {
+ "message": "Copier"
+ },
+ "copy_text": {
+ "message": "copie"
+ },
+ "prefs_THStats_1": {
+ "message": "Voulez-vous de belles statistiques sur vos e-mails ?"
+ },
+ "prefs_THStats_2": {
+ "message": "Cliquez ici ! Essayez ThunderStats !"
+ },
+ "prefs_OptionText_calendar_no_selection_missing_placeholder": {
+ "message": "L'invite doit contenir l'espace réservé {%mail_text_body_or_selected%} ou {%mail_html_body_or_selected%} pour activer cette option. Veuillez ajouter l'un de ces espaces réservés à l'invite ou rétablir la valeur par défaut."
+ },
+ "antispam_by": {
+ "message": "Antispam par"
}
}
diff --git a/_locales/it/messages.json b/_locales/it/messages.json
index 25ed2bf6..5bd0eb19 100644
--- a/_locales/it/messages.json
+++ b/_locales/it/messages.json
@@ -31,7 +31,7 @@
"message": "Traduci"
},
"prompt_this": {
- "message": "Chedi a ChatGPT"
+ "message": "Invia il testo come prompt"
},
"prompt_selection_needed": {
"message": "Per procedere è necessario che selezioni del testo!"
@@ -172,7 +172,7 @@
"message": "Riprova"
},
"chatgpt_sendbutton_not_found_error": {
- "message": "Premi il pulsante per inviare il prompt a ChatGPT."
+ "message": "Premi il pulsante per inviare il prompt."
},
"chatgpt_user_not_logged_in": {
"message": "Non sei connesso a ChatGPT. Effettua l'accesso con le tue credenziali, chiudi la finestra di ChatGPT e poi ripeti l'azione che avevi tentato. Rimarrai connesso in seguito."
@@ -1302,5 +1302,152 @@
},
"prefs_anthropic_temperature_Info": {
"message": "Quantità di casualità iniettata nella risposta. Il valore predefinito è 1,0. L'intervallo va da 0,0 a 1,0. Utilizza una temperatura più vicina a 0,0 per compiti analitici o a scelta multipla, e più vicina a 1,0 per compiti creativi e generativi. Nota che, anche con una temperatura di 0,0, i risultati non saranno completamente deterministici."
+ },
+ "placeholder_mail_text_body_or_selected": {
+ "message": "Corpo dell'email o testo selezionato"
+ },
+ "placeholder_mail_html_body_or_selected": {
+ "message": "Corpo dell'email o HTML selezionato"
+ },
+ "prefs_OptionText_chatgpt_web_load_wait_time": {
+ "message": "Tempo di attesa caricamento pagina"
+ },
+ "prefs_OptionText_chatgpt_web_load_wait_time_info": {
+ "message": "Tempo di attesa in millisecondi per il caricamento della pagina di ChatGPT prima di caricare i contenuti aggiuntivi. Il valore predefinito è 1000ms. Se viene definito un Custom GPT o un Progetto, verranno aggiunti ulteriori 1000ms a questo valore."
+ },
+ "prompt_get_calendar_event_from_clipboard": {
+ "message": "Aggiungi un evento a calendario dagli appunti"
+ },
+ "clipboard_read_error": {
+ "message": "Impossibile leggere il contenuto copiato negli appunti. Verifica i permessi."
+ },
+ "clipboard_empty_error": {
+ "message": "Gli appunti sono vuoti. Copia prima del testo."
+ },
+ "clipboard_permission_denied": {
+ "message": "Accesso agli appunti negato. Riattiva la funzione nelle impostazioni per concedere il permesso."
+ },
+ "clipboard_permission_error": {
+ "message": "Errore durante la richiesta dei permessi per gli appunti. Riprova."
+ },
+ "prefs_OptionText_get_calendar_event_from_clipboard": {
+ "message": "Ottieni un evento del calendario dagli appunti"
+ },
+ "prefs_OptionText_get_calendar_event_from_clipboard_Info": {
+ "message": "Mostra una voce di menu aggiuntiva per creare eventi di calendario dal contenuto di testo negli appunti."
+ },
+ "Summarize_prompt_prefs_title": {
+ "message": "Impostazioni riassunto"
+ },
+ "prompt_summarize": {
+ "message": "Riassumi email"
+ },
+ "prompt_summarize_full_text": {
+ "message": "Sei un assistente che riassume conversazioni via email.\n\nDato un thread di email, produci un riassunto conciso e accurato che includa:\n\n- L'argomento principale o lo scopo della conversazione\n- Decisioni chiave, conclusioni o accordi\n- Domande importanti, richieste o punti d'azione\n- Il responsabile per ogni punto d'azione (se indicato)\n\nOmetti saluti, firme, testo citato e scambi ridondanti.\nNon aggiungere supposizioni o informazioni non presenti nelle email.\n\nScrivi il riassunto con un linguaggio chiaro e neutro, adatto a un professionista impegnato."
+ },
+ "prompt_summarize_email_template": {
+ "message": "Template riassunto email"
+ },
+ "prompt_summarize_email_template_full_text": {
+ "message": "Da: {%author%}\nA: {%recipients%}\nCC: {%cc_list%}\nOggetto: {%mail_subject%}\nData: {%mail_datetime%}\nAllegati:\n{%mail_attachments_info%}\n\nCorpo del messaggio:\n{%mail_text_body%}"
+ },
+ "prompt_summarize_email_separator": {
+ "message": "Separatore email"
+ },
+ "prompt_summarize_email_separator_full_text": {
+ "message": "\n\n---------- PROSSIMA EMAIL ----------\n\n"
+ },
+ "prefs_OptionText_Summarize_infoline2": {
+ "message": "Puoi modificare il prompt come desideri: il primo campo è il prompt principale, il secondo è il modello per la singola email. L'elenco delle email sarà aggiunto al prompt principale. Le email saranno divise dal separatore specificato nel terzo campo."
+ },
+ "prefs_OptionText_Summarize_main_prompt": {
+ "message": "Il prompt principale che descrive l'attività da eseguire su tutte le email selezionate:"
+ },
+ "prefs_OptionText_Summarize_email_template": {
+ "message": "Il modello per la singola email:"
+ },
+ "prefs_OptionText_Summarize_email_separator": {
+ "message": "Il separatore tra le email:"
+ },
+ "prefs_OptionText_get_calendar_event_use_specific_integration_Info": {
+ "message": "Se selezionato, il Modello e l'API specificati di seguito verranno utilizzati per creare gli eventi di calendario, indipendentemente da quelli scelti nella pagina delle opzioni di ThunderAI."
+ },
+ "prefs_OptionText_summarize": {
+ "message": "Riassumi email"
+ },
+ "prefs_OptionText_summarize_use_specific_integration_Info": {
+ "message": "Se selezionato, il Modello e l'API specificati di seguito verranno utilizzati per riassumere le email, indipendentemente da quelli scelti nella pagina delle opzioni di ThunderAI."
+ },
+ "prefs_OptionText_summarize_Info": {
+ "message": "Se selezionato, aggiunge un'opzione al menu contestuale per riassumere le email."
+ },
+ "prefs_OptionText_btnManageSummarizeInfo": {
+ "message": "Gestisci le impostazioni di riassunto"
+ },
+ "Summarize_PageTitle": {
+ "message": "Gestisci Impostazioni di Riassunto"
+ },
+ "Summarize_info_default": {
+ "message": "In questa pagina puoi modificare il prompt predefinito utilizzato per riassumere le email."
+ },
+ "Summarize_prompt_text_title": {
+ "message": "Testo del prompt attuale"
+ },
+ "prefs_OptionText_spamfilter_show_msg_panel": {
+ "message": "Mostra pannello segnalazione spam"
+ },
+ "prefs_OptionText_spamfilter_show_msg_panel_Info": {
+ "message": "Se selezionato, verrà mostrato un pannello con il report spam sopra il messaggio."
+ },
+ "SpamReport_infoline": {
+ "message": "Queste informazioni sono salvate solo per la sessione corrente."
+ },
+ "Spam": {
+ "message": "Spam"
+ },
+ "Valid": {
+ "message": "Valido"
+ },
+ "context_menu_mzta-summarize": {
+ "message": "Riassumi"
+ },
+ "CORS_alternative_2_new": {
+ "message": "Premi il pulsante qui sotto per concedere le autorizzazioni all'host corrente ed evitare problemi di CORS."
+ },
+ "CORS_give_host_perm": {
+ "message": "Concedi l'autorizzazione all'host corrente"
+ },
+ "CORS_localhost_warn": {
+ "message": "Se stai utilizzando localhost o 127.0.0.1 perché il server IA è ospitato sul tuo PC, è necessaria l'autorizzazione ."
+ },
+ "customPrompts_export_include_api_settings": {
+ "message": "Vuoi includere le impostazioni API nell'esportazione? Attenzione: anche la Chiave API verrà salvata nel file!"
+ },
+ "prefs_OptionText_calendar_no_selection": {
+ "message": "Non chiedere di selezionare del testo"
+ },
+ "prefs_OptionText_calendar_no_selection_Info": {
+ "message": "Se questa opzione viene attivata, non sarà necessario selezionare del testo. Verrà utilizzato l'intero corpo del messaggio per creare l'evento di calendario."
+ },
+ "customPrompts_btnCopy": {
+ "message": "Copia"
+ },
+ "copy_text": {
+ "message": "copia"
+ },
+ "spam_check_in_progress": {
+ "message": "Controllo spam in corso..."
+ },
+ "prefs_THStats_1": {
+ "message": "Desideri delle belle statistiche sulle tue email?"
+ },
+ "prefs_THStats_2": {
+ "message": "Clicca qui! Prova ThunderStats!"
+ },
+ "prefs_OptionText_calendar_no_selection_missing_placeholder": {
+ "message": "Il prompt deve contenere il segnaposto {%mail_text_body_or_selected%} o {%mail_html_body_or_selected%} per abilitare questa opzione. Per favore, aggiungi uno di questi segnaposto al prompt o ripristina quello predefinito."
+ },
+ "antispam_by": {
+ "message": "Antispam di"
}
}
diff --git a/_locales/sv/messages.json b/_locales/sv/messages.json
index f4066bc8..90f0ea9f 100644
--- a/_locales/sv/messages.json
+++ b/_locales/sv/messages.json
@@ -1288,7 +1288,7 @@
"message": "Analysera följande e-postmeddelande och avgör om det är skräppost eller inte. Tänk på faktorer som misstänkta sökord, överdrivet reklamspråk, vilseledande ämnesrader, förfrågningar om personlig information och ovanliga avsändaradresser.\nAnge ett värde från 0 (inte skräppost) till 100 (skräppost) och en förklaring på högst 10 ord.\nOm meddelandedata saknas, sätt värdet till 0 (inte skräppost) och ange orsaken.\nGenerera ett svar endast i JSON-format. Inkludera inte ytterligare text eller förklaring; ange endast JSON. Här är formatet som ska användas:\n{\n\"spamValue\": ,\n\"explanation\": \"Kort förklaring av ditt resonemang\"\n}\nHär är e-postinformationen:\nAvsändare: \"{%author%}\"\nÄmne: \"{%mail_subject%}\"\nHtml-text: \"{%mail_html_body%}\""
},
"Summarize_prompt_prefs_title": {
- "message": "Lägg till sammanfattningsalternativ"
+ "message": "Sammanfattningsalternativ"
},
"prompt_summarize": {
"message": "Sammanfatta det här e-postmeddelandet eller dessa e-postmeddelanden"
@@ -1321,13 +1321,13 @@
"message": "Avgränsaren mellan e-postmeddelanden:"
},
"prefs_OptionText_summarize": {
- "message": "Sammanfatta e-postmeddelande"
+ "message": "Sammanfatta epostmeddelande"
},
"prefs_OptionText_summarize_use_specific_integration_Info": {
"message": "Om markerat kommer modellen och API:et som anges nedan att användas för att sammanfatta e-postmeddelanden, oavsett vilket som valts på ThunderAI-alternativsidan."
},
"prefs_OptionText_summarize_Info": {
- "message": "Om markerad läggs ett alternativ till i snabbmenyn för att sammanfatta e-post."
+ "message": "Om markerad läggs ett alternativ till i snabbmenyn för att sammanfatta epost(meddelanden)."
},
"prefs_OptionText_btnManageSummarizeInfo": {
"message": "Hantera sammanfattningsinställningar"
@@ -1421,5 +1421,17 @@
},
"spam_check_in_progress": {
"message": "Skräppostkontroll pågår..."
+ },
+ "prefs_THStats_1": {
+ "message": "Vill du ha snygg statistik om dina e-postmeddelanden?"
+ },
+ "prefs_THStats_2": {
+ "message": "Klicka här! Testa ThunderStats!"
+ },
+ "antispam_by": {
+ "message": "Antispam av"
+ },
+ "prefs_OptionText_calendar_no_selection_missing_placeholder": {
+ "message": "Prompten måste innehålla platshållaren {%mail_text_body_or_selected%} eller {%mail_html_body_or_selected%} för att aktivera det här alternativet. Lägg till en av dessa platshållare i prompten eller återställ den till standard."
}
}
diff --git a/api_webchat/messageInput.js b/api_webchat/messageInput.js
index 2907174f..567339ee 100644
--- a/api_webchat/messageInput.js
+++ b/api_webchat/messageInput.js
@@ -66,6 +66,13 @@ messagesInputStyle.textContent = `
border-radius: 5px;
padding: 5px;
background: #F2F2F2;
+ display: flex;
+ align-items: center;
+ gap: 3px;
+ }
+ #statusLoggerImg{
+ display: none;
+ vertical-align: middle;
}
#mzta-custom_text{
padding:10px;
@@ -183,8 +190,14 @@ messageInputTemplate.content.appendChild(stopButton);
const statusLogger = document.createElement('div');
statusLogger.id = 'statusLogger';
-statusLogger.textContent = '';
statusLogger.style.display = 'none';
+const statusLoggerImg = document.createElement('img');
+statusLoggerImg.id = 'statusLoggerImg';
+statusLoggerImg.src = browser.runtime.getURL('/images/mzta-loading.svg');
+statusLogger.appendChild(statusLoggerImg);
+const statusLoggerText = document.createElement('span');
+statusLoggerText.id = 'statusLoggerText';
+statusLogger.appendChild(statusLoggerText);
messageInputTemplate.content.appendChild(statusLogger);
//div per custom text
@@ -227,6 +240,8 @@ class MessageInput extends HTMLElement {
this._sendButton = shadowRoot.querySelector('#sendButton');
this._stopButton = shadowRoot.querySelector('#stopButton');
this._statusLogger = shadowRoot.querySelector('#statusLogger');
+ this._statusLoggerImg = shadowRoot.querySelector('#statusLoggerImg');
+ this._statusLoggerText = shadowRoot.querySelector('#statusLoggerText');
this._messageInputField.addEventListener('keydown', this._handleKeyDown.bind(this));
this._sendButton.addEventListener('click', this._handleClick.bind(this));
@@ -284,15 +299,16 @@ class MessageInput extends HTMLElement {
}
setStatusMessage(message) {
- this._statusLogger.textContent = message;
+ this._statusLoggerText.textContent = message;
}
showStatusMessage() {
- this._statusLogger.style.display = 'block';
+ this._statusLogger.style.display = 'flex';
}
hideStatusMessage() {
this._statusLogger.style.display = 'none';
+ this._statusLoggerImg.style.display = 'none';
}
_handleKeyDown(event) {
@@ -328,6 +344,7 @@ class MessageInput extends HTMLElement {
this.messagesAreaComponent.appendUserMessage(messageContent);
}
this.setStatusMessage(browser.i18n.getMessage('WaitingServerResponse') + '...');
+ this._statusLoggerImg.style.display = 'inline';
this.showStatusMessage();
this.worker.postMessage({ type: 'chatMessage', message: messageContent });
}
diff --git a/popup/mzta-loading.svg b/images/mzta-loading.svg
similarity index 98%
rename from popup/mzta-loading.svg
rename to images/mzta-loading.svg
index 27b59d6a..9dec98ab 100644
--- a/popup/mzta-loading.svg
+++ b/images/mzta-loading.svg
@@ -7,4 +7,4 @@
-
\ No newline at end of file
+
diff --git a/images/thunderstats.png b/images/thunderstats.png
new file mode 100644
index 00000000..c172e8a6
Binary files /dev/null and b/images/thunderstats.png differ
diff --git a/js/mzta-compose-script.js b/js/mzta-compose-script.js
index 1303866d..1d6579e8 100644
--- a/js/mzta-compose-script.js
+++ b/js/mzta-compose-script.js
@@ -641,8 +641,13 @@ switch (message.command) {
loadingImg.src = browser.runtime.getURL("/images/loading.gif");
loadingImg.style.cssText = "height: 16px; width: 16px;";
+ const brandingProgress = document.createElement('span');
+ brandingProgress.textContent = browser.i18n.getMessage("antispam_by") + " ThunderAI";
+ brandingProgress.style.cssText = 'margin-left: auto; font-style: italic; font-size: 11px; opacity: 0.7;';
+
containerProgress.appendChild(loadingImg);
containerProgress.appendChild(textProgress);
+ containerProgress.appendChild(brandingProgress);
document.body.insertBefore(containerProgress, document.body.firstChild);
return Promise.resolve(true);
@@ -693,9 +698,13 @@ switch (message.command) {
reasonText.textContent = browser.i18n.getMessage("Explanation") + ": " + data.explanation;
}
+ const branding = document.createElement('span');
+ branding.textContent = browser.i18n.getMessage("antispam_by") + " ThunderAI";
+ branding.style.cssText = 'margin-left: auto; font-style: italic; font-size: 11px; opacity: 0.7;';
+
const closeBtn = document.createElement('span');
closeBtn.textContent = '×';
- closeBtn.style.cssText = 'margin-left: auto; cursor: pointer; font-weight: bold; font-size: 16px; padding: 0 5px;';
+ closeBtn.style.cssText = 'cursor: pointer; font-weight: bold; font-size: 16px; padding: 0 5px;';
closeBtn.title = browser.i18n.getMessage("chatgpt_win_close");
closeBtn.onclick = function() {
container.remove();
@@ -704,6 +713,7 @@ switch (message.command) {
container.appendChild(scoreText);
container.appendChild(reasonText);
+ container.appendChild(branding);
container.appendChild(closeBtn);
document.body.insertBefore(container, document.body.firstChild);
diff --git a/js/mzta-placeholders.js b/js/mzta-placeholders.js
index c666e858..48de04a3 100644
--- a/js/mzta-placeholders.js
+++ b/js/mzta-placeholders.js
@@ -17,7 +17,10 @@
*/
import { prefs_default } from '../options/mzta-options-default.js';
-import { getMailHeader } from './mzta-utils.js';
+import {
+ getMailHeader,
+ sanitizeMailHeaders
+ } from './mzta-utils.js';
/* ================= PLACEHOLDERS PROPERTIES ========================================
@@ -545,7 +548,7 @@ export const placeholdersUtils = {
finalSubs['mail_folder_path'] = placeholdersUtils.failSafePlaceholders(curr_message.folder?.path);
break;
case 'mail_headers':
- finalSubs['mail_headers:' + currPH.custom_value] = placeholdersUtils.failSafePlaceholders(await getMailHeader(curr_message, currPH.custom_value));
+ finalSubs['mail_headers:' + currPH.custom_value] = placeholdersUtils.failSafePlaceholders(sanitizeMailHeaders(await getMailHeader(curr_message, currPH.custom_value)));
break;
case 'selected_text':
finalSubs['selected_text'] = placeholdersUtils.failSafePlaceholders(selection_text);
@@ -560,13 +563,13 @@ export const placeholdersUtils = {
finalSubs['mail_html_body_or_selected'] = placeholdersUtils.failSafePlaceholders(selection_html || msg_text?.html);
break;
case 'author':
- finalSubs['author'] = placeholdersUtils.failSafePlaceholders(curr_message.author);
+ finalSubs['author'] = placeholdersUtils.failSafePlaceholders(sanitizeMailHeaders(curr_message.author));
break;
case 'recipients':
- finalSubs['recipients'] = placeholdersUtils.failSafePlaceholders(curr_message.recipients?.join(", "));
+ finalSubs['recipients'] = placeholdersUtils.failSafePlaceholders(sanitizeMailHeaders(curr_message.recipients?.join(", ")));
break;
case 'cc_list':
- finalSubs['cc_list'] = placeholdersUtils.failSafePlaceholders(curr_message.ccList?.join(", "));
+ finalSubs['cc_list'] = placeholdersUtils.failSafePlaceholders(sanitizeMailHeaders(curr_message.ccList?.join(", ")));
break;
case 'junk_score':
finalSubs['junk_score'] = placeholdersUtils.failSafePlaceholders(curr_message.junkScore);
diff --git a/js/mzta-utils.js b/js/mzta-utils.js
index a8aabdb2..ab8d7ef5 100644
--- a/js/mzta-utils.js
+++ b/js/mzta-utils.js
@@ -207,7 +207,8 @@ export async function getMailHeader(curr_message, mail_header_id) {
let full_message = await browser.messages.getFull(curr_message.id);
// console.log(">>>>>>>>>>>> getMailHeader full_message: " + JSON.stringify(full_message));
if(full_message.hasOwnProperty("headers") && Object.keys(full_message.headers).some(header => header.toLowerCase() === mail_header_id.toLowerCase())){
- mail_header_value = full_message.headers[Object.keys(full_message.headers).find(header => header.toLowerCase() === mail_header_id.toLowerCase())];
+ const raw_value = full_message.headers[Object.keys(full_message.headers).find(header => header.toLowerCase() === mail_header_id.toLowerCase())];
+ mail_header_value = Array.isArray(raw_value) ? raw_value.join(", ") : raw_value;
}
// console.log(">>>>>>>>>>>> getMailHeader mail_header_value: " + mail_header_value)
return mail_header_value;
@@ -218,6 +219,12 @@ export function sanitizeHtml(input) {
return input.replace(/<(?!br\s*\/?)[^>]+>/gi, '');
}
+export function sanitizeMailHeaders(input){
+ console.log(">>>>>>>>>>>> sanitizeMailHeaders input: " + JSON.stringify(input));
+ if(!input) return '';
+ return input.replace(//g, '>');
+}
+
export function stripHtmlKeepLines(htmlString) {
// Replaces tags with a newline at the beginning
// and removes all other HTML tags
diff --git a/manifest.json b/manifest.json
index 9260970b..743688ab 100644
--- a/manifest.json
+++ b/manifest.json
@@ -2,7 +2,7 @@
"manifest_version": 2,
"name": "ThunderAI",
"description": "__MSG_extensionDescription__",
- "version": "4.0.0pre1",
+ "version": "4.0.0",
"author": "Mic (m@micz.it)",
"homepage_url": "https://micz.it/thunderbird-addon-thunderai/",
"browser_specific_settings": {
diff --git a/options/mzta-options.css b/options/mzta-options.css
index 86d168d1..37b55c20 100644
--- a/options/mzta-options.css
+++ b/options/mzta-options.css
@@ -142,7 +142,6 @@ div#miczTranslate{
border-radius: 4px;
padding: 15px;
font-weight: bold;
- margin-bottom: 5px;
text-align: center;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
}
@@ -155,6 +154,10 @@ div#miczTranslate{
color: #FF6600;
}
+#mzta_top_msg td{
+ border:0 !important;
+}
+
.btn_small{
font-size: 0.8em;
}
@@ -167,6 +170,20 @@ label:has(input[type="checkbox"]) {
cursor: pointer;
}
+#thstats div{
+ text-align: center;
+ padding: 10px !important;
+ border: 0 !important;
+ background: rgb(185, 238, 238);
+ font-weight: bold;
+ font-style: italic;
+ border-radius: 4px;
+}
+
+#thstats td{
+ border-top:0 !important;
+}
+
@media (prefers-color-scheme: dark) {
body {
background-color: rgb(35, 34, 43);
@@ -226,4 +243,8 @@ label:has(input[type="checkbox"]) {
.lightbold{
color: #f3f3f3;
}
+
+ #thstats div{
+ background: rgb(41, 70, 70);
+ }
}
\ No newline at end of file
diff --git a/options/mzta-options.html b/options/mzta-options.html
index c809c1e3..449d4320 100644
--- a/options/mzta-options.html
+++ b/options/mzta-options.html
@@ -12,6 +12,11 @@
|
+
+ |
+
+ |
+
|
diff --git a/options/mzta-release-notes.html b/options/mzta-release-notes.html
index 672ad7d6..e87ba394 100644
--- a/options/mzta-release-notes.html
+++ b/options/mzta-release-notes.html
@@ -29,6 +29,10 @@
- [ChatGPT Web] Added an option to define a custom time to wait for the page load. Sometimes, on slow PCs, the ChatGPT page loads slowly and ThunderAI inject its content too early. With this option you can adjust the waiting time [#634].
- ...
+ Version 3.8.5 - 22/02/2026
+
+ - Fix: Correctly showing email addresses when using mail headers in data placeholders [#672].
+
Version 3.8.4 - 10/02/2026
- [ChatGPT Web] Fix: Correctly importing the selected text into the compose windows also when ChatGPT shows the advanced mail editor in the response [#646].
diff --git a/pages/_lib/tom-select.base.js b/pages/_lib/tom-select.base.js
index a79fe394..2d1c3390 100644
--- a/pages/_lib/tom-select.base.js
+++ b/pages/_lib/tom-select.base.js
@@ -1,5 +1,5 @@
/**
-* Tom Select v2.4.6
+* Tom Select v2.5.2
* Licensed under the Apache License, Version 2.0 (the "License");
*/
@@ -1502,6 +1502,7 @@
create: null,
createOnBlur: false,
createFilter: null,
+ clearAfterSelect: false,
highlight: true,
openOnFocus: true,
shouldOpen: null,
@@ -2444,6 +2445,8 @@
self.createItem(null, () => {
if (self.settings.closeAfterSelect) {
self.close();
+ } else if (self.settings.clearAfterSelect) {
+ self.setTextboxValue();
}
});
} else {
@@ -2453,6 +2456,8 @@
self.addItem(value);
if (self.settings.closeAfterSelect) {
self.close();
+ } else if (self.settings.clearAfterSelect) {
+ self.setTextboxValue();
}
if (!self.settings.hideSelected && evt.type && /click/.test(evt.type)) {
self.setActiveOption(option);
@@ -2884,6 +2889,11 @@
// perform search
if (query !== self.lastQuery) {
self.lastQuery = query;
+ // temp fix for https://github.com/orchidjs/tom-select/issues/987
+ // UI crashed when more than 30 same chars in a row, prevent search and return empt result
+ if (/(.)\1{15,}/.test(query)) {
+ query = '';
+ }
result = self.sifter.search(query, Object.assign(options, {
score: calculateScore
}));
@@ -2896,7 +2906,7 @@
if (self.settings.hideSelected) {
result.items = result.items.filter(item => {
let hashed = hash_key(item.id);
- return !(hashed && self.items.indexOf(hashed) !== -1);
+ return !(hashed !== null && self.items.indexOf(hashed) !== -1);
});
}
return result;
@@ -2975,6 +2985,13 @@
optgroup = optgroups[j];
let order = option.$order;
let self_optgroup = self.optgroups[optgroup];
+ if (self_optgroup === undefined && typeof self.settings.optionGroupRegister === 'function') {
+ var regGroup;
+ if (regGroup = self.settings.optionGroupRegister.apply(self, [optgroup])) {
+ self.registerOptionGroup(regGroup);
+ }
+ }
+ self_optgroup = self.optgroups[optgroup];
if (self_optgroup === undefined) {
optgroup = '';
} else {
@@ -3434,6 +3451,11 @@
}
}
+ //remove input value when enabled
+ if (self.settings.clearAfterSelect) {
+ self.setTextboxValue();
+ }
+
// refreshOptions after setActiveOption(),
// otherwise setActiveOption() will be called by refreshOptions() with the wrong value
if (!self.isPending && !self.settings.closeAfterSelect) {
diff --git a/pages/customprompts/mzta-custom-prompts.js b/pages/customprompts/mzta-custom-prompts.js
index 8e45ac8c..cd9e776e 100644
--- a/pages/customprompts/mzta-custom-prompts.js
+++ b/pages/customprompts/mzta-custom-prompts.js
@@ -1020,7 +1020,8 @@ function handleCopyClick(e) {
// Show form
document.getElementById('formNew').style.display = 'block';
-
+ document.getElementById('btnNew').disabled = true;
+
// Scroll to top
window.scrollTo({
top: 0,
diff --git a/pages/get-calendar-event/mzta-get-calendar-event.js b/pages/get-calendar-event/mzta-get-calendar-event.js
index 7dc9a0e9..ca3c8ef7 100644
--- a/pages/get-calendar-event/mzta-get-calendar-event.js
+++ b/pages/get-calendar-event/mzta-get-calendar-event.js
@@ -98,6 +98,15 @@ document.addEventListener('DOMContentLoaded', async () => {
});
get_calendar_event_no_selection.addEventListener('change', async (event) => {
+ if (event.target.checked) {
+ const currentPromptText = get_calendar_event_textarea.value;
+ const hasBodyOrSelected = currentPromptText.includes('{%mail_text_body_or_selected%}') || currentPromptText.includes('{%mail_html_body_or_selected%}');
+ if (!hasBodyOrSelected) {
+ alert(browser.i18n.getMessage('prefs_OptionText_calendar_no_selection_missing_placeholder'));
+ event.target.checked = false;
+ return;
+ }
+ }
specialPrompts.find(prompt => prompt.id === 'prompt_get_calendar_event').need_selected = event.target.checked ? '0' : '1';
await setSpecialPrompts(specialPrompts);
browser.runtime.sendMessage({command: "reload_menus"});
diff --git a/pages/onboarding/onboarding.html b/pages/onboarding/onboarding.html
index 904a6610..953e3bef 100644
--- a/pages/onboarding/onboarding.html
+++ b/pages/onboarding/onboarding.html
@@ -29,7 +29,7 @@
Welcome to ThunderAI!
This add-on is designed to enhance your email management with the power of AI.
-
With ThunderAI, you can streamline your inbox, generate smart replies, summarize emails, and much more—all with the help of artificial intelligence.
+
With ThunderAI, you can streamline your inbox, generate smart replies, summarize emails, automatically add tags and filter spam, and much more, all with the help of artificial intelligence.
On this page, you'll find an overview of the key features available to help you make the most of ThunderAI.
Get ready to experience a smarter, more efficient way to handle your emails!
Let's see how to make best use of this add-on!
@@ -55,12 +55,12 @@
Defining your Custom Prompts
- From the options page you can open the Custom Prompts page.
+ From the options page you can open the Custom Prompts page.
From there you can add your prompts, and also disable the default ones.
You can find more info here.
- While defining your own prompts you can also use data placeholders, that will be substituted with the corresponding information when using the prompt.
+ While defining your own prompts you can also use data placeholders, that will be substituted with the corresponding information when using the prompt.
You can find more info here.
diff --git a/popup/mzta-popup.html b/popup/mzta-popup.html
index 1abeead3..02caba36 100644
--- a/popup/mzta-popup.html
+++ b/popup/mzta-popup.html
@@ -19,9 +19,9 @@