From 7292fe11254109266e7adb9937e5f0fa797711f6 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sun, 1 Nov 2020 12:19:30 +0100 Subject: Matrix: add invites tab, add /leave command, remove room when leaving, add async loading for more tasks --- plugins/Matrix.hpp | 98 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 89 insertions(+), 9 deletions(-) (limited to 'plugins') diff --git a/plugins/Matrix.hpp b/plugins/Matrix.hpp index 281f5a8..3d3c4b2 100644 --- a/plugins/Matrix.hpp +++ b/plugins/Matrix.hpp @@ -49,7 +49,7 @@ namespace QuickMedia { sf::Vector2i thumbnail_size; // Set to {0, 0} if not specified RelatedEventType related_event_type; bool mentions_me = false; - time_t timestamp = 0; + time_t timestamp = 0; // In milliseconds MessageType type; }; @@ -91,6 +91,8 @@ namespace QuickMedia { void set_pinned_events(std::vector new_pinned_events); std::set& get_tags_unsafe(); + void clear_data(); + std::string id; bool initial_fetch_finished = false; @@ -126,6 +128,14 @@ namespace QuickMedia { std::set tags; }; + struct Invite { + std::string room_name; + std::string room_avatar_url; + std::shared_ptr invited_by; + time_t timestamp = 0; // In milliseconds + bool new_invite = false; + }; + enum class MessageDirection { BEFORE, AFTER @@ -156,46 +166,65 @@ namespace QuickMedia { CHAT }; + enum class LeaveType { + LEAVE, + KICKED, + BANNED + }; + class MatrixDelegate { public: virtual ~MatrixDelegate() = default; - virtual void room_create(RoomData *room) = 0; + virtual void join_room(RoomData *room) = 0; + virtual void leave_room(RoomData *room, LeaveType leave_type, const std::string &reason) = 0; + // Note: calling |room| methods inside this function is not allowed virtual void room_add_tag(RoomData *room, const std::string &tag) = 0; // Note: calling |room| methods inside this function is not allowed virtual void room_remove_tag(RoomData *room, const std::string &tag) = 0; virtual void room_add_new_messages(RoomData *room, const Messages &messages, bool is_initial_sync) = 0; + virtual void add_invite(const std::string &room_id, const Invite &invite) = 0; + virtual void remove_invite(const std::string &room_id) = 0; + virtual void update(MatrixPageType page_type) { (void)page_type; } }; class Matrix; class MatrixRoomsPage; class MatrixRoomTagsPage; + class MatrixInvitesPage; + class MatrixChatPage; class MatrixQuickMedia : public MatrixDelegate { public: - MatrixQuickMedia(Program *program, Matrix *matrix, MatrixRoomsPage *rooms_page, MatrixRoomTagsPage *room_tags_page); + MatrixQuickMedia(Program *program, Matrix *matrix, MatrixRoomsPage *rooms_page, MatrixRoomTagsPage *room_tags_page, MatrixInvitesPage *invites_page); - void room_create(RoomData *room) override; + void join_room(RoomData *room) override; + void leave_room(RoomData *room, LeaveType leave_type, const std::string &reason) override; void room_add_tag(RoomData *room, const std::string &tag) override; void room_remove_tag(RoomData *room, const std::string &tag) override; void room_add_new_messages(RoomData *room, const Messages &messages, bool is_initial_sync) override; + void add_invite(const std::string &room_id, const Invite &invite) override; + void remove_invite(const std::string &room_id) override; + void update(MatrixPageType page_type) override; Program *program; Matrix *matrix; MatrixRoomsPage *rooms_page; MatrixRoomTagsPage *room_tags_page; + MatrixInvitesPage *invites_page; + private: + void update_pending_room_messages(MatrixPageType page_type); private: struct RoomMessagesData { Messages messages; bool is_initial_sync; }; - std::vector> room_body_items; std::map> room_body_item_by_room; std::map pending_room_messages; std::mutex pending_room_messages_mutex; @@ -213,14 +242,19 @@ namespace QuickMedia { void add_body_item(std::shared_ptr body_item); void move_room_to_top(RoomData *room); + void remove_body_item_by_room_id(const std::string &room_id); + + void set_current_chat_page(MatrixChatPage *chat_page); MatrixQuickMedia *matrix_delegate = nullptr; private: std::mutex mutex; std::vector> room_body_items; + std::vector pending_remove_body_items; Body *body; std::string title; MatrixRoomTagsPage *room_tags_page; + MatrixChatPage *current_chat_page; }; class MatrixRoomTagsPage : public Page { @@ -234,20 +268,56 @@ namespace QuickMedia { void remove_room_body_item_from_tag(std::shared_ptr body_item, const std::string &tag); void move_room_to_top(RoomData *room); + void remove_body_item_by_room_id(const std::string &room_id); + + void set_current_rooms_page(MatrixRoomsPage *rooms_page); MatrixQuickMedia *matrix_delegate = nullptr; - MatrixRoomsPage *current_rooms_page = nullptr; private: struct TagData { std::shared_ptr tag_item; std::vector> room_body_items; }; - std::mutex mutex; + std::recursive_mutex mutex; Body *body; std::map tag_body_items_by_name; std::map>> add_room_body_items_by_tags; std::map>> remove_room_body_items_by_tags; + MatrixRoomsPage *current_rooms_page = nullptr; + }; + + class MatrixInvitesPage : public Page { + public: + MatrixInvitesPage(Program *program, Matrix *matrix, Body *body); + + const char* get_title() const override { return title.c_str(); } + PluginResult submit(const std::string &title, const std::string &url, std::vector &result_tabs) override; + + void update() override; + void add_body_item(std::shared_ptr body_item); + void remove_body_item_by_room_id(const std::string &room_id); + private: + Matrix *matrix; + std::mutex mutex; + std::vector> body_items; + std::vector pending_remove_body_items; + Body *body; + std::string title = "Invites (0)"; + size_t prev_invite_count = 0; + }; + + class MatrixInviteDetailsPage : public Page { + public: + MatrixInviteDetailsPage(Program *program, Matrix *matrix, MatrixInvitesPage *invites_page, std::string room_id, std::string title) : + Page(program), matrix(matrix), invites_page(invites_page), room_id(std::move(room_id)), title(std::move(title)) {} + const char* get_title() const override { return title.c_str(); } + PluginResult submit(const std::string &title, const std::string &url, std::vector &result_tabs) override; + + Matrix *matrix; + MatrixInvitesPage *invites_page; + const std::string room_id; + const std::string title; }; // Dummy, only play one video. TODO: Play all videos in room, as related videos? @@ -266,7 +336,9 @@ namespace QuickMedia { class MatrixChatPage : public Page { public: - MatrixChatPage(Program *program, std::string room_id) : Page(program), room_id(std::move(room_id)) {} + MatrixChatPage(Program *program, std::string room_id, MatrixRoomsPage *rooms_page); + ~MatrixChatPage() override; + const char* get_title() const override { return ""; } PluginResult submit(const std::string &title, const std::string &url, std::vector &result_tabs) override { (void)title; @@ -279,6 +351,7 @@ namespace QuickMedia { const std::string room_id; MatrixQuickMedia *matrix_delegate = nullptr; + MatrixRoomsPage *rooms_page = nullptr; }; class Matrix { @@ -314,6 +387,9 @@ namespace QuickMedia { PluginResult set_read_marker(RoomData *room, const Message *message); + PluginResult join_room(const std::string &room_id); + PluginResult leave_room(const std::string &room_id); + // |message| is from |BodyItem.userdata| and is of type |Message*| bool was_message_posted_by_me(void *message); @@ -341,14 +417,16 @@ namespace QuickMedia { void events_set_room_name(const rapidjson::Value &events_json, RoomData *room_data); void events_add_pinned_events(const rapidjson::Value &events_json, RoomData *room_data); void events_add_room_to_tags(const rapidjson::Value &events_json, RoomData *room_data, MatrixDelegate *delegate); + void add_invites(const rapidjson::Value &invite_json, MatrixDelegate *delegate); + void remove_rooms(const rapidjson::Value &leave_json, MatrixDelegate *delegate); std::shared_ptr parse_message_event(const rapidjson::Value &event_item_json, RoomData *room_data); PluginResult upload_file(RoomData *room, const std::string &filepath, UploadInfo &file_info, UploadInfo &thumbnail_info, std::string &err_msg); void add_room(std::unique_ptr room); + void remove_room(const std::string &room_id); DownloadResult download_json(rapidjson::Document &result, const std::string &url, std::vector additional_args, bool use_browser_useragent = false, std::string *err_msg = nullptr) const; private: std::vector> rooms; std::unordered_map room_data_by_id; // value is an index into |rooms| - size_t room_list_read_index = 0; std::mutex room_data_mutex; std::string user_id; std::string username; @@ -357,6 +435,8 @@ namespace QuickMedia { std::optional upload_limit; std::string next_batch; + std::unordered_map invites; + std::thread sync_thread; bool sync_running = false; }; -- cgit v1.2.3