#pragma once #include "Plugin.hpp" #include #include namespace QuickMedia { struct UserInfo { std::string user_id; std::string display_name; std::string avatar_url; sf::Color display_name_color; }; enum class MessageType { TEXT, IMAGE, VIDEO }; struct Message { // Index into |RoomData.user_info| size_t user_id; std::string event_id; std::string body; std::string url; std::string thumbnail_url; std::string replaces_event_id; MessageType type; }; struct MessageInfo { int size = 0; int w = 0; int h = 0; const char* mimetype = nullptr; }; struct RoomData { std::string id; // Each room has its own list of user data, even if multiple rooms has the same user // because users can have different display names and avatars in different rooms. // The value is an index to |user_info|. std::unordered_map user_info_by_user_id; std::vector user_info; std::vector> messages; std::unordered_map> message_by_event_id; std::string name; std::string avatar_url; std::string prev_batch; bool initial_fetch_finished = false; size_t last_read_index = 0; }; enum class MessageDirection { BEFORE, AFTER }; class Matrix : public Plugin { public: Matrix(); virtual ~Matrix() = default; bool search_is_filter() override { return true; } bool search_suggestions_has_thumbnails() const override { return true; } bool search_results_has_thumbnails() const override { return false; } int get_search_delay() const override { return 0; } bool search_suggestion_is_search() const override { return true; } Page get_page_after_search() const override { return Page::EXIT; } PluginResult get_cached_sync(BodyItems &result_items); PluginResult sync(); PluginResult get_joined_rooms(BodyItems &result_items); PluginResult get_all_synced_room_messages(const std::string &room_id, BodyItems &result_items); PluginResult get_new_room_messages(const std::string &room_id, BodyItems &result_items); PluginResult get_previous_room_messages(const std::string &room_id, BodyItems &result_items); SearchResult search(const std::string &text, BodyItems &result_items) override; // |url| should only be set when uploading media. // TODO: Make api better. PluginResult post_message(const std::string &room_id, const std::string &body, const std::string &url = "", MessageType msgtype = MessageType::TEXT, MessageInfo *info = nullptr); // |relates_to| is from |BodyItem.userdata| and is of type |Message*| PluginResult post_reply(const std::string &room_id, const std::string &body, void *relates_to); // |relates_to| is from |BodyItem.userdata| and is of type |Message*| PluginResult post_edit(const std::string &room_id, const std::string &body, void *relates_to); // TODO: Make this work for all image types and videos and regular files PluginResult post_file(const std::string &room_id, const std::string &filepath); 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); PluginResult on_stop_typing(const std::string &room_id); // |message| is from |BodyItem.userdata| and is of type |Message*| bool was_message_posted_by_me(const std::string &room_id, void *message) const; private: PluginResult sync_response_to_body_items(const Json::Value &root); PluginResult get_previous_room_messages(const std::string &room_id, RoomData *room_data); void events_add_user_info(const Json::Value &events_json, RoomData *room_data); void events_add_messages(const Json::Value &events_json, RoomData *room_data, MessageDirection message_dir); void events_set_room_name(const Json::Value &events_json, RoomData *room_data); std::shared_ptr get_edited_message_original_message(RoomData *room_data, std::shared_ptr message); private: std::unordered_map> room_data_by_id; std::string user_id; std::string access_token; std::string homeserver; std::string next_batch; }; }