I#122 - Avoid delayed message send when editing the Outbox message

Closes https://gitlab.gnome.org/GNOME/evolution/issues/122
This commit is contained in:
Milan Crha
2018-09-10 17:44:17 +02:00
parent b8fea6e045
commit c021214d75
4 changed files with 110 additions and 24 deletions

View File

@ -2568,13 +2568,11 @@ e_mail_session_schedule_outbox_flush (EMailSession *session,
}
g_mutex_lock (&session->priv->preparing_flush_lock);
if (session->priv->outbox_flush_id > 0) {
g_source_remove (session->priv->outbox_flush_id);
session->priv->outbox_flush_id = 0;
if (!session->priv->outbox_flush_id) {
/* Do not reschedule the timer, it will be rescheduled
when needed after the flush attempt */
session->priv->outbox_flush_id = e_named_timeout_add_seconds (60 * delay_minutes, mail_session_flush_outbox_timeout_cb, session);
}
session->priv->outbox_flush_id = e_named_timeout_add_seconds (60 * delay_minutes, mail_session_flush_outbox_timeout_cb, session);
g_mutex_unlock (&session->priv->preparing_flush_lock);
}

View File

@ -908,6 +908,27 @@ exit:
/* ** SEND MAIL QUEUE ***************************************************** */
static void
maybe_schedule_next_flush (EMailSession *session,
time_t nearest_next_flush)
{
gint delay_seconds, delay_minutes;
if (!session || nearest_next_flush <= 0)
return;
delay_seconds = nearest_next_flush - time (NULL);
if (delay_seconds <= 0)
delay_seconds = 1;
delay_minutes = delay_seconds / 60 + ((delay_seconds % 60) > 0 ? 1 : 0);
if (!delay_minutes)
delay_minutes = 1;
e_mail_session_schedule_outbox_flush (session, delay_minutes);
}
static void
report_status (struct _send_queue_msg *m,
enum camel_filter_status_t status,
@ -934,8 +955,8 @@ send_queue_exec (struct _send_queue_msg *m,
{
CamelFolder *sent_folder;
GPtrArray *uids, *send_uids = NULL;
gint i, j;
time_t delay_send = 0;
gint i, j, delay_flush = 0;
time_t delay_send = 0, nearest_next_flush = 0;
GError *local_error = NULL;
d (printf ("sending queue\n"));
@ -945,7 +966,7 @@ send_queue_exec (struct _send_queue_msg *m,
settings = e_util_ref_settings ("org.gnome.evolution.mail");
if (g_settings_get_boolean (settings, "composer-use-outbox")) {
gint delay_flush = g_settings_get_int (settings, "composer-delay-outbox-flush");
delay_flush = g_settings_get_int (settings, "composer-delay-outbox-flush");
if (delay_flush > 0)
delay_send = time (NULL) - (60 * delay_flush);
@ -966,15 +987,27 @@ send_queue_exec (struct _send_queue_msg *m,
info = camel_folder_get_message_info (m->queue, uids->pdata[i]);
if (info) {
if ((camel_message_info_get_flags (info) & CAMEL_MESSAGE_DELETED) == 0 &&
(!delay_send || camel_message_info_get_date_sent (info) <= delay_send))
send_uids->pdata[j++] = uids->pdata[i];
if (!(camel_message_info_get_flags (info) & CAMEL_MESSAGE_DELETED)) {
gboolean is_editing = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (info), MAIL_USER_KEY_EDITING)) != 0;
if (!delay_send || (!is_editing && camel_message_info_get_date_sent (info) <= delay_send)) {
send_uids->pdata[j++] = uids->pdata[i];
} else if (!is_editing && (!nearest_next_flush || nearest_next_flush > camel_message_info_get_date_sent (info))) {
nearest_next_flush = camel_message_info_get_date_sent (info);
}
}
g_clear_object (&info);
}
}
if (nearest_next_flush > 0)
nearest_next_flush += (delay_flush * 60);
send_uids->len = j;
if (send_uids->len == 0) {
maybe_schedule_next_flush (m->session, nearest_next_flush);
/* nothing to send */
camel_folder_free_uids (m->queue, uids);
g_ptr_array_free (send_uids, TRUE);
@ -1077,6 +1110,8 @@ send_queue_exec (struct _send_queue_msg *m,
camel_folder_synchronize_sync (sent_folder, FALSE, NULL, NULL);
camel_operation_pop_message (cancellable);
maybe_schedule_next_flush (m->session, nearest_next_flush);
}
static void

View File

@ -33,6 +33,9 @@ G_BEGIN_DECLS
#include <libemail-engine/e-mail-session.h>
#include <libemail-engine/mail-mt.h>
/* Used to "tag" messages as being edited */
#define MAIL_USER_KEY_EDITING "mail-user-key-editing"
void mail_transfer_messages (EMailSession *session,
CamelFolder *source,
GPtrArray *uids,

View File

@ -1173,6 +1173,26 @@ em_utils_composer_save_to_drafts_cb (EMsgComposer *composer,
g_free (identity_uid);
}
static void
emcu_manage_flush_outbox (EMailSession *session)
{
GSettings *settings;
g_return_if_fail (E_IS_MAIL_SESSION (session));
settings = e_util_ref_settings ("org.gnome.evolution.mail");
if (g_settings_get_boolean (settings, "composer-use-outbox")) {
gint delay_flush = g_settings_get_int (settings, "composer-delay-outbox-flush");
if (delay_flush == 0) {
e_mail_session_flush_outbox (session);
} else if (delay_flush > 0) {
e_mail_session_schedule_outbox_flush (session, delay_flush);
}
}
g_object_unref (settings);
}
static void
composer_save_to_outbox_completed (GObject *source_object,
GAsyncResult *result,
@ -1183,7 +1203,6 @@ composer_save_to_outbox_completed (GObject *source_object,
EAlertSink *alert_sink;
GCancellable *cancellable;
AsyncContext *async_context;
GSettings *settings;
GError *local_error = NULL;
session = E_MAIL_SESSION (source_object);
@ -1224,17 +1243,7 @@ composer_save_to_outbox_completed (GObject *source_object,
G_OBJECT (activity), (GWeakNotify)
gtk_widget_destroy, async_context->composer);
settings = e_util_ref_settings ("org.gnome.evolution.mail");
if (g_settings_get_boolean (settings, "composer-use-outbox")) {
gint delay_flush = g_settings_get_int (settings, "composer-delay-outbox-flush");
if (delay_flush == 0) {
e_mail_session_flush_outbox (session);
} else if (delay_flush > 0) {
e_mail_session_schedule_outbox_flush (session, delay_flush);
}
}
g_object_unref (settings);
emcu_manage_flush_outbox (session);
exit:
async_context_free (async_context);
@ -2108,6 +2117,31 @@ emcu_message_references_existing_account (CamelMimeMessage *message,
return res;
}
typedef struct _OutboxData {
CamelSession *session;
CamelMessageInfo *info;
} OutboxData;
static void
outbox_data_free (gpointer ptr)
{
OutboxData *od = ptr;
if (od) {
if (od->info) {
g_object_set_data (G_OBJECT (od->info), MAIL_USER_KEY_EDITING, NULL);
if (od->session && !(camel_message_info_get_flags (od->info) & CAMEL_MESSAGE_DELETED)) {
emcu_manage_flush_outbox (E_MAIL_SESSION (od->session));
}
}
g_clear_object (&od->session);
g_clear_object (&od->info);
g_free (od);
}
}
/**
* em_utils_edit_message:
* @composer: an #EMsgComposer
@ -2237,9 +2271,25 @@ em_utils_edit_message (EMsgComposer *composer,
g_free (folder_uri);
} else if (message_uid != NULL && folder_is_outbox) {
CamelMessageInfo *info;
e_msg_composer_set_header (
composer, "X-Evolution-Replace-Outbox-UID",
message_uid);
info = camel_folder_get_message_info (folder, message_uid);
if (info) {
OutboxData *od;
/* This makes the message not to send it while it's being edited */
g_object_set_data (G_OBJECT (info), MAIL_USER_KEY_EDITING, GINT_TO_POINTER (1));
od = g_new0 (OutboxData, 1);
od->session = e_msg_composer_ref_session (composer);
od->info = info; /* takes ownership of it */
g_object_set_data_full (G_OBJECT (composer), MAIL_USER_KEY_EDITING, od, outbox_data_free);
}
}
composer_set_no_change (composer);