aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2021-05-20 22:33:32 +0200
committerdec05eba <dec05eba@protonmail.com>2021-05-20 22:33:32 +0200
commit80b48b270ed66e3557b98d9fc8e82ad868bcde80 (patch)
tree74e553cbcfbfed4eb6f5a2a931e46689e43a38cf /plugins
parent5b11322c33ef61d3aa8d6bc9c9bc0355f35afa52 (diff)
Add notifications tab to matrix
Diffstat (limited to 'plugins')
-rw-r--r--plugins/Matrix.hpp48
-rw-r--r--plugins/Page.hpp2
2 files changed, 43 insertions, 7 deletions
diff --git a/plugins/Matrix.hpp b/plugins/Matrix.hpp
index bff89b2..bcb4058 100644
--- a/plugins/Matrix.hpp
+++ b/plugins/Matrix.hpp
@@ -227,6 +227,15 @@ namespace QuickMedia {
BANNED
};
+ struct MatrixNotification {
+ RoomData *room;
+ std::string event_id;
+ std::string sender_user_id;
+ std::string body; // Without reply formatting
+ time_t timestamp; // The timestamp in milliseconds or 0
+ bool read;
+ };
+
// All of methods in this class are called in the main (ui) thread
class MatrixDelegate {
public:
@@ -244,7 +253,7 @@ namespace QuickMedia {
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 add_unread_notification(RoomData *room, std::string event_id, std::string sender, std::string body) = 0;
+ virtual void add_unread_notification(MatrixNotification notification) = 0;
virtual void add_user(MatrixEventUserInfo user_info) = 0;
virtual void remove_user(MatrixEventUserInfo user_info) = 0;
@@ -258,12 +267,13 @@ namespace QuickMedia {
class MatrixRoomTagsPage;
class MatrixInvitesPage;
class MatrixChatPage;
+ class MatrixNotificationsPage;
using UsersByRoom = std::unordered_multimap<RoomData*, MatrixEventUserInfo>;
class MatrixQuickMedia : public MatrixDelegate {
public:
- MatrixQuickMedia(Program *program, Matrix *matrix, MatrixRoomsPage *rooms_page, MatrixRoomTagsPage *room_tags_page, MatrixInvitesPage *invites_page);
+ MatrixQuickMedia(Program *program, Matrix *matrix, MatrixRoomsPage *rooms_page, MatrixRoomTagsPage *room_tags_page, MatrixInvitesPage *invites_page, MatrixNotificationsPage *notifications_page);
void join_room(RoomData *room) override;
void leave_room(RoomData *room, LeaveType leave_type, const std::string &reason) override;
@@ -274,13 +284,15 @@ namespace QuickMedia {
void add_invite(const std::string &room_id, const Invite &invite) override;
void remove_invite(const std::string &room_id) override;
- void add_unread_notification(RoomData *room, std::string event_id, std::string sender, std::string body) override;
+ void add_unread_notification(MatrixNotification notification) override;
void add_user(MatrixEventUserInfo user_info) override;
void remove_user(MatrixEventUserInfo user_info) override;
void set_user_info(MatrixEventUserInfo user_info) override;
void for_each_user_in_room(RoomData *room, std::function<void(const MatrixEventUserInfo&)> callback);
+ void set_room_as_read(RoomData *room);
+
void clear_data() override;
Program *program;
@@ -289,6 +301,7 @@ namespace QuickMedia {
MatrixRoomsPage *rooms_page;
MatrixRoomTagsPage *room_tags_page;
MatrixInvitesPage *invites_page;
+ MatrixNotificationsPage *notifications_page;
private:
void update_room_description(RoomData *room, const Messages &new_messages, bool is_initial_sync, bool sync_is_cache);
private:
@@ -315,6 +328,8 @@ namespace QuickMedia {
void set_current_chat_page(MatrixChatPage *chat_page);
+ void set_room_as_read(RoomData *room);
+
void clear_data();
MatrixQuickMedia *matrix_delegate = nullptr;
@@ -419,6 +434,8 @@ namespace QuickMedia {
void set_current_room(RoomData *room, Body *users_body);
size_t get_num_users_in_current_room() const;
+ void set_room_as_read(RoomData *room);
+
const std::string room_id;
MatrixRoomsPage *rooms_page = nullptr;
bool should_clear_data = false;
@@ -458,14 +475,21 @@ namespace QuickMedia {
int current_page;
};
- class MatrixNotificationsPage : public Page {
+ class MatrixNotificationsPage : public LazyFetchPage {
public:
- MatrixNotificationsPage(Program *program, Body *notifications_body) : Page(program), notifications_body(notifications_body) {}
- const char* get_title() const override { return "Notifications (0)"; }
+ MatrixNotificationsPage(Program *program, Matrix *matrix, Body *notifications_body);
+ const char* get_title() const override { return "Notifications"; }
PluginResult submit(const std::string&, const std::string&, std::vector<Tab>&) override {
return PluginResult::OK;
}
+ PluginResult get_page(const std::string &str, int page, BodyItems &result_items) override;
+ PluginResult lazy_fetch(BodyItems &result_items) override;
+ bool is_ready() override;
+
+ void add_notification(MatrixNotification notification);
+ void set_room_as_read(RoomData *room);
private:
+ Matrix *matrix;
Body *notifications_body;
};
@@ -477,11 +501,14 @@ namespace QuickMedia {
bool is_initial_sync_finished() const;
// Returns true if initial sync failed, and |err_msg| is set to the error reason in that case
bool did_initial_sync_fail(std::string &err_msg);
+ bool has_finished_fetching_notifications() const;
void get_room_sync_data(RoomData *room, SyncData &sync_data);
void get_all_synced_room_messages(RoomData *room, Messages &messages);
void get_all_pinned_events(RoomData *room, std::vector<std::string> &events);
PluginResult get_previous_room_messages(RoomData *room, Messages &messages, bool latest_messages = false);
+ PluginResult get_previous_notifications(std::function<void(const MatrixNotification&)> callback_func);
+ void get_cached_notifications(std::function<void(const MatrixNotification&)> callback_func);
// |url| should only be set when uploading media.
// TODO: Make api better.
@@ -546,7 +573,7 @@ namespace QuickMedia {
PluginResult set_qm_last_read_message_timestamp(RoomData *room, int64_t timestamp);
PluginResult parse_sync_response(const rapidjson::Document &root, bool is_additional_messages_sync, bool initial_sync);
- PluginResult parse_notifications(const rapidjson::Value &notifications_json);
+ PluginResult parse_notifications(const rapidjson::Value &notifications_json, std::function<void(const MatrixNotification&)> callback_func);
PluginResult parse_sync_account_data(const rapidjson::Value &account_data_json, std::optional<std::set<std::string>> &dm_rooms);
PluginResult parse_sync_room_data(const rapidjson::Value &rooms_json, bool is_additional_messages_sync, bool initial_sync);
PluginResult get_previous_room_messages(RoomData *room_data, bool latest_messages, size_t &num_new_messages);
@@ -571,6 +598,8 @@ namespace QuickMedia {
bool remove_invite(const std::string &room_id);
void set_next_batch(std::string new_next_batch);
std::string get_next_batch();
+ void set_next_notifications_token(std::string new_next_token);
+ std::string get_next_notifications_token();
void clear_sync_cache_for_new_sync();
std::shared_ptr<UserInfo> get_user_by_id(RoomData *room, const std::string &user_id, bool *is_new_user = nullptr, bool create_if_not_found = true);
std::string get_filter_cached();
@@ -585,11 +614,15 @@ namespace QuickMedia {
std::string homeserver_domain;
std::optional<int> upload_limit;
std::string next_batch;
+ std::string next_notifications_token;
std::mutex next_batch_mutex;
std::unordered_map<std::string, Invite> invites;
std::mutex invite_mutex;
+ std::vector<MatrixNotification> notifications;
+ std::mutex notifications_mutex;
+
std::thread sync_thread;
std::thread sync_additional_messages_thread;
std::thread notification_thread;
@@ -597,6 +630,7 @@ namespace QuickMedia {
bool sync_running = false;
bool sync_failed = false;
bool sync_is_cache = false;
+ bool finished_fetching_notifications = false;
std::string sync_fail_reason;
MatrixDelegate *delegate = nullptr;
std::optional<std::string> filter_cached;
diff --git a/plugins/Page.hpp b/plugins/Page.hpp
index be6eb76..db27fae 100644
--- a/plugins/Page.hpp
+++ b/plugins/Page.hpp
@@ -51,6 +51,8 @@ namespace QuickMedia {
virtual bool is_lazy_fetch_page() const { return false; }
// Note: If submit is done without any selection, then the search term is sent as the |title|, not |url|. Submit will only be sent if the input text is not empty or if an item is selected
virtual bool allow_submit_no_selection() const { return false; }
+ // This is used to delay loading of the page. For example if the page relies on an external factor to start loading
+ virtual bool is_ready() { return true; }
// This is called both when first navigating to page and when going back to page
virtual void on_navigate_to_page(Body *body) { (void)body; }