aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/Matrix.hpp6
-rw-r--r--src/QuickMedia.cpp56
-rw-r--r--src/plugins/Matrix.cpp24
3 files changed, 49 insertions, 37 deletions
diff --git a/plugins/Matrix.hpp b/plugins/Matrix.hpp
index 9fb35fe..7028e4d 100644
--- a/plugins/Matrix.hpp
+++ b/plugins/Matrix.hpp
@@ -76,7 +76,7 @@ namespace QuickMedia {
RelatedEventType related_event_type = RelatedEventType::NONE;
bool notification_mentions_me = false;
bool cache = false;
- bool provisional = false;
+ std::string transaction_id;
time_t timestamp = 0; // In milliseconds
MessageType type;
std::shared_ptr<Message> replaced_by = nullptr;
@@ -204,6 +204,7 @@ namespace QuickMedia {
bool message_contains_user_mention(const std::string &msg, const std::string &username);
bool message_is_timeline(Message *message);
void body_set_selected_item(Body *body, BodyItem *selected_item);
+ std::string create_transaction_id();
enum class MatrixPageType {
ROOM_LIST,
@@ -459,7 +460,8 @@ namespace QuickMedia {
// TODO: Make api better.
PluginResult post_message(RoomData *room, const std::string &body, std::string &event_id_response, const std::optional<UploadInfo> &file_info, const std::optional<UploadInfo> &thumbnail_info, const std::string &msgtype = "");
// |relates_to| is from |BodyItem.userdata| and is of type |Message*|
- PluginResult post_reply(RoomData *room, const std::string &body, void *relates_to, std::string &event_id_response);
+ // If |custom_transaction_id| is empty, then a new transaction id is generated
+ PluginResult post_reply(RoomData *room, const std::string &body, void *relates_to, std::string &event_id_response, const std::string &custom_transaction_id = "");
// |relates_to| is from |BodyItem.userdata| and is of type |Message*|
PluginResult post_edit(RoomData *room, const std::string &body, void *relates_to, std::string &event_id_response);
// |relates_to| is from |BodyItem.userdata| and is of type |Message*|
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index 205b201..e3653e5 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -3443,8 +3443,9 @@ namespace QuickMedia {
std::string event_id;
};
+ std::unordered_map<std::string, std::shared_ptr<Message>> pending_sent_replies;
+
// This is needed to keep the message shared ptr alive. TODO: Remove this shit, maybe even use raw pointers.
- std::unordered_map<std::string, ProvisionalMessage> sent_messages; // |event_id| is always empty in this. Use |message->event_id| instead
std::optional<ProvisionalMessage> provisional_message;
MessageQueue<ProvisionalMessage> provisional_message_queue;
MessageQueue<std::function<ProvisionalMessage()>> post_task_queue;
@@ -3458,15 +3459,6 @@ namespace QuickMedia {
};
std::thread post_thread(post_thread_handler);
- auto filter_sent_messages = [&sent_messages](Messages &messages) {
- for(auto it = messages.begin(); it != messages.end();) {
- if(sent_messages.find((*it)->event_id) != sent_messages.end())
- it = messages.erase(it);
- else
- ++it;
- }
- };
-
auto upload_file = [this, &tabs, &current_room](const std::string &filepath) {
TaskResult post_file_result = run_task_with_loading_screen([this, &current_room, filepath]() {
std::string event_id_response;
@@ -3485,7 +3477,7 @@ namespace QuickMedia {
}
};
- chat_input.on_submit_callback = [this, &tabs, &me, &chat_input, &selected_tab, &current_room, &new_page, &chat_state, &currently_operating_on_item, &post_task_queue, &process_reactions, &find_body_item_by_event_id](std::string text) mutable {
+ chat_input.on_submit_callback = [this, &tabs, &me, &chat_input, &selected_tab, &current_room, &new_page, &chat_state, &pending_sent_replies, &currently_operating_on_item, &post_task_queue, &process_reactions, &find_body_item_by_event_id](std::string text) mutable {
if(!current_room)
return false;
@@ -3582,17 +3574,20 @@ namespace QuickMedia {
tabs[MESSAGES_TAB_INDEX].body->select_last_item();
return true;
} else if(chat_state == ChatState::REPLYING) {
+ std::string transaction_id = create_transaction_id();
+ pending_sent_replies[transaction_id] = message;
+
void *related_to_message = currently_operating_on_item->userdata;
message->related_event_type = RelatedEventType::REPLY;
message->related_event_id = static_cast<Message*>(related_to_message)->event_id;
auto body_item = message_to_body_item(current_room, message.get(), current_room->get_user_avatar_url(me), me->user_id);
body_item->set_description_color(provisional_message_color);
tabs[MESSAGES_TAB_INDEX].body->insert_items_by_timestamps({body_item});
- post_task_queue.push([this, &current_room, text, related_to_message, body_item, message]() {
+ post_task_queue.push([this, &current_room, text, related_to_message, body_item, message, transaction_id]() {
ProvisionalMessage provisional_message;
provisional_message.body_item = body_item;
provisional_message.message = message;
- if(matrix->post_reply(current_room, text, related_to_message, provisional_message.event_id) != PluginResult::OK)
+ if(matrix->post_reply(current_room, text, related_to_message, provisional_message.event_id, transaction_id) != PluginResult::OK)
fprintf(stderr, "Failed to post matrix reply\n");
return provisional_message;
});
@@ -3923,12 +3918,26 @@ namespace QuickMedia {
}
};
- auto filter_provisional_messages = [](Messages &messages) {
+ auto filter_provisional_messages = [&find_body_item_by_event_id, &tabs, &pending_sent_replies](Messages &messages) {
for(auto it = messages.begin(); it != messages.end();) {
- if((*it)->provisional)
+ if(!(*it)->transaction_id.empty()) {
+ if((*it)->related_event_type == RelatedEventType::EDIT) {
+ auto body_item = find_body_item_by_event_id(tabs[MESSAGES_TAB_INDEX].body->items.data(), tabs[MESSAGES_TAB_INDEX].body->items.size(), (*it)->related_event_id);
+ if(body_item) {
+ Message *orig_message = static_cast<Message*>(body_item->userdata);
+ orig_message->replaced_by = (*it);
+ }
+ } else if((*it)->related_event_type == RelatedEventType::REPLY) {
+ auto pending_sent_reply_it = pending_sent_replies.find((*it)->transaction_id);
+ if(pending_sent_reply_it != pending_sent_replies.end()) {
+ pending_sent_reply_it->second->replaced_by = (*it);
+ pending_sent_replies.erase(pending_sent_reply_it);
+ }
+ }
it = messages.erase(it);
- else
+ } else {
++it;
+ }
}
};
@@ -4088,7 +4097,7 @@ namespace QuickMedia {
}
};
- auto cleanup_tasks = [&set_read_marker_future, &fetch_message_future, &fetch_users_future, &typing_state_queue, &typing_state_thread, &post_task_queue, &provisional_message_queue, &fetched_messages_set, &sent_messages, &post_thread, &tabs]() {
+ auto cleanup_tasks = [&set_read_marker_future, &fetch_message_future, &fetch_users_future, &typing_state_queue, &typing_state_thread, &post_task_queue, &provisional_message_queue, &fetched_messages_set, &pending_sent_replies, &post_thread, &tabs]() {
set_read_marker_future.cancel();
fetch_message_future.cancel();
fetch_users_future.cancel();
@@ -4104,7 +4113,7 @@ namespace QuickMedia {
}
provisional_message_queue.clear();
fetched_messages_set.clear();
- sent_messages.clear();
+ pending_sent_replies.clear();
//unreferenced_event_by_room.clear();
@@ -4545,8 +4554,8 @@ namespace QuickMedia {
chat_input.set_max_width(window_size.x - (logo_padding_x + logo_size.x + chat_input_padding_x + logo_padding_x + body_pos.x - body_padding_horizontal));
chat_input.set_position(sf::Vector2f(std::floor(body_pos.x - body_padding_horizontal + logo_padding_x + logo_size.x + chat_input_padding_x), window_size.y - chat_height - chat_input_padding_y));
- more_messages_below_rect.setSize(sf::Vector2f(window_size.x, gradient_height));
- more_messages_below_rect.setPosition(0.0f, std::floor(window_size.y - chat_input_height_full - gradient_height));
+ more_messages_below_rect.setSize(sf::Vector2f(chat_input_shade.getSize().x, gradient_height));
+ more_messages_below_rect.setPosition(chat_input_shade.getPosition().x, std::floor(window_size.y - chat_input_height_full - gradient_height));
logo_sprite.setPosition(body_pos.x - body_padding_horizontal + logo_padding_x, std::floor(window_size.y - chat_input_height_full * 0.5f - logo_size.y * 0.5f));
}
@@ -4558,7 +4567,6 @@ namespace QuickMedia {
if(!provisional_message->event_id.empty()) {
provisional_message->message->event_id = std::move(provisional_message->event_id);
provisional_message->body_item->set_description_color(sf::Color::White);
- sent_messages[provisional_message->message->event_id] = std::move(provisional_message.value());
} else if(provisional_message->body_item) {
provisional_message->body_item->set_description("Failed to send: " + provisional_message->body_item->get_description());
provisional_message->body_item->set_description_color(sf::Color::Red);
@@ -4590,7 +4598,6 @@ namespace QuickMedia {
all_messages.insert(all_messages.end(), new_messages.begin(), new_messages.end());
if(new_messages.empty())
fetched_enough_messages = true;
- filter_sent_messages(new_messages);
filter_existing_messages(new_messages);
fprintf(stderr, "Finished fetching older messages, num new messages: %zu\n", new_messages.size());
size_t num_new_messages = new_messages.size();
@@ -4702,7 +4709,7 @@ namespace QuickMedia {
gradient_inc += (frame_time_ms * 0.5);
sf::Color top_color = interpolate_colors(back_color, sf::Color(175, 180, 188), progress);
- gradient_points[0].position.x = 0.0f;
+ gradient_points[0].position.x = chat_input_shade.getPosition().x;
gradient_points[0].position.y = tab_shade_height;
gradient_points[1].position.x = window_size.x;
@@ -4711,7 +4718,7 @@ namespace QuickMedia {
gradient_points[2].position.x = window_size.x;
gradient_points[2].position.y = tab_shade_height + gradient_height;
- gradient_points[3].position.x = 0.0f;
+ gradient_points[3].position.x = chat_input_shade.getPosition().x;
gradient_points[3].position.y = tab_shade_height + gradient_height;
gradient_points[0].color = top_color;
@@ -4818,7 +4825,6 @@ namespace QuickMedia {
}
all_messages.insert(all_messages.end(), all_messages_new.begin(), all_messages_new.end());
//me = matrix->get_me(current_room);
- filter_sent_messages(all_messages_new);
add_new_messages_to_current_room(all_messages_new);
modify_related_messages_in_current_room(all_messages_new);
unresolved_reactions.clear();
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index a47b588..2b72f03 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -1857,12 +1857,12 @@ namespace QuickMedia {
if(origin_server_ts.IsInt64())
timestamp = origin_server_ts.GetInt64();
- bool provisional = false;
+ std::string transaction_id;
const rapidjson::Value &unsigned_json = GetMember(event_item_json, "unsigned");
if(unsigned_json.IsObject()) {
const rapidjson::Value &transaction_id_json = GetMember(unsigned_json, "transaction_id");
if(transaction_id_json.IsString() && my_events_transaction_ids.find(transaction_id_json.GetString()) != my_events_transaction_ids.end())
- provisional = true;
+ transaction_id = std::string(transaction_id_json.GetString(), transaction_id_json.GetStringLength());
}
RelatedEventType related_event_type = RelatedEventType::NONE;
@@ -1892,7 +1892,7 @@ namespace QuickMedia {
message->related_event_id = relates_to_event_id_json.GetString();
message->related_event_type = RelatedEventType::REACTION;
message->timestamp = timestamp;
- message->provisional = provisional;
+ message->transaction_id = std::move(transaction_id);
return message;
}
}
@@ -1911,7 +1911,7 @@ namespace QuickMedia {
message->body = "Message deleted";
message->timestamp = timestamp;
message->related_event_type = RelatedEventType::REDACTION;
- message->provisional = provisional;
+ message->transaction_id = std::move(transaction_id);
const rapidjson::Value &reason_json = GetMember(*content_json, "reason");
if(reason_json.IsString()) {
@@ -2033,7 +2033,7 @@ namespace QuickMedia {
message->related_event_id = std::move(related_event_id);
message->related_event_type = related_event_type;
message->timestamp = timestamp;
- message->provisional = provisional;
+ message->transaction_id = std::move(transaction_id);
return message;
} else {
auto message = std::make_shared<Message>();
@@ -2044,7 +2044,7 @@ namespace QuickMedia {
message->related_event_id = std::move(related_event_id);
message->related_event_type = related_event_type;
message->timestamp = timestamp;
- message->provisional = provisional;
+ message->transaction_id = std::move(transaction_id);
return message;
}
@@ -2118,7 +2118,7 @@ namespace QuickMedia {
message->related_event_id = std::move(related_event_id);
message->related_event_type = related_event_type;
message->timestamp = timestamp;
- message->provisional = provisional;
+ message->transaction_id = std::move(transaction_id);
return message;
}
@@ -2541,7 +2541,7 @@ namespace QuickMedia {
return result.str();
}
- static std::string create_transaction_id() {
+ std::string create_transaction_id() {
char random_characters[18];
if(!generate_random_characters(random_characters, sizeof(random_characters)))
return "";
@@ -2751,13 +2751,17 @@ namespace QuickMedia {
}
// TODO: Support greentext
- PluginResult Matrix::post_reply(RoomData *room, const std::string &body, void *relates_to, std::string &event_id_response) {
+ PluginResult Matrix::post_reply(RoomData *room, const std::string &body, void *relates_to, std::string &event_id_response, const std::string &custom_transaction_id) {
// TODO: Store shared_ptr<Message> instead of raw pointer...
Message *relates_to_message_raw = (Message*)relates_to;
- std::string transaction_id = create_transaction_id();
+ std::string transaction_id = custom_transaction_id;
+ if(transaction_id.empty())
+ transaction_id = create_transaction_id();
+
if(transaction_id.empty())
return PluginResult::ERR;
+
my_events_transaction_ids.insert(transaction_id);
rapidjson::Document in_reply_to_json(rapidjson::kObjectType);