aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO3
-rw-r--r--plugins/Matrix.hpp3
-rw-r--r--src/QuickMedia.cpp14
-rw-r--r--src/plugins/Matrix.cpp63
4 files changed, 43 insertions, 40 deletions
diff --git a/TODO b/TODO
index 999f0ce..819831b 100644
--- a/TODO
+++ b/TODO
@@ -6,7 +6,6 @@ Optimize shadow rendering for items (Right now they fill too much space that is
When continuing to read manga from a different page from the first and there is no cache for the chapter, then start downloading from the current page instead of page 1.
Show progress of manga in the history tab (current chapter out of total chapters).
Animate page navigation.
-Properly format text in items. For example for 4chan. The size of the item should also change.
Add greentext support for quotes.
Add support for special formatting for posts by admins on imageboards.
For image boards, track (You)'s and show notification when somebody replies to your post.
@@ -118,6 +117,7 @@ Preview rooms?
Handle matrix token being invalidated while running.
Update upload limit if its updated on the server (can it be updated while the server is running?).
Editing a reply removes reply formatting (both in body and formatted_body). Element also does this when you edit a reply twice. This breaks element mobile that is unable to display replied-to messages without correct formatting (doesn't fetch the replied-to message).
+This also removes the mentioned name which breaks mention for reply.
Implement m.room.tombstone.
Show a marker when a room uses encryption.
Remove replied-to message text in room preview. That shows ignored users text and we want to see the reply message instead anyways.
@@ -134,7 +134,6 @@ If manga page fails to download then show "failed to download image" as text and
Use <img src to add custom emojis, and add setting for adding/removing custom emoji.
Use window title when room name changes in matrix.
Prev token is incorrect if additional messages have been fetched and comparing to get_previous_messages set token, because prev token is not set when fetching additional messages.
-Use unsigned.transaction_id to match messages we post with messages in sync response (for filtering what we send).
Create multiple BodyItem types. BodyItem has a lot of fields and most of them are not always used.
Have a list of redacted events so when fetching previous events, we can filter out the redacted events (directly in the matrix plugin).
Add grid view to matrix and navigate between them using alt+arrow keys.
diff --git a/plugins/Matrix.hpp b/plugins/Matrix.hpp
index a806d98..da67470 100644
--- a/plugins/Matrix.hpp
+++ b/plugins/Matrix.hpp
@@ -5,6 +5,7 @@
#include "Page.hpp"
#include <SFML/Graphics/Color.hpp>
#include <unordered_map>
+#include <unordered_set>
#include <set>
#include <mutex>
#include <rapidjson/fwd.h>
@@ -544,5 +545,7 @@ namespace QuickMedia {
std::string sync_fail_reason;
MatrixDelegate *delegate = nullptr;
std::optional<std::string> filter_cached;
+
+ std::unordered_set<std::string> my_events_transaction_ids;
};
} \ No newline at end of file
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index 0f4c695..0b91876 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -3431,15 +3431,6 @@ namespace QuickMedia {
};
std::thread post_thread(post_thread_handler);
- auto filter_my_messages = [&me](Messages &messages) {
- for(auto it = messages.begin(); it != messages.end();) {
- if((*it)->user == me && ((*it)->type == MessageType::TEXT || (*it)->type == MessageType::REACTION))
- it = messages.erase(it);
- else
- ++it;
- }
- };
-
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())
@@ -3861,13 +3852,13 @@ namespace QuickMedia {
}
};
- auto add_new_messages_to_current_room = [&me, &tabs, &selected_tab, &current_room](Messages &messages) {
+ auto add_new_messages_to_current_room = [&me, &tabs, &selected_tab, &current_room, &chat_state](Messages &messages) {
if(messages.empty())
return;
int num_items = tabs[MESSAGES_TAB_INDEX].body->items.size();
bool scroll_to_end = num_items == 0;
- if(tabs[MESSAGES_TAB_INDEX].body->is_selected_item_last_visible_item() && selected_tab == MESSAGES_TAB_INDEX)
+ if(tabs[MESSAGES_TAB_INDEX].body->is_selected_item_last_visible_item() && selected_tab == MESSAGES_TAB_INDEX && chat_state != ChatState::TYPING_MESSAGE)
scroll_to_end = true;
BodyItem *selected_item = tabs[MESSAGES_TAB_INDEX].body->get_selected();
@@ -4456,7 +4447,6 @@ namespace QuickMedia {
matrix->get_room_sync_data(current_room, sync_data);
if(!sync_data.messages.empty()) {
all_messages.insert(all_messages.end(), sync_data.messages.begin(), sync_data.messages.end());
- filter_my_messages(sync_data.messages);
filter_existing_messages(sync_data.messages);
}
add_new_messages_to_current_room(sync_data.messages);
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index 05881d5..eeef477 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -1750,6 +1750,13 @@ namespace QuickMedia {
if(!type_json.IsString())
return nullptr;
+ 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())
+ return nullptr;
+ }
+
RelatedEventType related_event_type = RelatedEventType::NONE;
std::string related_event_id;
const rapidjson::Value &relates_to_json = GetMember(*content_json, "m.relates_to");
@@ -1823,7 +1830,6 @@ namespace QuickMedia {
reason_str = std::string(reason_json.GetString(), reason_json.GetStringLength());
const rapidjson::Value &membership_json = GetMember(*content_json, "membership");
if(strcmp(membership_json.GetString(), "join") == 0) {
- const rapidjson::Value &unsigned_json = GetMember(event_item_json, "unsigned");
if(unsigned_json.IsObject()) {
const rapidjson::Value &prev_sender = GetMember(unsigned_json, "prev_sender");
const rapidjson::Value &prev_content_json = GetMember(unsigned_json, "prev_content");
@@ -2399,6 +2405,15 @@ namespace QuickMedia {
return result.str();
}
+ static std::string create_transaction_id() {
+ char random_characters[18];
+ if(!generate_random_characters(random_characters, sizeof(random_characters)))
+ return "";
+
+ std::string random_readable_chars = random_characters_to_readable_string(random_characters, sizeof(random_characters));
+ return "m." + std::to_string(time(NULL)) + random_readable_chars;
+ }
+
static const char* content_type_to_message_type(ContentType content_type) {
if(is_content_type_video(content_type))
return "m.video";
@@ -2411,11 +2426,10 @@ namespace QuickMedia {
}
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) {
- char random_characters[18];
- if(!generate_random_characters(random_characters, sizeof(random_characters)))
+ std::string transaction_id = create_transaction_id();
+ if(transaction_id.empty())
return PluginResult::ERR;
-
- std::string random_readable_chars = random_characters_to_readable_string(random_characters, sizeof(random_characters));
+ my_events_transaction_ids.insert(transaction_id);
std::string formatted_body;
bool contains_formatted_text = false;
@@ -2493,7 +2507,7 @@ namespace QuickMedia {
};
char request_url[512];
- snprintf(request_url, sizeof(request_url), "%s/_matrix/client/r0/rooms/%s/send/m.room.message/m%ld.%.*s", homeserver.c_str(), room->id.c_str(), time(NULL), (int)random_readable_chars.size(), random_readable_chars.c_str());
+ snprintf(request_url, sizeof(request_url), "%s/_matrix/client/r0/rooms/%s/send/m.room.message/%s", homeserver.c_str(), room->id.c_str(), transaction_id.c_str());
rapidjson::Document json_root;
DownloadResult download_result = download_json(json_root, request_url, std::move(additional_args), true);
@@ -2596,11 +2610,10 @@ namespace QuickMedia {
// TODO: Store shared_ptr<Message> instead of raw pointer...
Message *relates_to_message_raw = (Message*)relates_to;
- char random_characters[18];
- if(!generate_random_characters(random_characters, sizeof(random_characters)))
+ std::string transaction_id = create_transaction_id();
+ if(transaction_id.empty())
return PluginResult::ERR;
-
- std::string random_readable_chars = random_characters_to_readable_string(random_characters, sizeof(random_characters));
+ 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());
@@ -2630,7 +2643,7 @@ namespace QuickMedia {
};
char request_url[512];
- snprintf(request_url, sizeof(request_url), "%s/_matrix/client/r0/rooms/%s/send/m.room.message/m%ld.%.*s", homeserver.c_str(), room->id.c_str(), time(NULL), (int)random_readable_chars.size(), random_readable_chars.c_str());
+ snprintf(request_url, sizeof(request_url), "%s/_matrix/client/r0/rooms/%s/send/m.room.message/%s", homeserver.c_str(), room->id.c_str(), transaction_id.c_str());
rapidjson::Document json_root;
DownloadResult download_result = download_json(json_root, request_url, std::move(additional_args), true);
@@ -2651,11 +2664,10 @@ namespace QuickMedia {
PluginResult Matrix::post_edit(RoomData *room, const std::string &body, void *relates_to, std::string &event_id_response) {
Message *relates_to_message_raw = (Message*)relates_to;
- char random_characters[18];
- if(!generate_random_characters(random_characters, sizeof(random_characters)))
+ std::string transaction_id = create_transaction_id();
+ if(transaction_id.empty())
return PluginResult::ERR;
-
- std::string random_readable_chars = random_characters_to_readable_string(random_characters, sizeof(random_characters));
+ my_events_transaction_ids.insert(transaction_id);
std::string formatted_body;
bool contains_formatted_text = false;
@@ -2715,7 +2727,7 @@ namespace QuickMedia {
};
char request_url[512];
- snprintf(request_url, sizeof(request_url), "%s/_matrix/client/r0/rooms/%s/send/m.room.message/m%ld.%.*s", homeserver.c_str(), room->id.c_str(), time(NULL), (int)random_readable_chars.size(), random_readable_chars.c_str());
+ snprintf(request_url, sizeof(request_url), "%s/_matrix/client/r0/rooms/%s/send/m.room.message/%s", homeserver.c_str(), room->id.c_str(), transaction_id.c_str());
rapidjson::Document json_root;
DownloadResult download_result = download_json(json_root, request_url, std::move(additional_args), true);
@@ -2736,11 +2748,10 @@ namespace QuickMedia {
PluginResult Matrix::post_reaction(RoomData *room, const std::string &body, void *relates_to, std::string &event_id_response) {
Message *relates_to_message_raw = (Message*)relates_to;
- char random_characters[18];
- if(!generate_random_characters(random_characters, sizeof(random_characters)))
+ std::string transaction_id = create_transaction_id();
+ if(transaction_id.empty())
return PluginResult::ERR;
-
- std::string random_readable_chars = random_characters_to_readable_string(random_characters, sizeof(random_characters));
+ 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());
@@ -2762,7 +2773,7 @@ namespace QuickMedia {
};
char request_url[512];
- snprintf(request_url, sizeof(request_url), "%s/_matrix/client/r0/rooms/%s/send/m.reaction/m%ld.%.*s", homeserver.c_str(), room->id.c_str(), time(NULL), (int)random_readable_chars.size(), random_readable_chars.c_str());
+ snprintf(request_url, sizeof(request_url), "%s/_matrix/client/r0/rooms/%s/send/m.reaction/%s", homeserver.c_str(), room->id.c_str(), transaction_id.c_str());
rapidjson::Document json_root;
DownloadResult download_result = download_json(json_root, request_url, std::move(additional_args), true);
@@ -3096,16 +3107,16 @@ namespace QuickMedia {
set_next_batch("");
invites.clear();
filter_cached.reset();
+ my_events_transaction_ids.clear();
return PluginResult::OK;
}
PluginResult Matrix::delete_message(RoomData *room, void *message, std::string &err_msg){
- char random_characters[18];
- if(!generate_random_characters(random_characters, sizeof(random_characters)))
+ std::string transaction_id = create_transaction_id();
+ if(transaction_id.empty())
return PluginResult::ERR;
-
- std::string random_readable_chars = random_characters_to_readable_string(random_characters, sizeof(random_characters));
+ my_events_transaction_ids.insert(transaction_id);
Message *message_typed = (Message*)message;
@@ -3123,7 +3134,7 @@ namespace QuickMedia {
};
char url[512];
- snprintf(url, sizeof(url), "%s/_matrix/client/r0/rooms/%s/redact/%s/m%ld.%.*s", homeserver.c_str(), room->id.c_str(), message_typed->event_id.c_str(), time(NULL), (int)random_readable_chars.size(), random_readable_chars.c_str());
+ snprintf(url, sizeof(url), "%s/_matrix/client/r0/rooms/%s/redact/%s/%s", homeserver.c_str(), room->id.c_str(), message_typed->event_id.c_str(), transaction_id.c_str());
rapidjson::Document json_root;
DownloadResult download_result = download_json(json_root, url, std::move(additional_args), true, &err_msg);