aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/QuickMedia.cpp54
-rw-r--r--src/plugins/Matrix.cpp47
2 files changed, 85 insertions, 16 deletions
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index d9b1041..0f4c695 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -3433,7 +3433,7 @@ namespace QuickMedia {
auto filter_my_messages = [&me](Messages &messages) {
for(auto it = messages.begin(); it != messages.end();) {
- if((*it)->user == me && (*it)->type == MessageType::TEXT)
+ if((*it)->user == me && ((*it)->type == MessageType::TEXT || (*it)->type == MessageType::REACTION))
it = messages.erase(it);
else
++it;
@@ -3467,7 +3467,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, &unreferenced_events, &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, &currently_operating_on_item, &post_task_queue, &process_reactions, &find_body_item_by_event_id](std::string text) mutable {
if(!current_room)
return false;
@@ -3500,8 +3500,11 @@ namespace QuickMedia {
} else if(strncmp(text.c_str(), "/me ", 4) == 0) {
msgtype = "m.emote";
text.erase(text.begin(), text.begin() + 4);
+ } else if(strncmp(text.c_str(), "/react ", 7) == 0) {
+ msgtype = "m.reaction";
+ text.erase(text.begin(), text.begin() + 7);
} else {
- fprintf(stderr, "Error: invalid command: %s, expected /upload, /logout or /me\n", text.c_str());
+ fprintf(stderr, "Error: invalid command: %s, expected /upload, /logout, /me or /react\n", text.c_str());
return false;
}
}
@@ -3523,17 +3526,38 @@ namespace QuickMedia {
scroll_to_end = true;
if(chat_state == ChatState::TYPING_MESSAGE) {
- 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, msgtype, body_item, message]() {
- 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)
- fprintf(stderr, "Failed to post matrix message\n");
- return provisional_message;
- });
+ BodyItem *selected_item = tabs[MESSAGES_TAB_INDEX].body->get_selected();
+ if(msgtype == "m.reaction" && selected_item) {
+ void *related_to_message = selected_item->userdata;
+ message->type = MessageType::REACTION;
+ message->related_event_type = RelatedEventType::REACTION;
+ 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);
+ tabs[MESSAGES_TAB_INDEX].body->insert_items_by_timestamps({body_item});
+ Messages messages;
+ messages.push_back(message);
+ process_reactions(messages);
+ post_task_queue.push([this, &current_room, text, body_item, message, related_to_message]() {
+ 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)
+ fprintf(stderr, "Failed to post matrix reaction\n");
+ return provisional_message;
+ });
+ } else {
+ 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, msgtype, body_item, message]() {
+ 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)
+ fprintf(stderr, "Failed to post matrix message\n");
+ return provisional_message;
+ });
+ }
chat_input.set_editable(false);
chat_state = ChatState::NAVIGATING;
if(scroll_to_end)
@@ -4107,8 +4131,6 @@ namespace QuickMedia {
if((selected_tab == MESSAGES_TAB_INDEX || selected_tab == PINNED_TAB_INDEX) && event.key.code == sf::Keyboard::Enter) {
BodyItem *selected = tabs[selected_tab].body->get_selected();
if(selected) {
- Message *mess = static_cast<Message*>(selected->userdata);
- fprintf(stderr, "Mess type: %d\n", mess->type);
if(!display_url_or_image(selected))
display_url_or_image(selected->embedded_item.get());
}
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index e5e4922..05881d5 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -2733,6 +2733,53 @@ namespace QuickMedia {
return PluginResult::OK;
}
+ 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)))
+ return PluginResult::ERR;
+
+ std::string random_readable_chars = random_characters_to_readable_string(random_characters, sizeof(random_characters));
+
+ 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());
+ relates_to_json.AddMember("key", rapidjson::StringRef(body.c_str()), relates_to_json.GetAllocator());
+ relates_to_json.AddMember("rel_type", "m.annotation", relates_to_json.GetAllocator());
+
+ rapidjson::Document request_json(rapidjson::kObjectType);
+ request_json.AddMember("m.relates_to", std::move(relates_to_json), request_json.GetAllocator());
+
+ rapidjson::StringBuffer buffer;
+ rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
+ request_json.Accept(writer);
+
+ std::vector<CommandArg> additional_args = {
+ { "-X", "PUT" },
+ { "-H", "content-type: application/json" },
+ { "-H", "Authorization: Bearer " + access_token },
+ { "--data-binary", buffer.GetString() }
+ };
+
+ 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());
+
+ rapidjson::Document json_root;
+ DownloadResult download_result = download_json(json_root, request_url, std::move(additional_args), true);
+ if(download_result != DownloadResult::OK) return download_result_to_plugin_result(download_result);
+
+ if(!json_root.IsObject())
+ return PluginResult::ERR;
+
+ const rapidjson::Value &event_id_json = GetMember(json_root, "event_id");
+ if(!event_id_json.IsString())
+ return PluginResult::ERR;
+
+ fprintf(stderr, "Matrix post reaction, response event id: %s\n", event_id_json.GetString());
+ event_id_response = std::string(event_id_json.GetString(), event_id_json.GetStringLength());
+ return PluginResult::OK;
+ }
+
std::shared_ptr<Message> Matrix::get_message_by_id(RoomData *room, const std::string &event_id) {
std::shared_ptr<Message> existing_room_message = room->get_message_by_id(event_id);
if(existing_room_message)