aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2022-11-12 19:05:13 +0100
committerdec05eba <dec05eba@protonmail.com>2022-11-12 19:05:13 +0100
commit01f23292bf2451a0c7b9ada88c6314dcb09509b1 (patch)
tree2423c0abecd39f314f3475b2288d68a702fd6344
parent224a5f3b2ed2141a94940fe73fc8ccb4b2f8d962 (diff)
Matrix: add option to silence invites without declining them or hiding them (ignore)
-rw-r--r--include/Path.hpp5
-rw-r--r--include/StringUtils.hpp4
-rw-r--r--plugins/Matrix.hpp5
-rw-r--r--src/StringUtils.cpp16
-rw-r--r--src/plugins/Matrix.cpp56
5 files changed, 73 insertions, 13 deletions
diff --git a/include/Path.hpp b/include/Path.hpp
index 3d849e2..c9047be 100644
--- a/include/Path.hpp
+++ b/include/Path.hpp
@@ -22,6 +22,11 @@ namespace QuickMedia {
return *this;
}
+ Path& append(const char *str) {
+ data += str;
+ return *this;
+ }
+
// Includes extension
const char* filename() const {
size_t index = data.rfind('/');
diff --git a/include/StringUtils.hpp b/include/StringUtils.hpp
index fb16d7a..2a01f54 100644
--- a/include/StringUtils.hpp
+++ b/include/StringUtils.hpp
@@ -7,8 +7,8 @@ namespace QuickMedia {
// Return false to stop iterating
using StringSplitCallback = std::function<bool(const char *str, size_t size)>;
- void string_split(const std::string &str, const std::string &delimiter, StringSplitCallback callback_func);
- void string_split(const std::string &str, char delimiter, StringSplitCallback callback_func);
+ void string_split(const std::string &str, const std::string &delimiter, StringSplitCallback callback_func, bool include_empty = true);
+ void string_split(const std::string &str, char delimiter, StringSplitCallback callback_func, bool include_empty = true);
// Returns the number of replaced substrings
size_t string_replace_all(std::string &str, char old_char, char new_char);
// Returns the number of replaced substrings
diff --git a/plugins/Matrix.hpp b/plugins/Matrix.hpp
index 61239fe..788050b 100644
--- a/plugins/Matrix.hpp
+++ b/plugins/Matrix.hpp
@@ -671,6 +671,9 @@ namespace QuickMedia {
PluginResult join_room(const std::string &room_id_or_name);
PluginResult leave_room(const std::string &room_id);
+ bool is_invite_silenced(const std::string &room_id, int64_t timestamp);
+ void silence_invite(const std::string &room_id, int64_t timestamp);
+
// If |since| is empty, then the first page is fetched
PluginResult get_public_rooms(const std::string &server, const std::string &search_term, const std::string &since, BodyItems &rooms, std::string &next_batch);
@@ -754,6 +757,7 @@ namespace QuickMedia {
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();
+ void load_silenced_invites();
private:
MessageQueue<std::function<void()>> ui_thread_tasks;
std::vector<std::unique_ptr<RoomData>> rooms;
@@ -793,5 +797,6 @@ namespace QuickMedia {
std::unordered_set<std::string> my_events_transaction_ids;
std::unordered_map<std::string, CustomEmoji> custom_emoji_by_key;
+ std::unordered_set<std::string> silenced_invites;
};
} \ No newline at end of file
diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp
index 927c6e1..bc59730 100644
--- a/src/StringUtils.cpp
+++ b/src/StringUtils.cpp
@@ -3,15 +3,17 @@
namespace QuickMedia {
template <typename T>
- static void string_split_t(const std::string &str, const T &delimiter, StringSplitCallback callback_func) {
+ static void string_split_t(const std::string &str, const T &delimiter, StringSplitCallback callback_func, bool include_empty) {
size_t index = 0;
while(index < str.size()) {
size_t new_index = str.find(delimiter, index);
if(new_index == std::string::npos)
new_index = str.size();
- if(!callback_func(str.data() + index, new_index - index))
- break;
+ if(include_empty || new_index - index > 0) {
+ if(!callback_func(str.data() + index, new_index - index))
+ break;
+ }
if constexpr(std::is_same<char, T>::value)
index = new_index + 1;
@@ -20,12 +22,12 @@ namespace QuickMedia {
}
}
- void string_split(const std::string &str, const std::string &delimiter, StringSplitCallback callback_func) {
- string_split_t(str, delimiter, callback_func);
+ void string_split(const std::string &str, const std::string &delimiter, StringSplitCallback callback_func, bool include_empty) {
+ string_split_t(str, delimiter, callback_func, include_empty);
}
- void string_split(const std::string &str, char delimiter, StringSplitCallback callback_func) {
- string_split_t(str, delimiter, callback_func);
+ void string_split(const std::string &str, char delimiter, StringSplitCallback callback_func, bool include_empty) {
+ string_split_t(str, delimiter, callback_func, include_empty);
}
size_t string_replace_all(std::string &str, char old_char, char new_char) {
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index a821158..133193b 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -510,8 +510,12 @@ namespace QuickMedia {
body_item->thumbnail_mask_type = ThumbnailMaskType::CIRCLE;
body_item->thumbnail_size = mgl::vec2i(32, 32);
body_item->set_timestamp(invite.timestamp);
+ body_item->userdata = body_item.get();
+ const bool silenced_invite = matrix->is_invite_silenced(room_id, invite.timestamp);
+ if(silenced_invite)
+ body_item->add_reaction("Silenced", nullptr);
invites_page->add_body_item(std::move(body_item));
- if(invite.new_invite) {
+ if(invite.new_invite && !silenced_invite) {
show_notification("QuickMedia matrix - " + invite.room_name, "You were invited to " + invite.room_name + " by " + invited_by_display_name + " (" + invite.invited_by->user_id + ")");
}
}
@@ -960,6 +964,10 @@ namespace QuickMedia {
auto body = create_body();
body->append_item(BodyItem::create("Accept"));
body->append_item(BodyItem::create("Decline"));
+ body->append_item(BodyItem::create("Silence"));
+ body->for_each_item([&](auto &body_item) {
+ body_item->userdata = args.userdata;
+ });
result_tabs.push_back(Tab{std::move(body), std::make_unique<MatrixInviteDetailsPage>(program, matrix, this, args.url, "Invite to " + title), nullptr});
return PluginResult::OK;
}
@@ -981,6 +989,9 @@ namespace QuickMedia {
} else {
show_notification("QuickMedia", "Failed to decline the room invite", Urgency::CRITICAL);
}
+ } else if(args.title == "Silence") {
+ BodyItem *body_item = (BodyItem*)args.userdata;
+ matrix->silence_invite(room_id, body_item->get_timestamp());
}
program->set_go_to_previous_page();
@@ -1544,6 +1555,7 @@ namespace QuickMedia {
sync_is_cache = false;
sync_running = true;
+ load_silenced_invites();
load_custom_emoji_from_cache();
sync_thread = std::thread([this, matrix_cache_dir]() {
@@ -2065,13 +2077,13 @@ namespace QuickMedia {
RoomData *room = get_room_by_id(std::string(room_id_json.GetString(), room_id_json.GetStringLength()));
if(!room) {
- fprintf(stderr, "Warning: got m.direct for room %s that we haven't created yet\n", room_id_json.GetString());
+ //fprintf(stderr, "Warning: got m.direct for room %s that we haven't created yet\n", room_id_json.GetString());
continue;
}
auto user = get_user_by_id(room, std::string(it.name.GetString(), it.name.GetStringLength()), nullptr, false);
if(!user) {
- fprintf(stderr, "Warning: got m.direct for user %s that doesn't exist in the room %s yet\n", it.name.GetString(), room_id_json.GetString());
+ //fprintf(stderr, "Warning: got m.direct for user %s that doesn't exist in the room %s yet\n", it.name.GetString(), room_id_json.GetString());
continue;
}
@@ -2090,7 +2102,9 @@ namespace QuickMedia {
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
content_json.Accept(writer);
- file_overwrite_atomic(get_cache_dir().join("matrix").join("custom_emoji.json"), std::string(buffer.GetString(), buffer.GetSize()));
+ Path matrix_dir = get_cache_dir().join("matrix");
+ create_directory_recursive(matrix_dir);
+ file_overwrite_atomic(matrix_dir.join("custom_emoji.json"), std::string(buffer.GetString(), buffer.GetSize()));
}
}
@@ -5242,6 +5256,28 @@ namespace QuickMedia {
return download_result_to_plugin_result(download_result);
}
+ bool Matrix::is_invite_silenced(const std::string &room_id, int64_t timestamp) {
+ return silenced_invites.find(room_id + "|" + std::to_string(timestamp)) != silenced_invites.end();
+ }
+
+ void Matrix::silence_invite(const std::string &room_id, int64_t timestamp) {
+ std::string line = room_id + "|" + std::to_string(timestamp);
+ auto it = silenced_invites.find(line);
+ if(it != silenced_invites.end())
+ return;
+
+ Path matrix_dir = get_storage_dir().join("matrix");
+ create_directory_recursive(matrix_dir);
+ Path silenced_invites_path = matrix_dir.join("silenced_invites");
+ FILE *file = fopen(silenced_invites_path.data.c_str(), "ab");
+ if(!file)
+ return;
+
+ line += "\n";
+ fwrite(line.data(), 1, line.size(), file);
+ fclose(file);
+ }
+
PluginResult Matrix::get_public_rooms(const std::string &server, const std::string &search_term, const std::string &since, BodyItems &rooms, std::string &next_batch) {
rapidjson::Document filter_data(rapidjson::kObjectType);
if(!search_term.empty())
@@ -5733,6 +5769,18 @@ namespace QuickMedia {
#endif
}
+ void Matrix::load_silenced_invites() {
+ std::string file_content;
+ if(file_get_content(get_storage_dir().join("matrix").join("silenced_invites"), file_content) != 0)
+ return;
+
+ silenced_invites.clear();
+ string_split(file_content, '\n', [&](const char *str, size_t size) {
+ silenced_invites.insert(std::string(str, size));
+ return true;
+ }, false);
+ }
+
void Matrix::update() {
mgl::Clock timer;
std::optional<std::function<void()>> task;