--- a/purplesatoriconnection.c Fri Aug 08 09:46:55 2025 +0800 +++ b/purplesatoriconnection.c Sat Aug 09 00:19:03 2025 +0800 @@ -27,6 +27,7 @@ #include <libsoup/soup-message.h> #include <libsoup/soup-types.h> #include <libsoup/soup-websocket-connection.h> +#include <time.h> #include "purplesatoriconnection.h" #include "purplesatoriprotocolcontacts.h" @@ -46,6 +47,43 @@ PURPLE_TYPE_CONNECTION, G_TYPE_FLAG_FINAL, {}); /****************************************************************************** + * PurpleConversation Helpers + *****************************************************************************/ + +static void +purple_satori_handle_pending_message(PurpleSatoriConnection *con, + SatoriUser *user, + SatoriChannel *chan, + JsonObject *msg_obj) +{ + PurpleConversation *conversation = \ + purple_satori_add_conversation_from_chan(con, chan); + PurpleConversationMember *mbr = \ + purple_satori_add_conversation_member_from_user( + con, conversation, user); + + const gchar *id = json_object_get_string_member_with_default( + msg_obj, "id", NULL); + const gchar *text = json_object_get_string_member_with_default( + msg_obj, "content", "Invalid Message"); + + time_t created_at = json_object_get_int_member_with_default( + msg_obj, "created_at", 0) / 1000; /* timestamp in mS */ + + PurpleMessage *message = purple_message_new(mbr, text); + if (id) purple_message_set_id(message, id); + + if (created_at) { + GDateTime *ts = g_date_time_new_from_unix_local(created_at); + purple_message_set_timestamp(message, ts); + g_date_time_unref(ts); + } else purple_message_set_timestamp_now(message); + + purple_conversation_write_message(conversation, message); + g_clear_object(&message); +} + +/****************************************************************************** * PurpleConnection WS Callbacks *****************************************************************************/ @@ -107,6 +145,39 @@ ? user.nick : user.name); satori_refresh_buddy_contacts(con, NULL); + satori_refresh_conversations(con, NULL); + break; + } + + case SATORI_WEBSOCKET_OP_EVENT: + { + const gchar *type = json_object_get_string_member(body, "type"); + if (purple_strequal(type, "message-created")) { + JsonObject *obj = json_object_get_object_member( + body, "message"); + + JsonObject *usr_obj = json_object_get_object_member( + json_object_get_object_member(body, "member"), + "user"); + + if (!usr_obj) + usr_obj = \ + json_object_get_object_member(body, "user"); + + if (!usr_obj) break; + + JsonObject *chan_obj = \ + json_object_get_object_member(body, "channel"); + + if (!chan_obj) break; + + SatoriChannel chan; + SatoriUser usr; + satori_channel_from_json(chan_obj, &chan); + satori_user_from_json(usr_obj, &usr); + + purple_satori_handle_pending_message(con, &usr, &chan, obj); + } break; } @@ -115,8 +186,6 @@ } - g_print("op = %d\n", op); - g_object_unref(parser); }