Fix showing duplicated messages

This commit also has some other changes sprinkled in but the main
effect is that messages are only shown precisely once. Next stage must
be to move away from serv_got_im and friends.
This commit is contained in:
2021-01-12 00:04:46 +00:00
parent 36b6b37e78
commit 6d4454f356
3 changed files with 51 additions and 20 deletions

View File

@@ -14,7 +14,7 @@
#define IMEX_RECEIVED_MESSAGE "Setup message received. To apply it, reply with:\nIMEX: %d nnnn-nnnn-nnnn-nnnn-nnnn-nnnn-nnnn-nnnn-nnnn\nNo whitespace in the setup-code!"
void delta_recv_im(DeltaConnectionData *conn, uint32_t msg_id);
void delta_recv_im(DeltaConnectionData *conn, dc_msg_t *msg);
void
_transpose_config(dc_context_t *mailbox, PurpleAccount *acct)
@@ -59,6 +59,7 @@ typedef struct {
// Used by delta_process_incoming_message
uint32_t msg_id;
gboolean msg_changed;
// Used by delta_process_connection_state
int connection_state;
@@ -71,8 +72,9 @@ delta_process_incoming_message(void *data)
g_assert(pr != NULL);
g_assert(pr->conn != NULL);
delta_recv_im(pr->conn, pr->msg_id);
dc_msg_t *msg = dc_get_msg(pr->conn->mailbox, pr->msg_id);
delta_recv_im(pr->conn, msg);
dc_msg_unref(msg);
g_free(data);
return FALSE;
@@ -107,19 +109,24 @@ delta_process_fresh_messages(void *data)
ProcessRequest *pr = (ProcessRequest *)data;
g_assert(pr != NULL);
g_assert(pr->conn != NULL);
g_assert(pr->conn->mailbox != NULL);
dc_context_t *mailbox = pr->conn->mailbox;
g_assert(mailbox != NULL);
// Spot any messages received while offline
dc_array_t *fresh_msgs = dc_get_fresh_msgs(pr->conn->mailbox);
dc_array_t *fresh_msgs = dc_get_fresh_msgs(mailbox);
size_t fresh_count = dc_array_get_cnt(fresh_msgs);
purple_debug_info(PLUGIN_ID, "fresh_count: %zu\n", fresh_count);
for(size_t i = 0; i < fresh_count; i++) {
delta_recv_im(pr->conn, dc_array_get_id(fresh_msgs, i));
uint32_t msg_id = dc_array_get_id(fresh_msgs, i);
dc_msg_t *msg = dc_get_msg(mailbox, msg_id);
delta_recv_im(pr->conn, msg);
}
g_free(fresh_msgs);
dc_array_unref(fresh_msgs);
return FALSE;
}
@@ -194,8 +201,10 @@ delta_event_handler(void *context)
pr = delta_build_process_request(conn);
if (msg_id) {
// FIXME: they won't all be incoming. Some will be changed
// FIXME: for now, only display IMEX setup messages to avoid duplicates
pr->msg_id = msg_id;
pr->msg_changed = TRUE;
purple_timeout_add(0, delta_process_incoming_message, pr);
} else {
purple_timeout_add(0, delta_process_fresh_messages, pr);
@@ -419,11 +428,11 @@ next:
}
g_free(stripped_message);
return 1; // success; echo the message to the chat window
return 0; // success; don't echo the message to the chat window since we display it anyway
}
void
delta_recv_im(DeltaConnectionData *conn, uint32_t msg_id)
delta_recv_im(DeltaConnectionData *conn, dc_msg_t *msg)
{
dc_context_t *mailbox = conn->mailbox;
g_assert(mailbox != NULL);
@@ -431,11 +440,12 @@ delta_recv_im(DeltaConnectionData *conn, uint32_t msg_id)
PurpleConnection *pc = conn->pc;
g_assert(pc != NULL);
dc_msg_t *msg = dc_get_msg(mailbox, msg_id);
uint32_t msg_id = dc_msg_get_id(msg);
int viewtype = dc_msg_get_viewtype(msg);
time_t timestamp = dc_msg_get_timestamp(msg);
char *text = dc_msg_get_text(msg);
uint32_t chat_id = dc_msg_get_chat_id(msg);
dc_contact_t *from = dc_get_contact(mailbox, dc_msg_get_from_id(msg));
dc_chat_t *chat = dc_get_chat(mailbox, chat_id);
dc_array_t *contacts = dc_get_chat_contacts(mailbox, chat_id);
int num_contacts = dc_array_get_cnt(contacts);
@@ -468,14 +478,21 @@ delta_recv_im(DeltaConnectionData *conn, uint32_t msg_id)
who = dc_chat_get_name(chat);
}
int flags = PURPLE_MESSAGE_RECV;
int flags = 0;
int state = dc_msg_get_state(msg);
if (state == DC_STATE_IN_FRESH || state == DC_STATE_IN_NOTICED || state == DC_STATE_IN_SEEN) {
flags |= PURPLE_MESSAGE_RECV;
} else {
flags |= PURPLE_MESSAGE_SEND;
}
// FIXME: as a massive hack, convert IMEX setup messages into a text message
// prompting the user how to trigger the IMEX filter in outgoing messages.
if (dc_msg_is_setupmessage(msg)) {
purple_debug_info(PLUGIN_ID, "Receiving IMEX: ID=%d\n", msg_id);
viewtype = DC_MSG_TEXT;
g_free(text);
dc_str_unref(text);
text = g_strndup("", 1024);
g_assert(text != NULL);
@@ -519,18 +536,25 @@ delta_recv_im(DeltaConnectionData *conn, uint32_t msg_id)
text = g_strdup_printf("<img id='%d'>", image_id);
}
serv_got_im(pc, who, text, flags, timestamp);
char *name = dc_contact_get_name(from);
int msglen = strlen(name) + 3 + strlen(text);
char *msgtext = malloc(msglen);
g_snprintf(msgtext, msglen, "%s: %s", name, text);
serv_got_im(pc, who, msgtext, flags, timestamp);
if (image_id > 0) {
purple_imgstore_unref_by_id(image_id);
}
dc_markseen_msgs(mailbox, &msg_id, 1);
g_free(who);
g_free(msgtext);
dc_str_unref(who);
dc_str_unref(name);
dc_contact_unref(contact);
out:
g_free(text);
dc_msg_unref(msg);
dc_str_unref(text);
dc_chat_unref(chat);
dc_array_unref(contacts);
}