aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2020-10-31 07:12:16 +0100
committerdec05eba <dec05eba@protonmail.com>2020-10-31 07:12:16 +0100
commit11f644afe434ce6b6d570c9da2a95590321871b3 (patch)
tree065ce7f5a9615daba7eb758bb30ccdd46bed3bc2
parent928f2525c29929de0c2ab520f48c82b5cb882aa7 (diff)
Make matrix posting, deleting, replying, edit async and video check if streamable async
-rw-r--r--TODO8
-rw-r--r--include/Program.hpp5
-rw-r--r--include/QuickMedia.hpp8
-rw-r--r--src/Program.cpp9
-rw-r--r--src/QuickMedia.cpp279
5 files changed, 188 insertions, 121 deletions
diff --git a/TODO b/TODO
index b7c43d2..a1020ca 100644
--- a/TODO
+++ b/TODO
@@ -32,14 +32,11 @@ Show filename at the bottom when viewing an image/video on 4chan.
Add ctrl+c keybinding to copy the url of the previewing image.
Add ctrl+c keybiding to copy the url to the currently selected post on 4chan.
Add ctrl+s to save the previewing image/video (for images that would be a copy, since its already stored in cache and for videos youtube-dl would be used).
-Show the last message in a room as the body item description in matrix room view.
Show some kind of indication that there are new messages in a room in matrix room view, and also show another indication if somebody mentioned us (and how many times).
Show the rooms menu on the left side when the window is large in matrix.
Use https://github.com/simdjson/simdjson as a json library in other parts than matrix.
Sanitize check: do not allow pasting more than 2gb of text.
Add search bar for matrix rooms.
-Put rooms with recent messages at the top and the ones that mention us further at the top (matrix), and also add a tab for favorited rooms? or tag them, whatever.
-Allow setting matrix room priority (if it should always be at top).
Only add related videos to recommendations if its the first time we watch the video. This is to prevent rewatching a video multiple times from messing up recommendations.
Fix incorrect body visible rows count (draws incorrect number of items and incorrect counted, also messed up pg(up/down)).
Implement mentions in matrix with an autofill list, like on element. Also do the same with / commands.
@@ -51,7 +48,7 @@ Respect ~/.Xresources dpi (read the file, loop lines and look for Xft.dpi). Fall
Merge body items in matrix if they are posted by the same author (there is a git stash for this).
Add joining/leaving room in matrix, and also show invites and add command to ban users. Also add joining by invite, and show invites in the rooms list.
Support peertube (works with mpv, but need to implement search and related videos).
-Scroll to bottom when receiving a new message even if the selected message is not the last one. It should instead school if the last message is visible on the screen.
+Scroll to bottom when receiving a new message even if the selected message is not the last one. It should instead scroll if the last message is visible on the screen.
Also add a tab for common directories and recently accessed files/directories (the directories would be the directory of used files).
Provide a way to go to the first unread message in matrix and also show a marker in the body (maybe a red line?) where the first unread message is.
Allow scrolling body item. A body item can be long and we wont be able to read all of it otherwise (such as a message on matrix). Pressing up/down should scroll such a large body item rather than moving to another one.
@@ -62,7 +59,7 @@ Add /me to matrix, emoji, reactions...
Set the icon of the window to be the icon of the plugin. Nice for KDE, GNOME, etc with titlebars.
Set a minimum wrap size for text. We dont want one line of text to fully fill the window vertically when the window size width is small. Its better to cut off the text and add eclipses.
Support matrix html (for replies and text styling, such as greentext).
-If --no-audio is used then music should be played with a lightweight music player instead. MPV is heavy even for music (60mb RAM).
+If --no-audio is used then music should be played with a lightweight music player instead. MPV is heavy even for music (60mb RAM). Maybe use sfml audio functions?
Optimize startup time.
Update 4chan thread in real time, just like 4chan-x.
Save the original event message, so when replying for example we can use the original message as the replying to message, rather than our converted "body" text.
@@ -119,7 +116,6 @@ Modify matrix sync to download and parse json but not handle it, and then add a
Room list in matrix ignores edited messages, which it should for unread messages but it should show the edited message if the edited message is the last message in the room.
For messages that mention us we only want a notification for the last edited version to show as a notification.
Fetch replies/pinned message using multiple threads.
-Replying to edited message shows incorrect body in matrix.
Show in room tags list when there is a message in any of the rooms in the tag.
Apply current search filter when adding new rooms to the room list.
Cancel video download when pressing escape or closing window (important in matrix).
diff --git a/include/Program.hpp b/include/Program.hpp
index 8ac2d2d..82c912a 100644
--- a/include/Program.hpp
+++ b/include/Program.hpp
@@ -20,9 +20,10 @@ int exec_program_pipe(const char **args, ReadProgram *read_program);
/*
@args need to have at least 2 arguments. The first which is the program name
- and the last which is NULL, which indicates end of args
+ and the last which is NULL, which indicates end of args.
+ |buffer_size| has to be between 1 and 65536.
*/
-int exec_program(const char **args, ProgramOutputCallback output_callback, void *userdata);
+int exec_program(const char **args, ProgramOutputCallback output_callback, void *userdata, int buffer_size = 4096);
// Return the exit status, or a negative value if waiting failed
int wait_program(pid_t process_id);
diff --git a/include/QuickMedia.hpp b/include/QuickMedia.hpp
index 6f8e3ff..b9ec2d9 100644
--- a/include/QuickMedia.hpp
+++ b/include/QuickMedia.hpp
@@ -36,6 +36,12 @@ namespace QuickMedia {
Path source;
Path destination;
};
+
+ enum class TaskResult {
+ TRUE,
+ FALSE,
+ CANCEL
+ };
class Program {
public:
@@ -65,6 +71,8 @@ namespace QuickMedia {
void chat_page(MatrixChatPage *chat_page, RoomData *current_room);
void after_matrix_login_page();
+ TaskResult run_task_with_loading_screen(std::function<bool()> callback);
+
enum class LoadImageResult {
OK,
FAILED,
diff --git a/src/Program.cpp b/src/Program.cpp
index 136a494..d9927af 100644
--- a/src/Program.cpp
+++ b/src/Program.cpp
@@ -86,7 +86,7 @@ int exec_program_pipe(const char **args, ReadProgram *read_program) {
}
}
-int exec_program(const char **args, ProgramOutputCallback output_callback, void *userdata) {
+int exec_program(const char **args, ProgramOutputCallback output_callback, void *userdata, int buffer_size) {
ReadProgram read_program;
int res = exec_program_pipe(args, &read_program);
if(res != 0)
@@ -96,10 +96,11 @@ int exec_program(const char **args, ProgramOutputCallback output_callback, void
int status;
int exit_status;
- char buffer[4097];
+ assert(buffer_size >= 1 && buffer_size <= 65536);
+ char *buffer = (char*)alloca(buffer_size + 1);
for(;;) {
- ssize_t bytes_read = read(read_program.read_fd, buffer, sizeof(buffer) - 1);
+ ssize_t bytes_read = read(read_program.read_fd, buffer, buffer_size);
if(bytes_read == 0) {
break;
} else if(bytes_read == -1) {
@@ -109,8 +110,6 @@ int exec_program(const char **args, ProgramOutputCallback output_callback, void
break;
}
- //check if running. Also do the same in download_to_json
-
buffer[bytes_read] = '\0';
if(output_callback) {
result = output_callback(buffer, bytes_read, userdata);
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index 3b99d55..e16f8a4 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -1086,7 +1086,6 @@ namespace QuickMedia {
redraw = true;
} else {
// TODO: Show the exact cause of error (get error message from curl).
- // TODO: Make asynchronous
show_notification("QuickMedia", std::string("Submit failed for page ") + tabs[selected_tab].page->get_title(), Urgency::CRITICAL);
}
};
@@ -1543,12 +1542,65 @@ namespace QuickMedia {
static bool video_url_is_non_streamable_mp4(const char *url) {
std::string result;
const char *args[] = { "curl", "-sLf", "-r", "0-40", "-H", useragent_str, "--", url, nullptr };
- exec_program(args, accumulate_string_limit_head, &result);
+ exec_program(args, accumulate_string_limit_head, &result, 40);
return (result.size() >= 40)
&& (memcmp(&result[4], "ftypisom", 8) == 0 || memcmp(&result[4], "ftypmp42", 8) == 0 || memcmp(&result[4], "ftymp42", 7) == 0 || memcmp(&result[4], "fty3gp5", 7) == 0)
&& (memcmp(&result[36], "moov", 4) != 0);
}
+ TaskResult Program::run_task_with_loading_screen(std::function<bool()> callback) {
+ std::promise<bool> result_promise;
+ std::future<bool> future = result_promise.get_future();
+ std::thread task_thread([](std::promise<bool> &&promise, std::function<bool()> callback) {
+ promise.set_value(callback());
+ }, std::move(result_promise), std::move(callback));
+
+ sf::Sprite load_sprite(loading_icon);
+ sf::Vector2u loading_icon_size = loading_icon.getSize();
+ load_sprite.setOrigin(loading_icon_size.x * 0.5f, loading_icon_size.y * 0.5f);
+
+ window_size.x = window.getSize().x;
+ window_size.y = window.getSize().y;
+ sf::Clock timer;
+ sf::Event event;
+ while(window.isOpen()) {
+ while(window.pollEvent(event)) {
+ if(event.type == sf::Event::Closed) {
+ program_kill_in_thread(task_thread.get_id());
+ task_thread.join();
+ current_page = PageType::EXIT;
+ window.close();
+ return TaskResult::CANCEL;
+ } else if(event.type == sf::Event::Resized) {
+ window_size.x = event.size.width;
+ window_size.y = event.size.height;
+ sf::FloatRect visible_area(0, 0, window_size.x, window_size.y);
+ window.setView(sf::View(visible_area));
+ } else if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape) {
+ program_kill_in_thread(task_thread.get_id());
+ task_thread.join();
+ return TaskResult::CANCEL;
+ }
+ }
+
+ if(is_future_ready(future)) {
+ bool future_result = future.get();
+ task_thread.join();
+ if(!future_result)
+ return TaskResult::FALSE;
+ break;
+ }
+
+ window.clear(back_color);
+ load_sprite.setPosition(window_size.x * 0.5f, window_size.y * 0.5f);
+ load_sprite.setRotation(timer.getElapsedTime().asSeconds() * 400.0);
+ window.draw(load_sprite);
+ window.display();
+ }
+
+ return TaskResult::TRUE;
+ }
+
#define CLEANMASK(mask) ((mask) & (ShiftMask|ControlMask|Mod1Mask|Mod4Mask|Mod5Mask))
void Program::video_content_page(Page *page, std::string video_url, std::string video_title, bool download_if_streaming_fails) {
@@ -1563,15 +1615,8 @@ namespace QuickMedia {
load_sprite.setOrigin(loading_icon_size.x * 0.5f, loading_icon_size.y * 0.5f);
bool video_url_is_local = false;
- if(download_if_streaming_fails && video_url_is_non_streamable_mp4(video_url.c_str())) {
- fprintf(stderr, "%s is detected to be a non-streamable mp4 file, downloading it before playing it...\n", video_url.c_str());
+ if(download_if_streaming_fails) {
Path video_cache_dir = get_cache_dir().join("video");
- if(create_directory_recursive(video_cache_dir) != 0) {
- show_notification("QuickMedia", "Failed to create video cache directory", Urgency::CRITICAL);
- current_page = previous_page;
- return;
- }
-
Path video_path = video_cache_dir;
SHA256 sha256;
sha256.add(video_url.data(), video_url.size());
@@ -1581,55 +1626,39 @@ namespace QuickMedia {
video_url = std::move(video_path.data);
video_url_is_local = true;
} else {
- std::promise<DownloadResult> download_result_promise;
- std::future<DownloadResult> download_future = download_result_promise.get_future();
- std::thread download_thread([this, &video_path, video_url](std::promise<DownloadResult> &&promise) {
- promise.set_value(download_to_file(video_url, video_path.data, {}, use_tor, true));
- }, std::move(download_result_promise));
-
- window_size.x = window.getSize().x;
- window_size.y = window.getSize().y;
- sf::Clock timer;
- sf::Event event;
- while(window.isOpen()) {
- while(window.pollEvent(event)) {
- if(event.type == sf::Event::Closed) {
- program_kill_in_thread(download_thread.get_id());
- download_thread.join();
- current_page = previous_page;
- window.close();
- return;
- } else if(event.type == sf::Event::Resized) {
- window_size.x = event.size.width;
- window_size.y = event.size.height;
- sf::FloatRect visible_area(0, 0, window_size.x, window_size.y);
- window.setView(sf::View(visible_area));
- } else if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape) {
- program_kill_in_thread(download_thread.get_id());
- download_thread.join();
- current_page = previous_page;
- return;
- }
+ TaskResult video_is_not_streamble_result = run_task_with_loading_screen([video_url]() {
+ return video_url_is_non_streamable_mp4(video_url.c_str());
+ });
+ if(video_is_not_streamble_result == TaskResult::TRUE) {
+ fprintf(stderr, "%s is detected to be a non-streamable mp4 file, downloading it before playing it...\n", video_url.c_str());
+ if(create_directory_recursive(video_cache_dir) != 0) {
+ show_notification("QuickMedia", "Failed to create video cache directory", Urgency::CRITICAL);
+ current_page = previous_page;
+ return;
}
- if(is_future_ready(download_future)) {
- DownloadResult download_result = download_future.get();
- download_thread.join();
- if(download_result != DownloadResult::OK) {
+ TaskResult download_file_result = run_task_with_loading_screen([this, &video_path, video_url]() {
+ return download_to_file(video_url, video_path.data, {}, use_tor, true) == DownloadResult::OK;
+ });
+ switch(download_file_result) {
+ case TaskResult::TRUE: {
+ video_url = std::move(video_path.data);
+ video_url_is_local = true;
+ break;
+ }
+ case TaskResult::FALSE: {
show_notification("QuickMedia", "Failed to download " + video_url, Urgency::CRITICAL);
current_page = previous_page;
return;
}
- video_url = std::move(video_path.data);
- video_url_is_local = true;
- break;
+ case TaskResult::CANCEL: {
+ current_page = previous_page;
+ return;
+ }
}
-
- window.clear(back_color);
- load_sprite.setPosition(window_size.x * 0.5f, window_size.y * 0.5f);
- load_sprite.setRotation(timer.getElapsedTime().asSeconds() * 400.0);
- window.draw(load_sprite);
- window.display();
+ } else if(video_is_not_streamble_result == TaskResult::CANCEL) {
+ current_page = previous_page;
+ return;
}
}
}
@@ -1778,6 +1807,8 @@ namespace QuickMedia {
}
};
+ bool fullscreen = false;
+
while (current_page == PageType::VIDEO_CONTENT && window.isOpen()) {
while (window.pollEvent(event)) {
base_event_handler(event, previous_page, related_media_body.get(), nullptr, true, false);
@@ -1816,6 +1847,7 @@ namespace QuickMedia {
related_media_body->clear_cache();
} else if(event.key.code == sf::Keyboard::F && event.key.control) {
window_set_fullscreen(disp, window.getSystemHandle(), WindowFullscreenState::TOGGLE);
+ fullscreen = !fullscreen;
} else if(event.key.code == sf::Keyboard::Enter) {
BodyItem *selected_item = related_media_body->get_selected();
if(!selected_item)
@@ -1844,6 +1876,7 @@ namespace QuickMedia {
current_page = previous_page;
} else if(pressed_keysym == XK_f && pressing_ctrl) {
window_set_fullscreen(disp, window.getSystemHandle(), WindowFullscreenState::TOGGLE);
+ fullscreen = !fullscreen;
} else if(pressed_keysym == XK_r && pressing_ctrl && strcmp(plugin_name, "4chan") != 0) {
if(!related_media_window) {
related_media_window_size.x = window_size.x * RELATED_MEDIA_WINDOW_WIDTH;
@@ -1935,7 +1968,8 @@ namespace QuickMedia {
}
window.setMouseCursorVisible(true);
- window_set_fullscreen(disp, window.getSystemHandle(), WindowFullscreenState::UNSET);
+ if(fullscreen)
+ window_set_fullscreen(disp, window.getSystemHandle(), WindowFullscreenState::UNSET);
auto window_size_u = window.getSize();
window_size.x = window_size_u.x;
@@ -3244,10 +3278,11 @@ namespace QuickMedia {
tabs[MESSAGES_TAB_INDEX].body->insert_items_by_timestamps(messages_to_body_items(all_messages, matrix->get_me(current_room).get()));
modify_related_messages_in_current_room(all_messages);
tabs[MESSAGES_TAB_INDEX].body->select_last_item();
+ all_messages.clear();
std::vector<std::string> pinned_events;
matrix->get_all_pinned_events(current_room, pinned_events);
- process_pinned_events(pinned_events);
+ process_pinned_events(std::move(pinned_events));
tabs[PINNED_TAB_INDEX].body->select_last_item();
room_name_text.setString(static_cast<BodyItem*>(current_room->userdata)->get_title());
@@ -3260,7 +3295,17 @@ namespace QuickMedia {
chat_input.draw_background = false;
chat_input.set_editable(false);
- chat_input.on_submit_callback = [this, &tabs, &chat_input, &selected_tab, &current_room, &new_page, &chat_state, &currently_operating_on_item](std::string text) mutable {
+ MessageQueue<std::function<void()>> post_task_queue;
+ std::thread post_thread([&post_task_queue]() {
+ while(true) {
+ std::optional<std::function<void()>> post_task_opt = post_task_queue.pop_wait();
+ if(!post_task_opt)
+ break;
+ post_task_opt.value()();
+ }
+ });
+
+ chat_input.on_submit_callback = [this, &chat_input, &selected_tab, &current_room, &new_page, &chat_state, &currently_operating_on_item, &post_task_queue](std::string text) mutable {
if(!current_room)
return false;
@@ -3290,41 +3335,33 @@ namespace QuickMedia {
}
if(chat_state == ChatState::TYPING_MESSAGE) {
- // TODO: Make asynchronous
- if(matrix->post_message(current_room, text, std::nullopt, std::nullopt, msgtype) == PluginResult::OK) {
- chat_input.set_editable(false);
- chat_state = ChatState::NAVIGATING;
- if(tabs[MESSAGES_TAB_INDEX].body->is_last_item_fully_visible())
- tabs[MESSAGES_TAB_INDEX].body->select_last_item();
- return true;
- } else {
- show_notification("QuickMedia", "Failed to post matrix message", Urgency::CRITICAL);
- return false;
- }
+ post_task_queue.push([this, &current_room, text, msgtype]() {
+ if(matrix->post_message(current_room, text, std::nullopt, std::nullopt, msgtype) != PluginResult::OK)
+ show_notification("QuickMedia", "Failed to post matrix message", Urgency::CRITICAL);
+ });
+ chat_input.set_editable(false);
+ chat_state = ChatState::NAVIGATING;
+ return true;
} else if(chat_state == ChatState::REPLYING) {
- // TODO: Make asynchronous
- if(matrix->post_reply(current_room, text, currently_operating_on_item->userdata) == PluginResult::OK) {
- chat_input.set_editable(false);
- chat_state = ChatState::NAVIGATING;
- currently_operating_on_item = nullptr;
- if(tabs[MESSAGES_TAB_INDEX].body->is_last_item_fully_visible())
- tabs[MESSAGES_TAB_INDEX].body->select_last_item();
- return true;
- } else {
- show_notification("QuickMedia", "Failed to post matrix reply", Urgency::CRITICAL);
- return false;
- }
+ void *related_to_message = currently_operating_on_item->userdata;
+ post_task_queue.push([this, &current_room, text, related_to_message]() {
+ if(matrix->post_reply(current_room, text, related_to_message) != PluginResult::OK)
+ show_notification("QuickMedia", "Failed to post matrix reply", Urgency::CRITICAL);
+ });
+ chat_input.set_editable(false);
+ chat_state = ChatState::NAVIGATING;
+ currently_operating_on_item = nullptr;
+ return true;
} else if(chat_state == ChatState::EDITING) {
- // TODO: Make asynchronous
- if(matrix->post_edit(current_room, text, currently_operating_on_item->userdata) == PluginResult::OK) {
- chat_input.set_editable(false);
- chat_state = ChatState::NAVIGATING;
- currently_operating_on_item = nullptr;
- return true;
- } else {
- show_notification("QuickMedia", "Failed to post matrix edit", Urgency::CRITICAL);
- return false;
- }
+ void *related_to_message = currently_operating_on_item->userdata;
+ post_task_queue.push([this, &current_room, text, related_to_message]() {
+ if(matrix->post_edit(current_room, text, related_to_message) != PluginResult::OK)
+ show_notification("QuickMedia", "Failed to post matrix edit", Urgency::CRITICAL);
+ });
+ chat_input.set_editable(false);
+ chat_state = ChatState::NAVIGATING;
+ currently_operating_on_item = nullptr;
+ return true;
}
}
return false;
@@ -3464,7 +3501,7 @@ namespace QuickMedia {
watched_videos.clear();
current_page = PageType::VIDEO_CONTENT;
// TODO: Add title
- video_content_page(video_page.get(), url, "No title", true);
+ video_content_page(video_page.get(), url, "No title", false);
redraw = true;
} else {
const char *launch_program = "xdg-open";
@@ -3526,7 +3563,7 @@ namespace QuickMedia {
bool prev_no_video = no_video;
no_video = is_audio;
// TODO: Add title
- video_content_page(video_page.get(), *selected_url, "No title", true);
+ video_content_page(video_page.get(), *selected_url, "No title", message_type == MessageType::VIDEO);
no_video = prev_no_video;
redraw = true;
return true;
@@ -3662,12 +3699,20 @@ namespace QuickMedia {
if(event.key.control && event.key.code == sf::Keyboard::V) {
frame_skip_text_entry = true;
- // TODO: Make asynchronous.
// TODO: Upload multiple files.
- std::string err_msg;
- if(matrix->post_file(current_room, sf::Clipboard::getString(), err_msg) != PluginResult::OK) {
- std::string desc = "Failed to upload media to room, error: " + err_msg;
- show_notification("QuickMedia", desc.c_str(), Urgency::CRITICAL);
+ std::string selected_file = sf::Clipboard::getString();
+ TaskResult post_file_result = run_task_with_loading_screen([this, &current_room, selected_file]() {
+ std::string err_msg;
+ if(matrix->post_file(current_room, selected_file, err_msg) == PluginResult::OK) {
+ return true;
+ } else {
+ show_notification("QuickMedia", "Failed to upload media to room, error: " + err_msg, Urgency::CRITICAL);
+ return false;
+ }
+ });
+ if(post_file_result == TaskResult::TRUE) {
+ if(tabs[MESSAGES_TAB_INDEX].body->is_last_item_fully_visible())
+ tabs[MESSAGES_TAB_INDEX].body->select_last_item();
}
}
@@ -3713,12 +3758,14 @@ namespace QuickMedia {
frame_skip_text_entry = true;
BodyItem *selected = tabs[selected_tab].body->get_selected();
if(selected) {
- // TODO: Make asynchronous
- std::string err_msg;
- if(matrix->delete_message(current_room, selected->userdata, err_msg) != PluginResult::OK) {
- // TODO: Show inline notification
- show_notification("QuickMedia", "Failed to delete message, reason: " + err_msg, Urgency::CRITICAL);
- }
+ void *selected_message = selected->userdata;
+ post_task_queue.push([this, &current_room, selected_message]() {
+ std::string err_msg;
+ if(matrix->delete_message(current_room, selected_message, err_msg) != PluginResult::OK) {
+ // TODO: Show inline notification
+ show_notification("QuickMedia", "Failed to delete message, reason: " + err_msg, Urgency::CRITICAL);
+ }
+ });
} else {
// TODO: Show inline notification
show_notification("QuickMedia", "No message selected for deletion");
@@ -3796,6 +3843,10 @@ namespace QuickMedia {
new_page = PageType::CHAT;
if(current_room) {
+ for(ChatTab &tab : tabs) {
+ tab.body->clear_cache();
+ }
+
auto file_manager_page = std::make_unique<FileManagerPage>(this);
file_manager_page->set_current_directory(get_home_dir().data);
auto file_manager_body = create_body();
@@ -3809,15 +3860,19 @@ namespace QuickMedia {
if(selected_files.empty()) {
fprintf(stderr, "No files selected!\n");
} else {
- // TODO: Make asynchronous.
// TODO: Upload multiple files.
- std::string err_msg;
- if(matrix->post_file(current_room, selected_files[0], err_msg) == PluginResult::OK) {
+ TaskResult post_file_result = run_task_with_loading_screen([this, &current_room]() {
+ std::string err_msg;
+ if(matrix->post_file(current_room, selected_files[0], err_msg) == PluginResult::OK) {
+ return true;
+ } else {
+ show_notification("QuickMedia", "Failed to upload media to room, error: " + err_msg, Urgency::CRITICAL);
+ return false;
+ }
+ });
+ if(post_file_result == TaskResult::TRUE) {
if(tabs[MESSAGES_TAB_INDEX].body->is_last_item_fully_visible())
tabs[MESSAGES_TAB_INDEX].body->select_last_item();
- } else {
- std::string desc = "Failed to upload media to room, error: " + err_msg;
- show_notification("QuickMedia", desc.c_str(), Urgency::CRITICAL);
}
}
redraw = true;
@@ -3835,10 +3890,15 @@ namespace QuickMedia {
typing_state_queue.close();
if(typing_state_thread.joinable())
typing_state_thread.join();
+ post_task_queue.close();
+ if(post_thread.joinable())
+ post_thread.join();
new_page = PageType::CHAT;
matrix->stop_sync();
matrix->logout();
- tabs[MESSAGES_TAB_INDEX].body->clear_cache();
+ for(ChatTab &tab : tabs) {
+ tab.body->clear_cache();
+ }
// TODO: Instead of doing this, exit this current function and navigate to chat login page instead.
// This doesn't currently work because at the end of this function there are futures that need to wait
// and one of them is /sync, which has a timeout of 30 seconds. That timeout has to be killed somehow.
@@ -4142,6 +4202,9 @@ namespace QuickMedia {
typing_state_queue.close();
if(typing_state_thread.joinable())
typing_state_thread.join();
+ post_task_queue.close();
+ if(post_thread.joinable())
+ post_thread.join();
for(auto &body_item : tabs[PINNED_TAB_INDEX].body->items) {
delete (PinnedEventData*)body_item->userdata;