diff --git a/CMakeLists.txt b/CMakeLists.txt index 849187f..2f750f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,7 @@ add_library(tox MODULE src/tox-weechat-config.c src/tox-weechat-data.c src/tox-weechat-completion.c + src/tox-weechat-messages.c ) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -Wextra -Werror-implicit-function-declaration -Wno-unused-parameter") diff --git a/src/tox-weechat-chats.c b/src/tox-weechat-chats.c index 9ebc9d1..fc2367f 100644 --- a/src/tox-weechat-chats.c +++ b/src/tox-weechat-chats.c @@ -25,6 +25,7 @@ #include "tox-weechat.h" #include "tox-weechat-identities.h" +#include "tox-weechat-messages.h" #include "tox-weechat-utils.h" #include "tox-weechat-chats.h" @@ -195,16 +196,12 @@ tox_weechat_buffer_input_callback(void *data, const char *input_data) { struct t_tox_weechat_chat *chat = data; - - tox_send_message(chat->identity->tox, - chat->friend_number, - (uint8_t *)input_data, - strlen(input_data)); + tox_weechat_send_friend_message(chat->identity, + chat->friend_number, + input_data); char *name = tox_weechat_get_self_name_nt(chat->identity->tox); - tox_weechat_chat_print_message(chat, name, input_data); - free(name); return WEECHAT_RC_OK; diff --git a/src/tox-weechat-data.c b/src/tox-weechat-data.c index 31d8962..f74b8d0 100644 --- a/src/tox-weechat-data.c +++ b/src/tox-weechat-data.c @@ -29,6 +29,7 @@ #include "tox-weechat.h" #include "tox-weechat-identities.h" #include "tox-weechat-friend-requests.h" +#include "tox-weechat-messages.h" #include "tox-weechat-utils.h" #include "tox-weechat-data.h" @@ -38,6 +39,9 @@ const char *tox_weechat_json_key_friend_requests = "friend_requests"; const char *tox_weechat_json_friend_request_key_client_id = "client_id"; const char *tox_weechat_json_friend_request_key_message = "message"; +const char *tox_weechat_json_key_unsent_messages = "unsent_messages"; +const char *tox_weechat_json_unsent_messages_key_recipient_id = "recipient_id"; +const char *tox_weechat_json_unsent_messages_key_message = "message"; json_t *tox_weechat_json_data = NULL; @@ -67,15 +71,14 @@ tox_weechat_json_get_identity_key(struct t_tox_weechat_identity *identity) } /** - * Save an identity's data. + * Save an identity's friend requests into a json array. */ -void -tox_weechat_data_identity_save(struct t_tox_weechat_identity *identity) +json_t * +tox_weechat_data_friend_requests_json(struct t_tox_weechat_identity *identity) { - json_t *json_data = json_object(); json_t *friend_request_array = json_array(); - if (!json_data || !friend_request_array) - return; + if (!friend_request_array) + return NULL; for (struct t_tox_weechat_friend_request *request = identity->friend_requests; request; @@ -104,10 +107,70 @@ tox_weechat_data_identity_save(struct t_tox_weechat_identity *identity) json_decref(json_request); } + return friend_request_array; +} + +/** + * Save an identity's unsent messages into a json array. + */ +json_t * +tox_weechat_data_unsent_messages_json(struct t_tox_weechat_identity *identity) +{ + json_t *unsent_messages_array = json_array(); + if (!unsent_messages_array) + return NULL; + + for (struct t_tox_weechat_unsent_message *message = identity->unsent_messages; + message; + message = message->next_message) + { + char hex_id[TOX_CLIENT_ID_SIZE * 2 + 1]; + tox_weechat_bin2hex(message->recipient_id, TOX_CLIENT_ID_SIZE, hex_id); + + json_t *json_message = json_object(); + json_t *json_id = json_string(hex_id); + json_t *json_message_data = json_string(message->message); + if (!json_message || !json_id || !json_message_data) + break; + + json_object_set(json_message, + tox_weechat_json_unsent_messages_key_recipient_id, + json_id); + json_decref(json_id); + + json_object_set(json_message, + tox_weechat_json_unsent_messages_key_message, + json_message_data); + json_decref(json_message_data); + + json_array_append(unsent_messages_array, json_message); + json_decref(json_message); + } + + return unsent_messages_array; +} + +/** + * Save an identity's data. + */ +void +tox_weechat_data_identity_save(struct t_tox_weechat_identity *identity) +{ + json_t *json_data = json_object(); + if (!json_data) + return; + + json_t *friend_requests = tox_weechat_data_friend_requests_json(identity); json_object_set(json_data, tox_weechat_json_key_friend_requests, - friend_request_array); - json_decref(friend_request_array); + friend_requests); + json_decref(friend_requests); + + json_t *unsent_messages = tox_weechat_data_unsent_messages_json(identity); + json_object_set(json_data, + tox_weechat_json_key_unsent_messages, + unsent_messages); + json_decref(unsent_messages); char *identity_key = tox_weechat_json_get_identity_key(identity); json_object_set(tox_weechat_json_data, identity_key, json_data); @@ -115,6 +178,62 @@ tox_weechat_data_identity_save(struct t_tox_weechat_identity *identity) json_decref(json_data); } +/** + * Load friend requests from a json array. + */ +void +tox_weechat_data_load_friend_requests(struct t_tox_weechat_identity *identity, + json_t *friend_requests) +{ + tox_weechat_friend_request_free_identity(identity); + + size_t index; + json_t *json_request; + json_array_foreach(friend_requests, index, json_request) + { + char client_id[TOX_CLIENT_ID_SIZE]; + const char *message; + + json_t *json_id = json_object_get(json_request, + tox_weechat_json_friend_request_key_client_id); + json_t *json_message = json_object_get(json_request, + tox_weechat_json_friend_request_key_message); + + tox_weechat_hex2bin(json_string_value(json_id), TOX_CLIENT_ID_SIZE * 2, client_id); + message = json_string_value(json_message); + + tox_weechat_friend_request_add(identity, + (uint8_t *)client_id, + message); + } +} + +/** + * Load unsent messages from a json array. + */ +void +tox_weechat_data_load_unsent_messages(struct t_tox_weechat_identity *identity, + json_t *friend_requests) +{ + size_t index; + json_t *json_message; + json_array_foreach(friend_requests, index, json_message) + { + char client_id[TOX_CLIENT_ID_SIZE]; + const char *message; + + json_t *json_id = json_object_get(json_message, + tox_weechat_json_unsent_messages_key_recipient_id); + json_t *json_message_data = json_object_get(json_message, + tox_weechat_json_unsent_messages_key_message); + + tox_weechat_hex2bin(json_string_value(json_id), TOX_CLIENT_ID_SIZE * 2, client_id); + message = json_string_value(json_message_data); + + // TODO + } +} + /** * Load an identity's data from a JSON object. */ @@ -125,33 +244,15 @@ tox_weechat_data_identity_load(struct t_tox_weechat_identity *identity) json_t *identity_data = json_object_get(tox_weechat_json_data, identity_key); free(identity_key); - json_t *friend_request_array = json_object_get(identity_data, - tox_weechat_json_key_friend_requests); + json_t *friend_requests = json_object_get(identity_data, + tox_weechat_json_key_friend_requests); + if (friend_requests) + tox_weechat_data_load_friend_requests(identity, friend_requests); - if (friend_request_array) - { - tox_weechat_friend_request_free_identity(identity); - - size_t index; - json_t *json_request; - json_array_foreach(friend_request_array, index, json_request) - { - char client_id[TOX_CLIENT_ID_SIZE]; - const char *message; - - json_t *json_id = json_object_get(json_request, - tox_weechat_json_friend_request_key_client_id); - json_t *json_message = json_object_get(json_request, - tox_weechat_json_friend_request_key_message); - - tox_weechat_hex2bin(json_string_value(json_id), TOX_CLIENT_ID_SIZE * 2, client_id); - message = json_string_value(json_message); - - tox_weechat_friend_request_add(identity, - (uint8_t *)client_id, - message); - } - } + json_t *unsent_messages = json_object_get(identity_data, + tox_weechat_json_key_unsent_messages); + if (unsent_messages) + tox_weechat_data_load_unsent_messages(identity, unsent_messages); } /** diff --git a/src/tox-weechat-identities.c b/src/tox-weechat-identities.c index de6e5b0..3c0cec2 100644 --- a/src/tox-weechat-identities.c +++ b/src/tox-weechat-identities.c @@ -207,6 +207,7 @@ tox_weechat_identity_new(const char *name) identity->tox_do_timer = NULL; identity->chats = identity->last_chat = NULL; identity->friend_requests = identity->last_friend_request = NULL; + identity->unsent_messages = identity->last_unsent_message = NULL; identity->tox_online = false; // set up config diff --git a/src/tox-weechat-identities.h b/src/tox-weechat-identities.h index c8ba1e0..6017839 100644 --- a/src/tox-weechat-identities.h +++ b/src/tox-weechat-identities.h @@ -23,6 +23,8 @@ #include #include +#include + enum t_tox_weechat_identity_option { TOX_WEECHAT_IDENTITY_OPTION_SAVEFILE = 0, @@ -50,6 +52,9 @@ struct t_tox_weechat_identity struct t_tox_weechat_friend_request *last_friend_request; unsigned int friend_request_count; + struct t_tox_weechat_unsent_message *unsent_messages; + struct t_tox_weechat_unsent_message *last_unsent_message; + struct t_tox_weechat_identity *next_identity; struct t_tox_weechat_identity *prev_identity; }; diff --git a/src/tox-weechat-messages.c b/src/tox-weechat-messages.c new file mode 100644 index 0000000..94e1219 --- /dev/null +++ b/src/tox-weechat-messages.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2014 Håvard Pettersson + * + * This file is part of Tox-WeeChat. + * + * Tox-WeeChat is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tox-WeeChat is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tox-WeeChat. If not, see . + */ + +#include + +#include + +#include "tox-weechat-identities.h" +#include "tox-weechat-utils.h" + +#include "tox-weechat-messages.h" + +void +tox_weechat_add_unsent_message(struct t_tox_weechat_identity *identity, + const uint8_t *recipient_id, + const char *message) +{ + struct t_tox_weechat_unsent_message *unsent_message = malloc(sizeof(*unsent_message)); + if (!message) + return; + + memcpy(unsent_message->recipient_id, recipient_id, TOX_CLIENT_ID_SIZE); + unsent_message->message = strdup(message); + + unsent_message->prev_message = identity->last_unsent_message; + unsent_message->next_message = NULL; + + if (identity->unsent_messages == NULL) + identity->unsent_messages = unsent_message; + else + identity->last_unsent_message->next_message = unsent_message; + + identity->last_unsent_message = unsent_message; +} + +uint32_t +tox_weechat_send_friend_message(struct t_tox_weechat_identity *identity, + int32_t friend_number, + const char *message) +{ + // TODO: split message + uint32_t rc = tox_send_message(identity->tox, + friend_number, + (uint8_t *)message, + strlen(message)); + + uint8_t recipient_id[TOX_CLIENT_ID_SIZE]; + tox_get_client_id(identity->tox, friend_number, recipient_id); + + if (rc == 0) + tox_weechat_add_unsent_message(identity, recipient_id, message); + + return rc; +} + diff --git a/src/tox-weechat-messages.h b/src/tox-weechat-messages.h new file mode 100644 index 0000000..c4e6c71 --- /dev/null +++ b/src/tox-weechat-messages.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2014 Håvard Pettersson + * + * This file is part of Tox-WeeChat. + * + * Tox-WeeChat is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Tox-WeeChat is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Tox-WeeChat. If not, see . + */ + +#ifndef TOX_WEECHAT_MESSAGES_H +#define TOX_WEECHAT_MESSAGES_H + +#include + +struct t_tox_weechat_identity; + +struct t_tox_weechat_unsent_message +{ + const char *message; + uint8_t recipient_id[TOX_CLIENT_ID_SIZE]; + + struct t_tox_weechat_unsent_message *next_message; + struct t_tox_weechat_unsent_message *prev_message; +}; + +uint32_t +tox_weechat_send_friend_message(struct t_tox_weechat_identity *identity, + int32_t friend_number, + const char *message); + +#endif // TOX_WEECHAT_MESSAGES_H