Skip to content

Commit

Permalink
Rework display of messages.
Browse files Browse the repository at this point in the history
Should help with #130 and #151.
  • Loading branch information
hoehermann committed Mar 14, 2023
1 parent f3bac71 commit 27eef20
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 58 deletions.
3 changes: 1 addition & 2 deletions src/c/bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@ struct gowhatsapp_message {
char msgtype; /// message type – see above
char subtype; /// loglevel, error severity, attachment type or online-state
char isGroup; /// this is a group chat message
char fromMe; /// this is (a copy of) an outgoing message
char system; /// this is a system-message, not user-generated
char isOutgoing; /// this is an outgoing message (echo sent from this instance)
};
typedef struct gowhatsapp_message gowhatsapp_message_t;

Expand Down
52 changes: 22 additions & 30 deletions src/c/display_message.c
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
#include "gowhatsapp.h"
#include "constants.h"

static
PurpleConversation *gowhatsapp_have_conversation(char *username, PurpleAccount *account) {
gowhatsapp_ensure_buddy_in_blist(account, username, NULL);

PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, username, account);
if (conv == NULL) {
conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, username); // MEMCHECK: caller takes ownership
}
return conv;
}

void
gowhatsapp_display_text_message(PurpleConnection *pc, gowhatsapp_message_t *gwamsg, PurpleMessageFlags flags)
{
Expand All @@ -31,35 +20,38 @@ gowhatsapp_display_text_message(PurpleConnection *pc, gowhatsapp_message_t *gwam
}
}

