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.
pull/280/head
Aleksander Machniak 9 years ago
parent bbbd02bd6a
commit 16c326380d

@ -3,6 +3,7 @@ CHANGELOG Roundcube Webmail
- Add possibility to print contact information (of a single contact)
- Add possibility to configure max_allowed_packet value for all database engines (#1490283)
- Improved handling of storage errors after message is sent
- Fix refreshing of drafts list when sending a message which was saved in meantime (#1490238)
- Fix saving/sending emoticon images when assets_dir is set
- Fix PHP fatal error when visiting Vacation interface and there's no sieve script yet

@ -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;
};

@ -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?';
?>

@ -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);

@ -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');

Loading…
Cancel
Save