diff --git a/language/az.php b/language/az.php index 5e1c54a187..e3f91e1ced 100755 --- a/language/az.php +++ b/language/az.php @@ -621,6 +621,7 @@ 'You must provide a name for your script' => false, 'Empty script' => false, 'Please create a profile for saving sent messages option' => false, + 'You have %d scheduled messages that won\'t be executed if you quit' => false, 'Attachment storage unavailable, please contact your site administrator' => false, 'Your subject is empty!' => false, 'Your body is empty!' => false, diff --git a/language/de.php b/language/de.php index 7150e9c182..8bd66b1a43 100755 --- a/language/de.php +++ b/language/de.php @@ -618,6 +618,7 @@ 'You must provide a name for your script' => false, 'Empty script' => false, 'Please create a profile for saving sent messages option' => false, + 'You have %d scheduled messages that won\'t be executed if you quit' => false, 'Attachment storage unavailable, please contact your site administrator' => false, 'Your subject is empty!' => false, 'Your body is empty!' => false, diff --git a/language/en.php b/language/en.php index f630f6a2d3..7dcf4bcccd 100755 --- a/language/en.php +++ b/language/en.php @@ -636,6 +636,7 @@ 'You must provide a name for your script' => false, 'Empty script' => false, 'Please create a profile for saving sent messages option' => false, + 'You have %d scheduled messages that won\'t be executed if you quit' => false, 'Attachment storage unavailable, please contact your site administrator' => false, 'Your subject is empty!' => false, 'Your body is empty!' => false, @@ -645,7 +646,6 @@ 'Are you sure you want to send this message?' => false, 'IMAP and JMAP Servers' => false, 'Junk' => false, - 'Trash' => false, 'Pasted text has leading or trailing spaces' => false, 'No tags available yet.' => false, 'Server capabilities' => false, diff --git a/language/es.php b/language/es.php index fa551b1ea9..c253b1f363 100755 --- a/language/es.php +++ b/language/es.php @@ -618,6 +618,7 @@ 'You must provide a name for your script' => false, 'Empty script' => false, 'Please create a profile for saving sent messages option' => false, + 'You have %d scheduled messages that won\'t be executed if you quit' => false, 'Attachment storage unavailable, please contact your site administrator' => false, 'Your subject is empty!' => false, 'Your body is empty!' => false, diff --git a/language/et.php b/language/et.php index 61b7b6addb..53e6207a9f 100755 --- a/language/et.php +++ b/language/et.php @@ -626,6 +626,7 @@ 'You must provide a name for your script' => false, 'Empty script' => false, 'Please create a profile for saving sent messages option' => false, + 'You have %d scheduled messages that won\'t be executed if you quit' => false, 'Attachment storage unavailable, please contact your site administrator' => false, 'Your subject is empty!' => false, 'Your body is empty!' => false, diff --git a/language/fa.php b/language/fa.php index b2ad0e2221..7a7b5ee481 100755 --- a/language/fa.php +++ b/language/fa.php @@ -670,6 +670,7 @@ 'You must provide a name for your script' => false, 'Empty script' => false, 'Please create a profile for saving sent messages option' => false, + 'You have %d scheduled messages that won\'t be executed if you quit' => false, 'Attachment storage unavailable, please contact your site administrator' => false, 'Your subject is empty!' => false, 'Your body is empty!' => false, @@ -679,7 +680,6 @@ 'Are you sure you want to send this message?' => false, 'IMAP and JMAP Servers' => false, 'Junk' => false, - 'Trash' => false, 'Pasted text has leading or trailing spaces' => false, 'No tags available yet.' => false, 'Server capabilities' => false, diff --git a/language/fr.php b/language/fr.php index b60c7c3592..eb7a176afe 100755 --- a/language/fr.php +++ b/language/fr.php @@ -617,6 +617,7 @@ 'You must provide a name for your script' => false, 'Empty script' => false, 'Please create a profile for saving sent messages option' => false, + 'You have %d scheduled messages that won\'t be executed if you quit' => false, 'Attachment storage unavailable, please contact your site administrator' => false, 'Your subject is empty!' => false, 'Your body is empty!' => false, diff --git a/language/hu.php b/language/hu.php index e91cd6a66d..7e9b587059 100755 --- a/language/hu.php +++ b/language/hu.php @@ -618,6 +618,7 @@ 'You must provide a name for your script' => false, 'Empty script' => false, 'Please create a profile for saving sent messages option' => false, + 'You have %d scheduled messages that won\'t be executed if you quit' => false, 'Attachment storage unavailable, please contact your site administrator' => false, 'Your subject is empty!' => false, 'Your body is empty!' => false, diff --git a/language/id.php b/language/id.php index 07b205ab8b..95c4ac6a5f 100755 --- a/language/id.php +++ b/language/id.php @@ -625,6 +625,7 @@ 'You must provide a name for your script' => false, 'Empty script' => false, 'Please create a profile for saving sent messages option' => false, + 'You have %d scheduled messages that won\'t be executed if you quit' => false, 'Attachment storage unavailable, please contact your site administrator' => false, 'Your subject is empty!' => false, 'Your body is empty!' => false, diff --git a/language/it.php b/language/it.php index 5147b4e8ad..d720e4214a 100755 --- a/language/it.php +++ b/language/it.php @@ -618,6 +618,7 @@ 'You must provide a name for your script' => false, 'Empty script' => false, 'Please create a profile for saving sent messages option' => false, + 'You have %d scheduled messages that won\'t be executed if you quit' => false, 'Attachment storage unavailable, please contact your site administrator' => false, 'Your subject is empty!' => false, 'Your body is empty!' => false, diff --git a/language/ja.php b/language/ja.php index 30596c066d..7c7d601ac5 100755 --- a/language/ja.php +++ b/language/ja.php @@ -618,6 +618,7 @@ 'You must provide a name for your script' => false, 'Empty script' => false, 'Please create a profile for saving sent messages option' => false, + 'You have %d scheduled messages that won\'t be executed if you quit' => false, 'Attachment storage unavailable, please contact your site administrator' => false, 'Your subject is empty!' => false, 'Your body is empty!' => false, diff --git a/language/nl.php b/language/nl.php index 1d1db295cc..82e94158d6 100755 --- a/language/nl.php +++ b/language/nl.php @@ -618,6 +618,7 @@ 'You must provide a name for your script' => false, 'Empty script' => false, 'Please create a profile for saving sent messages option' => false, + 'You have %d scheduled messages that won\'t be executed if you quit' => false, 'Attachment storage unavailable, please contact your site administrator' => false, 'Your subject is empty!' => false, 'Your body is empty!' => false, diff --git a/language/pt-BR.php b/language/pt-BR.php index 1fcf9142ec..7ad23625b8 100755 --- a/language/pt-BR.php +++ b/language/pt-BR.php @@ -617,6 +617,7 @@ 'You must provide a name for your script' => false, 'Empty script' => false, 'Please create a profile for saving sent messages option' => false, + 'You have %d scheduled messages that won\'t be executed if you quit' => false, 'Attachment storage unavailable, please contact your site administrator' => false, 'Your subject is empty!' => false, 'Your body is empty!' => false, diff --git a/language/ro.php b/language/ro.php index 5a52506d25..c019b88263 100755 --- a/language/ro.php +++ b/language/ro.php @@ -617,6 +617,7 @@ 'You must provide a name for your script' => false, 'Empty script' => false, 'Please create a profile for saving sent messages option' => false, + 'You have %d scheduled messages that won\'t be executed if you quit' => false, 'Attachment storage unavailable, please contact your site administrator' => false, 'Your subject is empty!' => false, 'Your body is empty!' => false, diff --git a/language/ru.php b/language/ru.php index 60813edac2..70cd16aa1c 100755 --- a/language/ru.php +++ b/language/ru.php @@ -619,6 +619,7 @@ 'You must provide a name for your script' => false, 'Empty script' => false, 'Please create a profile for saving sent messages option' => false, + 'You have %d scheduled messages that won\'t be executed if you quit' => false, 'Attachment storage unavailable, please contact your site administrator' => false, 'Your subject is empty!' => false, 'Your body is empty!' => false, diff --git a/language/zh-Hans.php b/language/zh-Hans.php index 8baf2310ff..526e932c4a 100644 --- a/language/zh-Hans.php +++ b/language/zh-Hans.php @@ -639,6 +639,7 @@ 'You must provide a name for your script' => '请提供脚本名称', 'Empty script' => '空脚本', 'Please create a profile for saving sent messages option' => '请创建用于保存已发送信息选项的配置文件', + 'You have %d scheduled messages that won\'t be executed if you quit' => false, 'Attachment storage unavailable, please contact your site administrator' => '附件存储不可用,请联系您的网站管理员', 'Your subject is empty!' => '主题为空!', 'Your body is empty!' => '内容为空!', diff --git a/modules/core/functions.php b/modules/core/functions.php index 39b06fd0eb..03deb0b2e3 100644 --- a/modules/core/functions.php +++ b/modules/core/functions.php @@ -623,3 +623,99 @@ function check_file_upload($request, $key) { } return true; }} + +if (!hm_exists('get_nexter_date')) { +function get_nexter_date($format, $only_label = false) { + if ($format == 'later_in_day') { + $date_string = 'today 18:00'; + $label = 'Later in the day'; + } elseif ($format == 'tomorrow') { + $date_string = '+1 day 08:00'; + $label = 'Tomorrow'; + } elseif ($format == 'next_weekend') { + $date_string = 'next Saturday 08:00'; + $label = 'Next weekend'; + } elseif ($format == 'next_week') { + $date_string = 'next week 08:00'; + $label = 'Next week'; + } elseif ($format == 'next_month') { + $date_string = 'next month 08:00'; + $label = 'Next month'; + } else { + $date_string = $format; + $label = 'Certain date'; + } + $time = strtotime($date_string); + if ($only_label) { + return [$label, date('D, H:i', $time)]; + } + return date('D, d M Y H:i', $time); +}} + +/** + * @subpackage imap/functions + */ +if (!hm_exists('nexter_formats')) { +function nexter_formats() { + $values = array( + 'tomorrow', + 'next_weekend', + 'next_week', + 'next_month' + ); + if (date('H') <= 16) { + array_push($values, 'later_in_day'); + } + return $values; +}} + +if (!hm_exists('schedule_dropdown')) { +function schedule_dropdown($output, $send_now = false) { + $values = nexter_formats(); + + $txt = ''; + if ($send_now) { + $txt .= ''; + } + + return $txt; +}} + +/** + * @subpackage imap/functions + */ +if (!hm_exists('parse_nexter_header')) { + function parse_nexter_header($header, $name) + { + $header = str_replace("$name: ", '', $header); + $result = []; + foreach (explode(';', $header) as $kv) + { + $kv = trim($kv); + $spacePos = strpos($kv, ' '); + if ($spacePos > 0) { + $result[rtrim(substr($kv, 0, $spacePos), ':')] = trim(substr($kv, $spacePos+1)); + } else { + $result[$kv] = true; + } + } + return $result; + }} diff --git a/modules/core/message_list_functions.php b/modules/core/message_list_functions.php index eac7e95a2f..368aa70098 100644 --- a/modules/core/message_list_functions.php +++ b/modules/core/message_list_functions.php @@ -316,11 +316,11 @@ function subject_callback($vals, $style, $output_mod) { */ if (!hm_exists('date_callback')) { function date_callback($vals, $style, $output_mod) { - $snooze_class = isset($vals[2]) && $vals[2]? ' snoozed_date': ''; + $nexter_class = isset($vals[2]) && $vals[2]? ' nexter_date': ''; if ($style == 'news') { - return sprintf('
%s
', $snooze_class, $output_mod->html_safe($vals[0]), $output_mod->html_safe($vals[1])); + return sprintf('
%s
', $nexter_class, $output_mod->html_safe($vals[0]), $output_mod->html_safe($vals[1])); } - return sprintf('%s', $snooze_class, $output_mod->html_safe(date('r', $vals[1])), $output_mod->html_safe($vals[0]), $output_mod->html_safe($vals[1])); + return sprintf('%s', $nexter_class, $output_mod->html_safe(date('r', $vals[1])), $output_mod->html_safe($vals[0]), $output_mod->html_safe($vals[1])); }} /** diff --git a/modules/core/site.css b/modules/core/site.css index 6b667ee132..dcfd9d7512 100644 --- a/modules/core/site.css +++ b/modules/core/site.css @@ -1268,7 +1268,7 @@ div.unseen, .mobile .imap_sort { width: 100%; } -.snoozed_date { +.nexter_date { color: var(--bs-primary) !important; } diff --git a/modules/core/site.js b/modules/core/site.js index eeab1d2fea..5081180fcf 100644 --- a/modules/core/site.js +++ b/modules/core/site.js @@ -1961,10 +1961,23 @@ var imap_smtp_edit_action = function(event) { } }; + var hasLeadingOrTrailingSpaces = function(str) { return str !== str.trim(); }; +var sprintf = function(format, ...args) { + let i = 0; + return format.replace(/%([sd])/g, (match, type) => { + let arg = args[i++]; + switch (type) { + case 's': return String(arg); + case 'd': return Number(arg); + default: return match; + } + }); +} + /* create a default message list object */ var Hm_Message_List = new Message_List(); @@ -1998,7 +2011,7 @@ $(function() { /* fire up the job scheduler */ Hm_Timer.fire(); - + /* show any pending notices */ Hm_Utils.show_sys_messages(); @@ -2215,7 +2228,7 @@ function handleSmtpImapCheckboxChange(checkbox) { if ($('#srv_setup_stepper_is_sender').prop('checked') && $('#srv_setup_stepper_is_receiver').prop('checked')) { $('#srv_setup_stepper_profile_bloc').show(); $('#srv_setup_stepper_profile_checkbox_bloc').show(); - + } else if(! $('#srv_setup_stepper_is_sender').prop('checked') || ! $('#srv_setup_stepper_is_receiver').prop('checked')) { $('#srv_setup_stepper_profile_bloc').hide(); $('#srv_setup_stepper_profile_checkbox_bloc').hide(); @@ -2267,7 +2280,7 @@ function display_config_step(stepNumber) { $(`#${item.key}-error`).text('Required'); isValid = false; } - + } else { $(`#${item.key}-error`).text(''); } @@ -2553,7 +2566,7 @@ const observeMessageTextMutationAndHandleExternalResources = (inline) => { if (mutation.addedNodes.length > 0) { mutation.addedNodes.forEach(function (node) { if (node.classList.contains('msg_text_inner')) { - handleExternalResources(inline); + handleExternalResources(inline); } }); } @@ -2563,3 +2576,29 @@ const observeMessageTextMutationAndHandleExternalResources = (inline) => { }); } }; + +var setup_nexter_date = function(callback) { + $(document).on('click', '.nexter_date_picker', function(e) { + document.querySelector('.nexter_input_date').showPicker(); + }); + $(document).on('click', '.nexter_date_helper', function(e) { + e.preventDefault(); + $('.nexter_input').val($(this).attr('data-value')).trigger('change'); + }); + $(document).on('input', '.nexter_input_date', function(e) { + var now = new Date(); + now.setMinutes(now.getMinutes() + 1); + $(this).attr('min', now.toJSON().slice(0, 16)); + if (new Date($(this).val()).getTime() <= now.getTime()) { + $('.nexter_date_picker').css('border', '1px solid red'); + } else { + $('.nexter_date_picker').css({'border': 'unset', 'border-top': '1px solid #ddd'}); + } + }); + $(document).on('change', '.nexter_input_date', function(e) { + if ($(this).val() && new Date().getTime() < new Date($(this).val()).getTime()) { + $('.nexter_input').val($(this).val()).trigger('change'); + } + }); + $(document).on('change', '.nexter_input', callback); +} diff --git a/modules/imap/functions.php b/modules/imap/functions.php index 13bef44782..7c14227f82 100644 --- a/modules/imap/functions.php +++ b/modules/imap/functions.php @@ -237,10 +237,14 @@ function format_imap_message_list($msg_list, $output_module, $parent_list=false, $nofrom = ' nofrom'; } $is_snoozed = !empty($msg['x_snoozed']) && hex2bin($msg['folder']) == 'Snoozed'; + $is_scheduled = !empty($msg['x_schedule']) && hex2bin($msg['folder']) == 'Scheduled'; if ($is_snoozed) { - $snooze_header = parse_snooze_header('X-Snoozed: '.$msg['x_snoozed']); + $snooze_header = parse_nexter_header('X-Snoozed: '.$msg['x_snoozed'], 'X-Snoozed'); $date = $snooze_header['until']; $timestamp = strtotime($date); + } elseif ($is_scheduled) { + $date = $msg['x_schedule']; + $timestamp = strtotime($date); } else { if ($list_sort == 'date') { $date_field = 'date'; @@ -315,7 +319,7 @@ function format_imap_message_list($msg_list, $output_module, $parent_list=false, array('safe_output_callback', 'source', $source, $icon), array('safe_output_callback', 'from'.$nofrom, $from, null, str_replace(array($from, '<', '>'), '', $msg['from'])), array('subject_callback', $subject, $url, $flags), - array('date_callback', $date, $timestamp, $is_snoozed), + array('date_callback', $date, $timestamp, $is_snoozed || $is_scheduled), array('icon_callback', $flags) ), $id, @@ -1300,7 +1304,7 @@ function snooze_message($imap, $msg_id, $folder, $snooze_tag) { preg_match("/^X-Snoozed:.*(\r?\n[ \t]+.*)*\r?\n?/im", $msg, $matches); if (count($matches)) { $msg = str_replace($matches[0], '', $msg); - $old_folder = parse_snooze_header($matches[0])['from']; + $old_folder = parse_nexter_header($matches[0], 'X-Snoozed')['from']; } if ($snooze_tag) { $from = $old_folder ?? $folder; @@ -1326,7 +1330,7 @@ function snooze_message($imap, $msg_id, $folder, $snooze_tag) { } } } else { - $snooze_headers = parse_snooze_header($matches[0]); + $snooze_headers = parse_nexter_header($matches[0], 'X-Snoozed'); $original_folder = $snooze_headers['from']; if ($imap->select_mailbox($original_folder) && $imap->append_start($original_folder, mb_strlen($msg))) { $imap->append_feed($msg."\r\n"); @@ -1453,21 +1457,21 @@ function snooze_formats() { */ if (!hm_exists('snooze_dropdown')) { function snooze_dropdown($output, $unsnooze = false) { - $values = snooze_formats(); + $values = nexter_formats(); $txt = ''; @@ -1600,3 +1604,42 @@ function connect_to_imap_server($address, $name, $port, $user, $pass, $tls, $ima } } } + +if (!hm_exists('save_sent_msg')) { +function save_sent_msg($handler, $imap_id, $imap, $imap_details, $msg, $msg_id, $show_errors = true) { + $specials = get_special_folders($handler, $imap_id); + if (array_key_exists('sent', $specials) && $specials['sent']) { + $sent_folder = $specials['sent']; + } + + if (!$sent_folder) { + $auto_sent = $imap->get_special_use_mailboxes('sent'); + if (!array_key_exists('sent', $auto_sent)) { + return; + } + $sent_folder = $auto_sent['sent']; + } + if (!$sent_folder) { + Hm_Debug::add(sprintf("Unable to save sent message, no sent folder for IMAP %s", $imap_details['server'])); + } + $uid = null; + if ($sent_folder) { + Hm_Debug::add(sprintf("Attempting to save sent message for IMAP server %s in folder %s", $imap_details['server'], $sent_folder)); + if ($imap->append_start($sent_folder, strlen($msg), true)) { + $imap->append_feed($msg."\r\n"); + if (!$imap->append_end() && $show_errors) { + Hm_Msgs::add('ERRAn error occurred saving the sent message'); + } + } + + $mailbox_page = $imap->get_mailbox_page($sent_folder, 'ARRIVAL', true, 'ALL', 0, 10); + foreach ($mailbox_page[1] as $mail) { + $msg_header = $imap->get_message_headers($mail['uid']); + if ($msg_header['Message-Id'] === $msg_id) { + $uid = $mail['uid']; + break; + } + } + } + return $uid; +}} diff --git a/modules/imap/handler_modules.php b/modules/imap/handler_modules.php index 4525307f67..d495fe0667 100644 --- a/modules/imap/handler_modules.php +++ b/modules/imap/handler_modules.php @@ -367,6 +367,9 @@ public function process() { break; } } + } + $uid = save_sent_msg($this, $imap_id, $imap, $imap_details, $msg, $mime->get_headers()['Message-Id']); + if ($uid) { if ($uid && $this->user_config->get('review_sent_email_setting', false)) { $this->out('redirect_url', '?page=message&uid='.$uid.'&list_path=imap_'.$imap_id.'_'.bin2hex($sent_folder)); } @@ -1063,7 +1066,7 @@ public function process() { $snooze_tag = null; if ($form['imap_snooze_until'] != 'unsnooze') { $at = date('D, d M Y H:i:s O'); - $until = get_snooze_date($form['imap_snooze_until']); + $until = get_nexter_date($form['imap_snooze_until']); $snooze_tag = "X-Snoozed: at $at; until $until"; } $ids = explode(',', $form['imap_snooze_ids']); @@ -1153,7 +1156,7 @@ public function process() { $msg_headers = $imap->get_message_headers($msg['uid']); if (isset($msg_headers['X-Snoozed'])) { try { - $snooze_headers = parse_snooze_header($msg_headers['X-Snoozed']); + $snooze_headers = parse_nexter_header($msg_headers['X-Snoozed'], 'X-Snoozed'); if (new DateTime($snooze_headers['until']) <= new DateTime()) { snooze_message($imap, $msg['uid'], $folder, null); } diff --git a/modules/imap/hm-imap.php b/modules/imap/hm-imap.php index a15444893a..46e36b124d 100644 --- a/modules/imap/hm-imap.php +++ b/modules/imap/hm-imap.php @@ -890,7 +890,7 @@ public function get_message_list($uids, $raw=false) { if ($this->is_supported( 'X-GM-EXT-1' )) { $command .= 'X-GM-MSGID X-GM-THRID X-GM-LABELS '; } - $command .= "BODY.PEEK[HEADER.FIELDS (SUBJECT X-AUTO-BCC FROM DATE CONTENT-TYPE X-PRIORITY TO LIST-ARCHIVE REFERENCES MESSAGE-ID X-SNOOZED)])\r\n"; + $command .= "BODY.PEEK[HEADER.FIELDS (SUBJECT X-AUTO-BCC FROM DATE CONTENT-TYPE X-PRIORITY TO LIST-ARCHIVE REFERENCES MESSAGE-ID X-SNOOZED X-SCHEDULE X-PROFILE-ID X-DELIVERY)])\r\n"; $cache_command = $command.(string)$raw; $cache = $this->check_cache($cache_command); if ($cache !== false) { @@ -900,8 +900,8 @@ public function get_message_list($uids, $raw=false) { $res = $this->get_response(false, true); $status = $this->check_response($res, true); $tags = array('X-GM-MSGID' => 'google_msg_id', 'X-GM-THRID' => 'google_thread_id', 'X-GM-LABELS' => 'google_labels', 'UID' => 'uid', 'FLAGS' => 'flags', 'RFC822.SIZE' => 'size', 'INTERNALDATE' => 'internal_date'); - $junk = array('X-AUTO-BCC', 'MESSAGE-ID', 'REFERENCES', 'X-SNOOZED', 'LIST-ARCHIVE', 'SUBJECT', 'FROM', 'CONTENT-TYPE', 'TO', '(', ')', ']', 'X-PRIORITY', 'DATE'); - $flds = array('x-auto-bcc' => 'x_auto_bcc', 'message-id' => 'message_id', 'references' => 'references', 'x-snoozed' => 'x_snoozed', 'list-archive' => 'list_archive', 'date' => 'date', 'from' => 'from', 'to' => 'to', 'subject' => 'subject', 'content-type' => 'content_type', 'x-priority' => 'x_priority'); + $junk = array('X-AUTO-BCC', 'MESSAGE-ID', 'REFERENCES', 'X-SNOOZED', 'X-SCHEDULE', 'X-PROFILE-ID', 'X-DELIVERY', 'LIST-ARCHIVE', 'SUBJECT', 'FROM', 'CONTENT-TYPE', 'TO', '(', ')', ']', 'X-PRIORITY', 'DATE'); + $flds = array('x-auto-bcc' => 'x_auto_bcc', 'message-id' => 'message_id', 'references' => 'references', 'x-snoozed' => 'x_snoozed', 'x-schedule' => 'x_schedule', 'x-profile-id' => 'x_profile_id', 'x-delivery' => 'x_delivery', 'list-archive' => 'list_archive', 'date' => 'date', 'from' => 'from', 'to' => 'to', 'subject' => 'subject', 'content-type' => 'content_type', 'x-priority' => 'x_priority'); $headers = array(); foreach ($res as $n => $vals) { if (isset($vals[0]) && $vals[0] == '*') { @@ -923,6 +923,9 @@ public function get_message_list($uids, $raw=false) { $google_labels = ''; $x_auto_bcc = ''; $x_snoozed = ''; + $x_schedule = ''; + $x_profile_id = ''; + $x_delivery = ''; $count = count($vals); for ($i=0;$i<$count;$i++) { if ($vals[$i] == 'BODY[HEADER.FIELDS') { @@ -972,7 +975,7 @@ public function get_message_list($uids, $raw=false) { 'timestamp' => time(), 'charset' => $cset, 'x-priority' => $x_priority, 'google_msg_id' => $google_msg_id, 'google_thread_id' => $google_thread_id, 'google_labels' => $google_labels, 'list_archive' => $list_archive, 'references' => $references, 'message_id' => $message_id, 'x_auto_bcc' => $x_auto_bcc, - 'x_snoozed' => $x_snoozed); + 'x_snoozed' => $x_snoozed, 'x_schedule' => $x_schedule, 'x_profile_id' => $x_profile_id, 'x_delivery' => $x_delivery); if ($raw) { $headers[$uid] = array_map('trim', $headers[$uid]); diff --git a/modules/imap/output_modules.php b/modules/imap/output_modules.php index a3d4f04e8e..e045f45cf0 100644 --- a/modules/imap/output_modules.php +++ b/modules/imap/output_modules.php @@ -202,9 +202,9 @@ protected function output() { $txt .= $this->html_safe($value).''; } elseif ($fld == 'x-snoozed') { - $snooze_header = parse_snooze_header($value); + $snooze_header = parse_nexter_header($value, 'X-Snoozed'); $txt .= ''; - $txt .= $this->trans('Snoozed').''.$this->trans('Until').' '.$this->html_safe($snooze_header['until']).' Unsnooze'; + $txt .= $this->trans('Snoozed').''.$this->trans('Until').' '.$this->html_safe($snooze_header['until']).' Unsnooze'; } elseif ($fld == 'date') { try { @@ -388,6 +388,9 @@ protected function output() { if($this->get('tags')){ $txt .= ' | '. tags_dropdown($this, $headers); } + if (isset($headers['X-Schedule'])) { + $txt .= ' | ' . schedule_dropdown($this, true); + } $is_draft = isset($headers['Flags']) && mb_stristr($headers['Flags'], 'draft'); if ($this->get('sieve_filters_enabled') && !$is_draft) { diff --git a/modules/imap/site.css b/modules/imap/site.css index 7dad732212..c381b92358 100644 --- a/modules/imap/site.css +++ b/modules/imap/site.css @@ -126,7 +126,7 @@ .header_links { padding-top: 10px !important; } -.header_links #dropdownMenuSnooze { +.header_links #dropdownMenuNexterDate { padding: 0; border: unset; font-variant: inherit; @@ -134,7 +134,7 @@ font-size: inherit; vertical-align: baseline; } -.header_links #dropdownMenuSnooze:hover { +.header_links #dropdownMenuNexterDate:hover { background-color: inherit; color: inherit; } diff --git a/modules/imap/site.js b/modules/imap/site.js index 5d0ce57b28..532360ec8a 100644 --- a/modules/imap/site.js +++ b/modules/imap/site.js @@ -1,6 +1,6 @@ 'use strict'; -var imap_delete_action = function(event) { +var imap_delete_action = function (event) { if (!hm_delete_prompt()) { return false; } @@ -9,25 +9,25 @@ var imap_delete_action = function(event) { var form = $(this).closest('.imap_connect'); Hm_Ajax.request( form.serializeArray(), - function(res) { + function (res) { if (res.deleted_server_id) { - const section = form.parent().hasClass('imap_server') ? 'imap': 'jmap'; + const section = form.parent().hasClass('imap_server') ? 'imap' : 'jmap'; decrease_servers(section); Hm_Utils.set_unsaved_changes(1); Hm_Folders.reload_folders(true); form.parent().fadeOutAndRemove() } }, - {'imap_delete': 1} + { 'imap_delete': 1 } ); }; -var imap_hide_action = function(form, server_id, hide) { +var imap_hide_action = function (form, server_id, hide) { Hm_Ajax.request( - [{'name': 'hm_ajax_hook', 'value': 'ajax_imap_debug'}, - {'name': 'imap_server_id', 'value': server_id}, - {'name': 'hide_imap_server', 'value': hide}], - function() { + [{ 'name': 'hm_ajax_hook', 'value': 'ajax_imap_debug' }, + { 'name': 'imap_server_id', 'value': server_id }, + { 'name': 'hide_imap_server', 'value': hide }], + function () { if (hide) { $('.unhide_imap_connection', form).show(); $('.hide_imap_connection', form).hide(); @@ -41,7 +41,7 @@ var imap_hide_action = function(form, server_id, hide) { ); }; -var imap_hide = function(event) { +var imap_hide = function (event) { event.preventDefault(); Hm_Notices.hide(true); var form = $(this).closest('.imap_connect'); @@ -49,7 +49,7 @@ var imap_hide = function(event) { imap_hide_action(form, server_id, 1); }; -var imap_unhide = function(event) { +var imap_unhide = function (event) { event.preventDefault(); Hm_Notices.hide(true); var form = $(this).closest('.imap_connect'); @@ -57,14 +57,14 @@ var imap_unhide = function(event) { imap_hide_action(form, server_id, 0); }; -var imap_forget_action = function(event) { +var imap_forget_action = function (event) { event.preventDefault(); Hm_Notices.hide(true); var form = $(this).closest('.imap_connect'); var btnContainer = $(this).parent(); Hm_Ajax.request( form.serializeArray(), - function(res) { + function (res) { if (res.just_forgot_credentials) { form.find('.credentials').prop('disabled', false); form.find('.credentials').val(''); @@ -75,18 +75,18 @@ var imap_forget_action = function(event) { Hm_Folders.reload_folders(true); } }, - {'imap_forget': 1} + { 'imap_forget': 1 } ); }; -var imap_save_action = function(event) { +var imap_save_action = function (event) { event.preventDefault(); Hm_Notices.hide(true); var form = $(this).closest('.imap_connect'); var btnContainer = $(this).parent(); Hm_Ajax.request( form.serializeArray(), - function(res) { + function (res) { if (res.just_saved_credentials) { form.find('.credentials').attr('disabled', true); form.find('.save_imap_connection').hide(); @@ -98,11 +98,11 @@ var imap_save_action = function(event) { Hm_Folders.reload_folders(true); } }, - {'imap_save': 1} + { 'imap_save': 1 } ); }; -var imap_test_action = function(event) { +var imap_test_action = function (event) { $('.imap_folder_data').empty(); event.preventDefault(); Hm_Notices.hide(true); @@ -110,11 +110,11 @@ var imap_test_action = function(event) { Hm_Ajax.request( form.serializeArray(), false, - {'imap_connect': 1} + { 'imap_connect': 1 } ); } -var imapServersPageHandler = function() { +var imapServersPageHandler = function () { $('.imap_delete').on('click', imap_delete_action); $('.save_imap_connection').on('click', imap_save_action); $('.hide_imap_connection').on('click', imap_hide); @@ -132,18 +132,18 @@ var imapServersPageHandler = function() { } }; -var set_message_content = function(path, msg_uid) { +var set_message_content = function (path, msg_uid) { if (!path) { path = getListPathParam(); } if (!msg_uid) { msg_uid = getMessageUidParam(); } - var key = msg_uid+'_'+path; + var key = msg_uid + '_' + path; Hm_Utils.save_to_local_storage(key, $('.msg_text').html()); }; -var imap_delete_message = function(state, supplied_uid, supplied_detail) { +var imap_delete_message = function (state, supplied_uid, supplied_detail) { if (!hm_delete_prompt()) { return false; } @@ -157,16 +157,16 @@ var imap_delete_message = function(state, supplied_uid, supplied_detail) { } if (detail && uid) { Hm_Ajax.request( - [{'name': 'hm_ajax_hook', 'value': 'ajax_imap_delete_message'}, - {'name': 'imap_msg_uid', 'value': uid}, - {'name': 'imap_server_id', 'value': detail.server_id}, - {'name': 'folder', 'value': detail.folder}], - function(res) { + [{ 'name': 'hm_ajax_hook', 'value': 'ajax_imap_delete_message' }, + { 'name': 'imap_msg_uid', 'value': uid }, + { 'name': 'imap_server_id', 'value': detail.server_id }, + { 'name': 'folder', 'value': detail.folder }], + function (res) { if (!res.imap_delete_error) { if (Hm_Utils.get_from_global('msg_uid', false)) { return; } - var msg_cache_key = 'imap_'+detail.server_id+'_'+getMessageUidParam()+'_'+detail.folder; + var msg_cache_key = 'imap_' + detail.server_id + '_' + getMessageUidParam() + '_' + detail.folder; remove_from_cached_imap_pages(msg_cache_key); var nlink = $('.nlink'); if (nlink.length && Hm_Utils.get_from_global('auto_advance_email_enabled')) { @@ -174,10 +174,10 @@ var imap_delete_message = function(state, supplied_uid, supplied_detail) { } else { if (!hm_list_parent()) { - Hm_Utils.redirect("?page=message_list&list_path="+getListPathParam()); + Hm_Utils.redirect("?page=message_list&list_path=" + getListPathParam()); } else { - Hm_Utils.redirect("?page=message_list&list_path="+hm_list_parent()); + Hm_Utils.redirect("?page=message_list&list_path=" + hm_list_parent()); } } } @@ -187,7 +187,7 @@ var imap_delete_message = function(state, supplied_uid, supplied_detail) { return false; }; -var imap_unread_message = function(supplied_uid, supplied_detail) { +var imap_unread_message = function (supplied_uid, supplied_detail) { var uid = getMessageUidParam(); var detail = Hm_Utils.parse_folder_path(getListPathParam(), 'imap'); if (supplied_uid) { @@ -197,31 +197,31 @@ var imap_unread_message = function(supplied_uid, supplied_detail) { detail = supplied_detail; } if (detail && uid) { - var selected = detail.type+'_'+detail.server_id+'_'+uid+'_'+detail.folder; + var selected = detail.type + '_' + detail.server_id + '_' + uid + '_' + detail.folder; Hm_Ajax.request( - [{'name': 'hm_ajax_hook', 'value': 'ajax_message_action'}, - {'name': 'action_type', 'value': 'unread'}, - {'name': 'message_ids', 'value': selected}], - function(res) { - if (Hm_Utils.get_from_global('uid', false)) { - return; - } - var nlink = $('.nlink'); - if (nlink.length && Hm_Utils.get_from_global('auto_advance_email_enabled')) { - Hm_Utils.redirect(nlink.attr('href')); + [{ 'name': 'hm_ajax_hook', 'value': 'ajax_message_action' }, + { 'name': 'action_type', 'value': 'unread' }, + { 'name': 'message_ids', 'value': selected }], + function (res) { + if (Hm_Utils.get_from_global('uid', false)) { + return; + } + var nlink = $('.nlink'); + if (nlink.length && Hm_Utils.get_from_global('auto_advance_email_enabled')) { + Hm_Utils.redirect(nlink.attr('href')); + } + else { + if (!hm_list_parent()) { + Hm_Utils.redirect("?page=message_list&list_path=" + getListPathParam()); } else { - if (!hm_list_parent()) { - Hm_Utils.redirect("?page=message_list&list_path="+getListPathParam()); - } - else { - Hm_Utils.redirect("?page=message_list&list_path="+hm_list_parent()); - } + Hm_Utils.redirect("?page=message_list&list_path=" + hm_list_parent()); } + } }, [], false, - function() { + function () { var cache = $('').append($(Hm_Utils.get_from_local_storage('formatted_unread_data'))); Hm_Message_List.adjust_unread_total($('tr', cache).length, true); } @@ -230,7 +230,7 @@ var imap_unread_message = function(supplied_uid, supplied_detail) { return false; } -var imap_flag_message = function(state, supplied_uid, supplied_detail) { +var imap_flag_message = function (state, supplied_uid, supplied_detail) { var uid = getMessageUidParam(); var detail = Hm_Utils.parse_folder_path(getListPathParam(), 'imap'); if (supplied_uid) { @@ -241,12 +241,12 @@ var imap_flag_message = function(state, supplied_uid, supplied_detail) { } if (detail && uid) { Hm_Ajax.request( - [{'name': 'hm_ajax_hook', 'value': 'ajax_imap_flag_message'}, - {'name': 'imap_msg_uid', 'value': uid}, - {'name': 'imap_flag_state', 'value': state}, - {'name': 'imap_server_id', 'value': detail.server_id}, - {'name': 'folder', 'value': detail.folder}], - function() { + [{ 'name': 'hm_ajax_hook', 'value': 'ajax_imap_flag_message' }, + { 'name': 'imap_msg_uid', 'value': uid }, + { 'name': 'imap_flag_state', 'value': state }, + { 'name': 'imap_server_id', 'value': detail.server_id }, + { 'name': 'folder', 'value': detail.folder }], + function () { if (state === 'flagged') { $('#flag_msg').show(); $('#unflag_msg').hide(); @@ -263,23 +263,23 @@ var imap_flag_message = function(state, supplied_uid, supplied_detail) { return false; }; -var imap_status_update = function() { +var imap_status_update = function () { var id; var i; if ($('.imap_server_ids').length) { var ids = $('.imap_server_ids').val().split(','); - if ( ids && ids !== '') { - var process_result = function(res) { + if (ids && ids !== '') { + var process_result = function (res) { var id = res.imap_status_server_id; - $('.imap_status_'+id).html(res.imap_status_display); - $('.imap_detail_'+id).html(res.sieve_detail_display); - $('.imap_capabilities_'+id).html(res.imap_extensions_display); + $('.imap_status_' + id).html(res.imap_status_display); + $('.imap_detail_' + id).html(res.sieve_detail_display); + $('.imap_capabilities_' + id).html(res.imap_extensions_display); }; - for (i=0;iimap '+folder+''); - var count = $('.src_count').text()*1; +var add_auto_folder = function (folder) { + $('.list_sources').append('
imap ' + folder + '
'); + var count = $('.src_count').text() * 1; count++; $('.src_count').html(count); }; -var cache_folder_data = function() { - if (['sent', 'drafts', 'junk', 'trash','tag'].includes(getListPathParam())) { - Hm_Message_List.set_message_list_state('formatted_'+getListPathParam()+'_data'); +var cache_folder_data = function () { + if (['sent', 'drafts', 'junk', 'trash', 'tag'].includes(getListPathParam())) { + Hm_Message_List.set_message_list_state('formatted_' + getListPathParam() + '_data'); } }; -var imap_all_mail_content = function(id, folder) { +var imap_all_mail_content = function (id, folder) { return imap_message_list_content(id, folder, 'ajax_imap_combined_inbox', Hm_Message_List.set_all_mail_state); }; -var imap_search_page_content = function(id, folder) { +var imap_search_page_content = function (id, folder) { if (hm_search_terms()) { return imap_message_list_content(id, folder, 'ajax_imap_search', Hm_Message_List.set_search_state); } return false; }; -var update_imap_combined_source = function(path, state, event) { +var update_imap_combined_source = function (path, state, event) { clear_imap_page_combined_inbox(); event.preventDefault(); Hm_Ajax.request( - [{'name': 'hm_ajax_hook', 'value': 'ajax_imap_update_combined_source'}, - {'name': 'list_path', 'value': path}, - {'name': 'combined_source_state', 'value': state}], - function() { + [{ 'name': 'hm_ajax_hook', 'value': 'ajax_imap_update_combined_source' }, + { 'name': 'list_path', 'value': path }, + { 'name': 'combined_source_state', 'value': state }], + function () { if (state === 1) { $('.add_source').hide(); $('.remove_source').show(); @@ -364,85 +364,85 @@ var update_imap_combined_source = function(path, state, event) { return false; }; -var remove_imap_combined_source = function(event) { +var remove_imap_combined_source = function (event) { return update_imap_combined_source(getListPathParam(), 0, event); }; -var add_imap_combined_source = function(event) { +var add_imap_combined_source = function (event) { return update_imap_combined_source(getListPathParam(), 1, event); }; -var imap_combined_unread_content = function(id, folder) { +var imap_combined_unread_content = function (id, folder) { return imap_message_list_content(id, folder, 'ajax_imap_unread', Hm_Message_List.set_unread_state); }; -var imap_combined_flagged_content = function(id, folder) { +var imap_combined_flagged_content = function (id, folder) { return imap_message_list_content(id, folder, 'ajax_imap_flagged', Hm_Message_List.set_flagged_state); }; -var imap_combined_inbox_content = function(id, folder) { +var imap_combined_inbox_content = function (id, folder) { return imap_message_list_content(id, folder, 'ajax_imap_combined_inbox', Hm_Message_List.set_combined_inbox_state); }; -var imap_folder_content = function(id, folder) { +var imap_folder_content = function (id, folder) { return imap_message_list_content(id, folder, 'ajax_imap_folder_data', cache_folder_data); }; -var imap_tag_content = function(id, folder) { +var imap_tag_content = function (id, folder) { return imap_message_list_content(id, folder, 'ajax_imap_tag_data', cache_folder_data); }; -var cache_imap_page = function() { - var key = 'imap_'+Hm_Utils.get_url_page_number()+'_'+getListPathParam(); +var cache_imap_page = function () { + var key = 'imap_' + Hm_Utils.get_url_page_number() + '_' + getListPathParam(); var data = Hm_Message_List.filter_list(); data.find('input[type=checkbox]').removeAttr('checked'); Hm_Utils.save_to_local_storage(key, data.html()); - Hm_Utils.save_to_local_storage(key+'_page_links', $('.page_links').html()); + Hm_Utils.save_to_local_storage(key + '_page_links', $('.page_links').html()); } -var clear_imap_page_combined_inbox = function() { +var clear_imap_page_combined_inbox = function () { var key = 'imap_1_combined_inbox'; Hm_Utils.save_to_local_storage(key, ''); - Hm_Utils.save_to_local_storage(key+'_page_links', ''); + Hm_Utils.save_to_local_storage(key + '_page_links', ''); } -var fetch_cached_imap_page = function() { - var key = 'imap_'+Hm_Utils.get_url_page_number()+'_'+getListPathParam(); +var fetch_cached_imap_page = function () { + var key = 'imap_' + Hm_Utils.get_url_page_number() + '_' + getListPathParam(); var page = Hm_Utils.get_from_local_storage(key); - var links = Hm_Utils.get_from_local_storage(key+'_page_links'); - return [ page, links ]; + var links = Hm_Utils.get_from_local_storage(key + '_page_links'); + return [page, links]; } -var remove_from_cached_imap_pages = function(msg_cache_key) { - var keys = ['imap_'+Hm_Utils.get_url_page_number()+'_'+getListPathParam()]; +var remove_from_cached_imap_pages = function (msg_cache_key) { + var keys = ['imap_' + Hm_Utils.get_url_page_number() + '_' + getListPathParam()]; if (hm_list_parent()) { - keys.push('imap_'+Hm_Utils.get_url_page_number()+'_'+hm_list_parent()); + keys.push('imap_' + Hm_Utils.get_url_page_number() + '_' + hm_list_parent()); if (['combined_inbox', 'unread', 'flagged', 'advanced_search', 'search', 'sent'].includes(hm_list_parent())) { - keys.push('formatted_'+hm_list_parent()); + keys.push('formatted_' + hm_list_parent()); } } - keys.forEach(function(key) { + keys.forEach(function (key) { var data = Hm_Utils.get_from_local_storage(key); if (data) { var page_data = $('
').append(data); - page_data.find('.'+msg_cache_key).remove(); + page_data.find('.' + msg_cache_key).remove(); Hm_Utils.save_to_local_storage(key, page_data.html()); } }); } -async function select_imap_folder(path, reload, processInTheBackground = false, abortController = null) { +async function select_imap_folder(path, reload, processInTheBackground = false, abortController = null) { const messages = new Hm_MessagesStore(path, Hm_Utils.get_url_page_number(), null, abortController); - await messages.load(reload, processInTheBackground).then(() => { + await messages.load(reload, processInTheBackground).then(() => { display_imap_mailbox(messages.rows, messages.links, path); }); return messages; }; -var setup_imap_folder_page = async function(listPath) { +var setup_imap_folder_page = async function (listPath) { $('.remove_source').on("click", remove_imap_combined_source); $('.add_source').on("click", add_imap_combined_source); - $('.refresh_link').on("click", function(e) { + $('.refresh_link').on("click", function (e) { e.preventDefault(); if ($('.imap_keyword').val()) { $('#imap_filter_form').trigger('submit'); @@ -451,14 +451,14 @@ var setup_imap_folder_page = async function(listPath) { select_imap_folder(listPath, true); } }); - $('.imap_filter').on("change", function() { $('#imap_filter_form').trigger('submit'); }); - $('.imap_sort').on("change", function() { + $('.imap_filter').on("change", function () { $('#imap_filter_form').trigger('submit'); }); + $('.imap_sort').on("change", function () { $('#imap_filter_form').trigger('submit'); }); - $('.imap_keyword').on('search', function() { + $('.imap_keyword').on('search', function () { $('#imap_filter_form').trigger('submit'); }); - Hm_Ajax.add_callback_hook('ajax_message_action', function() { select_imap_folder(listPath, true); }); + Hm_Ajax.add_callback_hook('ajax_message_action', function () { select_imap_folder(listPath, true); }); const hadLocalData = new Hm_MessagesStore(listPath, Hm_Utils.get_url_page_number()).hasLocalData(); await select_imap_folder(listPath); @@ -478,7 +478,7 @@ var setup_imap_folder_page = async function(listPath) { return [interval, backgroundAbortController]; }; -$('#imap_filter_form').on('submit', async function(event) { +$('#imap_filter_form').on('submit', async function (event) { event.preventDefault(); const url = new URL(location.href); url.search = $(this).serialize(); @@ -492,7 +492,7 @@ $('#imap_filter_form').on('submit', async function(event) { } }); -var display_imap_mailbox = function(rows, links, path = getListPathParam()) { +var display_imap_mailbox = function (rows, links, path = getListPathParam()) { const detail = Hm_Utils.parse_folder_path(path, 'imap'); const serverIds = []; if (detail) { @@ -502,12 +502,12 @@ var display_imap_mailbox = function(rows, links, path = getListPathParam()) { Hm_Message_List.update(serverIds, rows, 'imap'); Hm_Message_List.check_empty_list(); $('.page_links').html(links); - $('input[type=checkbox]').on("click", function(e) { + $('input[type=checkbox]').on("click", function (e) { Hm_Message_List.toggle_msg_controls(); - }); + }); - const messages = Object.values(rows); - messages.forEach(function(item) { + const messages = Object.values(rows); + messages.forEach(function (item) { const tr = $(item['0']); const path = item['1']; const uid = tr.data('uid'); @@ -523,12 +523,12 @@ var display_imap_mailbox = function(rows, links, path = getListPathParam()) { function preFetchMessageContent(msgPart, uid, path) { const detail = Hm_Utils.parse_folder_path(path, 'imap'); Hm_Ajax.request([ - {'name': 'hm_ajax_hook', 'value': 'ajax_imap_message_content'}, - {'name': 'imap_msg_uid', 'value': uid}, - {'name': 'imap_msg_part', 'value': msgPart}, - {'name': 'imap_server_id', 'value': detail.server_id}, - {'name': 'folder', 'value': detail.folder}, - {'name': 'imap_prefetch', 'value': true} + { 'name': 'hm_ajax_hook', 'value': 'ajax_imap_message_content' }, + { 'name': 'imap_msg_uid', 'value': uid }, + { 'name': 'imap_msg_part', 'value': msgPart }, + { 'name': 'imap_server_id', 'value': detail.server_id }, + { 'name': 'folder', 'value': detail.folder }, + { 'name': 'imap_prefetch', 'value': true } ], (res) => { Hm_Utils.save_to_local_storage(getMessageStorageKey(uid), JSON.stringify(res)); }, null, true) @@ -548,36 +548,36 @@ async function markPrefetchedMessagesAsRead(uid) { if (!messages.flagAsReadOnOpen) { return; } - + if (messages.markRowAsRead(uid)) { const folderId = `${detail.type}_${detail.server_id}_${detail.folder}`; Hm_Folders.unread_counts[folderId] -= 1; Hm_Folders.update_unread_counts(folderId); Hm_Ajax.request([ - {'name': 'hm_ajax_hook', 'value': 'ajax_message_action'}, - {'name': 'action_type', 'value': 'read'}, - {'name': 'message_ids', 'value': [msgId]} + { 'name': 'hm_ajax_hook', 'value': 'ajax_message_action' }, + { 'name': 'action_type', 'value': 'read' }, + { 'name': 'message_ids', 'value': [msgId] } ], null, null, true); } } -var expand_imap_mailbox = function(res) { +var expand_imap_mailbox = function (res) { if (res.imap_expanded_folder_path) { - $('.'+Hm_Utils.clean_selector(res.imap_expanded_folder_path), $('.email_folders')).append(res.imap_expanded_folder_formatted); + $('.' + Hm_Utils.clean_selector(res.imap_expanded_folder_path), $('.email_folders')).append(res.imap_expanded_folder_formatted); $('.imap_folder_link', $('.email_folders')).off('click'); - $('.imap_folder_link', $('.email_folders')).on("click", function() { return expand_imap_folders($(this)); }); + $('.imap_folder_link', $('.email_folders')).on("click", function () { return expand_imap_folders($(this)); }); Hm_Folders.update_unread_counts(); } }; -var prefetch_imap_folders = function() { +var prefetch_imap_folders = function () { var id_el = $('#imap_prefetch_ids'); if (!id_el.length) { return; } var ids = id_el.val().split(','); - if (ids.length == 0 ) { + if (ids.length == 0) { return; } var id = ids.shift(); @@ -586,12 +586,12 @@ var prefetch_imap_folders = function() { } Hm_Ajax.request( - [{'name': 'hm_ajax_hook', 'value': 'ajax_imap_folder_expand'}, - {'name': 'imap_server_id', 'value': id}, - {'name': 'imap_prefetch', 'value': true}, - {'name': 'folder', 'value': ''}], - function(res) { - $('#imap_prefetch_ids').val(ids.join(',')); + [{ 'name': 'hm_ajax_hook', 'value': 'ajax_imap_folder_expand' }, + { 'name': 'imap_server_id', 'value': id }, + { 'name': 'imap_prefetch', 'value': true }, + { 'name': 'folder', 'value': '' }], + function (res) { + $('#imap_prefetch_ids').val(ids.join(',')); prefetch_imap_folders(); if ($('.email_folders ul.folders li').length == 1) { expand_imap_mailbox(res); @@ -603,18 +603,18 @@ var prefetch_imap_folders = function() { }; -var expand_imap_folders = function(element) { +var expand_imap_folders = function (element) { var path = element.data('target'); var detail = Hm_Utils.parse_folder_path(path, 'imap'); - var list = $('.imap_'+detail.server_id+'_'+Hm_Utils.clean_selector(detail.folder), $('.email_folders')); + var list = $('.imap_' + detail.server_id + '_' + Hm_Utils.clean_selector(detail.folder), $('.email_folders')); if ($('li', list).length === 0) { $('.expand_link', list).html(''); if (detail) { element.addClass('disabled_link'); Hm_Ajax.request( - [{'name': 'hm_ajax_hook', 'value': 'ajax_imap_folder_expand'}, - {'name': 'imap_server_id', 'value': detail.server_id}, - {'name': 'folder', 'value': detail.folder}], + [{ 'name': 'hm_ajax_hook', 'value': 'ajax_imap_folder_expand' }, + { 'name': 'imap_server_id', 'value': detail.server_id }, + { 'name': 'folder', 'value': detail.folder }], function (res) { element.removeClass('disabled_link'); expand_imap_mailbox(res); @@ -622,7 +622,7 @@ var expand_imap_folders = function(element) { [], false, Hm_Folders.save_folder_list, - function() { + function () { element.removeClass('disabled_link'); } ); @@ -636,7 +636,7 @@ var expand_imap_folders = function(element) { return false; }; -var get_message_content = function(msg_part, uid, list_path, detail, callback, noupdate) { +var get_message_content = function (msg_part, uid, list_path, detail, callback, noupdate) { if (!uid) { uid = $('.msg_uid').val(); } @@ -645,9 +645,9 @@ var get_message_content = function(msg_part, uid, list_path, detail, callback, n } if (detail && uid) { if (getPageNameParam() == 'message') { - window.scrollTo(0,0); + window.scrollTo(0, 0); } - const onSuccess = function(res) { + const onSuccess = function (res) { if (!noupdate) { $('.msg_text').html(''); $('.msg_text').append(res.msg_headers); @@ -657,7 +657,7 @@ var get_message_content = function(msg_part, uid, list_path, detail, callback, n imap_message_view_finished(); } else { - $('.reply_link, .reply_all_link, .forward_link').each(function() { + $('.reply_link, .reply_all_link, .forward_link').each(function () { $(this).attr("href", $(this).data("href")); $(this).removeClass('disabled_link'); }); @@ -667,7 +667,7 @@ var get_message_content = function(msg_part, uid, list_path, detail, callback, n } globals.auto_advance_email_enabled = Boolean(res.auto_advance_email_enabled); }; - + if (!msg_part) { const msgContent = get_local_message_content(uid, list_path); if (msgContent) { @@ -680,12 +680,12 @@ var get_message_content = function(msg_part, uid, list_path, detail, callback, n } Hm_Ajax.request( - [{'name': 'hm_ajax_hook', 'value': 'ajax_imap_message_content'}, - {'name': 'imap_msg_uid', 'value': uid}, - {'name': 'imap_msg_part', 'value': msg_part}, - {'name': 'imap_server_id', 'value': detail.server_id}, - {'name': 'folder', 'value': detail.folder}], - function(res) { + [{ 'name': 'hm_ajax_hook', 'value': 'ajax_imap_message_content' }, + { 'name': 'imap_msg_uid', 'value': uid }, + { 'name': 'imap_msg_part', 'value': msg_part }, + { 'name': 'imap_server_id', 'value': detail.server_id }, + { 'name': 'folder', 'value': detail.folder }], + function (res) { onSuccess(res); if (!noupdate && !msg_part) { Hm_Utils.save_to_local_storage(getMessageStorageKey(uid), JSON.stringify(res)); @@ -699,7 +699,7 @@ var get_message_content = function(msg_part, uid, list_path, detail, callback, n return false; }; -var imap_mark_as_read = function(uid, detail) { +var imap_mark_as_read = function (uid, detail) { if (!uid) { uid = $('.msg_uid').val(); } @@ -708,11 +708,11 @@ var imap_mark_as_read = function(uid, detail) { } if (detail && uid) { Hm_Ajax.request( - [{'name': 'hm_ajax_hook', 'value': 'ajax_imap_mark_as_read'}, - {'name': 'imap_msg_uid', 'value': uid}, - {'name': 'imap_server_id', 'value': detail.server_id}, - {'name': 'folder', 'value': detail.folder}], - function() {}, + [{ 'name': 'hm_ajax_hook', 'value': 'ajax_imap_mark_as_read' }, + { 'name': 'imap_msg_uid', 'value': uid }, + { 'name': 'imap_server_id', 'value': detail.server_id }, + { 'name': 'folder', 'value': detail.folder }], + function () { }, false, true ); @@ -720,18 +720,18 @@ var imap_mark_as_read = function(uid, detail) { return false; }; -var block_unblock_sender = function(msg_uid, detail, scope, action, sender = '', reject_message = '') { +var block_unblock_sender = function (msg_uid, detail, scope, action, sender = '', reject_message = '') { Hm_Ajax.request( [ - {'name': 'hm_ajax_hook', 'value': 'ajax_sieve_block_unblock'}, - {'name': 'imap_msg_uid', 'value': msg_uid}, - {'name': 'imap_server_id', 'value': detail.server_id}, - {'name': 'folder', 'value': detail.folder}, - {'name': 'block_action', 'value': action}, - {'name': 'scope', 'value': scope}, - {'name': 'reject_message', 'value': reject_message} + { 'name': 'hm_ajax_hook', 'value': 'ajax_sieve_block_unblock' }, + { 'name': 'imap_msg_uid', 'value': msg_uid }, + { 'name': 'imap_server_id', 'value': detail.server_id }, + { 'name': 'folder', 'value': detail.folder }, + { 'name': 'block_action', 'value': action }, + { 'name': 'scope', 'value': scope }, + { 'name': 'reject_message', 'value': reject_message } ], - function(res) { + function (res) { if (/^(Sender|Domain) Blocked$/.test(res.router_user_msgs[0])) { var title = scope == 'domain' ? 'UNBLOCK DOMAIN' @@ -756,7 +756,7 @@ var block_unblock_sender = function(msg_uid, detail, scope, action, sender = '', ); } -var imap_message_view_finished = function(msg_uid, detail, skip_links) { +var imap_message_view_finished = function (msg_uid, detail, skip_links) { var class_name = false; if (!detail) { detail = Hm_Utils.parse_folder_path(getListPathParam(), 'imap'); @@ -765,7 +765,7 @@ var imap_message_view_finished = function(msg_uid, detail, skip_links) { msg_uid = getMessageUidParam(); } if (detail && !skip_links) { - class_name = 'imap_'+detail.server_id+'_'+msg_uid+'_'+detail.folder; + class_name = 'imap_' + detail.server_id + '_' + msg_uid + '_' + detail.folder; if (hm_list_parent() === 'combined_inbox') { Hm_Message_List.prev_next_links('formatted_combined_inbox', class_name); } @@ -797,7 +797,7 @@ var imap_message_view_finished = function(msg_uid, detail, skip_links) { Hm_Message_List.prev_next_links('formatted_tag_data', class_name); } else { - var key = 'imap_'+Hm_Utils.get_url_page_number()+'_'+getListPathParam(); + var key = 'imap_' + Hm_Utils.get_url_page_number() + '_' + getListPathParam(); Hm_Message_List.prev_next_links(key, class_name); } } @@ -806,23 +806,23 @@ var imap_message_view_finished = function(msg_uid, detail, skip_links) { Hm_Message_List.adjust_unread_total(-1); } } - $('.all_headers').on("click", function() { return Hm_Utils.toggle_long_headers(); }); - $('.small_headers').on("click", function() { return Hm_Utils.toggle_long_headers(); }); - $('#flag_msg').on("click", function() { return imap_flag_message($(this).data('state')); }); - $('#unflag_msg').on("click", function() { return imap_flag_message($(this).data('state')); }); - $('#delete_message').on("click", function() { return imap_delete_message(); }); - $('#move_message').on("click", function(e) { return imap_move_copy(e, 'move', 'message');}); - $('#copy_message').on("click", function(e) { return imap_move_copy(e, 'copy', 'message');}); - $('#archive_message').on("click", function(e) { return imap_archive_message();}); - $('#unread_message').on("click", function() { return inline_imap_unread_message(msg_uid, detail);}); - $('#block_sender').on("click", function(e) { + $('.all_headers').on("click", function () { return Hm_Utils.toggle_long_headers(); }); + $('.small_headers').on("click", function () { return Hm_Utils.toggle_long_headers(); }); + $('#flag_msg').on("click", function () { return imap_flag_message($(this).data('state')); }); + $('#unflag_msg').on("click", function () { return imap_flag_message($(this).data('state')); }); + $('#delete_message').on("click", function () { return imap_delete_message(); }); + $('#move_message').on("click", function (e) { return imap_move_copy(e, 'move', 'message'); }); + $('#copy_message').on("click", function (e) { return imap_move_copy(e, 'copy', 'message'); }); + $('#archive_message').on("click", function (e) { return imap_archive_message(); }); + $('#unread_message').on("click", function () { return inline_imap_unread_message(msg_uid, detail); }); + $('#block_sender').on("click", function (e) { e.preventDefault(); var scope = $('[name=scope]').val(); var action = $('[name=block_action]').val(); var sender = $('[name=scope]').data('sender'); var reject_message = action == 'reject_with_message' ? $('#reject_message_textarea').val() : ''; - if (action == 'reject_with_message' && ! reject_message) { + if (action == 'reject_with_message' && !reject_message) { $('#reject_message_textarea').css('border', '1px solid brown'); return; } @@ -833,12 +833,12 @@ var imap_message_view_finished = function(msg_uid, detail, skip_links) { return block_unblock_sender(msg_uid, detail, scope, action, sender, reject_message); }); - $('#show_message_source').on("click", function(e) { + $('#show_message_source').on("click", function (e) { e.preventDefault(); const detail = Hm_Utils.parse_folder_path(getListPathParam(), 'imap'); window.open(`?page=message_source&imap_msg_uid=${getMessageUidParam()}&imap_server_id=${detail.server_id}&imap_folder=${detail.folder}`); }); - $(document).on('click', '#unblock_sender', function(e) { + $(document).on('click', '#unblock_sender', function (e) { e.preventDefault(); var sender = ''; if ($(this).data('target') == 'domain') { @@ -854,7 +854,7 @@ var imap_message_view_finished = function(msg_uid, detail, skip_links) { handleViewMessagePart(); }; -var get_local_message_content = function(msg_uid, path) { +var get_local_message_content = function (msg_uid, path) { if (!path) { path = getListPathParam(); } @@ -865,18 +865,18 @@ var get_local_message_content = function(msg_uid, path) { return Hm_Utils.get_from_local_storage(getMessageStorageKey(msg_uid)); }; -var imap_setup_message_view_page = function(uid, details, list_path, callback) { +var imap_setup_message_view_page = function (uid, details, list_path, callback) { if (!uid) { uid = getMessageUidParam(); } - const callbackFn = (...args) => { + const callbackFn = (...args) => { markPrefetchedMessagesAsRead(uid); observeMessageTextMutationAndHandleExternalResources(); if (callback) { callback(...args); } }; - + const msg_content = get_local_message_content(uid, list_path); if (!msg_content) { get_message_content(false, uid, list_path, details, callbackFn); @@ -884,13 +884,13 @@ var imap_setup_message_view_page = function(uid, details, list_path, callback) { else { const msgResponse = JSON.parse(msg_content); $('.msg_text').append(msgResponse.msg_headers) - .append(msgResponse.msg_text) - .append(msgResponse.msg_parts); + .append(msgResponse.msg_text) + .append(msgResponse.msg_parts); document.title = $('.header_subject th').text(); $('.header_subject th').append(''); - $('.close_inline_msg').on("click", function() { msg_inline_close(); }); + $('.close_inline_msg').on("click", function () { msg_inline_close(); }); - $('.reply_link, .reply_all_link, .forward_link').each(function() { + $('.reply_link, .reply_all_link, .forward_link').each(function () { $(this).data("href", $(this).attr("href")).removeAttr("href"); $(this).addClass('disabled_link'); }); @@ -899,7 +899,7 @@ var imap_setup_message_view_page = function(uid, details, list_path, callback) { } }; -var display_reply_content = function(res) { +var display_reply_content = function (res) { $('.compose_to').prop('disabled', false); $('.smtp_send').prop('disabled', false); $('.compose_subject').prop('disabled', false); @@ -911,24 +911,24 @@ var display_reply_content = function(res) { document.title = res.reply_subject; }; -var imap_background_unread_content_result = function(res) { +var imap_background_unread_content_result = function (res) { if (!$.isEmptyObject(res.folder_status)) { var detail = Hm_Utils.parse_folder_path(Object.keys(res.folder_status)[0], 'imap'); - var ids = [detail.server_id+'_'+detail.folder]; + var ids = [detail.server_id + '_' + detail.folder]; var cache = $('').append($(Hm_Utils.get_from_local_storage('formatted_unread_data'))); globals.Hm_Background_Unread.update(ids, res.formatted_message_list, 'imap', cache); Hm_Utils.save_to_local_storage('formatted_unread_data', cache.html()); } }; -var check_select_for_imap = function() { +var check_select_for_imap = function () { $('body').off('change', 'input[type=checkbox]'); - $('body').on('change', 'input[type=checkbox]', function(e) { search_selected_for_imap(); }); + $('body').on('change', 'input[type=checkbox]', function (e) { search_selected_for_imap(); }); }; -var search_selected_for_imap = function() { +var search_selected_for_imap = function () { var imap_selected = false; - $('input[type=checkbox]').each(function() { + $('input[type=checkbox]').each(function () { if (this.checked && this.id.search('imap') != -1) { imap_selected = true; return false; @@ -937,31 +937,31 @@ var search_selected_for_imap = function() { if (imap_selected) { $('.imap_move').removeClass('disabled_input'); $('.imap_move').off('click'); - $('.imap_move').on("click", function(e) {return imap_move_copy(e, $(this).data('action'), 'list');}); + $('.imap_move').on("click", function (e) { return imap_move_copy(e, $(this).data('action'), 'list'); }); } else { $('.imap_move').addClass('disabled_input'); $('.imap_move').off('click'); - $('.imap_move').on("click", function() { return false; }); + $('.imap_move').on("click", function () { return false; }); $('.move_to_location').html(''); $('.move_to_location').hide(); } }; -var unselect_non_imap_messages = function() { +var unselect_non_imap_messages = function () { var unselected = 0; - $('input[type=checkbox]').each(function() { + $('input[type=checkbox]').each(function () { if (this.checked && this.id.search('imap') == -1) { this.checked = false; unselected++; } }); if (unselected > 0) { - Hm_Notices.show({0: 'ERR'+$('.move_to_string3').val()}); + Hm_Notices.show({ 0: 'ERR' + $('.move_to_string3').val() }); } }; -var imap_move_copy = function(e, action, context) { +var imap_move_copy = function (e, action, context) { var move_to; if (!e.target || e.target.classList.contains('imap_move')) { move_to = $('.msg_controls .move_to_location'); @@ -983,13 +983,13 @@ var imap_move_copy = function(e, action, context) { else { label = $('.move_to_string2').val(); } - folders.prepend('
'+label+'
'); + folders.prepend('
' + label + '
'); move_to.html(folders.html()); - $('.imap_move_folder_link', move_to).on("click", function() { return expand_imap_move_to_folders($(this).data('target'), context); }); + $('.imap_move_folder_link', move_to).on("click", function () { return expand_imap_move_to_folders($(this).data('target'), context); }); $('a', move_to).not('.imap_move_folder_link').not('.close_move_to').off('click'); - $('a', move_to).not('.imap_move_folder_link').not('.close_move_to').on("click", function() { imap_perform_move_copy($(this).data('id'), context); return false; }); + $('a', move_to).not('.imap_move_folder_link').not('.close_move_to').on("click", function () { imap_perform_move_copy($(this).data('id'), context); return false; }); $('.move_to_type').val(action); - $('.close_move_to').on("click", function() { + $('.close_move_to').on("click", function () { $('.move_to_location').html(''); $('.move_to_location').hide(); return false; @@ -998,7 +998,7 @@ var imap_move_copy = function(e, action, context) { return false; }; -var imap_perform_move_copy = function(dest_id, context, action = null) { +var imap_perform_move_copy = function (dest_id, context, action = null) { if (!action) { action = $('.move_to_type').val(); } @@ -1016,11 +1016,11 @@ var imap_perform_move_copy = function(dest_id, context, action = null) { else if (page == 'message') { var uid = getMessageUidParam(); var path = Hm_Utils.parse_folder_path(getListPathParam()); - ids.push('imap_'+path['server_id']+'_'+uid+'_'+path['folder']); + ids.push('imap_' + path['server_id'] + '_' + uid + '_' + path['folder']); } } else if (context == 'list') { - $('input[type=checkbox]').each(function() { + $('input[type=checkbox]').each(function () { if (this.checked && this.id.search('imap') != -1) { ids.push(this.id); } @@ -1028,18 +1028,18 @@ var imap_perform_move_copy = function(dest_id, context, action = null) { } if (ids.length > 0 && dest_id) { Hm_Ajax.request( - [{'name': 'hm_ajax_hook', 'value': 'ajax_imap_move_copy_action'}, - {'name': 'imap_move_ids', 'value': ids.join(',')}, - {'name': 'imap_move_to', 'value': dest_id}, - {'name': 'imap_move_page', 'value': page}, - {'name': 'imap_move_action', 'value': action}], - function(res) { + [{ 'name': 'hm_ajax_hook', 'value': 'ajax_imap_move_copy_action' }, + { 'name': 'imap_move_ids', 'value': ids.join(',') }, + { 'name': 'imap_move_to', 'value': dest_id }, + { 'name': 'imap_move_page', 'value': page }, + { 'name': 'imap_move_action', 'value': action }], + function (res) { var index; if (getPageNameParam() == 'message_list') { Hm_Message_List.reset_checkboxes(); if (action == 'move' || action == 'screen_mail') { for (index in res.move_count) { - $('.'+Hm_Utils.clean_selector(res.move_count[index])).remove(); + $('.' + Hm_Utils.clean_selector(res.move_count[index])).remove(); } } if (getListPathParam().substr(0, 4) === 'imap') { @@ -1059,10 +1059,10 @@ var imap_perform_move_copy = function(dest_id, context, action = null) { if (getPageNameParam() == 'search') { window.location.reload(); } - else if (getPageNameParam() == 'advanced_search'){ + else if (getPageNameParam() == 'advanced_search') { process_advanced_search(); } else { - Hm_Utils.redirect("?page=message_list&list_path="+hm_list_parent()); + Hm_Utils.redirect("?page=message_list&list_path=" + hm_list_parent()); } } } @@ -1072,30 +1072,30 @@ var imap_perform_move_copy = function(dest_id, context, action = null) { } }; -var expand_imap_move_to_mailbox = function(res, context) { +var expand_imap_move_to_mailbox = function (res, context) { if (res.imap_expanded_folder_path) { var move_to = $('.move_to_location'); var folders = $(res.imap_expanded_folder_formatted); folders.find('.manage_folders_li').remove(); - $('.'+Hm_Utils.clean_selector(res.imap_expanded_folder_path), $('.move_to_location')).append(folders); + $('.' + Hm_Utils.clean_selector(res.imap_expanded_folder_path), $('.move_to_location')).append(folders); $('.imap_folder_link', move_to).addClass('imap_move_folder_link').removeClass('imap_folder_link'); $('.imap_move_folder_link', move_to).off('click'); - $('.imap_move_folder_link', move_to).on("click", function() { return expand_imap_move_to_folders($(this).data('target'), context); }); + $('.imap_move_folder_link', move_to).on("click", function () { return expand_imap_move_to_folders($(this).data('target'), context); }); $('a', move_to).not('.imap_move_folder_link').off('click'); - $('a', move_to).not('.imap_move_folder_link').on("click", function() { imap_perform_move_copy($(this).data('id'), context); return false; }); + $('a', move_to).not('.imap_move_folder_link').on("click", function () { imap_perform_move_copy($(this).data('id'), context); return false; }); } }; -var expand_imap_move_to_folders = function(path, context) { +var expand_imap_move_to_folders = function (path, context) { var detail = Hm_Utils.parse_folder_path(path, 'imap'); - var list = $('.imap_'+detail.server_id+'_'+Hm_Utils.clean_selector(detail.folder), $('.move_to_location')); + var list = $('.imap_' + detail.server_id + '_' + Hm_Utils.clean_selector(detail.folder), $('.move_to_location')); if ($('li', list).length === 0) { $('.expand_link', list).html(''); if (detail) { Hm_Ajax.request( - [{'name': 'hm_ajax_hook', 'value': 'ajax_imap_folder_expand'}, - {'name': 'imap_server_id', 'value': detail.server_id}, - {'name': 'folder', 'value': detail.folder}], + [{ 'name': 'hm_ajax_hook', 'value': 'ajax_imap_folder_expand' }, + { 'name': 'imap_server_id', 'value': detail.server_id }, + { 'name': 'folder', 'value': detail.folder }], function (res) { expand_imap_move_to_mailbox(res, context); } ); } @@ -1107,15 +1107,15 @@ var expand_imap_move_to_folders = function(path, context) { return false; }; -var imap_background_unread_content = function(id, folder) { +var imap_background_unread_content = function (id, folder) { Hm_Ajax.request( - [{'name': 'hm_ajax_hook', 'value': 'ajax_imap_unread'}, - {'name': 'folder', 'value': folder}, - {'name': 'imap_server_ids', 'value': id}], + [{ 'name': 'hm_ajax_hook', 'value': 'ajax_imap_unread' }, + { 'name': 'folder', 'value': folder }, + { 'name': 'imap_server_ids', 'value': id }], imap_background_unread_content_result, [], false, - function() { + function () { var cache = $('').append($(Hm_Utils.get_from_local_storage('formatted_unread_data'))); Hm_Message_List.adjust_unread_total($('tr', cache).length, true); } @@ -1123,11 +1123,11 @@ var imap_background_unread_content = function(id, folder) { return false; }; -var get_imap_folder_status = function(id, folder) { +var get_imap_folder_status = function (id, folder) { Hm_Ajax.request( - [{'name': 'hm_ajax_hook', 'value': 'ajax_imap_folder_status'}, - {'name': 'imap_server_id', 'value': id}, - {'name': 'folder', 'value': folder}], + [{ 'name': 'hm_ajax_hook', 'value': 'ajax_imap_folder_status' }, + { 'name': 'imap_server_id', 'value': id }, + { 'name': 'folder', 'value': folder }], false, [], true, @@ -1135,7 +1135,7 @@ var get_imap_folder_status = function(id, folder) { ); } -var imap_folder_status = function() { +var imap_folder_status = function () { var source; var sources = hm_data_sources(); if (!sources || !sources.length) { @@ -1149,18 +1149,18 @@ var imap_folder_status = function() { } }; -var imap_setup_tags = function() { - $(document).on('click', '.label-checkbox', function() { +var imap_setup_tags = function () { + $(document).on('click', '.label-checkbox', function () { var folder_id = $(this).data('id'); var ids = []; if (getPageNameParam() == 'message') { var list_path = getListPathParam().split('_'); - ids.push(list_path[1]+'_'+getMessageUidParam()+'_'+list_path[2]); + ids.push(list_path[1] + '_' + getMessageUidParam() + '_' + list_path[2]); } else { - $('input[type=checkbox]').each(function() { + $('input[type=checkbox]').each(function () { if (this.checked && this.id.search('imap') != -1) { var parts = this.id.split('_'); - ids.push(parts[1]+'_'+parts[2]+'_'+parts[3]); + ids.push(parts[1] + '_' + parts[2] + '_' + parts[3]); } }); if (ids.length == 0) { @@ -1169,55 +1169,55 @@ var imap_setup_tags = function() { } Hm_Ajax.request( - [{'name': 'hm_ajax_hook', 'value': 'ajax_imap_tag'}, - {'name': 'tag_id', 'value': folder_id}, - {'name': 'imap_server_ids', 'value': ids}], - function(res) { + [{ 'name': 'hm_ajax_hook', 'value': 'ajax_imap_tag' }, + { 'name': 'tag_id', 'value': folder_id }, + { 'name': 'imap_server_ids', 'value': ids }], + function (res) { if (!res.router_user_msgs[0].startsWith('ERR')) { Hm_Utils.search_from_local_storage("/^\d+_imap_.+/")?.forEach((source) => Hm_Utils.save_to_local_storage(source, 1)); Hm_Folders.reload_folders(true); - var path = hm_list_parent()? hm_list_parent(): getListPathParam(); - window.location.replace('?page=message_list&list_path='+path); + var path = hm_list_parent() ? hm_list_parent() : getListPathParam(); + window.location.replace('?page=message_list&list_path=' + path); } } ); }); } -var imap_setup_snooze = function() { - $(document).on('click', '.snooze_date_picker', function(e) { +var imap_setup_snooze = function () { + $(document).on('click', '.snooze_date_picker', function (e) { document.querySelector('.snooze_input_date').showPicker(); }); - $(document).on('click', '.snooze_helper', function(e) { + $(document).on('click', '.snooze_helper', function (e) { e.preventDefault(); $('.snooze_input').val($(this).attr('data-value')).trigger('change'); }); - $(document).on('input', '.snooze_input_date', function(e) { + $(document).on('input', '.snooze_input_date', function (e) { var now = new Date(); now.setMinutes(now.getMinutes() + 1); $(this).attr('min', now.toJSON().slice(0, 16)); if (new Date($(this).val()).getTime() <= now.getTime()) { $('.snooze_date_picker').css('border', '1px solid red'); } else { - $('.snooze_date_picker').css({'border': 'unset', 'border-top': '1px solid #ddd'}); + $('.snooze_date_picker').css({ 'border': 'unset', 'border-top': '1px solid #ddd' }); } }); - $(document).on('change', '.snooze_input_date', function(e) { + $(document).on('change', '.snooze_input_date', function (e) { if ($(this).val() && new Date().getTime() < new Date($(this).val()).getTime()) { $('.snooze_input').val($(this).val()).trigger('change'); } }); - $(document).on('change', '.snooze_input', function(e) { + $(document).on('change', '.snooze_input', function (e) { $('.snooze_dropdown').hide(); var ids = []; if (getPageNameParam() == 'message') { var list_path = getListPathParam().split('_'); - ids.push(list_path[1]+'_'+getMessageUidParam()+'_'+list_path[2]); + ids.push(list_path[1] + '_' + getMessageUidParam() + '_' + list_path[2]); } else { - $('input[type=checkbox]').each(function() { + $('input[type=checkbox]').each(function () { if (this.checked && this.id.search('imap') != -1) { var parts = this.id.split('_'); - ids.push(parts[1]+'_'+parts[2]+'_'+parts[3]); + ids.push(parts[1] + '_' + parts[2] + '_' + parts[3]); } }); if (ids.length == 0) { @@ -1225,24 +1225,24 @@ var imap_setup_snooze = function() { }; } Hm_Ajax.request( - [{'name': 'hm_ajax_hook', 'value': 'ajax_imap_snooze'}, - {'name': 'imap_snooze_ids', 'value': ids}, - {'name': 'imap_snooze_until', 'value': $(this).val()}], - function(res) { + [{ 'name': 'hm_ajax_hook', 'value': 'ajax_imap_snooze' }, + { 'name': 'imap_snooze_ids', 'value': ids }, + { 'name': 'imap_snooze_until', 'value': $(this).val() }], + function (res) { if (res.snoozed_messages > 0) { Hm_Folders.reload_folders(true); - var path = hm_list_parent()? hm_list_parent(): getListPathParam(); - window.location.replace('?page=message_list&list_path='+path); + var path = hm_list_parent() ? hm_list_parent() : getListPathParam(); + window.location.replace('?page=message_list&list_path=' + path); } } ); }); } -var imap_unsnooze_messages = function() { +var imap_unsnooze_messages = function () { Hm_Ajax.request( - [{'name': 'hm_ajax_hook', 'value': 'ajax_imap_unsnooze'}], - function() {}, + [{ 'name': 'hm_ajax_hook', 'value': 'ajax_imap_unsnooze' }], + function () { }, ); } @@ -1250,7 +1250,7 @@ if (getListPathParam() == 'sent') { Hm_Message_List.page_caches.sent = 'formatted_sent_data'; } -$(function() { +$(function () { $(document).on('click', '#enable_sieve_filter', function () { $('.sieve_config').toggle(); }); @@ -1275,7 +1275,7 @@ $(function() { return true; }); - $(document).on('click', '.checkbox_label', function(e) { + $(document).on('click', '.checkbox_label', function (e) { setTimeout(search_selected_for_imap, 100); }); @@ -1286,10 +1286,10 @@ $(function() { if ($('.imap_move').length > 0) { check_select_for_imap(); - $('.toggle_link').on("click", function() { setTimeout(search_selected_for_imap, 100); }); + $('.toggle_link').on("click", function () { setTimeout(search_selected_for_imap, 100); }); Hm_Ajax.add_callback_hook('ajax_imap_folder_display', check_select_for_imap); Hm_Message_List.callbacks.push(check_select_for_imap); - $('.imap_move').on("click", function() { return false; }); + $('.imap_move').on("click", function () { return false; }); } if (getListPathParam() !== 'unread') { @@ -1305,7 +1305,7 @@ $(function() { }); -var imap_archive_message = function(state, supplied_uid, supplied_detail) { +var imap_archive_message = function (state, supplied_uid, supplied_detail) { var uid = getMessageUidParam(); var detail = Hm_Utils.parse_folder_path(getListPathParam(), 'imap'); if (supplied_uid) { @@ -1316,11 +1316,11 @@ var imap_archive_message = function(state, supplied_uid, supplied_detail) { } if (detail && uid) { Hm_Ajax.request( - [{'name': 'hm_ajax_hook', 'value': 'ajax_imap_archive_message'}, - {'name': 'imap_msg_uid', 'value': uid}, - {'name': 'imap_server_id', 'value': detail.server_id}, - {'name': 'folder', 'value': detail.folder}], - function(res) { + [{ 'name': 'hm_ajax_hook', 'value': 'ajax_imap_archive_message' }, + { 'name': 'imap_msg_uid', 'value': uid }, + { 'name': 'imap_server_id', 'value': detail.server_id }, + { 'name': 'folder', 'value': detail.folder }], + function (res) { if (!res.imap_archive_error) { if (Hm_Utils.get_from_global('msg_uid', false)) { return; @@ -1331,10 +1331,10 @@ var imap_archive_message = function(state, supplied_uid, supplied_detail) { } else { if (!hm_list_parent()) { - Hm_Utils.redirect("?page=message_list&list_path="+getListPathParam()); + Hm_Utils.redirect("?page=message_list&list_path=" + getListPathParam()); } else { - Hm_Utils.redirect("?page=message_list&list_path="+hm_list_parent()); + Hm_Utils.redirect("?page=message_list&list_path=" + hm_list_parent()); } } } @@ -1344,12 +1344,12 @@ var imap_archive_message = function(state, supplied_uid, supplied_detail) { return false; }; -var imap_show_add_contact_popup = function() { +var imap_show_add_contact_popup = function () { var popup = document.getElementById("contact_popup"); popup.classList.toggle("show"); }; -var imap_hide_add_contact_popup = function(event) { +var imap_hide_add_contact_popup = function (event) { event.stopPropagation() var popup = document.getElementById("contact_popup"); popup.classList.toggle("show"); @@ -1357,7 +1357,7 @@ var imap_hide_add_contact_popup = function(event) { observeMessageTextMutationAndHandleExternalResources(); -const handleDownloadMsgSource = function() { +const handleDownloadMsgSource = function () { const messageSource = document.querySelector('pre.msg_source'); const blob = new Blob([messageSource.textContent], { type: "message/rfc822" }); const url = URL.createObjectURL(blob); @@ -1370,17 +1370,17 @@ const handleDownloadMsgSource = function() { document.body.removeChild(a); }; -const handleCopyMsgSource = function(e) { +const handleCopyMsgSource = function (e) { e.preventDefault(); const messageSource = document.querySelector('pre.msg_source'); navigator.clipboard.writeText(messageSource.textContent); Hm_Notices.show(['Copied to clipboard']); } -var imap_screen_email = function() { +var imap_screen_email = function () { var list_msg_uid = []; - - $('input[type=checkbox]').each(function() { + + $('input[type=checkbox]').each(function () { if (this.checked && this.id.search('imap') != -1) { list_msg_uid.push($(this).parent().parent().attr("data-uid")); } @@ -1388,32 +1388,32 @@ var imap_screen_email = function() { if ($("#move_messages_in_screen_email").val() == 1) { imap_perform_move_copy("Screen email", "list", 'screen_mail'); } - list_msg_uid.forEach(function(msg_uid) { + list_msg_uid.forEach(function (msg_uid) { block_unblock_sender(msg_uid, Hm_Utils.parse_folder_path(getListPathParam()), 'sender', 'blocked'); }) }; -var add_email_in_contact_trusted = function(list_email) { +var add_email_in_contact_trusted = function (list_email) { if (list_email) { - Hm_Ajax.request( - [ - { name: 'hm_ajax_hook', value: 'ajax_add_contact' }, - { name: 'email_address', value: list_email.join(',') }, - ], - function (res) { - window.location.reload(); - } - ); + Hm_Ajax.request( + [ + { name: 'hm_ajax_hook', value: 'ajax_add_contact' }, + { name: 'email_address', value: list_email.join(',') }, + ], + function (res) { + window.location.reload(); + } + ); } - }; +}; -$('.screen-email-unlike').on("click", function() { imap_screen_email(); return false; }); +$('.screen-email-unlike').on("click", function () { imap_screen_email(); return false; }); -$('.screen-email-like').on("click", function() { +$('.screen-email-like').on("click", function () { var list_email = []; - $('input[type=checkbox]').each(function() { + $('input[type=checkbox]').each(function () { if (this.checked && this.id.search('imap') != -1) { - let email = $('.'+ this.id +' .from').attr("data-title") + let email = $('.' + this.id + ' .from').attr("data-title") if (email = email.trim()) { list_email.push(email); } @@ -1422,14 +1422,14 @@ $('.screen-email-like').on("click", function() { add_email_in_contact_trusted(list_email); return false; }); -$(document).on('click', '[data-bs-dismiss="modal"]', function() { +$(document).on('click', '[data-bs-dismiss="modal"]', function () { $('#shareFolderModal').modal('hide'); }); -$(document).on('click', 'a.dropdown-item.share', function(e) { +$(document).on('click', 'a.dropdown-item.share', function (e) { e.preventDefault(); const listItem = e.target.closest('li'); - if(listItem) { + if (listItem) { listItem.getAttribute('data-id'); const uid = listItem.getAttribute('data-id'); const folder_uid = listItem.getAttribute('data-folder-uid'); @@ -1445,10 +1445,10 @@ $(document).on('click', 'a.dropdown-item.share', function(e) { $('#loadingSpinner').show(); Hm_Ajax.request( [ - { name: 'hm_ajax_hook', value: 'ajax_share_folders' }, - { name: 'imap_server_id', value: uid }, - { name: 'imap_folder_uid', value: folder_uid }, - { name: 'imap_folder', value: folder }, + { name: 'hm_ajax_hook', value: 'ajax_share_folders' }, + { name: 'imap_server_id', value: uid }, + { name: 'imap_folder_uid', value: folder_uid }, + { name: 'imap_folder', value: folder }, ], function (res) { $('#loadingSpinner').hide(); @@ -1464,7 +1464,7 @@ $(document).on('click', 'a.dropdown-item.share', function(e) { } }); -var populate_permissions_table = function(permissions) { +var populate_permissions_table = function (permissions) { $('#shareFolderModal table tbody').empty(); for (const [email, permissionList] of Object.entries(permissions)) { const translatedPermissions = permissionList.split(',').map(permission => { @@ -1484,7 +1484,7 @@ var populate_permissions_table = function(permissions) { } } -$(document).on('click', '.edit-permission', function(e) { +$(document).on('click', '.edit-permission', function (e) { e.preventDefault(); const email = $(this).data('email'); @@ -1510,7 +1510,7 @@ $(document).on('click', '.edit-permission', function(e) { $('#shareFolderModal').modal('show'); }); -$(document).on('submit', '#shareForm', function(e) { +$(document).on('submit', '#shareForm', function (e) { e.preventDefault(); const server_id = $('#server_id').val(); const folder = $('#folder').val(); @@ -1533,16 +1533,16 @@ $(document).on('submit', '#shareForm', function(e) { const action = permissions === '' ? 'remove' : 'add'; Hm_Ajax.request( [ - { name: 'hm_ajax_hook', value: 'ajax_share_folders' }, - { name: 'imap_server_id', value: server_id }, - { name: 'identifier', value: identifier }, - { name: 'imap_folder', value: folder }, - { name: 'action', value: action }, - { name: 'permissions', value: permissions }, + { name: 'hm_ajax_hook', value: 'ajax_share_folders' }, + { name: 'imap_server_id', value: server_id }, + { name: 'identifier', value: identifier }, + { name: 'imap_folder', value: folder }, + { name: 'action', value: action }, + { name: 'permissions', value: permissions }, ], function (res) { - if(res.ajax_imap_folders_permissions) { - console.log("ajax_imap_folders_permissions",res.ajax_imap_folders_permissions); + if (res.ajax_imap_folders_permissions) { + console.log("ajax_imap_folders_permissions", res.ajax_imap_folders_permissions); const permissions = res.ajax_imap_folders_permissions; populate_permissions_table(permissions); } diff --git a/modules/profiles/functions.php b/modules/profiles/functions.php index bb7abe0148..228cc936d0 100644 --- a/modules/profiles/functions.php +++ b/modules/profiles/functions.php @@ -12,7 +12,7 @@ function add_profile($name, $signature, $reply_to, $is_default, $email, $server_ 'replyto' => $reply_to, 'default' => $is_default, 'address' => $email, - 'server' => $server_mail, + 'server' => $imap_server_id, 'user' => $email, 'type' => 'imap' ); diff --git a/modules/profiles/hm-profiles.php b/modules/profiles/hm-profiles.php index 16997e0582..966827baa1 100644 --- a/modules/profiles/hm-profiles.php +++ b/modules/profiles/hm-profiles.php @@ -109,4 +109,14 @@ public static function loadLegacy($hmod) { } } } + + public static function search($fld, $value) { + $res = array(); + foreach (self::getAll() as $profile) { + if (!empty($profile[$fld]) && $profile[$fld] == $value) { + $res[] = $profile; + } + } + return $res; + } } diff --git a/modules/smtp/hm-mime-message.php b/modules/smtp/hm-mime-message.php index 1b775e0941..64cfe7b9dc 100644 --- a/modules/smtp/hm-mime-message.php +++ b/modules/smtp/hm-mime-message.php @@ -21,10 +21,15 @@ class Hm_MIME_Msg { private $final_msg = ''; /* build mime message data */ - function __construct($to, $subject, $body, $from, $html=false, $cc='', $bcc='', $in_reply_to_id='', $from_name='', $reply_to='') { + function __construct($to, $subject, $body, $from, $html=false, $cc='', $bcc='', $in_reply_to_id='', $from_name='', $reply_to='', $delivery_receipt='', $schedule='', $profile_id = '') { if ($cc) { $this->headers['Cc'] = $cc; } + if ($schedule) { + $this->headers['X-Schedule'] = $schedule; + $this->headers['X-Profile-ID'] = $profile_id; + } + if ($in_reply_to_id) { $this->headers['In-Reply-To'] = $in_reply_to_id; } @@ -41,6 +46,9 @@ function __construct($to, $subject, $body, $from, $html=false, $cc='', $bcc='', else { $this->headers['Reply-To'] = $from; } + if ($delivery_receipt) { + $this->headers['X-Delivery'] = $delivery_receipt; + } $this->headers['To'] = $to; $this->headers['Subject'] = html_entity_decode($subject, ENT_QUOTES); $this->headers['Date'] = date('r'); @@ -190,7 +198,7 @@ function prep_fld($val, $name) { return $this->encode_fld($val); } - function find_addresses($str) { + static function find_addresses($str) { $res = array(); foreach (process_address_fld($str) as $vals) { $res[] = $vals['email']; @@ -210,7 +218,7 @@ function get_recipient_addresses() { else { continue; } - $res = array_merge($res, $this->find_addresses($v)); + $res = array_merge($res, self::find_addresses($v)); } return $res; } diff --git a/modules/smtp/modules.php b/modules/smtp/modules.php index 053638eb24..78ccfe39ae 100644 --- a/modules/smtp/modules.php +++ b/modules/smtp/modules.php @@ -114,6 +114,8 @@ public function process() { } } + + /** * @subpackage smtp/handler */ @@ -210,6 +212,7 @@ public function process() { } } + /** * @subpackage smtp/handler */ @@ -319,6 +322,8 @@ public function process() { $draft_id = array_key_exists('draft_id', $this->request->post) ? $this->request->post['draft_id'] : false; $draft_notice = array_key_exists('draft_notice', $this->request->post) ? $this->request->post['draft_notice'] : false; $uploaded_files = array_key_exists('uploaded_files', $this->request->post) ? $this->request->post['uploaded_files'] : false; + $delivery_receipt = array_key_exists('compose_delivery_receipt', $this->request->post) ? $this->request->post['compose_delivery_receipt'] : false; + $schedule = array_key_exists('schedule', $this->request->post) ? $this->request->post['schedule'] : ''; if (array_key_exists('delete_uploaded_files', $this->request->post) && $this->request->post['delete_uploaded_files']) { delete_uploaded_files($this->session, $draft_id); @@ -348,12 +353,14 @@ public function process() { $new_draft_id = save_imap_draft($msg_attrs, $draft_id, $this->session, $this, $this->cache, $uploaded_files, $profile); if ($new_draft_id >= 0) { if ($draft_notice) { - Hm_Msgs::add('Draft saved'); + $msg = $schedule ? 'Message scheduled to be sent later' : 'Draft saved'; + Hm_Msgs::add($msg); } $this->out('draft_id', $new_draft_id); } elseif ($draft_notice) { - Hm_Msgs::add('ERRUnable to save draft'); + $msg = $schedule ? 'Something went wrong when scheduling draft' : 'Unable to save draft'; + Hm_Msgs::add('ERR' . $msg); } return; } @@ -720,6 +727,7 @@ public function process() { 'draft_subject' => $form['compose_subject'], 'draft_smtp' => $smtp_id ); + $delivery_receipt = !empty($this->request->post['compose_delivery_receipt']); $from_params = ''; $recipients_params = ''; @@ -738,8 +746,7 @@ public function process() { /* msg details */ list($body, $cc, $bcc, $in_reply_to, $draft) = get_outbound_msg_detail($this->request->post, $draft, $body_type); - - if ($this->user_config->get('enable_compose_delivery_receipt_setting', false) && !empty($this->request->post['compose_delivery_receipt'])) { + if ($delivery_receipt) { $from_params = 'RET=HDRS'; $recipients_params = 'NOTIFY=SUCCESS,FAILURE'; } @@ -771,7 +778,7 @@ public function process() { } /* build message */ - $mime = new Hm_MIME_Msg($to, $subject, $body, $from, $body_type, $cc, $bcc, $in_reply_to, $from_name, $reply_to); + $mime = new Hm_MIME_Msg($to, $subject, $body, $from, $body_type, $cc, $bcc, $in_reply_to, $from_name, $reply_to, $delivery_receipt); /* add attachments */ $mime->add_attachments($uploaded_files); @@ -939,6 +946,132 @@ protected function output() { ' value="1" id="enable_compose_delivery_receipt" name="enable_compose_delivery_receipt" />'.$reset.''; } } + +/** + * Send scheduled messages + * @subpackage smtp/handler + */ +class Hm_Handler_send_scheduled_messages extends Hm_Handler_Module { + /** + * Send delayed messages + * This should use cron + */ + public function process() { + if (!($this->module_is_supported('imap') || $this->module_is_supported('profiles'))) { + return; + } + $servers = Hm_IMAP_List::dump(); + $scheduled_msg_count = 0; + foreach (array_keys($servers) as $server_id) { + $cache = Hm_IMAP_List::get_cache($this->cache, $server_id); + $imap = Hm_IMAP_List::connect($server_id, $cache); + if (imap_authed($imap)) { + $folder = 'Scheduled'; + $ret = $imap->get_mailbox_page($folder, 'DATE', false, 'ALL'); + foreach ($ret[1] as $msg) { + $msg_headers = $imap->get_message_headers($msg['uid']); + try { + if (!empty($msg_headers['X-Schedule'])) { + $scheduled_msg_count++; + } else { + continue; + } + if (new DateTime($msg_headers['X-Schedule']) <= new DateTime()) { + $profile = Hm_Profiles::get($msg_headers['X-Profile-ID']); + if (!$profile) { + $profiles = Hm_Profiles::search('server', $imap_details['server']); + + if (!$profiles) { + Hm_Debug::add(sprintf('ERRCannot find profiles corresponding with IMAP server: %s', $imap_details['server'])); + continue; + } + $profile = $profiles[0]; + } + + $smtp = Hm_SMTP_List::connect($profile['smtp_id'], false); + + if (smtp_authed($smtp)) { + if (isset($msg_headers['X-Delivery'])) { + $from_params = 'RET=HDRS'; + $recipients_params = 'NOTIFY=SUCCESS,FAILURE'; + } else { + $from_params = ''; + $recipients_params = ''; + } + $recipients = []; + foreach (['To', 'Cc', 'Bcc'] as $fld) { + if (array_key_exists($fld, $msg_headers)) { + $recipients = array_merge($recipients, Hm_MIME_Msg::find_addresses($msg_headers[$fld])); + } + } + $msg_content = $imap->get_message_content($msg['uid'], 0); + $from = process_address_fld($msg_headers['From']); + + $err_msg = $smtp->send_message($from[0]['email'], $recipients, $msg_content, $from_params, $recipients_params); + + if (!$err_msg) { + if ($imap->message_action('DELETE', [$msg['uid']])) { + $imap->message_action('EXPUNGE', [$msg['uid']]); + } + save_sent_msg($this, $server_id, $imap, $imap_details, $msg_content, $msg['uid'], false); + $scheduled_msg_count--; + } + } + } + } catch (Exception $e) { + Hm_Debug::add(sprintf('ERRCannot send message: %s', $msg_headers['subject'])); + if (send_scheduled_message($this, $imap, $msg, $server_id)) { + $scheduled_msg_count++; + } + } + } + } + } + $this->out('scheduled_msg_count', $scheduled_msg_count); + } +} + +/** + * Changes the schedule of the message + * @subpackage smtp/handler + */ +class Hm_Handler_re_schedule_message_sending extends Hm_Handler_Module { + public function process() { + if (!($this->module_is_supported('imap') || $this->module_is_supported('profiles'))) { + return; + } + list($success, $form) = $this->process_form(array('schedule_date', 'scheduled_msg_ids')); + if (!$success) { + return; + } + $scheduled_msg_count = 0; + if ($form['schedule_date'] != 'now') { + $new_schedule_date = get_nexter_date($form['schedule_date']); + } + $ids = explode(',', $form['scheduled_msg_ids']); + foreach ($ids as $msg_part) { + list($imap_server_id, $msg_id, $folder) = explode('_', $msg_part); + $cache = Hm_IMAP_List::get_cache($this->cache, $imap_server_id); + $imap = Hm_IMAP_List::connect($imap_server_id, $cache); + if (imap_authed($imap)) { + $folder = hex2bin($folder); + if (reschedule_message_sending($this, $imap, $msg_id, $folder, $new_schedule_date, $imap_server_id)) { + $scheduled_msg_count++; + } + } + } + $this->out('scheduled_msg_count', $scheduled_msg_count); + if ($scheduled_msg_count == count($ids)) { + $msg = 'Operation successful'; + } elseif ($scheduled_msg_count > 0) { + $msg = 'Some messages have been scheduled for sending'; + } else { + $msg = 'ERRFailed to schedule sending for messages'; + } + Hm_Msgs::add($msg); + $this->save_hm_msgs(); + } +} /** * @subpackage keyboard_shortcuts/output @@ -1300,11 +1433,15 @@ protected function output() { } } } - $res .= ''. smtp_server_dropdown($this->module_output(), $this, $recip, $selected_id). - ''; - + '
+ + '. + schedule_dropdown($this). + '
'; if ($this->get('list_path') && ($reply_type == 'reply' || $reply_type == 'reply_all')) { $res .= ''; } @@ -1599,6 +1736,20 @@ protected function output() { } } +/** + * Add scheduled send to the message list controls + * @subpackage imap/output + */ +class Hm_Output_scheduled_send_msg_control extends Hm_Output_Module { + protected function output() { + $parts = explode('_', $this->get('list_path')); + if ($parts[0] == 'imap' && hex2bin($parts[2]) == 'Scheduled') { + $res = schedule_dropdown($this, true); + $this->concat('msg_controls_extra', $res); + } + } +} + /** * @subpackage smtp/functions */ @@ -1979,13 +2130,23 @@ function save_imap_draft($atts, $id, $session, $mod, $mod_cache, $uploaded_files $specials = get_special_folders($mod, $imap_profile['id']); - if (!array_key_exists('draft', $specials) || !$specials['draft']) { + if ((!array_key_exists('draft', $specials) || !$specials['draft']) && !array_key_exists('schedule', $atts)) { Hm_Msgs::add('ERRThere is no draft directory configured for this account.'); return -1; } $cache = Hm_IMAP_List::get_cache($mod_cache, $imap_profile['id']); $imap = Hm_IMAP_List::connect($imap_profile['id'], $cache); - $draft_folder = $imap->select_mailbox($specials['draft']); + + if (!empty($atts['schedule'])) { + $folder ='Scheduled'; + if (!count($imap->get_mailbox_status($folder))) { + $imap->create_mailbox($folder); + } + $atts['schedule'] = get_nexter_date($atts['schedule']); + } else { + $folder = $specials['draft']; + } + $imap->select_mailbox($folder); $mime = prepare_draft_mime($atts, $uploaded_files, $from, $name); $res = $mime->process_attachments(); @@ -2002,7 +2163,7 @@ function save_imap_draft($atts, $id, $session, $mod, $mod_cache, $uploaded_files } } - $mailbox_page = $imap->get_mailbox_page($specials['draft'], 'ARRIVAL', true, 'DRAFT', 0, 10); + $mailbox_page = $imap->get_mailbox_page($folder, 'ARRIVAL', true, 'DRAFT', 0, 10); // Remove old version from the mailbox if ($id) { @@ -2291,3 +2452,102 @@ function recip_count_check($headers, $omod) { Hm_Msgs::add('ERRMessage contains more than the maximum number of recipients, proceed with caution'); } }} + +/** + * @subpackage smtp/functions + */ +if (!hm_exists('send_scheduled_message')) { +function send_scheduled_message($handler, $imap, $msg, $server_id) { + $msg_headers = $imap->get_message_headers($msg['uid']); + $imap_details = Hm_IMAP_List::dump($server_id); + if (empty($imap_details)) { + return; + } + try { + if (empty($msg_headers['X-Schedule'])) { + return; + } + if (new DateTime($msg_headers['X-Schedule']) <= new DateTime()) { + $profile = Hm_Profiles::get($msg_headers['X-Profile-ID']); + if (!$profile) { + $profiles = Hm_Profiles::search('server', $imap_details['server']); + + if (!$profiles) { + Hm_Debug::add(sprintf('ERRCannot find profiles corresponding with IMAP server: %s', $imap_details['server'])); + return; + } + $profile = $profiles[0]; + } + + $smtp = Hm_SMTP_List::connect($profile['smtp_id'], false); + + if (smtp_authed($smtp)) { + if (isset($msg_headers['X-Delivery'])) { + $from_params = 'RET=HDRS'; + $recipients_params = 'NOTIFY=SUCCESS,FAILURE'; + } else { + $from_params = ''; + $recipients_params = ''; + } + $recipients = []; + foreach (['To', 'Cc', 'Bcc'] as $fld) { + if (array_key_exists($fld, $msg_headers)) { + $recipients = array_merge($recipients, Hm_MIME_Msg::find_addresses($msg_headers[$fld])); + } + } + $msg_content = $imap->get_message_content($msg['uid'], 0); + $from = process_address_fld($msg_headers['From']); + + $err_msg = $smtp->send_message($from[0]['email'], $recipients, $msg_content, $from_params, $recipients_params); + + if (!$err_msg) { + if ($imap->message_action('DELETE', [$msg['uid']])) { + $imap->message_action('EXPUNGE', [$msg['uid']]); + } + save_sent_msg($handler, $server_id, $imap, $imap_details, $msg_content, $msg['uid'], false); + return true; + } + } + } + } catch (Exception $e) { + Hm_Debug::add(sprintf('ERRCannot send message: %s', $msg_headers['subject'])); + } + return; +}} + +if (!hm_exists('reschedule_message_sending')) { +function reschedule_message_sending($handler, $imap, $msg_id, $folder, $new_date, $server_id) { + if (!$imap->select_mailbox($folder)) { + return; + } + $msg = $imap->get_message_content($msg_id, 0); + if ($new_date == 'now') { + return send_scheduled_message($handler, $imap, $msg, $server_id); + } + preg_match("/^X-Schedule:.*(\r?\n[ \t]+.*)*\r?\n?/im", $msg, $matches); + if (count($matches)) { + $new_date = get_nexter_date($new_date); + $msg = str_replace($matches[0], "X-Schedule: {$new_date}\n", $msg); + } else { + return; + } + $msg = str_replace("\r\n", "\n", $msg); + $msg = str_replace("\n", "\r\n", $msg); + $msg = rtrim($msg)."\r\n"; + + $schedule_folder = 'Scheduled'; + if (!count($imap->get_mailbox_status($schedule_folder))) { + return; + } + $res = false; + if ($imap->select_mailbox($schedule_folder) && $imap->append_start($schedule_folder, strlen($msg))) { + $imap->append_feed($msg."\r\n"); + if ($imap->append_end()) { + if ($imap->select_mailbox($folder) && $imap->message_action('DELETE', array($msg_id))) { + $imap->message_action('EXPUNGE', array($msg_id)); + $res = true; + } + } + } + return $res; +}} diff --git a/modules/smtp/setup.php b/modules/smtp/setup.php index edb7987acb..eb9362401f 100644 --- a/modules/smtp/setup.php +++ b/modules/smtp/setup.php @@ -21,6 +21,7 @@ add_handler('compose', 'load_smtp_is_imap_forward_as_attachment', true, 'smtp', 'load_user_data', 'after'); add_handler('compose', 'load_smtp_is_imap_forward', true, 'smtp', 'load_smtp_is_imap_forward_as_attachment', 'after'); + add_handler('functional_api', 'default_smtp_server', true, 'smtp'); add_handler('profiles', 'load_smtp_servers_from_config', true, 'smtp', 'load_user_data', 'after'); @@ -104,6 +105,20 @@ add_handler('settings', 'process_enable_compose_delivery_receipt_setting', true, 'core', 'save_user_settings', 'before'); add_output('settings', 'enable_compose_delivery_receipt_setting', true, 'core', 'start_general_settings', 'after'); +/* send delayed emails */ +setup_base_ajax_page('ajax_send_scheduled_messages', 'core'); +add_handler('ajax_send_scheduled_messages', 'load_imap_servers_from_config', true, 'imap', 'load_user_data', 'after'); +add_handler('ajax_send_scheduled_messages', 'load_smtp_servers_from_config', true, 'smtp', 'load_user_data', 'after'); +add_handler('ajax_send_scheduled_messages', 'compose_profile_data', true, 'profiles'); +add_handler('ajax_send_scheduled_messages', 'send_scheduled_messages', true, 'smtp'); + +setup_base_ajax_page('ajax_re_schedule_message_sending', 'core'); +add_handler('ajax_re_schedule_message_sending', 'load_imap_servers_from_config', true, 'imap', 'load_user_data', 'after'); +add_handler('ajax_re_schedule_message_sending', 'load_smtp_servers_from_config', true, 'smtp', 'load_user_data', 'after'); +add_handler('ajax_re_schedule_message_sending', 'compose_profile_data', true, 'profiles'); +add_handler('ajax_re_schedule_message_sending', 're_schedule_message_sending', true, 'smtp'); + +add_output('message_list', 'scheduled_send_msg_control', true, 'smtp', 'imap_custom_controls', 'after'); return array( 'allowed_pages' => array( @@ -114,7 +129,9 @@ 'ajax_profiles_status', 'ajax_attachment_reminder_check', 'ajax_get_test_chunk', - 'ajax_upload_chunk' + 'ajax_upload_chunk', + 'ajax_send_scheduled_messages', + 'ajax_re_schedule_message_sending' ), 'allowed_get' => array( 'imap_draft' => FILTER_VALIDATE_INT, @@ -146,9 +163,13 @@ 'msg_sent_and_archived' => array(FILTER_VALIDATE_BOOLEAN, false), 'sent_msg_id' => array(FILTER_VALIDATE_BOOLEAN, false), 'enable_attachment_reminder' => array(FILTER_VALIDATE_BOOLEAN, false), + 'scheduled_msg_count' => array(FILTER_VALIDATE_INT, false), ), 'allowed_post' => array( 'post_archive' => FILTER_VALIDATE_INT, + 'send_tomorrow_morning' => FILTER_DEFAULT, + 'send_today_afternoon' => FILTER_DEFAULT, + 'schedule_sending' => FILTER_DEFAULT, 'attachment_id' => FILTER_DEFAULT, 'smtp_compose_type' => FILTER_VALIDATE_INT, 'new_smtp_name' => FILTER_DEFAULT, @@ -189,6 +210,9 @@ 'uploaded_files' => FILTER_DEFAULT, 'send_uploaded_files' => FILTER_DEFAULT, 'next_email_post' => FILTER_DEFAULT, - 'enable_attachment_reminder' => FILTER_VALIDATE_INT + 'enable_attachment_reminder' => FILTER_VALIDATE_INT, + 'schedule' => FILTER_DEFAULT, + 'schedule_date' => FILTER_DEFAULT, + 'scheduled_msg_ids' => FILTER_DEFAULT, ) ); diff --git a/modules/smtp/site.js b/modules/smtp/site.js index 490649e56e..2ff6a2519d 100644 --- a/modules/smtp/site.js +++ b/modules/smtp/site.js @@ -1,42 +1,42 @@ 'use strict'; -var get_smtp_profile = function(profile_value) { +var get_smtp_profile = function (profile_value) { if (typeof profile_value === "undefined" || profile_value == "0" || profile_value == "") { Hm_Notices.show([err_msg('Please create a profile for saving sent messages option')]); } else { Hm_Ajax.request( - [{'name': 'hm_ajax_hook', 'value': 'ajax_profiles_status'}, - {'name': 'profile_value', 'value': profile_value}], - function(res) { + [{ 'name': 'hm_ajax_hook', 'value': 'ajax_profiles_status' }, + { 'name': 'profile_value', 'value': profile_value }], + function (res) { } ); } }; -var check_attachment_dir_access = function() { +var check_attachment_dir_access = function () { Hm_Notices.show([err_msg('Attachment storage unavailable, please contact your site administrator')]); }; -var smtp_test_action = function(event) { +var smtp_test_action = function (event) { event.preventDefault(); var form = $(this).closest('.smtp_connect'); Hm_Notices.hide(true); Hm_Ajax.request( form.serializeArray(), false, - {'smtp_connect': 1} + { 'smtp_connect': 1 } ); }; -var smtp_save_action = function(event) { +var smtp_save_action = function (event) { event.preventDefault(); var form = $(this).closest('.smtp_connect'); var btnContainer = $(this).parent(); Hm_Notices.hide(true); Hm_Ajax.request( form.serializeArray(), - function(res) { + function (res) { if (res.just_saved_credentials) { form.find('.credentials').attr('disabled', true); form.find('.save_smtp_connection').hide(); @@ -48,18 +48,18 @@ var smtp_save_action = function(event) { Hm_Folders.reload_folders(true); } }, - {'smtp_save': 1} + { 'smtp_save': 1 } ); }; -var smtp_forget_action = function(event) { +var smtp_forget_action = function (event) { event.preventDefault(); var form = $(this).closest('.smtp_connect'); var btnContainer = $(this).parent(); Hm_Notices.hide(true); Hm_Ajax.request( form.serializeArray(), - function(res) { + function (res) { if (res.just_forgot_credentials) { form.find('.credentials').prop('disabled', false); form.find('.credentials').val(''); @@ -70,11 +70,11 @@ var smtp_forget_action = function(event) { Hm_Folders.reload_folders(true); } }, - {'smtp_forget': 1} + { 'smtp_forget': 1 } ); }; -var smtp_delete_action = function(event) { +var smtp_delete_action = function (event) { if (!hm_delete_prompt()) { return false; } @@ -83,7 +83,7 @@ var smtp_delete_action = function(event) { var form = $(this).closest('.smtp_connect'); Hm_Ajax.request( form.serializeArray(), - function(res) { + function (res) { if (res.deleted_server_id) { form.parent().fadeOutAndRemove() Hm_Utils.set_unsaved_changes(1); @@ -91,34 +91,34 @@ var smtp_delete_action = function(event) { decrease_servers('smtp'); } }, - {'smtp_delete': 1} + { 'smtp_delete': 1 } ); }; -var smtp_delete_draft = function(id) { +var smtp_delete_draft = function (id) { Hm_Ajax.request( - [{'name': 'hm_ajax_hook', 'value': 'ajax_smtp_delete_draft'}, - {'name': 'draft_id', 'value': id}], - function(res) { + [{ 'name': 'hm_ajax_hook', 'value': 'ajax_smtp_delete_draft' }, + { 'name': 'draft_id', 'value': id }], + function (res) { if (res.draft_id != -1) { - $('.draft_'+id).remove(); + $('.draft_' + id).remove(); $('.draft_list').toggle(); } } ); }; -var send_archive = function() { +var send_archive = function () { $('.compose_post_archive').val(1); document.getElementsByClassName("smtp_send_placeholder")[0].click(); } -var save_compose_state = function(no_files, notice) { +var save_compose_state = function (no_files, notice, schedule, callback) { var no_icon = true; if (notice) { no_icon = false; } - var uploaded_files = $("input[name='uploaded_files[]']").map(function(){return $(this).val();}).get(); + var uploaded_files = $("input[name='uploaded_files[]']").map(function () { return $(this).val(); }).get(); var body = $('.compose_body').val(); var subject = $('.compose_subject').val(); var to = $('.compose_to').val(); @@ -126,36 +126,46 @@ var save_compose_state = function(no_files, notice) { var cc = $('.compose_cc').val(); var bcc = $('.compose_bcc').val(); var inreplyto = $('.compose_in_reply_to').val(); + var delivery_receipt = $('#compose_delivery_receipt').prop('checked'); var draft_id = $('.compose_draft_id').val(); - if (globals.draft_state == body+subject+to+smtp+cc+bcc+uploaded_files) { + if (globals.draft_state == body + subject + to + smtp + cc + bcc + uploaded_files) { return; } - globals.draft_state = body+subject+to+smtp+cc+bcc+uploaded_files; + globals.draft_state = body + subject + to + smtp + cc + bcc + uploaded_files; if (!body && !subject && !to && !cc && !bcc) { return; } $('.compose_draft_id').val(0) + $('.smtp_send_placeholder').prop('disabled', true); + $('.smtp_send_placeholder, .smtp_schedule_send').addClass('disabled_input'); Hm_Ajax.request( - [{'name': 'hm_ajax_hook', 'value': 'ajax_smtp_save_draft'}, - {'name': 'draft_body', 'value': body}, - {'name': 'draft_id', 'value': draft_id}, - {'name': 'draft_smtp', 'value': smtp}, - {'name': 'draft_subject', 'value': subject}, - {'name': 'draft_cc', 'value': cc}, - {'name': 'draft_bcc', 'value': bcc}, - {'name': 'draft_notice', 'value': notice}, - {'name': 'draft_in_reply_to', 'value': inreplyto}, - {'name': 'delete_uploaded_files', 'value': no_files}, - {'name': 'draft_to', 'value': to}, - {'name': 'uploaded_files', 'value': uploaded_files}], - function(res) { + [{ 'name': 'hm_ajax_hook', 'value': 'ajax_smtp_save_draft' }, + { 'name': 'draft_body', 'value': body }, + { 'name': 'draft_id', 'value': draft_id }, + { 'name': 'draft_smtp', 'value': smtp }, + { 'name': 'draft_subject', 'value': subject }, + { 'name': 'draft_cc', 'value': cc }, + { 'name': 'draft_bcc', 'value': bcc }, + { 'name': 'draft_notice', 'value': notice }, + { 'name': 'draft_in_reply_to', 'value': inreplyto }, + { 'name': 'delete_uploaded_files', 'value': no_files }, + { 'name': 'draft_to', 'value': to }, + { 'name': 'schedule', 'value': schedule }, + { 'name': 'compose_delivery_receipt', 'value': delivery_receipt }, + { 'name': 'uploaded_files', 'value': uploaded_files }], + function (res) { + $('.smtp_send_placeholder').prop('disabled', false); + $('.smtp_send_placeholder, .smtp_schedule_send').removeClass('disabled_input'); if (res.draft_id) { $('.compose_draft_id').val(res.draft_id); } if (res.draft_subject) { - $('.draft_list .draft_'+draft_id+' a').text(res.draft_subject); + $('.draft_list .draft_' + draft_id + ' a').text(res.draft_subject); + } + if (callback) { + callback(res); } }, [], @@ -163,7 +173,7 @@ var save_compose_state = function(no_files, notice) { ); }; -var toggle_recip_flds = function() { +var toggle_recip_flds = function () { var symbol = ''; if ($('.toggle_recipients').html() == '') { symbol = ''; @@ -184,7 +194,7 @@ function smtpServersPageHandler() { } } -var reset_smtp_form = function() { +var reset_smtp_form = function (save = true) { $('.compose_body').val(''); $('.compose_subject').val(''); $('.compose_to').val(''); @@ -192,45 +202,48 @@ var reset_smtp_form = function() { $('.compose_bcc').val(''); $('.ke-content', $('iframe').contents()).html(''); $('.uploaded_files').html(''); - save_compose_state(true); + $('#compose_delivery_receipt').prop('checked', false); + if (save) { + save_compose_state(true); + } }; var replace_cursor_positon = function (txtElement) { - txtElement.val('\r\n\r\n\r\n'+txtElement.val()); - txtElement.prop('selectionEnd',0); + txtElement.val('\r\n\r\n\r\n' + txtElement.val()); + txtElement.prop('selectionEnd', 0); txtElement.focus(); } var init_resumable_upload = function () { var r = new Resumable({ - target:'?page=compose&hm_ajax_hook=ajax_upload_chunk&draft_smtp=' + $(".compose_server").val(), - testTarget:'?page=compose&hm_ajax_hook=ajax_get_test_chunk&draft_smtp=' + $(".compose_server").val(), + target: '?page=compose&hm_ajax_hook=ajax_upload_chunk&draft_smtp=' + $(".compose_server").val(), + testTarget: '?page=compose&hm_ajax_hook=ajax_get_test_chunk&draft_smtp=' + $(".compose_server").val(), testMethod: 'POST', headers: { 'X-Requested-with': 'xmlhttprequest' } }); r.assignBrowse(document.getElementsByClassName('compose_attach_button')); - r.on('fileAdded', function(file, event){ - $('.uploaded_files').append('' - +file.fileName+''+file.file.type+' ' + (Math.round((file.file.size/1024) * 100)/100) + 'KB ' - +'Pause' - +'
'); + r.on('fileAdded', function (file, event) { + $('.uploaded_files').append('' + + file.fileName + '' + file.file.type + ' ' + (Math.round((file.file.size / 1024) * 100) / 100) + 'KB ' + + 'Pause' + + '
'); r.upload() $('.pause_upload').on('click', function (e) { e.preventDefault(); r.pause(); }); - $('.resume_upload').on('click', function(e) { + $('.resume_upload').on('click', function (e) { e.preventDefault(); $('.remove_attachment').css('display', 'none'); $('.pause_upload').css('display', ''); $('.resume_upload').css('display', 'none'); r.upload(); }); - $('.remove_attachment').on('click', function(e) { + $('.remove_attachment').on('click', function (e) { e.preventDefault(); var fileUniqueId = $(this).attr('id').replace('remove-', ''); file = r.getFromUniqueIdentifier(fileUniqueId); @@ -241,27 +254,27 @@ var init_resumable_upload = function () { $(this).parent().parent().remove(); }); }); - r.on('fileProgress', function(file) { + r.on('fileProgress', function (file) { var progress = Math.floor(file.progress() * 100); - $('#progress-' + file.uniqueIdentifier).css('width', progress+'%'); + $('#progress-' + file.uniqueIdentifier).css('width', progress + '%'); }); - r.on('fileSuccess', function(file) { + r.on('fileSuccess', function (file) { $('.remove_attachment').css('display', ''); $('.pause_upload').css('display', 'none'); $('.resume_upload').css('display', 'none'); - $('#tr-'+file.uniqueIdentifier).append(''); + $('#tr-' + file.uniqueIdentifier).append(''); $('#progress-bar-' + file.uniqueIdentifier).css('background-color', 'green'); $('#progress-' + file.uniqueIdentifier).parent().css('opacity', '0'); }); - r.on('fileError', function(file, message) { + r.on('fileError', function (file, message) { $('#progress-bar-' + file.uniqueIdentifier).css('background-color', 'red'); }); - r.on('pause', function() { + r.on('pause', function () { $('.remove_attachment').css('display', 'none'); $('.pause_upload').css('display', 'none'); $('.resume_upload').css('display', ''); }); - $('.remove_attachment').on('click', function(e) { + $('.remove_attachment').on('click', function (e) { e.preventDefault(); var fileUniqueId = $(this).attr('id').replace('remove-', ''); $(this).parent().parent().next('tr').remove(); @@ -271,30 +284,30 @@ var init_resumable_upload = function () { }); } -var move_recipient_to_section = function(e) { +var move_recipient_to_section = function (e) { e.preventDefault(); var id = e.dataTransfer.getData("text"); var target = $(e.target); if (!target.hasClass('compose_container')) { target = target.closest('.compose_container'); } - target.find('.bubbles').append($('#'+id)); + target.find('.bubbles').append($('#' + id)); var input = target.find('input'); input.focus(); resize_input(input[0]); }; -var allow_drop = function(e) { +var allow_drop = function (e) { e.preventDefault(); }; -var drag = function(e) { +var drag = function (e) { e.dataTransfer.setData('text', e.target.id); }; -var bubbles_to_text = function(input) { +var bubbles_to_text = function (input) { var value = ''; - $(input).prev().children().each(function() { + $(input).prev().children().each(function () { if (value) { value = value + ', '; } @@ -310,13 +323,13 @@ var bubbles_to_text = function(input) { $(input).css('width', '95%'); }; -var resize_input = function(input) { +var resize_input = function (input) { $(input).css('width', 'auto'); var input_width = $(input).parent().outerWidth() - $(input).position().left; $(input).css('width', input_width); }; -var text_to_bubbles = function(input) { +var text_to_bubbles = function (input) { var contact_id = input.getAttribute("data-id"); var contact_type = input.getAttribute("data-type"); var contact_source = input.getAttribute("data-source"); @@ -342,8 +355,8 @@ var text_to_bubbles = function(input) { }; var bubble_index = 0; -var append_bubble = function(value, to, id, type, source) { - var bubble = '
'+value+'×
'; +var append_bubble = function (value, to, id, type, source) { + var bubble = '
' + value + '×
'; $(to).prev().append(bubble); bubble_index++; }; @@ -370,17 +383,17 @@ var toggle_bubble_dropdown = function (element) { dropdownContent.classList.toggle('show'); } -var copy_text_to_clipboard = function(e) { +var copy_text_to_clipboard = function (e) { navigator.clipboard.writeText(e.dataset.value); $(".bubble_dropdown-content").remove(); } -var is_valid_recipient = function(recipient) { +var is_valid_recipient = function (recipient) { var valid_regex = /^[\p{L}|\d' ]*(<)?[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*(>)?$/u; return recipient.match(valid_regex); }; -var process_compose_form = function(){ +var process_compose_form = function () { var msg_uid = getMessageUidParam(); var detail = Hm_Utils.parse_folder_path(getListPathParam(), 'imap'); var class_name = 'imap_' + detail.server_id + '_' + msg_uid + '_' + detail.folder; @@ -398,10 +411,10 @@ var process_compose_form = function(){ $('.smtp_send_archive').addClass('disabled_input'); $('.smtp_send').on("click", function () { return false; }); } -var force_send_message = function() { +var force_send_message = function () { // Check if the force_send input already exists var forceSendInput = document.getElementById('force_send'); - if (! forceSendInput) { + if (!forceSendInput) { // Create a hidden input element var hiddenInput = document.createElement('input'); hiddenInput.type = 'hidden'; @@ -416,11 +429,11 @@ var force_send_message = function() { } function smtpSettingsPageHandler() { - $('#clear_chunks_button').on('click', function(e) { + $('#clear_chunks_button').on('click', function (e) { e.preventDefault(); Hm_Ajax.request( - [{'name': 'hm_ajax_hook', 'value': 'ajax_clear_attachment_chunks'}], - function(res) { + [{ 'name': 'hm_ajax_hook', 'value': 'ajax_clear_attachment_chunks' }], + function (res) { }, []