aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2022-11-13 02:05:27 +0100
committerdec05eba <dec05eba@protonmail.com>2022-11-13 02:05:27 +0100
commitaea90e2c43d6dbf8b8276e1209f4d4abe1cea128 (patch)
treea21cd16b95e027d7e277e25089b63b45e2bdb735
parent01f23292bf2451a0c7b9ada88c6314dcb09509b1 (diff)
Matrix: fix message edits not being applied correctly
-rw-r--r--TODO4
-rw-r--r--plugins/Matrix.hpp7
-rw-r--r--src/Body.cpp24
-rw-r--r--src/QuickMedia.cpp190
-rw-r--r--src/plugins/Matrix.cpp69
5 files changed, 162 insertions, 132 deletions
diff --git a/TODO b/TODO
index 3838cfd..d708f6d 100644
--- a/TODO
+++ b/TODO
@@ -106,7 +106,6 @@ Add client side 4chan max comment chars limit.
Dynamically fetch 4chan api key, if it ever changes in the future. Same for youtube.
Set curl download limits everywhere (when saving to file, downloading to json, etc...).
In the downloader if we already have the url in thumbnail/video cache, then copy it to the destination instead of redownloading it. This would also fix downloading images when viewing a manga page.
-Update timestamp of messages posted with matrix (and move them to the correct place in the timeline) when we receive the message from the server. This is needed when the localtime is messed up (for example when rebooting from windows into linux).
When sfml dependency is removed use libvips for image manipulation. Its a very fast library, especially for thumbnail creation.
Readd copying of Text in Body copy constructor. Find out why we need to make the text dirty on copy.
Body items that are no longer visible should stop their thumbnail download.
@@ -162,7 +161,7 @@ Synapse is gay and mentions do not actually include the whole mxid. It only incl
Make it possible to redact invites.
Reapply filter when changing body item text.
When fetching previous messages in matrix, ignore user info updates.
-Use event timestamp to sort events to apply them in order when fetching previous messages or additional messages.
+Use event timestamp to sort all matrix events.
Try to reconnect media proxy on disconnect. The internet may be unstable (for example on mobile internet).
Opening a media url should display it directly in quickmedia.
Automatically resize body item thumbnail if body is small, or move thumbnail above the text.
@@ -228,7 +227,6 @@ Add option to use invidious, and the invidious front page.
Add proper vim modal mode. Maybe switch focused part with tab? then also need to show which part is focused.
Send clipboard content to clipboard manager when destroying the window, if we are the clipboard owner.
Bypass compositor when fullscreening application.
-Sort matrix events by timestamp. This is needed to make name change and other similar things work properly, otherwise @ mention wont work as it may show an older name if a previous event is fetched and contains name change. Also applies to join/leave events and other things.
Automatically cleanup old cache files.
Download manga pages in parallel. This helps downloading for certain websites such as mangakatana where a single page can take more than 2 seconds but loading 5 at once allows each page to load in 0.4 seconds.
Allow pasting a file link (with or without file://) directly into matrix chat to upload a file (if the chat input is empty). This allows replying-with-media to work with ctrl+v.
diff --git a/plugins/Matrix.hpp b/plugins/Matrix.hpp
index 788050b..77ef252 100644
--- a/plugins/Matrix.hpp
+++ b/plugins/Matrix.hpp
@@ -636,14 +636,14 @@ namespace QuickMedia {
// |url| should only be set when uploading media.
// 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 = "");
+ 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 = "", const std::string &custom_transaction_id = "");
// |relates_to| is from |BodyItem.userdata| and is of type |Message*|
// 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 = "", const std::optional<UploadInfo> &file_info = std::nullopt, const std::optional<UploadInfo> &thumbnail_info = std::nullopt);
// |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);
+ PluginResult post_edit(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_reaction(RoomData *room, const std::string &body, void *relates_to, std::string &event_id_response);
+ PluginResult post_reaction(RoomData *room, const std::string &body, void *relates_to, std::string &event_id_response, const std::string &custom_transaction_id = "");
// If filename is empty then the filename is extracted from filepath
PluginResult post_file(RoomData *room, const std::string &filepath, std::string filename, std::string &event_id_response, std::string &err_msg, void *relates_to = nullptr);
@@ -795,7 +795,6 @@ namespace QuickMedia {
std::vector<std::unique_ptr<RoomData>> invite_rooms;
- std::unordered_set<std::string> my_events_transaction_ids;
std::unordered_map<std::string, CustomEmoji> custom_emoji_by_key;
std::unordered_set<std::string> silenced_invites;
};
diff --git a/src/Body.cpp b/src/Body.cpp
index adb774c..9eb3c98 100644
--- a/src/Body.cpp
+++ b/src/Body.cpp
@@ -315,6 +315,15 @@ namespace QuickMedia {
for(size_t i = 0; i < items.size(); ++i) {
if(body_item->get_timestamp() > items[i]->get_timestamp()) {
items.insert(items.begin() + i, std::move(body_item));
+ /*
+ if((int)i <= selected_item) {
+ if(attach_side == AttachSide::TOP)
+ selected_item -= 1;
+ else
+ selected_item += 1;
+ clamp_selection();
+ }
+ */
return i;
}
}
@@ -328,6 +337,15 @@ namespace QuickMedia {
for(size_t i = 0; i < items.size(); ++i) {
if(body_item->get_timestamp() < items[i]->get_timestamp()) {
items.insert(items.begin() + i, std::move(body_item));
+ /*
+ if((int)i <= selected_item) {
+ if(attach_side == AttachSide::TOP)
+ selected_item -= 1;
+ else
+ selected_item += 1;
+ clamp_selection();
+ }
+ */
return i;
}
}
@@ -1631,19 +1649,19 @@ namespace QuickMedia {
if(item->author_text) {
item->author_text->set_position(text_pos);
item->author_text->draw(window);
- text_offset_y += item->author_text->getHeight();
+ text_offset_y += item->author_text->getHeight() + std::floor(5.0f * get_config().scale);
}
if(item->title_text) {
item->title_text->set_position(text_pos + mgl::vec2f(0.0f, text_offset_y));
item->title_text->draw(window);
- text_offset_y += item->title_text->getHeight();
+ text_offset_y += item->title_text->getHeight() + std::floor(5.0f * get_config().scale);
}
if(item->description_text) {
item->description_text->set_position(text_pos + mgl::vec2f(0.0f, text_offset_y));
item->description_text->draw(window);
- text_offset_y += item->description_text->getHeight();
+ text_offset_y += item->description_text->getHeight() + std::floor(5.0f * get_config().scale);
}
const float gradient_height = 5.0f;
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index e8c76d7..74cd4a1 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -5261,37 +5261,45 @@ namespace QuickMedia {
static const mgl::vec2i CHAT_MESSAGE_THUMBNAIL_MAX_SIZE(600, 337);
- // TODO: Optimize
+ static Message* get_original_message(Message *message) {
+ while(message) {
+ if(!message->replaces)
+ break;
+ message = message->replaces;
+ }
+ return message;
+ }
+
+ // TODO: Optimize.
+ // Note: finds the original message if it's an edit
static std::shared_ptr<BodyItem> find_body_item_by_event_id(const std::shared_ptr<BodyItem> *body_items, size_t num_body_items, const std::string &event_id, size_t *index_result = nullptr) {
if(event_id.empty())
return nullptr;
for(size_t i = 0; i < num_body_items; ++i) {
auto &body_item = body_items[i];
- if(body_item->userdata && static_cast<Message*>(body_item->userdata)->event_id == event_id) {
- if(index_result)
- *index_result = i;
- return body_item;
+ Message *message = static_cast<Message*>(body_item->userdata);
+ if(message && message->event_id == event_id) {
+ const Message *original_message = get_original_message(message);
+ if(original_message == message) {
+ if(index_result)
+ *index_result = i;
+ return body_item;
+ } else {
+ return find_body_item_by_event_id(body_items, num_body_items, original_message->event_id, index_result);
+ }
}
}
return nullptr;
}
- // TODO: Optimize
static std::shared_ptr<BodyItem> find_body_item_by_event_id(BodyItemList body_items, const std::string &event_id, int *index_result) {
- if(event_id.empty())
- return nullptr;
-
- for(int i = 0; i < (int)body_items.size(); ++i) {
- auto &body_item = body_items[i];
- if(body_item->userdata && static_cast<Message*>(body_item->userdata)->event_id == event_id) {
- if(index_result)
- *index_result = i;
- return body_item;
- }
- }
- return nullptr;
+ size_t index_result_z = 0;
+ auto result = find_body_item_by_event_id(body_items.data(), body_items.size(), event_id, &index_result_z);
+ if(index_result)
+ *index_result = index_result_z;
+ return result;
}
// Returns true if cached and loaded
@@ -5319,9 +5327,10 @@ namespace QuickMedia {
}
static std::shared_ptr<BodyItem> message_to_body_item(Matrix *matrix, RoomData *room, Message *message, const std::string &my_display_name, const std::string &my_user_id) {
+ Message *latest_message = get_latest_message_in_edit_chain(message);
auto body_item = BodyItem::create("");
body_item->set_author(extract_first_line_remove_newline_elipses(room->get_user_display_name(message->user), AUTHOR_MAX_LENGTH));
- body_item->set_description(strip(message_to_qm_text(matrix, message)));
+ body_item->set_description(strip(message_to_qm_text(matrix, latest_message)));
body_item->set_timestamp(message->timestamp);
if(!message->thumbnail_url.empty()) {
body_item->thumbnail_url = message->thumbnail_url;
@@ -5422,19 +5431,6 @@ namespace QuickMedia {
user_update_display_info(body_item->embedded_item.get(), room, (Message*)body_item->embedded_item->userdata);
}
- static Message* get_original_message(Message *message) {
- if(!message)
- return nullptr;
-
- Message *replaces = message->replaces;
- while(replaces) {
- if(!replaces->replaces)
- return replaces;
- replaces = replaces->replaces;
- }
- return message;
- }
-
bool Program::chat_page(MatrixChatPage *matrix_chat_page, RoomData *current_room) {
assert(current_room);
assert(strcmp(plugin_name, "matrix") == 0);
@@ -5445,6 +5441,8 @@ namespace QuickMedia {
window.set_title(("QuickMedia - matrix - " + current_room->get_name()).c_str());
bool move_room = false;
+ // Year 2500.. The year that humanity is wiped out. Also we want our local message to appear at the bottom even if time is not synced with ntp, until it's replaced by the server
+ constexpr int64_t timestamp_provisional_event = 16755030000LL * 1000LL;
const float room_name_text_height = std::floor(18.0f * get_config().scale * get_config().font_scale);
mgl::Text room_name_text("", *FontLoader::get_font(FontLoader::FontType::LATIN_BOLD, room_name_text_height));
@@ -5843,7 +5841,7 @@ namespace QuickMedia {
std::string event_id;
};
- std::unordered_map<std::string, std::shared_ptr<Message>> pending_sent_replies;
+ std::unordered_map<std::string, ProvisionalMessage> pending_sent_events;
// 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
@@ -5860,38 +5858,6 @@ namespace QuickMedia {
};
std::thread post_thread(post_thread_handler);
- auto message_set_replaced_by = [&tabs, &pending_sent_replies, MESSAGES_TAB_INDEX](std::shared_ptr<Message> message) {
- if(message->related_event_type == RelatedEventType::EDIT) {
- auto body_item = find_body_item_by_event_id(tabs[MESSAGES_TAB_INDEX].body->get_items().data(), tabs[MESSAGES_TAB_INDEX].body->get_items().size(), message->related_event_id);
- if(body_item) {
- Message *reply_to_message = static_cast<Message*>(body_item->userdata);
- if(!reply_to_message) {
- show_notification("QuickMedia", "Unexpected error, failed to set replaced by message", Urgency::CRITICAL);
- return;
- }
- message->replaces = reply_to_message;
- reply_to_message->replaced_by = message;
- }
- } else if(message->related_event_type == RelatedEventType::REPLY) {
- auto pending_sent_reply_it = pending_sent_replies.find(message->transaction_id);
- if(pending_sent_reply_it != pending_sent_replies.end()) {
- pending_sent_reply_it->second->replaced_by = message;
- pending_sent_replies.erase(pending_sent_reply_it);
- }
- }
- };
-
- auto filter_sent_messages = [&sent_messages, &message_set_replaced_by](Messages &messages) {
- for(auto it = messages.begin(); it != messages.end();) {
- if(!(*it)->event_id.empty() && sent_messages.find((*it)->event_id) != sent_messages.end()) {
- message_set_replaced_by(*it);
- it = messages.erase(it);
- } else {
- ++it;
- }
- }
- };
-
auto upload_file = [this, &current_room, &tabs, &ui_tabs, &chat_state](const std::string &filepath, const std::string &filename) {
const int selected_tab = ui_tabs.get_selected();
std::shared_ptr<BodyItem> selected = tabs[selected_tab].body->get_selected_shared();
@@ -6064,7 +6030,7 @@ namespace QuickMedia {
"/me [text]: Send a message of type \"m.emote\".\n"
"/react [text]: React to the selected message (also works if you are replying to a message).\n"
"/id: Show the room id.";
- message->timestamp = time(nullptr) * 1000;
+ message->timestamp = time(nullptr) * 1000; // TODO: What if the user has broken local time?
matrix->append_system_message(current_room, std::move(message));
chat_input.set_editable(false);
@@ -6075,7 +6041,7 @@ namespace QuickMedia {
message->type = MessageType::SYSTEM;
message->user = me;
message->body = current_room->id;
- message->timestamp = time(nullptr) * 1000;
+ message->timestamp = time(nullptr) * 1000; // TODO: What if the user has broken local time?
matrix->append_system_message(current_room, std::move(message));
chat_input.set_editable(false);
@@ -6110,7 +6076,9 @@ namespace QuickMedia {
message->body = matrix->body_to_formatted_body(current_room, text);
}
message->type = MessageType::TEXT;
- message->timestamp = time(NULL) * 1000;
+ message->timestamp = timestamp_provisional_event;
+ const std::string transaction_id = create_transaction_id();
+ message->transaction_id = transaction_id;
if(chat_state == ChatState::TYPING_MESSAGE || (chat_state == ChatState::REPLYING && msgtype == "m.reaction")) {
BodyItem *selected_item = tabs[MESSAGES_TAB_INDEX].body->get_selected();
@@ -6125,15 +6093,21 @@ namespace QuickMedia {
message->related_event_id = static_cast<Message*>(related_to_message)->event_id;
auto body_item = message_to_body_item(matrix, current_room, message.get(), current_room->get_user_avatar_url(me), me->user_id);
load_cached_related_embedded_item(body_item.get(), message.get(), me, current_room, tabs[MESSAGES_TAB_INDEX].body->get_items());
- tabs[MESSAGES_TAB_INDEX].body->insert_items_by_timestamps({body_item});
+ tabs[MESSAGES_TAB_INDEX].body->append_item(body_item);
+
+ ProvisionalMessage provisional_message;
+ provisional_message.body_item = body_item;
+ provisional_message.message = message;
+ pending_sent_events[message->transaction_id] = std::move(provisional_message);
+
Messages messages;
messages.push_back(message);
process_reactions(messages);
- post_task_queue.push([this, &current_room, text, body_item, message, related_to_message]() {
+ post_task_queue.push([this, &current_room, text, body_item, message, related_to_message, transaction_id]() {
ProvisionalMessage provisional_message;
provisional_message.body_item = body_item;
provisional_message.message = message;
- if(matrix->post_reaction(current_room, text, related_to_message, provisional_message.event_id) != PluginResult::OK)
+ if(matrix->post_reaction(current_room, text, related_to_message, provisional_message.event_id, transaction_id) != PluginResult::OK)
fprintf(stderr, "Failed to post matrix reaction\n");
return provisional_message;
});
@@ -6141,12 +6115,18 @@ namespace QuickMedia {
auto body_item = message_to_body_item(matrix, current_room, message.get(), current_room->get_user_avatar_url(me), me->user_id);
body_item->set_description_color(get_theme().provisional_message_color);
load_cached_related_embedded_item(body_item.get(), message.get(), me, current_room, tabs[MESSAGES_TAB_INDEX].body->get_items());
- tabs[MESSAGES_TAB_INDEX].body->insert_items_by_timestamps({body_item});
- post_task_queue.push([this, &current_room, text, msgtype, body_item, message]() {
+ tabs[MESSAGES_TAB_INDEX].body->append_item(body_item);
+
+ ProvisionalMessage provisional_message;
+ provisional_message.body_item = body_item;
+ provisional_message.message = message;
+ pending_sent_events[message->transaction_id] = std::move(provisional_message);
+
+ post_task_queue.push([this, &current_room, text, msgtype, body_item, message, transaction_id]() {
ProvisionalMessage provisional_message;
provisional_message.body_item = body_item;
provisional_message.message = message;
- if(matrix->post_message(current_room, text, provisional_message.event_id, std::nullopt, std::nullopt, msgtype) != PluginResult::OK)
+ if(matrix->post_message(current_room, text, provisional_message.event_id, std::nullopt, std::nullopt, msgtype, transaction_id) != PluginResult::OK)
fprintf(stderr, "Failed to post matrix message\n");
return provisional_message;
});
@@ -6157,16 +6137,19 @@ 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(matrix, current_room, message.get(), current_room->get_user_avatar_url(me), me->user_id);
body_item->set_description_color(get_theme().provisional_message_color);
load_cached_related_embedded_item(body_item.get(), message.get(), me, current_room, tabs[MESSAGES_TAB_INDEX].body->get_items());
- tabs[MESSAGES_TAB_INDEX].body->insert_items_by_timestamps({body_item});
+ tabs[MESSAGES_TAB_INDEX].body->append_item(body_item);
+
+ ProvisionalMessage provisional_message;
+ provisional_message.body_item = body_item;
+ provisional_message.message = message;
+ pending_sent_events[message->transaction_id] = std::move(provisional_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;
@@ -6185,9 +6168,10 @@ namespace QuickMedia {
Message *related_to_message = (Message*)currently_operating_on_item->userdata;
message->related_event_type = RelatedEventType::EDIT;
message->related_event_id = related_to_message->event_id;
- // TODO:
- //related_to_message->replaced_by = message;
- //message->replaces = related_to_message;
+
+ //Message *latest_message_related_to = get_latest_message_in_edit_chain(related_to_message);
+ //latest_message_related_to->replaced_by = message;
+ //message->replaces = latest_message_related_to;
size_t body_item_index = 0;
auto body_item = find_body_item_by_event_id(tabs[MESSAGES_TAB_INDEX].body->get_items().data(), tabs[MESSAGES_TAB_INDEX].body->get_items().size(), message->related_event_id, &body_item_index);
if(body_item) {
@@ -6198,17 +6182,17 @@ namespace QuickMedia {
body_item_shared_ptr->set_description(std::move(qm_formatted_text));
body_item_shared_ptr->set_description_color(get_theme().provisional_message_color);
- auto edit_body_item = message_to_body_item(matrix, current_room, message.get(), current_room->get_user_avatar_url(me), me->user_id);
- edit_body_item->visible = false;
- load_cached_related_embedded_item(edit_body_item.get(), message.get(), me, current_room, tabs[MESSAGES_TAB_INDEX].body->get_items());
- tabs[MESSAGES_TAB_INDEX].body->insert_items_by_timestamps({edit_body_item});
+ //auto edit_body_item = message_to_body_item(matrix, current_room, message.get(), current_room->get_user_avatar_url(me), me->user_id);
+ //edit_body_item->visible = false;
+ //load_cached_related_embedded_item(edit_body_item.get(), message.get(), me, current_room, tabs[MESSAGES_TAB_INDEX].body->get_items());
+ //tabs[MESSAGES_TAB_INDEX].body->append_item(edit_body_item);
//unreferenced_events.push_back(message);
- post_task_queue.push([this, &current_room, text, related_to_message, message, body_item_shared_ptr]() {
+ post_task_queue.push([this, &current_room, text, related_to_message, message, body_item_shared_ptr, transaction_id]() {
ProvisionalMessage provisional_message;
provisional_message.message = message;
provisional_message.body_item = body_item_shared_ptr;
- if(matrix->post_edit(current_room, text, related_to_message, provisional_message.event_id) != PluginResult::OK)
+ if(matrix->post_edit(current_room, text, related_to_message, provisional_message.event_id, transaction_id) != PluginResult::OK)
fprintf(stderr, "Failed to post matrix edit\n");
return provisional_message;
});
@@ -6505,14 +6489,24 @@ namespace QuickMedia {
}
};
- auto filter_provisional_messages = [&message_set_replaced_by](Messages &messages) {
- for(auto it = messages.begin(); it != messages.end();) {
- if(!(*it)->transaction_id.empty()) {
- message_set_replaced_by(*it);
- it = messages.erase(it);
- } else {
- ++it;
+ auto filter_provisional_messages = [&](Messages &messages) {
+ auto &messages_body = tabs[MESSAGES_TAB_INDEX].body;
+ for(auto message_it = messages.begin(); message_it != messages.end();) {
+ auto &message = *message_it;
+ auto it = pending_sent_events.find(message->transaction_id);
+ if(it != pending_sent_events.end()) {
+ if(message->type == MessageType::REACTION) {
+ message_it = messages.erase(message_it);
+ pending_sent_events.erase(it);
+ continue;
+ }
+
+ messages_body->erase_item([&](auto &body_item) {
+ return body_item == it->second.body_item;
+ });
+ pending_sent_events.erase(it);
}
+ ++message_it;
}
};
@@ -6706,7 +6700,7 @@ namespace QuickMedia {
provisional_message_queue.clear();
fetched_messages_set.clear();
sent_messages.clear();
- pending_sent_replies.clear();
+ pending_sent_events.clear();
//unreferenced_event_by_room.clear();
@@ -7436,7 +7430,7 @@ namespace QuickMedia {
if(new_messages_result.message_dir == MessageDirection::AFTER)
fetched_enough_messages_bottom = new_messages_result.reached_end;
- filter_sent_messages(new_messages_result.messages);
+ filter_provisional_messages(new_messages_result.messages);
filter_existing_messages(new_messages_result.messages);
size_t num_new_messages = new_messages_result.messages.size();
if(num_new_messages > 0) {
@@ -7595,7 +7589,7 @@ namespace QuickMedia {
for(; last_timeline_message >= 0; --last_timeline_message) {
BodyItem *item = body_items[last_timeline_message].get();
Message *message = static_cast<Message*>(item->userdata);
- if(item->visible && message && message_is_timeline(message))
+ if(message && message_is_timeline(message) && !message->event_id.empty())
break;
}
@@ -7744,7 +7738,7 @@ 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);
+ filter_provisional_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 133193b..6e6264f 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -999,7 +999,7 @@ namespace QuickMedia {
}
void MatrixInvitesPage::add_body_item(std::shared_ptr<BodyItem> body_item) {
- body->insert_item_by_timestamp_reverse(std::move(body_item));
+ body->insert_item_by_timestamp(std::move(body_item));
if(body->get_num_items() != prev_invite_count) {
prev_invite_count = body->get_num_items();
title = "Invites (" + std::to_string(body->get_num_items()) + ")";
@@ -1604,7 +1604,7 @@ namespace QuickMedia {
PluginResult result;
bool initial_sync = true;
while(sync_running) {
- char url[1024];
+ char url[2048];
if(next_batch.empty())
snprintf(url, sizeof(url), "%s/_matrix/client/r0/sync?filter=%s&timeout=0", homeserver.c_str(), filter_encoded.c_str());
else
@@ -1762,7 +1762,6 @@ namespace QuickMedia {
next_notifications_token.clear();
invites.clear();
filter_cached.reset();
- my_events_transaction_ids.clear();
finished_fetching_notifications = false;
custom_emoji_by_key.clear();
}
@@ -2162,7 +2161,7 @@ namespace QuickMedia {
bool has_unread_notifications = false;
const rapidjson::Value &unread_notification_json = GetMember(it.value, "unread_notifications");
- if(unread_notification_json.IsObject() && !is_additional_messages_sync) {
+ if(unread_notification_json.IsObject() && !is_additional_messages_sync && !sync_is_cache) {
const rapidjson::Value &highlight_count_json = GetMember(unread_notification_json, "highlight_count");
if(highlight_count_json.IsInt64() && (highlight_count_json.GetInt64() > 0 || initial_sync)) {
room->unread_notification_count = highlight_count_json.GetInt64();
@@ -2392,7 +2391,8 @@ namespace QuickMedia {
if(!timestamp_json.IsInt64())
continue;
- room_data->read_marker_event_timestamp = timestamp_json.GetInt64();
+ if(timestamp_json.GetInt64() > room_data->read_marker_event_timestamp)
+ room_data->read_marker_event_timestamp = timestamp_json.GetInt64();
}
}
}
@@ -2878,7 +2878,7 @@ namespace QuickMedia {
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())
+ if(transaction_id_json.IsString())
transaction_id = std::string(transaction_id_json.GetString(), transaction_id_json.GetStringLength());
}
@@ -2915,6 +2915,26 @@ namespace QuickMedia {
}
}
+ /*
+ if(related_event_id.empty() && unsigned_json.IsObject()) {
+ const rapidjson::Value &relations_json = GetMember(unsigned_json, "m.relations");
+ if(relations_json.IsObject()) {
+ const rapidjson::Value &replace_json = GetMember(relations_json, "m.replace");
+ if(replace_json.IsObject()) {
+ const rapidjson::Value &event_id_json = GetMember(replace_json, "event_id");
+ const rapidjson::Value &origin_server_ts = GetMember(replace_json, "origin_server_ts");
+ if(origin_server_ts.IsInt64())
+ timestamp = origin_server_ts.GetInt64();
+
+ if(event_id_json.IsString()) {
+ related_event_id = event_id_json.GetString();
+ related_event_type = RelatedEventType::EDIT;
+ }
+ }
+ }
+ }
+ */
+
const rapidjson::Value &new_content_json = GetMember(*content_json, "m.new_content");
if(new_content_json.IsObject())
content_json = &new_content_json;
@@ -3286,11 +3306,11 @@ namespace QuickMedia {
if(user_info.size() == 0)
result = extract_user_name_from_user_id(fallback_user_id);
else if(user_info.size() == 1)
- result = extract_first_line_remove_newline_elipses(user_info[0]->room->get_user_display_name(user_info[0]), AUTHOR_MAX_LENGTH);
+ result = user_info[0]->room->get_user_display_name(user_info[0]);
else if(user_info.size() == 2)
- result = extract_first_line_remove_newline_elipses(user_info[0]->room->get_user_display_name(user_info[0]) + " and " + user_info[1]->room->get_user_display_name(user_info[1]), 64);
+ result = user_info[0]->room->get_user_display_name(user_info[0]) + " and " + user_info[1]->room->get_user_display_name(user_info[1]);
else if(user_info.size() > 2)
- result = extract_first_line_remove_newline_elipses(user_info[0]->room->get_user_display_name(user_info[0]) + ", " + user_info[1]->room->get_user_display_name(user_info[1]) + " and " + std::to_string(user_info.size() - 2) + " other(s)", 64);
+ result = user_info[0]->room->get_user_display_name(user_info[0]) + ", " + user_info[1]->room->get_user_display_name(user_info[1]) + " and " + std::to_string(user_info.size() - 2) + " other(s)";
return result;
}
@@ -3901,15 +3921,16 @@ namespace QuickMedia {
}
void Matrix::on_exit_room(RoomData *room) {
- my_events_transaction_ids.clear();
+
}
- PluginResult Matrix::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) {
- std::string transaction_id = create_transaction_id();
+ PluginResult Matrix::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, const std::string &custom_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;
- if(!file_info)
- my_events_transaction_ids.insert(transaction_id);
std::string formatted_body;
if(!file_info)
@@ -4085,9 +4106,6 @@ namespace QuickMedia {
if(transaction_id.empty())
return PluginResult::ERR;
- if(!file_info)
- my_events_transaction_ids.insert(transaction_id);
-
rapidjson::Document in_reply_to_json(rapidjson::kObjectType);
in_reply_to_json.AddMember("event_id", rapidjson::StringRef(relates_to_message_raw->event_id.c_str()), in_reply_to_json.GetAllocator());
@@ -4191,14 +4209,16 @@ namespace QuickMedia {
return body_to_formatted_body(room, " * " + body);
}
- PluginResult Matrix::post_edit(RoomData *room, const std::string &body, void *relates_to, std::string &event_id_response) {
+ PluginResult Matrix::post_edit(RoomData *room, const std::string &body, void *relates_to, std::string &event_id_response, const std::string &custom_transaction_id) {
Message *relates_to_message_raw = (Message*)relates_to;
Message *replied_to_message = get_replied_to_message_recursive(this, room, relates_to_message_raw);
- 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 request_data(rapidjson::kObjectType);
@@ -4252,13 +4272,15 @@ namespace QuickMedia {
return PluginResult::OK;
}
- PluginResult Matrix::post_reaction(RoomData *room, const std::string &body, void *relates_to, std::string &event_id_response) {
+ PluginResult Matrix::post_reaction(RoomData *room, const std::string &body, void *relates_to, std::string &event_id_response, const std::string &custom_transaction_id) {
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 relates_to_json(rapidjson::kObjectType);
relates_to_json.AddMember("event_id", rapidjson::StringRef(relates_to_message_raw->event_id.c_str()), relates_to_json.GetAllocator());
@@ -4887,7 +4909,6 @@ namespace QuickMedia {
std::string transaction_id = create_transaction_id();
if(transaction_id.empty())
return PluginResult::ERR;
- //my_events_transaction_ids.insert(transaction_id);
Message *message_typed = (Message*)message;