aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--TODO3
-rw-r--r--include/Storage.hpp1
-rw-r--r--plugins/Matrix.hpp11
-rw-r--r--src/Storage.cpp15
-rw-r--r--src/plugins/Matrix.cpp42
6 files changed, 65 insertions, 9 deletions
diff --git a/README.md b/README.md
index 94abede..c9781ff 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@ If you are running arch linux then you can install QuickMedia from aur: [https:/
Installing `lld` (the LLVM linker) can improve compile times.\
There is also an unofficial ebuild for gentoo users. On gentoo you can install QuickMedia by running these commands:
```bash
-eselect repository add overlay-from-plan9 git https://gitea.plan9.rocks/9/overlay-from-plan9
+eselect repository add overlay-from-plan9 git https://git.plan9.rocks/cat/overlay-from-plan9
emerge --sync overlay-from-plan9
emerge -av quickmedia
```
diff --git a/TODO b/TODO
index 195e17b..0d7af13 100644
--- a/TODO
+++ b/TODO
@@ -297,4 +297,5 @@ v0.m3u8 doesn't work for some lbry videos (such as https://odysee.com/@MoneroMag
Use DPMSInfoNotify.
Use stb_image_resize2.h
Youtube audio only download if audio stream not available, also for youtube-dl fallback.
-Make history (local-manga and others) use relative path to the downloads directory for thumbnails. Otherwise the thumbnails wont show when moving the download directory. \ No newline at end of file
+Make history (local-manga and others) use relative path to the downloads directory for thumbnails. Otherwise the thumbnails wont show when moving the download directory.
+Keep the rooms that we were kicked/banned from so we can still read them and re-read the reason for why we were kicked/banned. Or add a list of historical rooms with leave reason. \ No newline at end of file
diff --git a/include/Storage.hpp b/include/Storage.hpp
index 60c15f6..86c34d2 100644
--- a/include/Storage.hpp
+++ b/include/Storage.hpp
@@ -34,6 +34,7 @@ namespace QuickMedia {
bool file_get_last_modified_time_seconds(const char *path, time_t *result);
int file_overwrite(const Path &path, const std::string &data);
int file_overwrite_atomic(const Path &path, const std::string &data);
+ bool file_append(const Path &path, const std::string &data);
// The callback is called with 0 as the argument (last_modified_seconds)
void for_files_in_dir(const Path &path, FileIteratorCallback callback);
void for_files_in_dir_sort_last_modified(const Path &path, FileIteratorCallback callback, FileSortDirection sort_dir = FileSortDirection::ASC);
diff --git a/plugins/Matrix.hpp b/plugins/Matrix.hpp
index a3ce633..23b0a8a 100644
--- a/plugins/Matrix.hpp
+++ b/plugins/Matrix.hpp
@@ -320,7 +320,7 @@ namespace QuickMedia {
virtual ~MatrixDelegate() = default;
virtual void join_room(RoomData *room) = 0;
- virtual void leave_room(RoomData *room, LeaveType leave_type, const std::string &reason) = 0;
+ virtual void leave_room(RoomData *room, const std::string &event_id, 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;
@@ -356,7 +356,7 @@ namespace QuickMedia {
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;
+ void leave_room(RoomData *room, const std::string &event_id, 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, MessageDirection message_dir) override;
@@ -759,6 +759,11 @@ namespace QuickMedia {
MatrixDelegate* get_delegate();
+ bool is_another_instance_running() const { return matrix_instance_already_running; }
+
+ void mark_other_notification_as_read(const std::string &event_id);
+ bool is_other_notification_read(const std::string &event_id) const;
+
// Calls the |MatrixDelegate| pending events.
// Should be called from the main (ui) thread
void update();
@@ -783,6 +788,7 @@ namespace QuickMedia {
void add_new_invites();
void parse_custom_emoji(const rapidjson::Value &custom_emoji_json);
void load_custom_emoji_from_cache();
+ void load_other_notifications();
PluginResult get_previous_room_messages(RoomData *room_data, bool latest_messages, size_t &num_new_messages, bool *reached_end = nullptr);
void events_add_user_info(const rapidjson::Value &events_json, RoomData *room_data, int64_t timestamp);
std::shared_ptr<UserInfo> parse_user_info(const rapidjson::Value &json, const std::string &user_id, RoomData *room_data, int64_t timestamp);
@@ -850,6 +856,7 @@ namespace QuickMedia {
std::unordered_map<std::string, CustomEmoji> custom_emoji_by_key;
std::unordered_set<std::string> silenced_invites;
std::unordered_map<std::string, int64_t> qm_read_markers_by_room_cache;
+ std::unordered_set<std::string> other_notifications_read;
MessageQueue<std::shared_ptr<MatrixChatBodyDecryptJob>> decrypt_task;
std::thread decrypt_thread;
diff --git a/src/Storage.cpp b/src/Storage.cpp
index 7bb3be6..5c12911 100644
--- a/src/Storage.cpp
+++ b/src/Storage.cpp
@@ -244,6 +244,21 @@ namespace QuickMedia {
return rename_atomic(tmp_path.data.c_str(), path.data.c_str());
}
+ bool file_append(const Path &path, const std::string &data) {
+ FILE *file = fopen_eintr(path.data.c_str(), "ab");
+ if(!file) {
+ perror(path.data.c_str());
+ return false;
+ }
+
+ if(fwrite_eintr(data.data(), data.size(), file) != data.size()) {
+ fclose(file);
+ return false;
+ }
+
+ return fclose(file) == 0;
+ }
+
void for_files_in_dir(const Path &path, FileIteratorCallback callback) {
try {
for(auto &p : std::filesystem::directory_iterator(path.data)) {
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index 1b43b2d..7080bf9 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -629,12 +629,15 @@ namespace QuickMedia {
rooms_page->add_body_item(body_item);
}
- void MatrixQuickMedia::leave_room(RoomData *room, LeaveType leave_type, const std::string &reason) {
+ void MatrixQuickMedia::leave_room(RoomData *room, const std::string &event_id, LeaveType leave_type, const std::string &reason) {
room_body_item_by_room.erase(room);
rooms_page->remove_body_item_by_room_id(room->id);
room_tags_page->remove_body_item_by_room_id(room->id);
- if(leave_type != LeaveType::LEAVE)
+ if(leave_type != LeaveType::LEAVE && (event_id.empty() || !matrix->is_other_notification_read(event_id))) {
show_notification("QuickMedia", reason);
+ if(!event_id.empty())
+ matrix->mark_other_notification_as_read(event_id);
+ }
}
void MatrixQuickMedia::room_add_tag(RoomData *room, const std::string &tag) {
@@ -1674,6 +1677,7 @@ namespace QuickMedia {
load_silenced_invites();
load_custom_emoji_from_cache();
+ load_other_notifications();
sync_thread = std::thread([this, matrix_cache_dir]() {
FILE *sync_cache_file;
@@ -1858,8 +1862,8 @@ namespace QuickMedia {
fwrite(json_data.data(), 1, json_data.size(), sync_cache_file);
file_overwrite(get_cache_dir().join("matrix").join(update_cache_file_name), "1"); // To make sure the cache format is up to date
- malloc_trim(0);
}
+ malloc_trim(0);
fclose(sync_cache_file);
}
}
@@ -2208,6 +2212,18 @@ namespace QuickMedia {
parse_custom_emoji(json_root);
}
+ void Matrix::load_other_notifications() {
+ std::string result;
+ if(file_get_content(get_storage_dir().join("matrix").join("other_notifications_read"), result) != 0)
+ return;
+
+ other_notifications_read.clear();
+ string_split_view(result, '\n', [this](const char *str, size_t line) {
+ other_notifications_read.insert(std::string(str, line));
+ return true;
+ });
+ }
+
PluginResult Matrix::parse_sync_account_data(const rapidjson::Value &account_data_json) {
if(!account_data_json.IsObject())
return PluginResult::OK;
@@ -3884,6 +3900,10 @@ namespace QuickMedia {
if(!type_json.IsString() || strcmp(type_json.GetString(), "m.room.member") != 0)
continue;
+ const rapidjson::Value &event_id_json = GetMember(event_json, "event_id");
+ if(!event_id_json.IsString())
+ continue;
+
const rapidjson::Value &sender_json = GetMember(event_json, "sender");
if(!sender_json.IsString())
continue;
@@ -3924,7 +3944,10 @@ namespace QuickMedia {
if(!reason_str.empty())
desc += ", reason: " + reason_str;
- ui_thread_tasks.push([this, room, leave_type, desc{std::move(desc)}]{ delegate->leave_room(room, leave_type, desc); });
+ std::string event_id_str = event_id_json.GetString();
+ ui_thread_tasks.push([this, room, event_id_str{std::move(event_id_str)}, leave_type, desc{std::move(desc)}]{
+ delegate->leave_room(room, event_id_str, leave_type, desc);
+ });
remove_room(room_id_str);
break;
}
@@ -4213,6 +4236,15 @@ namespace QuickMedia {
return delegate;
}
+ void Matrix::mark_other_notification_as_read(const std::string &event_id) {
+ other_notifications_read.insert(event_id);
+ file_append(get_storage_dir().join("matrix").join("other_notifications_read"), event_id + "\n");
+ }
+
+ bool Matrix::is_other_notification_read(const std::string &event_id) const {
+ return other_notifications_read.find(event_id) != other_notifications_read.end();
+ }
+
PluginResult Matrix::post_message(RoomData *room, const std::string &body, std::string &event_id_response, const std::optional<UploadInfo> &file_info, const std::optional<UploadInfo> &thumbnail_info, const std::string &msgtype, const std::string &custom_transaction_id) {
std::string transaction_id = custom_transaction_id;
if(transaction_id.empty())
@@ -5629,7 +5661,7 @@ namespace QuickMedia {
if(download_result == DownloadResult::OK) {
RoomData *room = get_room_by_id(room_id);
if(room) {
- ui_thread_tasks.push([this, room]{ delegate->leave_room(room, LeaveType::LEAVE, ""); });
+ ui_thread_tasks.push([this, room]{ delegate->leave_room(room, "", LeaveType::LEAVE, ""); });
remove_room(room_id);
}
}