if (gwamsg->fromMe) {
// special handling of messages sent by self incoming from remote, addressing issue #32
// copied from EionRobb/purple-discord/blob/master/libdiscord.c
flags |= PURPLE_MESSAGE_SEND | PURPLE_MESSAGE_REMOTE_SEND | PURPLE_MESSAGE_DELAYED;
if (purple_strequal(purple_account_get_username(gwamsg->account), gwamsg->senderJid)) {
flags |= PURPLE_MESSAGE_SEND;
// Note: For outgoing messages (no matter if local echo or sent by other device),
// PURPLE_MESSAGE_SEND must be set due to how purple_conversation_write is implemented
if (!gwamsg->isOutgoing) {
// special handling of messages sent by self incoming from remote, addressing issue #32
// adjusted for Spectrum, see issue #130
flags |= PURPLE_MESSAGE_REMOTE_SEND;
}
} else {
flags |= PURPLE_MESSAGE_RECV;
}

if (gwamsg->isGroup) {
PurpleConversation *conv = gowhatsapp_enter_group_chat(pc, gwamsg->remoteJid, NULL);
if (conv != NULL) {
// participants in group chats have their senderJid supplied
const char *who = gwamsg->senderJid;
if (gwamsg->fromMe) {
who = purple_account_get_username(gwamsg->account);
}
PurpleConvChat *conv_chat = purple_conversation_get_chat_data(conv);
purple_conv_chat_write(conv_chat, who, gwamsg->text, flags, gwamsg->timestamp);
purple_serv_got_chat_in(pc, g_str_hash(gwamsg->remoteJid), gwamsg->senderJid, flags, gwamsg->text, gwamsg->timestamp);
}
} else {
if (gwamsg->fromMe) {
PurpleConversation *conv = gowhatsapp_have_conversation(gwamsg->remoteJid, gwamsg->account);
// display message sent from own account (but other device) here
purple_conversation_write(conv, gwamsg->remoteJid, gwamsg->text, flags, gwamsg->timestamp);
if (flags & PURPLE_MESSAGE_SEND) {
// display message sent from own account (other device as well as local echo)
// cannot use purple_serv_got_im since it sets the flag PURPLE_MESSAGE_RECV
PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, gwamsg->remoteJid, gwamsg->account);
if (conv == NULL) {
conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, gwamsg->account, gwamsg->remoteJid); // MEMCHECK: caller takes ownership
}
purple_conv_im_write(purple_conversation_get_im_data(conv), gwamsg->remoteJid, gwamsg->text, flags, gwamsg->timestamp);
} else {
// messages sometimes arrive before buddy has been
// created... this method will be missing a display
// name, but i don't think i ever saw one of them anyway
// messages sometimes arrive before buddy has been created
// a buddy created here may be missing a display name,
// but i don't think i ever saw one of them anyway
gowhatsapp_ensure_buddy_in_blist(gwamsg->account, gwamsg->remoteJid, gwamsg->name);
// normal mode: direct incoming message
purple_serv_got_im(pc, gwamsg->remoteJid, gwamsg->text, flags, gwamsg->timestamp);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/c/process_message.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ gowhatsapp_process_message(gowhatsapp_message_t *gwamsg)
return;
}
purple_debug_info(
GOWHATSAPP_NAME, "recieved %s (subtype %d) for account %p remote %s (isGroup %d) sender %s (alias %s, fromMe %d) sent %ld: %s\n",
GOWHATSAPP_NAME, "recieved %s (subtype %d) for account %p remote %s (isGroup %d) sender %s (alias %s, isOutgoing %d) sent %ld: %s\n",
gowhatsapp_message_type_string[gwamsg->msgtype],
gwamsg->subtype,
gwamsg->account,
gwamsg->remoteJid,
gwamsg->isGroup,
gwamsg->senderJid,
gwamsg->name,
gwamsg->fromMe,
gwamsg->isOutgoing,
gwamsg->timestamp,
gwamsg->text
);
Expand Down
1 change: 1 addition & 0 deletions src/c/purple_compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#define purple_im_conversation_new(account, from) PURPLE_CONV_IM(purple_conversation_new(PURPLE_CONV_TYPE_IM, account, from))
#define PURPLE_CONVERSATION(chatorim) ((chatorim) == NULL ? NULL : (chatorim)->conv)
#define purple_serv_got_im serv_got_im
#define purple_serv_got_chat_in serv_got_chat_in
#define purple_connection_set_flags(pc, f) ((pc)->flags = (f))
#define purple_connection_get_flags(pc) ((pc)->flags)
#define purple_connection_get_protocol purple_connection_get_prpl
Expand Down
40 changes: 20 additions & 20 deletions src/go/bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,16 +293,16 @@ func purple_disconnected(account *PurpleAccount) {
* This will display a text message.
* Single participants and group chats.
*/
func purple_display_text_message(account *PurpleAccount, remoteJid string, isGroup bool, isFromMe bool, senderJid string, pushName *string, timestamp time.Time, text string) {
func purple_display_text_message(account *PurpleAccount, remoteJid string, isGroup bool, isOutgoing bool, senderJid string, pushName *string, timestamp time.Time, text string) {
cmessage := C.struct_gowhatsapp_message{
account: account,
msgtype: C.char(C.gowhatsapp_message_type_text),
remoteJid: C.CString(remoteJid),
senderJid: C.CString(senderJid),
timestamp: C.time_t(timestamp.Unix()),
text: C.CString(text),
isGroup: bool_to_Cchar(isGroup),
fromMe: bool_to_Cchar(isFromMe),
account: account,
msgtype: C.char(C.gowhatsapp_message_type_text),
remoteJid: C.CString(remoteJid),
senderJid: C.CString(senderJid),
timestamp: C.time_t(timestamp.Unix()),
text: C.CString(text),
isGroup: bool_to_Cchar(isGroup),
isOutgoing: bool_to_Cchar(isOutgoing),
}
if pushName != nil {
cmessage.name = C.CString(*pushName)
Expand Down Expand Up @@ -349,18 +349,18 @@ func purple_update_name(account *PurpleAccount, remoteJid string, pushName strin
* while in fact the file has already been received and they may only chose
* where to store it.
*/
func purple_handle_attachment(account *PurpleAccount, remoteJid string, isGroup bool, senderJid string, isFromMe bool, data_type C.int, mimetype *string, filename string, data []byte) {
func purple_handle_attachment(account *PurpleAccount, remoteJid string, isGroup bool, senderJid string, isOutgoing bool, data_type C.int, mimetype *string, filename string, data []byte) {
cmessage := C.struct_gowhatsapp_message{
account: account,
msgtype: C.char(C.gowhatsapp_message_type_attachment),
subtype: C.char(data_type),
remoteJid: C.CString(remoteJid),
isGroup: bool_to_Cchar(isGroup),
senderJid: C.CString(senderJid),
fromMe: bool_to_Cchar(isFromMe),
name: C.CString(filename),
blob: C.CBytes(data),
blobsize: C.size_t(len(data)), // contrary to https://golang.org/pkg/builtin/#len and https://golang.org/ref/spec#Numeric_types, len returns an int of 64 bits on 32 bit Windows machines (see https://github.com/hoehermann/purple-gowhatsapp/issues/1)
account: account,
msgtype: C.char(C.gowhatsapp_message_type_attachment),
subtype: C.char(data_type),
remoteJid: C.CString(remoteJid),
isGroup: bool_to_Cchar(isGroup),
senderJid: C.CString(senderJid),
isOutgoing: bool_to_Cchar(isOutgoing),
name: C.CString(filename),
blob: C.CBytes(data),
blobsize: C.size_t(len(data)), // contrary to https://golang.org/pkg/builtin/#len and https://golang.org/ref/spec#Numeric_types, len returns an int of 64 bits on 32 bit Windows machines (see https://github.com/hoehermann/purple-gowhatsapp/issues/1)
}
if mimetype != nil {
cmessage.text = C.CString(*mimetype)
Expand Down
4 changes: 2 additions & 2 deletions src/go/handle_message.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func (handler *Handler) handle_message(message *waProto.Message, id string, sour
handler.log.Warnf("Received a message without any text.")
} else {
// note: info.PushName always denotes the sender (not the chat)
purple_display_text_message(handler.account, source.Chat.ToNonAD().String(), source.IsGroup, source.IsFromMe, source.Sender.ToNonAD().String(), name, timestamp, text)
purple_display_text_message(handler.account, source.Chat.ToNonAD().String(), source.IsGroup, false, source.Sender.ToNonAD().String(), name, timestamp, text)
handler.addToCache(CachedMessage{id: id, text: text, timestamp: timestamp})
if !source.IsFromMe && !is_historical { // do not send receipt for own messages or historical messages
handler.mark_read_defer(id, source.Chat, source.Sender)
Expand Down Expand Up @@ -167,6 +167,6 @@ func (handler *Handler) handle_attachment(message *waProto.Message, source types
// so source is known even when receiving from group chats
filename = fmt.Sprintf("%s_%s", sender.User, filename)
}
purple_handle_attachment(handler.account, chat, source.IsGroup, sender.String(), source.IsFromMe, data_type, mimetype, filename, data)
purple_handle_attachment(handler.account, chat, source.IsGroup, sender.String(), false, data_type, mimetype, filename, data)
}
}
5 changes: 3 additions & 2 deletions src/go/send_message.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ func (handler *Handler) send_text_message(recipient types.JID, isGroup bool, mes
// inject message back to self to indicate success
setting := purple_get_string(handler.account, C.GOWHATSAPP_ECHO_OPTION, C.GOWHATSAPP_ECHO_CHOICE_ON_SUCCESS)
if setting == C.GoString(C.GOWHATSAPP_ECHO_CHOICE_ON_SUCCESS) {
ownJid := "" // TODO: find out if this messes up group chats
purple_display_text_message(handler.account, recipient.ToNonAD().String(), isGroup, true, ownJid, nil, resp.Timestamp, message)
ownJid := handler.client.Store.ID.ToNonAD().String()
recipientJid := recipient.ToNonAD().String()
purple_display_text_message(handler.account, recipientJid, isGroup, true, ownJid, nil, resp.Timestamp, message)
}
handler.addToCache(CachedMessage{id: resp.ID, text: message, timestamp: resp.Timestamp})
}
Expand Down

0 comments on commit 27eef20

Please sign in to comment.