aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--plugins/Matrix.hpp44
-rw-r--r--src/QuickMedia.cpp107
-rw-r--r--src/plugins/Matrix.cpp72
3 files changed, 106 insertions, 117 deletions
diff --git a/plugins/Matrix.hpp b/plugins/Matrix.hpp
index c953364..a48cf69 100644
--- a/plugins/Matrix.hpp
+++ b/plugins/Matrix.hpp
@@ -93,6 +93,12 @@ namespace QuickMedia {
std::string prev_batch;
bool initial_fetch_finished = false;
+ // These 4 variables are set by QuickMedia, not the matrix plugin
+ bool last_message_read = true;
+ time_t last_read_message_timestamp = 0;
+ bool has_unread_mention = false;
+ void *userdata = nullptr; // Pointer to BodyItem. Note: this has to be valid as long as the room is valid
+
// These are messages fetched with |Matrix::get_message_by_id|. Needed to show replies, when replying to old message not part of /sync.
// The value is nullptr if the message is fetched and cached but the event if referenced an invalid message.
// TODO: Verify if replied to messages are also part of /sync; then this is not needed.
@@ -121,8 +127,8 @@ namespace QuickMedia {
};
using Messages = std::vector<std::shared_ptr<Message>>;
- using RoomSyncMessages = std::unordered_map<std::shared_ptr<RoomData>, Messages>;
- using Rooms = std::vector<std::shared_ptr<RoomData>>;
+ using RoomSyncMessages = std::unordered_map<RoomData*, Messages>;
+ using Rooms = std::vector<RoomData*>;
bool message_contains_user_mention(const std::string &msg, const std::string &username);
@@ -130,30 +136,30 @@ namespace QuickMedia {
public:
PluginResult sync(RoomSyncMessages &room_messages);
void get_room_join_updates(Rooms &new_rooms);
- PluginResult get_all_synced_room_messages(std::shared_ptr<RoomData> room, Messages &messages);
- PluginResult get_previous_room_messages(std::shared_ptr<RoomData> room, Messages &messages);
+ PluginResult get_all_synced_room_messages(RoomData *room, Messages &messages);
+ PluginResult get_previous_room_messages(RoomData *room, Messages &messages);
// |url| should only be set when uploading media.
// TODO: Make api better.
- PluginResult post_message(std::shared_ptr<RoomData> room, const std::string &body, const std::optional<UploadInfo> &file_info, const std::optional<UploadInfo> &thumbnail_info);
+ PluginResult post_message(RoomData *room, const std::string &body, const std::optional<UploadInfo> &file_info, const std::optional<UploadInfo> &thumbnail_info);
// |relates_to| is from |BodyItem.userdata| and is of type |Message*|
- PluginResult post_reply(std::shared_ptr<RoomData> room, const std::string &body, void *relates_to);
+ PluginResult post_reply(RoomData *room, const std::string &body, void *relates_to);
// |relates_to| is from |BodyItem.userdata| and is of type |Message*|
- PluginResult post_edit(std::shared_ptr<RoomData> room, const std::string &body, void *relates_to);
+ PluginResult post_edit(RoomData *room, const std::string &body, void *relates_to);
- PluginResult post_file(std::shared_ptr<RoomData> room, const std::string &filepath, std::string &err_msg);
+ PluginResult post_file(RoomData *room, const std::string &filepath, std::string &err_msg);
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(std::shared_ptr<RoomData> room, void *message, std::string &err_msg);
+ PluginResult delete_message(RoomData *room, void *message, std::string &err_msg);
PluginResult load_and_verify_cached_session();
- PluginResult on_start_typing(std::shared_ptr<RoomData> room);
- PluginResult on_stop_typing(std::shared_ptr<RoomData> room);
+ PluginResult on_start_typing(RoomData *room);
+ PluginResult on_stop_typing(RoomData *room);
- PluginResult set_read_marker(std::shared_ptr<RoomData> room, const Message *message);
+ PluginResult set_read_marker(RoomData *room, const Message *message);
// |message| is from |BodyItem.userdata| and is of type |Message*|
bool was_message_posted_by_me(void *message);
@@ -163,7 +169,7 @@ namespace QuickMedia {
// Cached
PluginResult get_config(int *upload_size);
- std::shared_ptr<UserInfo> get_me(std::shared_ptr<RoomData> room);
+ std::shared_ptr<UserInfo> get_me(RoomData *room);
// Returns nullptr if message cant be found. Note: cached
std::shared_ptr<Message> get_message_by_id(RoomData *room, const std::string &event_id);
@@ -171,21 +177,21 @@ namespace QuickMedia {
bool use_tor = false;
private:
PluginResult sync_response_to_body_items(const rapidjson::Document &root, RoomSyncMessages &room_messages);
- PluginResult get_previous_room_messages(std::shared_ptr<RoomData> &room_data);
+ PluginResult get_previous_room_messages(RoomData *room_data);
void events_add_user_info(const rapidjson::Value &events_json, RoomData *room_data);
void events_add_user_read_markers(const rapidjson::Value &events_json, RoomData *room_data);
- void events_add_messages(const rapidjson::Value &events_json, std::shared_ptr<RoomData> &room_data, MessageDirection message_dir, RoomSyncMessages *room_messages, bool has_unread_notifications);
+ void events_add_messages(const rapidjson::Value &events_json, RoomData *room_data, MessageDirection message_dir, RoomSyncMessages *room_messages, bool has_unread_notifications);
void events_set_room_name(const rapidjson::Value &events_json, RoomData *room_data);
std::shared_ptr<Message> parse_message_event(const rapidjson::Value &event_item_json, RoomData *room_data);
- PluginResult upload_file(std::shared_ptr<RoomData> room, const std::string &filepath, UploadInfo &file_info, UploadInfo &thumbnail_info, std::string &err_msg);
+ PluginResult upload_file(RoomData *room, const std::string &filepath, UploadInfo &file_info, UploadInfo &thumbnail_info, std::string &err_msg);
std::shared_ptr<Message> get_edited_message_original_message(RoomData *room_data, std::shared_ptr<Message> message);
- std::shared_ptr<RoomData> get_room_by_id(const std::string &id);
- void add_room(std::shared_ptr<RoomData> room);
+ RoomData* get_room_by_id(const std::string &id);
+ void add_room(std::unique_ptr<RoomData> room);
DownloadResult download_json(rapidjson::Document &result, const std::string &url, std::vector<CommandArg> additional_args, bool use_browser_useragent = false, std::string *err_msg = nullptr) const;
private:
- std::vector<std::shared_ptr<RoomData>> rooms;
+ std::vector<std::unique_ptr<RoomData>> rooms;
std::unordered_map<std::string, size_t> room_data_by_id; // value is an index into |rooms|
size_t room_list_read_index = 0;
std::mutex room_data_mutex;
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index 659e59c..a32febb 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -2961,21 +2961,10 @@ namespace QuickMedia {
// This is needed to get initial data, with joined rooms etc. TODO: Remove this once its cached
// and allow asynchronous update of rooms
bool synced = false;
-
- struct RoomBodyData {
- std::shared_ptr<BodyItem> body_item;
- bool last_message_read;
- time_t last_read_message_timestamp;
- };
-
- std::unordered_map<std::shared_ptr<RoomData>, RoomBodyData> body_items_by_room;
- std::shared_ptr<RoomData> current_room;
- RoomBodyData *current_room_body_data = nullptr;
-
+ RoomData *current_room = nullptr;
bool is_window_focused = window.hasFocus();
- // TODO: Always keep the mentioned rooms at the top, and then the ones with unread messages below?
- auto process_new_room_messages = [this, &tabs, &body_items_by_room, &current_room, &is_window_focused](RoomSyncMessages &room_sync_messages, bool is_first_sync) mutable {
+ auto process_new_room_messages = [this, &tabs, &current_room, &is_window_focused](RoomSyncMessages &room_sync_messages, bool is_first_sync) mutable {
size_t room_swap_index = 0;
for(auto &[room, messages] : room_sync_messages) {
if(messages.empty())
@@ -2985,6 +2974,7 @@ namespace QuickMedia {
for(auto &message : messages) {
if(message->mentions_me) {
was_mentioned = true;
+ room->has_unread_mention = true;
//message->mentions_me = false;
// TODO: What if the message or username begins with "-"? also make the notification image be the avatar of the user
if(!is_window_focused || room != current_room)
@@ -2992,9 +2982,8 @@ namespace QuickMedia {
}
}
- auto room_body_item_it = body_items_by_room.find(room);
- if(room_body_item_it == body_items_by_room.end())
- continue;
+ BodyItem *room_body_item = static_cast<BodyItem*>(room->userdata);
+ assert(room_body_item);
// TODO: this wont always work because we dont display all types of messages from server, such as "joined", "left", "kicked", "banned", "changed avatar", "changed display name", etc.
bool unread_messages = false;
@@ -3006,19 +2995,20 @@ namespace QuickMedia {
std::string room_desc = "Unread: " + matrix->message_get_author_displayname(messages.back().get()) + ": " + extract_first_line(messages.back()->body, 150);
if(was_mentioned)
room_desc += "\n** You were mentioned **"; // TODO: Better notification?
- room_body_item_it->second.body_item->set_description(std::move(room_desc));
- room_body_item_it->second.body_item->set_title_color(sf::Color(255, 100, 100));
- room_body_item_it->second.last_message_read = false;
+ room_body_item->set_description(std::move(room_desc));
+ room_body_item->set_title_color(sf::Color(255, 100, 100));
+ room->last_message_read = false;
// Swap room with the top one
// TODO: Optimize with hash map instead of linear search? or cache the index
- int room_body_index = tabs[ROOMS_TAB_INDEX].body->get_index_by_body_item(room_body_item_it->second.body_item.get());
+ int room_body_index = tabs[ROOMS_TAB_INDEX].body->get_index_by_body_item(room_body_item);
if(room_body_index != -1) {
std::swap(tabs[ROOMS_TAB_INDEX].body->items[room_body_index], tabs[ROOMS_TAB_INDEX].body->items[room_swap_index]);
++room_swap_index;
}
} else if(is_first_sync) {
- room_body_item_it->second.body_item->set_description(matrix->message_get_author_displayname(messages.back().get()) + ": " + extract_first_line(messages.back()->body, 150));
+ room_body_item->set_description(matrix->message_get_author_displayname(messages.back().get()) + ": " + extract_first_line(messages.back()->body, 150));
+ room->has_unread_mention = false;
}
}
};
@@ -3058,14 +3048,6 @@ namespace QuickMedia {
bool redraw = true;
- auto get_room_by_ptr = [&body_items_by_room](RoomData *room_ptr) -> std::shared_ptr<RoomData> {
- for(auto &[room, body_data] : body_items_by_room) {
- if(room.get() == room_ptr)
- return room;
- }
- return nullptr;
- };
-
// TODO: Optimize with hash map?
auto find_body_item_by_event_id = [](std::shared_ptr<BodyItem> *body_items, size_t num_body_items, const std::string &event_id) -> std::shared_ptr<BodyItem> {
for(size_t i = 0; i < num_body_items; ++i) {
@@ -3077,7 +3059,7 @@ namespace QuickMedia {
};
// TODO: What if these never end up referencing events? clean up automatically after a while?
- std::unordered_map<std::shared_ptr<RoomData>, Messages> unreferenced_event_by_room;
+ std::unordered_map<RoomData*, Messages> unreferenced_event_by_room;
auto set_body_as_deleted = [](Message *message, BodyItem *body_item) {
body_item->embedded_item = nullptr;
@@ -3137,9 +3119,9 @@ namespace QuickMedia {
};
room_search_bar.onTextSubmitCallback =
- [this, &tabs, &selected_tab, &current_room, &current_room_body_data, &room_name_text,
- &get_room_by_ptr, &body_items_by_room, &modify_related_messages_in_current_room,
- &room_avatar_thumbnail_data, &read_marker_timeout_ms, &redraw]
+ [this, &tabs, &selected_tab, &current_room, &room_name_text,
+ &modify_related_messages_in_current_room, &room_avatar_thumbnail_data,
+ &read_marker_timeout_ms, &redraw]
(const std::string&)
{
BodyItem *selected_item = tabs[ROOMS_TAB_INDEX].body->get_selected();
@@ -3148,7 +3130,7 @@ namespace QuickMedia {
tabs[ROOMS_TAB_INDEX].body->clear_cache();
- current_room = get_room_by_ptr((RoomData*)selected_item->userdata);
+ current_room = (RoomData*)selected_item->userdata;
assert(current_room);
selected_tab = MESSAGES_TAB_INDEX;
tabs[MESSAGES_TAB_INDEX].body->clear_items();
@@ -3163,12 +3145,8 @@ namespace QuickMedia {
show_notification("QuickMedia", err_msg, Urgency::CRITICAL);
}
- auto room_body_item_it = body_items_by_room.find(current_room);
- if(room_body_item_it != body_items_by_room.end()) {
- current_room_body_data = &room_body_item_it->second;
- room_name_text.setString(current_room_body_data->body_item->get_title());
- room_avatar_thumbnail_data = std::make_shared<ThumbnailData>();
- }
+ room_name_text.setString(static_cast<BodyItem*>(current_room->userdata)->get_title());
+ room_avatar_thumbnail_data = std::make_shared<ThumbnailData>();
read_marker_timeout_ms = 0;
redraw = true;
@@ -3255,11 +3233,11 @@ namespace QuickMedia {
std::future<Messages> previous_messages_future;
bool fetching_previous_messages_running = false;
- std::shared_ptr<RoomData> previous_messages_future_room;
+ RoomData *previous_messages_future_room = nullptr;
std::future<std::shared_ptr<Message>> fetch_reply_message_future;
bool fetching_reply_message_running = false;
- std::shared_ptr<RoomData> fetch_reply_future_room;
+ RoomData *fetch_reply_future_room = nullptr;
BodyItem *fetch_reply_body_item = nullptr;
// TODO: How about instead fetching all messages we have, not only the visible ones? also fetch with multiple threads.
@@ -3287,7 +3265,7 @@ namespace QuickMedia {
body_item->embedded_item_status = EmbeddedItemStatus::LOADING;
// TODO: Check if the message is already cached before calling async? is this needed? is async creation expensive?
fetch_reply_message_future = std::async(std::launch::async, [this, &fetch_reply_future_room, message_event_id]() {
- return matrix->get_message_by_id(fetch_reply_future_room.get(), message_event_id);
+ return matrix->get_message_by_id(fetch_reply_future_room, message_event_id);
});
};
@@ -3318,7 +3296,7 @@ namespace QuickMedia {
float tab_vertical_offset = 0.0f;
- auto typing_async_func = [this](bool new_state, std::shared_ptr<RoomData> room) {
+ auto typing_async_func = [this](bool new_state, RoomData *room) {
if(new_state) {
matrix->on_start_typing(room);
} else {
@@ -3381,7 +3359,7 @@ namespace QuickMedia {
}
};
- auto add_new_rooms = [&tabs, &body_items_by_room, &current_room, &current_room_body_data, &room_name_text, &room_search_bar](Rooms &rooms) {
+ auto add_new_rooms = [&tabs, &current_room, &room_name_text, &room_search_bar](Rooms &rooms) {
if(rooms.empty())
return;
@@ -3395,23 +3373,19 @@ namespace QuickMedia {
auto body_item = BodyItem::create(std::move(room_name));
body_item->thumbnail_url = room->avatar_url;
- body_item->userdata = room.get(); // Note: this has to be valid as long as the room list is valid!
+ body_item->userdata = room; // Note: this has to be valid as long as the room list is valid!
body_item->thumbnail_mask_type = ThumbnailMaskType::CIRCLE;
body_item->thumbnail_size = sf::Vector2i(32, 32);
tabs[ROOMS_TAB_INDEX].body->filter_search_fuzzy_item(search_filter_text, body_item.get());
tabs[ROOMS_TAB_INDEX].body->items.push_back(body_item);
- body_items_by_room[room] = { body_item, true, 0 };
+ room->userdata = body_item.get();
}
if(current_room)
return;
current_room = rooms[0];
- auto room_body_item_it = body_items_by_room.find(current_room);
- if(room_body_item_it != body_items_by_room.end()) {
- current_room_body_data = &room_body_item_it->second;
- room_name_text.setString(current_room_body_data->body_item->get_title());
- }
+ room_name_text.setString(static_cast<BodyItem*>(current_room->userdata)->get_title());
};
float tab_shade_height = 0.0f;
@@ -3738,8 +3712,8 @@ namespace QuickMedia {
++it;
}
- if(current_room_body_data && room_avatar_thumbnail_data->loading_state == LoadingState::NOT_LOADED)
- async_image_loader.load_thumbnail(current_room_body_data->body_item->thumbnail_url, false, sf::Vector2i(32, 32), use_tor, room_avatar_thumbnail_data);
+ if(current_room && current_room->userdata && room_avatar_thumbnail_data->loading_state == LoadingState::NOT_LOADED)
+ async_image_loader.load_thumbnail(static_cast<BodyItem*>(current_room->userdata)->thumbnail_url, false, sf::Vector2i(32, 32), use_tor, room_avatar_thumbnail_data);
if(room_avatar_thumbnail_data->loading_state == LoadingState::FINISHED_LOADING && room_avatar_thumbnail_data->image->getSize().x > 0 && room_avatar_thumbnail_data->image->getSize().y > 0) {
if(!room_avatar_thumbnail_data->texture.loadFromImage(*room_avatar_thumbnail_data->image))
@@ -3987,20 +3961,23 @@ namespace QuickMedia {
tabs[MESSAGES_TAB_INDEX].body->draw_item(window, currently_operating_on_item.get(), body_item_pos, body_item_size);
}
- if(tabs[selected_tab].type == ChatTabType::MESSAGES && current_room_body_data) {
+ if(tabs[selected_tab].type == ChatTabType::MESSAGES && current_room && current_room->userdata) {
if(tabs[selected_tab].body->is_last_item_fully_visible()) {
- if(!current_room_body_data->last_message_read) {
- std::string room_desc = current_room_body_data->body_item->get_description();
+ if(!current_room->last_message_read) {
+ BodyItem *current_room_body_item = static_cast<BodyItem*>(current_room->userdata);
+ std::string room_desc = current_room_body_item->get_description();
if(strncmp(room_desc.c_str(), "Unread: ", 8) == 0)
room_desc = room_desc.substr(8);
if(room_desc.size() >= 25 && strncmp(room_desc.c_str() + room_desc.size() - 25, "\n** You were mentioned **", 25) == 0)
room_desc = room_desc.substr(0, room_desc.size() - 25);
- current_room_body_data->body_item->set_description(std::move(room_desc));
+ current_room_body_item->set_description(std::move(room_desc));
// TODO: Show a line like nheko instead for unread messages, or something else
- current_room_body_data->body_item->set_title_color(sf::Color::White);
- current_room_body_data->last_message_read = true;
+ current_room_body_item->set_title_color(sf::Color::White);
+ current_room->last_message_read = true;
+ // TODO: Maybe set this instead when the mention is visible on the screen?
+ current_room->has_unread_mention = false;
}
- } else if(!current_room_body_data->last_message_read) {
+ } else if(!current_room->last_message_read) {
window.draw(more_messages_below_rect);
}
}
@@ -4014,15 +3991,15 @@ namespace QuickMedia {
if(tabs[selected_tab].type == ChatTabType::MESSAGES && current_room) {
BodyItem *last_visible_item = tabs[selected_tab].body->get_last_fully_visible_item();
- if(is_window_focused && chat_state != ChatState::URL_SELECTION && current_room_body_data && last_visible_item && !setting_read_marker && read_marker_timer.getElapsedTime().asMilliseconds() >= read_marker_timeout_ms) {
+ if(is_window_focused && chat_state != ChatState::URL_SELECTION && current_room && last_visible_item && !setting_read_marker && read_marker_timer.getElapsedTime().asMilliseconds() >= read_marker_timeout_ms) {
Message *message = (Message*)last_visible_item->userdata;
// TODO: What if two messages have the same timestamp?
- if(message->timestamp > current_room_body_data->last_read_message_timestamp) {
+ if(message->timestamp > current_room->last_read_message_timestamp) {
read_marker_timeout_ms = read_marker_timeout_ms_default;
- current_room_body_data->last_read_message_timestamp = message->timestamp;
+ current_room->last_read_message_timestamp = message->timestamp;
// TODO: What if the message is no longer valid?
setting_read_marker = true;
- std::shared_ptr<RoomData> room = current_room;
+ RoomData *room = current_room;
set_read_marker_future = std::async(std::launch::async, [this, room, message]() mutable {
if(matrix->set_read_marker(room, message) != PluginResult::OK) {
fprintf(stderr, "Warning: failed to set read marker to %s\n", message->event_id.c_str());
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index bfdd496..35f5302 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -139,19 +139,23 @@ namespace QuickMedia {
void Matrix::get_room_join_updates(Rooms &new_rooms) {
std::lock_guard<std::mutex> lock(room_data_mutex);
- new_rooms.insert(new_rooms.end(), rooms.begin() + room_list_read_index, rooms.end());
size_t num_new_rooms = rooms.size() - room_list_read_index;
+ size_t new_rooms_prev_size = new_rooms.size();
+ new_rooms.resize(new_rooms_prev_size + num_new_rooms);
+ for(size_t i = new_rooms_prev_size; i < new_rooms.size(); ++i) {
+ new_rooms[i] = rooms[room_list_read_index + i].get();
+ }
room_list_read_index += num_new_rooms;
}
- PluginResult Matrix::get_all_synced_room_messages(std::shared_ptr<RoomData> room, Messages &messages) {
+ PluginResult Matrix::get_all_synced_room_messages(RoomData *room, Messages &messages) {
room->acquire_room_lock();
messages = room->get_messages_thread_unsafe();
room->release_room_lock();
return PluginResult::OK;
}
- PluginResult Matrix::get_previous_room_messages(std::shared_ptr<RoomData> room, Messages &messages) {
+ PluginResult Matrix::get_previous_room_messages(RoomData *room, Messages &messages) {
room->acquire_room_lock();
size_t num_messages_before = room->get_messages_thread_unsafe().size();
room->release_room_lock();
@@ -189,18 +193,19 @@ namespace QuickMedia {
std::string room_id_str = room_id.GetString();
- auto room = get_room_by_id(room_id_str);
+ RoomData *room = get_room_by_id(room_id_str);
if(!room) {
- room = std::make_shared<RoomData>();
- room->id = room_id_str;
- add_room(room);
+ auto new_room = std::make_unique<RoomData>();
+ new_room->id = room_id_str;
+ room = new_room.get();
+ add_room(std::move(new_room));
}
const rapidjson::Value &state_json = GetMember(it.value, "state");
if(state_json.IsObject()) {
const rapidjson::Value &events_json = GetMember(state_json, "events");
- events_add_user_info(events_json, room.get());
- events_set_room_name(events_json, room.get());
+ events_add_user_info(events_json, room);
+ events_set_room_name(events_json, room);
}
const rapidjson::Value &timeline_json = GetMember(it.value, "timeline");
@@ -222,15 +227,15 @@ namespace QuickMedia {
}
const rapidjson::Value &events_json = GetMember(timeline_json, "events");
- events_add_user_info(events_json, room.get());
+ events_add_user_info(events_json, room);
events_add_messages(events_json, room, MessageDirection::AFTER, &room_messages, has_unread_notifications);
- events_set_room_name(events_json, room.get());
+ events_set_room_name(events_json, room);
}
const rapidjson::Value &ephemeral_json = GetMember(it.value, "ephemeral");
if(ephemeral_json.IsObject()) {
const rapidjson::Value &events_json = GetMember(ephemeral_json, "events");
- events_add_user_read_markers(events_json, room.get());
+ events_add_user_read_markers(events_json, room);
}
}
@@ -443,7 +448,7 @@ namespace QuickMedia {
return false;
}
- void Matrix::events_add_messages(const rapidjson::Value &events_json, std::shared_ptr<RoomData> &room_data, MessageDirection message_dir, RoomSyncMessages *room_messages, bool has_unread_notifications) {
+ void Matrix::events_add_messages(const rapidjson::Value &events_json, RoomData *room_data, MessageDirection message_dir, RoomSyncMessages *room_messages, bool has_unread_notifications) {
if(!events_json.IsArray())
return;
@@ -451,7 +456,7 @@ namespace QuickMedia {
auto me = get_me(room_data);
for(const rapidjson::Value &event_item_json : events_json.GetArray()) {
- std::shared_ptr<Message> new_message = parse_message_event(event_item_json, room_data.get());
+ std::shared_ptr<Message> new_message = parse_message_event(event_item_json, room_data);
if(!new_message)
continue;
@@ -731,7 +736,7 @@ namespace QuickMedia {
}
}
- PluginResult Matrix::get_previous_room_messages(std::shared_ptr<RoomData> &room_data) {
+ PluginResult Matrix::get_previous_room_messages(RoomData *room_data) {
std::string from = room_data->prev_batch;
if(from.empty()) {
fprintf(stderr, "Info: missing previous batch for room: %s, using /sync next batch\n", room_data->id.c_str());
@@ -766,8 +771,8 @@ namespace QuickMedia {
return PluginResult::ERR;
const rapidjson::Value &state_json = GetMember(json_root, "state");
- events_add_user_info(state_json, room_data.get());
- events_set_room_name(state_json, room_data.get());
+ events_add_user_info(state_json, room_data);
+ events_set_room_name(state_json, room_data);
const rapidjson::Value &chunk_json = GetMember(json_root, "chunk");
events_add_messages(chunk_json, room_data, MessageDirection::BEFORE, nullptr, false);
@@ -818,7 +823,7 @@ namespace QuickMedia {
return "m.file";
}
- PluginResult Matrix::post_message(std::shared_ptr<RoomData> room, const std::string &body, const std::optional<UploadInfo> &file_info, const std::optional<UploadInfo> &thumbnail_info) {
+ PluginResult Matrix::post_message(RoomData *room, const std::string &body, const std::optional<UploadInfo> &file_info, const std::optional<UploadInfo> &thumbnail_info) {
char random_characters[18];
if(!generate_random_characters(random_characters, sizeof(random_characters)))
return PluginResult::ERR;
@@ -990,11 +995,11 @@ namespace QuickMedia {
}
// TODO: Support greentext
- PluginResult Matrix::post_reply(std::shared_ptr<RoomData> room, const std::string &body, void *relates_to) {
+ PluginResult Matrix::post_reply(RoomData *room, const std::string &body, void *relates_to) {
// TODO: Store shared_ptr<Message> instead of raw pointer...
Message *relates_to_message_raw = (Message*)relates_to;
std::shared_ptr<Message> relates_to_message_shared = room->get_message_by_id(relates_to_message_raw->event_id);
- std::shared_ptr<Message> relates_to_message_original = get_edited_message_original_message(room.get(), relates_to_message_shared);
+ std::shared_ptr<Message> relates_to_message_original = get_edited_message_original_message(room, relates_to_message_shared);
if(!relates_to_message_original) {
fprintf(stderr, "Failed to get the original message for message with event id: %s\n", relates_to_message_raw->event_id.c_str());
return PluginResult::ERR;
@@ -1051,10 +1056,10 @@ namespace QuickMedia {
return PluginResult::OK;
}
- PluginResult Matrix::post_edit(std::shared_ptr<RoomData> room, const std::string &body, void *relates_to) {
+ PluginResult Matrix::post_edit(RoomData *room, const std::string &body, void *relates_to) {
Message *relates_to_message_raw = (Message*)relates_to;
std::shared_ptr<Message> relates_to_message_shared = room->get_message_by_id(relates_to_message_raw->event_id);
- std::shared_ptr<Message> relates_to_message_original = get_edited_message_original_message(room.get(), relates_to_message_shared);
+ std::shared_ptr<Message> relates_to_message_original = get_edited_message_original_message(room, relates_to_message_shared);
if(!relates_to_message_original) {
fprintf(stderr, "Failed to get the original message for message with event id: %s\n", relates_to_message_raw->event_id.c_str());
return PluginResult::ERR;
@@ -1205,7 +1210,7 @@ namespace QuickMedia {
return filename;
}
- PluginResult Matrix::post_file(std::shared_ptr<RoomData> room, const std::string &filepath, std::string &err_msg) {
+ PluginResult Matrix::post_file(RoomData *room, const std::string &filepath, std::string &err_msg) {
UploadInfo file_info;
UploadInfo thumbnail_info;
PluginResult upload_file_result = upload_file(room, filepath, file_info, thumbnail_info, err_msg);
@@ -1221,7 +1226,7 @@ namespace QuickMedia {
return post_message(room, filename, file_info_opt, thumbnail_info_opt);
}
- PluginResult Matrix::upload_file(std::shared_ptr<RoomData> room, const std::string &filepath, UploadInfo &file_info, UploadInfo &thumbnail_info, std::string &err_msg) {
+ PluginResult Matrix::upload_file(RoomData *room, const std::string &filepath, UploadInfo &file_info, UploadInfo &thumbnail_info, std::string &err_msg) {
FileAnalyzer file_analyzer;
if(!file_analyzer.load_file(filepath.c_str())) {
err_msg = "Failed to load " + filepath;
@@ -1400,6 +1405,7 @@ namespace QuickMedia {
// Make sure all fields are reset here!
rooms.clear();
+ room_list_read_index = 0;
room_data_by_id.clear();
user_id.clear();
username.clear();
@@ -1411,7 +1417,7 @@ namespace QuickMedia {
return PluginResult::OK;
}
- PluginResult Matrix::delete_message(std::shared_ptr<RoomData> room, void *message, std::string &err_msg){
+ 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)))
return PluginResult::ERR;
@@ -1517,7 +1523,7 @@ namespace QuickMedia {
return PluginResult::OK;
}
- PluginResult Matrix::on_start_typing(std::shared_ptr<RoomData> room) {
+ PluginResult Matrix::on_start_typing(RoomData *room) {
rapidjson::Document request_data(rapidjson::kObjectType);
request_data.AddMember("typing", true, request_data.GetAllocator());
request_data.AddMember("timeout", 30000, request_data.GetAllocator()); // 30 sec timeout
@@ -1540,7 +1546,7 @@ namespace QuickMedia {
return PluginResult::OK;
}
- PluginResult Matrix::on_stop_typing(std::shared_ptr<RoomData> room) {
+ PluginResult Matrix::on_stop_typing(RoomData *room) {
rapidjson::Document request_data(rapidjson::kObjectType);
request_data.AddMember("typing", false, request_data.GetAllocator());
@@ -1562,7 +1568,7 @@ namespace QuickMedia {
return PluginResult::OK;
}
- PluginResult Matrix::set_read_marker(std::shared_ptr<RoomData> room, const Message *message) {
+ PluginResult Matrix::set_read_marker(RoomData *room, const Message *message) {
rapidjson::Document request_data(rapidjson::kObjectType);
request_data.AddMember("m.fully_read", rapidjson::StringRef(message->event_id.c_str()), request_data.GetAllocator());
request_data.AddMember("m.read", rapidjson::StringRef(message->event_id.c_str()), request_data.GetAllocator());
@@ -1628,22 +1634,22 @@ namespace QuickMedia {
return PluginResult::OK;
}
- std::shared_ptr<UserInfo> Matrix::get_me(std::shared_ptr<RoomData> room) {
+ std::shared_ptr<UserInfo> Matrix::get_me(RoomData *room) {
return room->get_user_by_id(user_id);
}
- std::shared_ptr<RoomData> Matrix::get_room_by_id(const std::string &id) {
+ RoomData* Matrix::get_room_by_id(const std::string &id) {
std::lock_guard<std::mutex> lock(room_data_mutex);
auto room_it = room_data_by_id.find(id);
if(room_it == room_data_by_id.end())
return nullptr;
- return rooms[room_it->second];
+ return rooms[room_it->second].get();
}
- void Matrix::add_room(std::shared_ptr<RoomData> room) {
+ void Matrix::add_room(std::unique_ptr<RoomData> room) {
std::lock_guard<std::mutex> lock(room_data_mutex);
room_data_by_id.insert(std::make_pair(room->id, rooms.size()));
- rooms.push_back(room);
+ rooms.push_back(std::move(room));
}
DownloadResult Matrix::download_json(rapidjson::Document &result, const std::string &url, std::vector<CommandArg> additional_args, bool use_browser_useragent, std::string *err_msg) const {