aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2020-11-01 12:19:30 +0100
committerdec05eba <dec05eba@protonmail.com>2020-11-01 12:19:30 +0100
commit7292fe11254109266e7adb9937e5f0fa797711f6 (patch)
treea581c05e0f0b795646fb1458ce118adf5bb5bd88 /plugins
parent2278d52b59e9818f08bd73ec6583a1589d9512f2 (diff)
Matrix: add invites tab, add /leave command, remove room when leaving, add async loading for more tasks
Diffstat (limited to 'plugins')
-rw-r--r--plugins/Matrix.hpp98
1 files changed, 89 insertions, 9 deletions
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<std::string> new_pinned_events);
std::set<std::string>& get_tags_unsafe();
+ void clear_data();
+
std::string id;
bool initial_fetch_finished = false;
@@ -126,6 +128,14 @@ namespace QuickMedia {
std::set<std::string> tags;
};
+ struct Invite {
+ std::string room_name;
+ std::string room_avatar_url;
+ std::shared_ptr<UserInfo> 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<std::shared_ptr<BodyItem>> room_body_items;
std::map<RoomData*, std::shared_ptr<BodyItem>> room_body_item_by_room;
std::map<RoomData*, RoomMessagesData> pending_room_messages;
std::mutex pending_room_messages_mutex;
@@ -213,14 +242,19 @@ namespace QuickMedia {
void add_body_item(std::shared_ptr<BodyItem> 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<std::shared_ptr<BodyItem>> room_body_items;
+ std::vector<std::string> 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<BodyItem> 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<BodyItem> tag_item;
std::vector<std::shared_ptr<BodyItem>> room_body_items;
};
- std::mutex mutex;
+ std::recursive_mutex mutex;
Body *body;
std::map<std::string, TagData> tag_body_items_by_name;
std::map<std::string, std::vector<std::shared_ptr<BodyItem>>> add_room_body_items_by_tags;
std::map<std::string, std::vector<std::shared_ptr<BodyItem>>> 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<Tab> &result_tabs) override;
+
+ void update() override;
+ void add_body_item(std::shared_ptr<BodyItem> body_item);
+ void remove_body_item_by_room_id(const std::string &room_id);
+ private:
+ Matrix *matrix;
+ std::mutex mutex;
+ std::vector<std::shared_ptr<BodyItem>> body_items;
+ std::vector<std::string> 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<Tab> &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<Tab> &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<Message> 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<RoomData> room);
+ void remove_room(const std::string &room_id);
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::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;
std::string user_id;
std::string username;
@@ -357,6 +435,8 @@ namespace QuickMedia {
std::optional<int> upload_limit;
std::string next_batch;
+ std::unordered_map<std::string, Invite> invites;
+
std::thread sync_thread;
bool sync_running = false;
};