summaryrefslogtreecommitdiff
path: root/program
diff options
context:
space:
mode:
authorAleksander Machniak <alec@alec.pl>2015-02-25 08:07:11 -0500
committerAleksander Machniak <alec@alec.pl>2015-02-25 08:07:11 -0500
commitc5c8e73351c38ece1b3814a8c82a0439e7424fc4 (patch)
treef8141b3fc2f3afab4f724b028ca1a20aec58fbdb /program
parent216b31dd99b54e7be3df8feebeafae72e423bb1c (diff)
Improved handling of storage errors after message is sent
After sending a message it is stored in Sent folder, this operation may fail, e.g. because of "over quota" error. In such a case we'll not close the compose window, but display the error and, if user clicks Send/Save button, we'll display a dialog informing about the situation and providing an option to try the save operation again.
Diffstat (limited to 'program')
-rw-r--r--program/js/app.js45
-rw-r--r--program/localization/en_US/messages.inc1
-rw-r--r--program/steps/mail/compose.inc3
-rw-r--r--program/steps/mail/sendmail.inc39
4 files changed, 66 insertions, 22 deletions
diff --git a/program/js/app.js b/program/js/app.js
index e818955bd..56d07f37e 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -654,7 +654,7 @@ function rcube_webmail()
// check input before leaving compose step
if (this.task == 'mail' && this.env.action == 'compose' && $.inArray(command, this.env.compose_commands) < 0 && !this.env.server_error) {
- if (this.cmp_hash != this.compose_field_hash() && !confirm(this.get_label('notsentwarning')))
+ if (!this.env.is_sent && this.cmp_hash != this.compose_field_hash() && !confirm(this.get_label('notsentwarning')))
return false;
// remove copy from local storage if compose screen is left intentionally
@@ -1115,7 +1115,7 @@ function rcube_webmail()
break;
case 'send':
- if (!props.nocheck && !this.check_compose_input(command))
+ if (!props.nocheck && !this.env.is_sent && !this.check_compose_input(command))
break;
// Reset the auto-save timer
@@ -3489,15 +3489,35 @@ function rcube_webmail()
.attr({ 'autocomplete': 'off', 'aria-autocomplete': 'list', 'aria-expanded': 'false', 'role': 'combobox' });
};
- this.submit_messageform = function(draft)
+ this.submit_messageform = function(draft, saveonly)
{
var form = this.gui_objects.messageform;
if (!form)
return;
+ // the message has been sent but not saved, ask the user what to do
+ if (!saveonly && this.env.is_sent) {
+ return this.show_popup_dialog(this.get_label('messageissent'), '',
+ [{
+ text: this.get_label('save'),
+ 'class': 'mainaction',
+ click: function() {
+ ref.submit_messageform(false, true);
+ $(this).dialog('close');
+ }
+ },
+ {
+ text: this.get_label('cancel'),
+ click: function() {
+ $(this).dialog('close');
+ }
+ }]
+ );
+ }
+
// all checks passed, send message
- var msgid = this.set_busy(true, draft ? 'savingmessage' : 'sendingmessage'),
+ var msgid = this.set_busy(true, draft || saveonly ? 'savingmessage' : 'sendingmessage'),
lang = this.spellcheck_lang(),
files = [];
@@ -3511,6 +3531,10 @@ function rcube_webmail()
form.action = this.add_url(form.action, '_lang', lang);
form.action = this.add_url(form.action, '_framed', 1);
+ if (saveonly) {
+ form.action = this.add_url(form.action, '_saveonly', 1);
+ }
+
// register timer to notify about connection timeout
this.submit_timer = setTimeout(function(){
ref.set_busy(false, null, msgid);
@@ -4358,13 +4382,14 @@ function rcube_webmail()
};
// action executed after mail is sent
- this.sent_successfully = function(type, msg, folders)
+ this.sent_successfully = function(type, msg, folders, save_error)
{
this.display_message(msg, type);
this.compose_skip_unsavedcheck = true;
if (this.env.extwin) {
- this.lock_form(this.gui_objects.messageform);
+ if (!save_error)
+ this.lock_form(this.gui_objects.messageform);
var filter = {task: 'mail', action: ''},
rc = this.opener(false, filter) || this.opener(true, filter);
@@ -4377,12 +4402,16 @@ function rcube_webmail()
}
}
- setTimeout(function() { window.close(); }, 1000);
+ if (!save_error)
+ setTimeout(function() { window.close(); }, 1000);
}
- else {
+ else if (!save_error) {
// before redirect we need to wait some time for Chrome (#1486177)
setTimeout(function() { ref.list_mailbox(); }, 500);
}
+
+ if (save_error)
+ this.env.is_sent = true;
};
diff --git a/program/localization/en_US/messages.inc b/program/localization/en_US/messages.inc
index e5b368f22..e0de3654e 100644
--- a/program/localization/en_US/messages.inc
+++ b/program/localization/en_US/messages.inc
@@ -179,5 +179,6 @@ $messages['parentnotwritable'] = 'Unable to create/move folder into selected par
$messages['messagetoobig'] = 'The message part is too big to process it.';
$messages['attachmentvalidationerror'] = 'WARNING! This attachment is suspicious because its type doesn\'t match the type declared in the message. If you do not trust the sender, you shouldn\'t open it in the browser because it may contain malicious contents.<br/><br/><em>Expected: $expected; found: $detected</em>';
$messages['noscriptwarning'] = 'Warning: This webmail service requires Javascript! In order to use it please enable Javascript in your browser\'s settings.';
+$messages['messageissent'] = 'The message was already sent, but not saved yet. Do you want to save it now?';
?>
diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc
index db4efc7ce..4c3ecfbc0 100644
--- a/program/steps/mail/compose.inc
+++ b/program/steps/mail/compose.inc
@@ -83,7 +83,7 @@ $OUTPUT->add_label('nosubject', 'nosenderwarning', 'norecipientwarning', 'nosubj
'messagesaved', 'converting', 'editorwarning', 'searching', 'uploading', 'uploadingmany',
'fileuploaderror', 'sendmessage', 'newresponse', 'responsename', 'responsetext', 'save',
'savingresponse', 'restoresavedcomposedata', 'restoremessage', 'delete', 'restore', 'ignore',
- 'selectimportfile');
+ 'selectimportfile', 'messageissent');
$OUTPUT->set_pagetitle($RCMAIL->gettext('compose'));
@@ -93,6 +93,7 @@ $OUTPUT->set_env('mailbox', $RCMAIL->storage->get_folder());
$OUTPUT->set_env('top_posting', intval($RCMAIL->config->get('reply_mode')) > 0);
$OUTPUT->set_env('recipients_separator', trim($RCMAIL->config->get('recipients_separator', ',')));
$OUTPUT->set_env('save_localstorage', (bool)$RCMAIL->config->get('compose_save_localstorage'));
+$OUTPUT->set_env('is_sent', false);
$drafts_mbox = $RCMAIL->config->get('drafts_mbox');
$config_show_sig = $RCMAIL->config->get('show_sig', 1);
diff --git a/program/steps/mail/sendmail.inc b/program/steps/mail/sendmail.inc
index 4f672ac8b..e90b0ef61 100644
--- a/program/steps/mail/sendmail.inc
+++ b/program/steps/mail/sendmail.inc
@@ -24,7 +24,8 @@
$OUTPUT->reset();
$OUTPUT->framed = TRUE;
-$savedraft = !empty($_POST['_draft']) ? true : false;
+$saveonly = !empty($_GET['_saveonly']);
+$savedraft = !empty($_POST['_draft']) && !$saveonly;
$sendmail_delay = (int) $RCMAIL->config->get('sendmail_delay');
$drafts_mbox = $RCMAIL->config->get('drafts_mbox');
@@ -689,24 +690,36 @@ else {
// we'll refresh the list if currently opened folder is one of them (#1490238)
$folders = array();
- if (in_array($COMPOSE['mode'], array('reply', 'forward', 'draft'))) {
- $folders[] = $COMPOSE['mailbox'];
- }
- if (!empty($COMPOSE['param']['draft_uid']) && $drafts_mbox) {
- $folders[] = $drafts_mbox;
+ if (!$saveonly) {
+ if (in_array($COMPOSE['mode'], array('reply', 'forward', 'draft'))) {
+ $folders[] = $COMPOSE['mailbox'];
+ }
+ if (!empty($COMPOSE['param']['draft_uid']) && $drafts_mbox) {
+ $folders[] = $drafts_mbox;
+ }
}
- rcmail_compose_cleanup($COMPOSE_ID);
- $OUTPUT->command('remove_compose_data', $COMPOSE_ID);
-
if ($store_folder && !$saved) {
- $RCMAIL->display_server_error('errorsavingsent', null, null, array('prefix' => true));
+ $params = $saveonly ? null : array('prefix' => true);
+ $RCMAIL->display_server_error('errorsavingsent', null, null, $params);
+ if ($saveonly) {
+ $OUTPUT->send('iframe');
+ }
+
+ $save_error = true;
}
- else if ($store_folder) {
- $folders[] = $store_target;
+ else {
+ rcmail_compose_cleanup($COMPOSE_ID);
+ $OUTPUT->command('remove_compose_data', $COMPOSE_ID);
+
+ if ($store_folder) {
+ $folders[] = $store_target;
+ }
}
- $OUTPUT->command('sent_successfully', 'confirmation', $RCMAIL->gettext('messagesent'), $folders);
+ $msg = $RCMAIL->gettext($saveonly ? 'successfullysaved' : 'messagesent');
+
+ $OUTPUT->command('sent_successfully', 'confirmation', $msg, $folders, $save_error);
}
$OUTPUT->send('iframe');