Skip to content

Commit

Permalink
Merge pull request #868 from jacob-js/empty-body
Browse files Browse the repository at this point in the history
[NEW] add a modal dialog to warn the user about sending an email without a body
  • Loading branch information
kroky authored Jan 30, 2024
2 parents 7ec960b + cf8788a commit 6c83e4a
Show file tree
Hide file tree
Showing 6 changed files with 232 additions and 18 deletions.
101 changes: 101 additions & 0 deletions modules/core/site.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
46 changes: 46 additions & 0 deletions modules/core/site.js
Original file line number Diff line number Diff line change
Expand Up @@ -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<string>} btnsTexts buttons texts
* @param {Array<Function>} btnsCbs array of callbacks for each button @default Hm_Modals.hide()
*/
show: function (title = '', content = '', btnsTexts = [], btnsCbs = []) {
const modal = `
<div id="cypht-modal" class="cypht-modal">
<div class="cypht-modal-bg"></div>
<div class="cypht-modal-content">
<span class="cypht-modal-content-close">&times;</span>
<div class="cypht-modal-header">
${title}
</div>
<div class="cypht-modal-body">
${content}
</div>
<div class="cypht-modal-footer">
${btnsTexts.map((text, index) => `<button class="cypht-modal-btn-${index + 1}">${text}</button>`).join('')}
</div>
</div>
</div>
`;
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,
Expand Down
4 changes: 3 additions & 1 deletion modules/smtp/hm-mime-message.php
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
6 changes: 3 additions & 3 deletions modules/smtp/modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1074,7 +1074,7 @@ protected function output() {
'" /><div id="cc_contacts"></div></div><div class="compose_container" ><div class="bubbles bubble_dropdown"></div><input autocomplete="off" value="'.$this->html_safe($bcc).
'" name="compose_bcc" class="compose_bcc" type="text" placeholder="'.$this->trans('Bcc').'" />'.
'<div id="bcc_contacts"></div></div></div><input value="'.$this->html_safe($subject).
'" required name="compose_subject" class="compose_subject" type="text" placeholder="'.
'" name="compose_subject" class="compose_subject" type="text" placeholder="'.
$this->trans('Subject').'" /><textarea id="compose_body" name="compose_body" class="compose_body">'.
$this->html_safe($body).'</textarea>';
if ($html == 2) {
Expand Down
1 change: 0 additions & 1 deletion modules/smtp/site.css
Original file line number Diff line number Diff line change
Expand Up @@ -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;}

92 changes: 79 additions & 13 deletions modules/smtp/site.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = "<p>Your subject is empty</p>";
}

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

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

// 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 + `
<p>Are you sure you want to send this message?</p>
`;
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();
Expand Down

0 comments on commit 6c83e4a

Please sign in to comment.