From ae02ed04389117d100070c47f3ae69abb9080231 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Thu, 1 Oct 2020 07:34:47 +0200 Subject: Matrix: add message delete with ctrl+d --- README.md | 1 + TODO | 3 ++- plugins/Matrix.hpp | 3 +++ src/QuickMedia.cpp | 13 +++++++++++ src/plugins/Matrix.cpp | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 82 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2358ecb..cbb0a5c 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ Press `Ctrl + P` to view image/video attached to matrix message.\ Press `Ctrl + M` to begin writing a message in a matrix room, press `ESC` to cancel.\ Press `Ctrl + R` to reply to a message on matrix, press `ESC` to cancel.\ Press `Ctrl + E` to edit a message on matrix, press `ESC` to cancel. Currently only works for your own messages.\ +Press `Ctrl + D` to delete a message on matrix. Currently deleting a message only deletes the event, so if you delete an edit then the original message wont be deleted. ## Matrix commands `/upload` to upload an image. TODO: Support regular files and videos.\ `/logout` to logout. diff --git a/TODO b/TODO index 5aea62a..427578b 100644 --- a/TODO +++ b/TODO @@ -52,4 +52,5 @@ Allow setting matrix room priority (if it should always be at top). Use Entry instead of SearchBar for 4chan commenting as well. Only add related videos to recommendations if its the first time we watch the video. This is to prevent rewatching a video multiple times from messing up recommendations. Fix incorrect body visible rows count (draws incorrect number of items and incorrect counted, also messed up pg(up/down)). -Replace messages on matrix instead of appending edits (messages that begin with " * "). This also fixes edit of already edited messages. \ No newline at end of file +Replace messages on matrix instead of appending edits (messages that begin with " * "). This also fixes edit of already edited messages. +When deleting an edited message on matrix, delete the original message instead of the edit. This should also be fixed when edits actually edits the original message instead of appending, by maybe it should be done anyways to prevent race condition. \ No newline at end of file diff --git a/plugins/Matrix.hpp b/plugins/Matrix.hpp index 7a588e8..fdd3392 100644 --- a/plugins/Matrix.hpp +++ b/plugins/Matrix.hpp @@ -88,6 +88,9 @@ namespace QuickMedia { PluginResult login(const std::string &username, const std::string &password, const std::string &homeserver, std::string &err_msg); PluginResult logout(); + // |message| is from |BodyItem.userdata| and is of type |Message*| + PluginResult delete_message(const std::string &room_id, void *message, std::string &err_msg); + PluginResult load_and_verify_cached_session(); PluginResult on_start_typing(const std::string &room_id); diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index ecb44d5..cb58a27 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -3585,6 +3585,19 @@ namespace QuickMedia { // TODO: Show inline notification show_notification("QuickMedia", "No message selected for editing"); } + } else if(tabs[selected_tab].type == ChatTabType::MESSAGES && event.key.control && event.key.code == sf::Keyboard::D) { + BodyItem *selected = tabs[selected_tab].body->get_selected(); + if(selected) { + // TODO: Make asynchronous + std::string err_msg; + if(matrix->delete_message(current_room_id, selected->userdata, err_msg) != PluginResult::OK) { + // TODO: Show inline notification + show_notification("QuickMedia", "Failed to delete message, reason: " + err_msg, Urgency::CRITICAL); + } + } else { + // TODO: Show inline notification + show_notification("QuickMedia", "No message selected for deletion"); + } } } diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp index b93164e..b5eb617 100644 --- a/src/plugins/Matrix.cpp +++ b/src/plugins/Matrix.cpp @@ -1255,6 +1255,69 @@ namespace QuickMedia { return PluginResult::OK; } + PluginResult Matrix::delete_message(const std::string &room_id, void *message, std::string &err_msg){ + char random_characters[18]; + if(!generate_random_characters(random_characters, sizeof(random_characters))) + return PluginResult::ERR; + + std::string random_readable_chars = random_characters_to_readable_string(random_characters, sizeof(random_characters)); + + Message *message_typed = (Message*)message; + + // request_data could contains "reason", maybe it should be added sometime in the future? + Json::Value request_data(Json::objectValue); + Json::StreamWriterBuilder builder; + builder["commentStyle"] = "None"; + builder["indentation"] = ""; + + std::vector additional_args = { + { "-X", "PUT" }, + { "-H", "content-type: application/json" }, + { "-H", "Authorization: Bearer " + access_token }, + { "--data-binary", Json::writeString(builder, std::move(request_data)) } + }; + + 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()); + fprintf(stderr, "load initial room data, url: |%s|\n", url); + + std::string server_response; + if(download_to_string(url, server_response, std::move(additional_args), use_tor, true, false) != DownloadResult::OK) { + err_msg = std::move(server_response); + return PluginResult::NET_ERR; + } + + if(server_response.empty()) + return PluginResult::ERR; + + Json::Value json_root; + Json::CharReaderBuilder json_builder; + std::unique_ptr json_reader(json_builder.newCharReader()); + std::string json_errors; + if(!json_reader->parse(&server_response[0], &server_response[server_response.size()], &json_root, &json_errors)) { + err_msg = "Matrix delete message response parse error: " + json_errors; + return PluginResult::ERR; + } + + if(!json_root.isObject()) { + err_msg = "Failed to parse matrix login response"; + return PluginResult::ERR; + } + + const Json::Value &error = json_root["error"]; + if(error.isString()) { + err_msg = error.asString(); + return PluginResult::ERR; + } + + const Json::Value &event_id_json = json_root["event_id"]; + if(!event_id_json.isString()) + return PluginResult::ERR; + + fprintf(stderr, "Matrix delete message, response event id: %s\n", event_id_json.asCString()); + return PluginResult::OK; + } + PluginResult Matrix::load_and_verify_cached_session() { Path session_path = get_storage_dir().join(name).join("session.json"); std::string session_json_content; -- cgit v1.2.3