From cf8788a0f2d9436714f69d3b10358954ba0b1517 Mon Sep 17 00:00:00 2001 From: Merci Jacob Date: Sun, 14 Jan 2024 15:01:50 +0200 Subject: [PATCH] [NEW] add a modal dialog to warn the user about sending an email without a subject or body --- modules/core/site.css | 101 +++++++++++++++++++++++++++++++ modules/core/site.js | 46 ++++++++++++++ modules/smtp/hm-mime-message.php | 4 +- modules/smtp/modules.php | 6 +- modules/smtp/site.css | 1 - modules/smtp/site.js | 92 ++++++++++++++++++++++++---- 6 files changed, 232 insertions(+), 18 deletions(-) diff --git a/modules/core/site.css b/modules/core/site.css index 345f267621..7796aafbfe 100644 --- a/modules/core/site.css +++ b/modules/core/site.css @@ -329,4 +329,105 @@ div.unseen, .unseen .subject { font-weight: 700; } } .drag_target { background-color: #888 !important; +} + +.cypht-modal { + display: block; + position: fixed; + z-index: 1; + left: 0; + top: 0; + width: 100%; + height: 100%; +} + +.cypht-modal-bg { + background-color: rgba(0,0,0,0.4); + position: fixed; + left: 0; + top: 0; + width: 100%; + height: 100%; +} + +.cypht-modal-content { + background-color: #fefefe; + margin: 15% auto; + padding: 20px; + border: 1px solid #888; + width: 50%; + display: flex; + flex-direction: column; + gap: 20px; + position: relative; +} + +.cypht-modal-content-close { + color: #aaa; + float: right; + font-size: 28px; + font-weight: bold; + align-self: flex-end; + position: absolute; +} + +.cypht-modal-content-close:hover, +.cypht-modal-content-close:focus { + color: black; + text-decoration: none; + cursor: pointer; +} + +.cypht-modal-header { + font-size: 1.5rem; + font-weight: 600; +} + +.cypht-modal-footer { + display: flex; + justify-content: flex-end; + gap: 10px; +} + +.cypht-modal-footer button { + padding: 10px 20px; + cursor: pointer; +} + +.cypht-modal-content-close:hover, +.cypht-modal-content-close:focus { + color: black; + text-decoration: none; + cursor: pointer; +} + +.cypht-modal-header { + font-size: 1.5rem; + font-weight: 600; +} + +.cypht-modal-footer { + display: flex; + flex-wrap: wrap; + justify-content: flex-end; + gap: 10px; +} + +.cypht-modal-footer button { + padding: 10px 20px; + cursor: pointer; + height: max-content; + width: max-content; +} + +.mobile .cypht-modal-content { + width: 75%; +} + +.mobile .cypht-modal-footer { + justify-content: flex-start; +} + +.mobile .cypht-modal-footer button { + padding: 5px 10px; } \ No newline at end of file diff --git a/modules/core/site.js b/modules/core/site.js index 36aec28ed2..a103df0608 100644 --- a/modules/core/site.js +++ b/modules/core/site.js @@ -303,6 +303,52 @@ var Hm_Ajax_Request = function() { return { } }}; +/** + * Show a modal dialog with a title, content and buttons. + */ +const Hm_Modals = { + /** + * show the modal + * @param {string | HTMLElement} title title of the modal + * @param {string | HTMLElement} content content of the modal + * @param {Array} btnsTexts buttons texts + * @param {Array} btnsCbs array of callbacks for each button @default Hm_Modals.hide() + */ + show: function (title = '', content = '', btnsTexts = [], btnsCbs = []) { + const modal = ` +
+
+
+ × +
+ ${title} +
+ +
+ ${content} +
+ + +
+
+ `; + document.querySelector('body').insertAdjacentHTML('beforeend', modal); + + btnsTexts.forEach((_, index) => { + document.querySelector(`.cypht-modal-btn-${index + 1}`).addEventListener('click', btnsCbs[index] || this.hide); + }); + + document.querySelector('.cypht-modal-content-close').addEventListener('click', this.hide); + document.querySelector('.cypht-modal-bg').addEventListener('click', this.hide); + }, + + hide: () => { + document.querySelector('#cypht-modal').remove(); + } +} + /* user notification manager */ var Hm_Notices = { hide_id: false, diff --git a/modules/smtp/hm-mime-message.php b/modules/smtp/hm-mime-message.php index 0c2c8dca8a..45f7d87002 100644 --- a/modules/smtp/hm-mime-message.php +++ b/modules/smtp/hm-mime-message.php @@ -89,7 +89,9 @@ function process_attachments() { /* output mime message */ function get_mime_msg() { - $this->prep_message_body(); + if (!empty($this->body)) { + $this->prep_message_body(); + } $res = ''; $headers = ''; foreach ($this->headers as $name => $val) { diff --git a/modules/smtp/modules.php b/modules/smtp/modules.php index c40a03c541..8afbd1d5c5 100644 --- a/modules/smtp/modules.php +++ b/modules/smtp/modules.php @@ -646,12 +646,12 @@ function get_mime_type($filename) class Hm_Handler_process_compose_form_submit extends Hm_Handler_Module { public function process() { /* not sending */ - if (!array_key_exists('smtp_send', $this->request->post)) { + if (!array_key_exists("compose_smtp_id", $this->request->post)) { return; } /* missing field */ - list($success, $form) = $this->process_form(array('compose_to', 'compose_subject', 'compose_smtp_id', 'draft_id', 'post_archive', 'next_email_post')); + list($success, $form) = $this->process_form(array('compose_to', 'compose_subject', 'compose_body', 'compose_smtp_id', 'draft_id', 'post_archive', 'next_email_post')); if (!$success) { Hm_Msgs::add('ERRRequired field missing'); return; @@ -1074,7 +1074,7 @@ protected function output() { '" />
'. '
'; if ($html == 2) { diff --git a/modules/smtp/site.css b/modules/smtp/site.css index 0bd8467b0e..3fed9c81a0 100644 --- a/modules/smtp/site.css +++ b/modules/smtp/site.css @@ -44,4 +44,3 @@ .bubble_dropdown-content ul li span, .bubble_dropdown-content ul li a {display: flex; align-items: center; padding: 8px 4px;text-decoration: none;color: #333;} .bubble_dropdown-content ul li span:hover, .bubble_dropdown-content ul li a:hover { background-color: #f1f1f1;cursor: pointer;} .bubble_dropdown-content ul li img { width: 16px;height: 16px;margin-right: 8px;} - diff --git a/modules/smtp/site.js b/modules/smtp/site.js index 874f23ff15..ea1478a73b 100644 --- a/modules/smtp/site.js +++ b/modules/smtp/site.js @@ -406,20 +406,86 @@ $(function() { $('.delete_draft').on("click", function() { smtp_delete_draft($(this).data('id')); }); $('.smtp_save').on("click", function() { save_compose_state(false, true); }); $('.smtp_send_archive').on("click", function() { send_archive(false, true); }); - $('.compose_form').on('submit', function() { - var msg_uid = hm_msg_uid(); - var detail = Hm_Utils.parse_folder_path(hm_list_path(), 'imap'); - var class_name = 'imap_'+detail.server_id+'_'+msg_uid+'_'+detail.folder; - var key = 'imap_'+Hm_Utils.get_url_page_number()+'_'+hm_list_path(); - var next_message = Hm_Message_List.prev_next_links(key, class_name)[1]; - if (next_message) { - $('.compose_next_email_data').val(next_message); + $('.compose_form').on('submit', function(e) { + e.preventDefault(); + const body = $('.compose_body').val().trim(); + const subject = $('.compose_subject').val().trim(); + + let modalContentHeadline = ''; + let dontWanValueInStorage = ''; + + // If the subject is empty, we should warn the user + if (!subject) { + dontWanValueInStorage = 'dont_warn_empty_subject'; + modalContentHeadline = "

Your subject is empty

"; + } + + // If the body is empty, we should warn the user + if (!body) { + dontWanValueInStorage = 'dont_warn_empty_body'; + modalContentHeadline = "

Your body is empty!

"; + } + + // if both the subject and the body are empty, we should warn the user + if (!body && !subject) { + dontWanValueInStorage = 'dont_warn_empty_subject_body'; + modalContentHeadline = "

Your subject and body are empty!

"; + } + + // If the user has disabled the warning, we should send the message + if (Boolean(Hm_Utils.get_from_local_storage(dontWanValueInStorage))) { + return handleSendAnyway(); + } + // Otherwise, we should show the modal if we have a headline + if (modalContentHeadline) { + return showModal(); + } + + // Subject and body are not empty, we can send the message + handleSendAnyway(); + + /* + ======================================== + Functions declarations + ======================================== + */ + function showModal() { + const modalContent = modalContentHeadline + ` +

Are you sure you want to send this message?

+ `; + const modalButtons = [ + "Cancel sending", + "Send anyway", + "Send anyway and don't warn me in the future", + ]; + Hm_Modals.show('Warning', modalContent, modalButtons, [Hm_Modals.hide, handleSendAnyway, handleSendAnywayAndDontWarnMe]); + } + + function handleSendAnyway() { + e.target.submit(); + handleFiles(); + }; + + function handleSendAnywayAndDontWarnMe() { + Hm_Utils.save_to_local_storage(dontWanValueInStorage, true); + handleSendAnyway(); + }; + + function handleFiles() { + var msg_uid = hm_msg_uid(); + var detail = Hm_Utils.parse_folder_path(hm_list_path(), 'imap'); + var class_name = 'imap_' + detail.server_id + '_' + msg_uid + '_' + detail.folder; + var key = 'imap_' + Hm_Utils.get_url_page_number() + '_' + hm_list_path(); + var next_message = Hm_Message_List.prev_next_links(key, class_name)[1]; + if (next_message) { + $('.compose_next_email_data').val(next_message); + } + var uploaded_files = $("input[name='uploaded_files[]']").map(function () { return $(this).val(); }).get(); + $('#send_uploaded_files').val(uploaded_files); + Hm_Ajax.show_loading_icon(); $('.smtp_send').addClass('disabled_input'); + $('.smtp_send_archive').addClass('disabled_input'); + $('.smtp_send').on("click", function () { return false; }); } - var uploaded_files = $("input[name='uploaded_files[]']").map(function(){return $(this).val();}).get(); - $('#send_uploaded_files').val(uploaded_files); - Hm_Ajax.show_loading_icon(); $('.smtp_send').addClass('disabled_input'); - $('.smtp_send_archive').addClass('disabled_input'); - $('.smtp_send').on("click", function() { return false; }); }); if ($('.compose_cc').val() || $('.compose_bcc').val()) { toggle_recip_flds();