diff options
author | dec05eba <dec05eba@protonmail.com> | 2020-11-01 23:29:01 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2020-11-01 23:29:01 +0100 |
commit | 4262ae6c87b4c11f7fe958a91fdd3333a8c5138c (patch) | |
tree | f5e4da0790d208029cbf06c3da178b04a036e967 /src/QuickMedia.cpp | |
parent | 438729255b8d62ddac0688011e5fe9641db696f7 (diff) |
Matrix: cache sync
Diffstat (limited to 'src/QuickMedia.cpp')
-rw-r--r-- | src/QuickMedia.cpp | 167 |
1 files changed, 94 insertions, 73 deletions
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index e6d7b9a..ad9cc7f 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -330,6 +330,9 @@ namespace QuickMedia { abort(); } loading_icon.setSmooth(true); + load_sprite.setTexture(loading_icon, true); + sf::Vector2u loading_icon_size = loading_icon.getSize(); + load_sprite.setOrigin(loading_icon_size.x * 0.5f, loading_icon_size.y * 0.5f); struct sigaction action; action.sa_handler = sigpipe_handler; @@ -589,23 +592,15 @@ namespace QuickMedia { if(matrix) { matrix->use_tor = use_tor; - TaskResult task_result = run_task_with_loading_screen([this]() { - return matrix->load_and_verify_cached_session() == PluginResult::OK; - }); - - if(task_result == TaskResult::TRUE) { + if(matrix->load_cached_session() == PluginResult::OK) { current_page = PageType::CHAT; - } else if(task_result == TaskResult::FALSE) { + } else { fprintf(stderr, "Failed to load session cache, redirecting to login page\n"); current_page = PageType::CHAT_LOGIN; chat_login_page(); - } else { - exit(exit_code); } after_matrix_login_page(); - exit(exit_code); // Exit immediately without waiting for anything to finish - //matrix->stop_sync(); } return exit_code; @@ -1329,6 +1324,12 @@ namespace QuickMedia { window.draw(tab_associated_data[selected_tab].search_result_text); } + if(matrix && !matrix->is_initial_sync_finished()) { + load_sprite.setPosition(body_pos.x + body_size.x * 0.5f, body_pos.y + body_size.y * 0.5f); + load_sprite.setRotation(load_sprite_timer.getElapsedTime().asSeconds() * 400.0); + window.draw(load_sprite); + } + window.display(); if(go_to_previous_page) { @@ -1516,13 +1517,8 @@ namespace QuickMedia { 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)) { @@ -1555,7 +1551,7 @@ namespace QuickMedia { 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); + load_sprite.setRotation(load_sprite_timer.getElapsedTime().asSeconds() * 400.0); window.draw(load_sprite); window.display(); } @@ -3073,7 +3069,7 @@ namespace QuickMedia { Message *message = nullptr; }; - void Program::chat_page(MatrixChatPage *chat_page, RoomData *current_room) { + void Program::chat_page(MatrixChatPage *matrix_chat_page, RoomData *current_room) { assert(strcmp(plugin_name, "matrix") == 0); auto video_page = std::make_unique<MatrixVideoPage>(this); @@ -3341,20 +3337,18 @@ namespace QuickMedia { }; AsyncTask<Messages> previous_messages_future; - bool fetching_previous_messages_running = false; RoomData *previous_messages_future_room = nullptr; //const int num_fetch_message_threads = 4; AsyncTask<std::shared_ptr<Message>> fetch_message_future; - bool fetching_message_running = false; RoomData *fetch_future_room = nullptr; BodyItem *fetch_body_item = nullptr; int fetch_message_tab = -1; // TODO: How about instead fetching all messages we have, not only the visible ones? also fetch with multiple threads. // TODO: Cancel when going to another room? - tabs[PINNED_TAB_INDEX].body->body_item_render_callback = [this, ¤t_room, &fetch_message_future, &tabs, &find_body_item_by_event_id, &fetching_message_running, &fetch_future_room, &fetch_body_item, &fetch_message_tab](BodyItem *body_item) { - if(fetching_message_running || !current_room) + tabs[PINNED_TAB_INDEX].body->body_item_render_callback = [this, ¤t_room, &fetch_message_future, &tabs, &find_body_item_by_event_id, &fetch_future_room, &fetch_body_item, &fetch_message_tab](BodyItem *body_item) { + if(fetch_message_future.valid() || !current_room) return; PinnedEventData *event_data = static_cast<PinnedEventData*>(body_item->userdata); @@ -3371,7 +3365,6 @@ namespace QuickMedia { return; } - fetching_message_running = true; std::string message_event_id = event_data->event_id; fetch_future_room = current_room; fetch_body_item = body_item; @@ -3385,8 +3378,8 @@ namespace QuickMedia { // TODO: How about instead fetching all messages we have, not only the visible ones? also fetch with multiple threads. // TODO: Cancel when going to another room? - tabs[MESSAGES_TAB_INDEX].body->body_item_render_callback = [this, ¤t_room, &fetch_message_future, &tabs, &find_body_item_by_event_id, &fetching_message_running, &fetch_future_room, &fetch_body_item, &fetch_message_tab](BodyItem *body_item) { - if(fetching_message_running || !current_room) + tabs[MESSAGES_TAB_INDEX].body->body_item_render_callback = [this, ¤t_room, &fetch_message_future, &tabs, &find_body_item_by_event_id, &fetch_future_room, &fetch_body_item, &fetch_message_tab](BodyItem *body_item) { + if(fetch_message_future.valid() || !current_room) return; Message *message = static_cast<Message*>(body_item->userdata); @@ -3402,7 +3395,6 @@ namespace QuickMedia { return; } - fetching_message_running = true; std::string message_event_id = message->related_event_id; fetch_future_room = current_room; fetch_body_item = body_item; @@ -3565,6 +3557,28 @@ namespace QuickMedia { return false; }; + auto cleanup_tasks = [&set_read_marker_future, &previous_messages_future, &fetch_message_future, &typing_state_queue, &typing_state_thread, &post_task_queue, &post_thread, &unreferenced_event_by_room, &tabs]() { + set_read_marker_future.cancel(); + previous_messages_future.cancel(); + fetch_message_future.cancel(); + typing_state_queue.close(); + program_kill_in_thread(typing_state_thread.get_id()); + if(typing_state_thread.joinable()) + typing_state_thread.join(); + post_task_queue.close(); + program_kill_in_thread(post_thread.get_id()); + if(post_thread.joinable()) + post_thread.join(); + + unreferenced_event_by_room.clear(); + + for(auto &body_item : tabs[PINNED_TAB_INDEX].body->items) { + delete (PinnedEventData*)body_item->userdata; + } + + tabs.clear(); + }; + float tab_shade_height = 0.0f; bool frame_skip_text_entry = false; @@ -3600,9 +3614,8 @@ namespace QuickMedia { hit_top = false; break; } - if(hit_top && !fetching_previous_messages_running && selected_tab == MESSAGES_TAB_INDEX && current_room) { + if(hit_top && !previous_messages_future.valid() && selected_tab == MESSAGES_TAB_INDEX && current_room) { gradient_inc = 0; - fetching_previous_messages_running = true; previous_messages_future_room = current_room; previous_messages_future = [this, &previous_messages_future_room]() { Messages messages; @@ -3809,7 +3822,7 @@ namespace QuickMedia { } frame_skip_text_entry = false; - chat_page->update(); + matrix_chat_page->update(); switch(new_page) { case PageType::FILE_MANAGER: { @@ -3853,26 +3866,11 @@ namespace QuickMedia { break; } case PageType::CHAT_LOGIN: { - set_read_marker_future.cancel(); - previous_messages_future.cancel(); - fetch_message_future.cancel(); - typing_state_queue.close(); - program_kill_in_thread(typing_state_thread.get_id()); - if(typing_state_thread.joinable()) - typing_state_thread.join(); - post_task_queue.close(); - program_kill_in_thread(post_thread.get_id()); - if(post_thread.joinable()) - post_thread.join(); + cleanup_tasks(); new_page = PageType::CHAT; matrix->stop_sync(); matrix->logout(); - 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. //delete current_plugin; //current_plugin = new Matrix(); current_page = PageType::CHAT_LOGIN; @@ -3974,7 +3972,7 @@ namespace QuickMedia { setting_read_marker = false; } - if(fetching_previous_messages_running && previous_messages_future.ready()) { + if(previous_messages_future.ready()) { Messages new_messages = previous_messages_future.get(); fprintf(stderr, "Finished fetching older messages, num new messages: %zu\n", new_messages.size()); // Ignore finished fetch of messages if it happened in another room. When we navigate back to the room we will get the messages again @@ -3992,10 +3990,9 @@ namespace QuickMedia { modify_related_messages_in_current_room(new_messages); resolve_unreferenced_events_with_body_items(tabs[MESSAGES_TAB_INDEX].body->items.data(), num_new_body_items); } - fetching_previous_messages_running = false; } - if(fetching_message_running && fetch_message_future.ready()) { + if(fetch_message_future.ready()) { std::shared_ptr<Message> message = fetch_message_future.get(); fprintf(stderr, "Finished fetching message: %s\n", message ? message->event_id.c_str() : "(null)"); // Ignore finished fetch of messages if it happened in another room. When we navigate back to the room we will get the messages again @@ -4020,7 +4017,6 @@ namespace QuickMedia { } } } - fetching_message_running = false; fetch_message_tab = -1; } @@ -4079,7 +4075,7 @@ namespace QuickMedia { } // TODO: Have one for each room. Also add bottom one? for fetching new messages (currently not implemented, is it needed?) - if(fetching_previous_messages_running && selected_tab == MESSAGES_TAB_INDEX) { + if(previous_messages_future.valid() && selected_tab == MESSAGES_TAB_INDEX) { double progress = 0.5 + std::sin(std::fmod(gradient_inc, 360.0) * 0.017453292519943295 - 1.5707963267948966*0.5) * 0.5; gradient_inc += (frame_time_ms * 0.5); sf::Color top_color = interpolate_colors(back_color, sf::Color(175, 180, 188), progress); @@ -4135,7 +4131,7 @@ namespace QuickMedia { } } - if(selected_tab == MESSAGES_TAB_INDEX && current_room) { + if(selected_tab == MESSAGES_TAB_INDEX && current_room && matrix->is_initial_sync_finished()) { BodyItem *last_visible_item = tabs[selected_tab].body->get_last_fully_visible_item(); if(is_window_focused && chat_state != ChatState::URL_SELECTION && current_room && last_visible_item && !setting_read_marker && read_marker_timer.getElapsedTime().asMilliseconds() >= read_marker_timeout_ms) { Message *message = (Message*)last_visible_item->userdata; @@ -4159,8 +4155,31 @@ namespace QuickMedia { window.draw(logo_sprite); } + if(matrix && !matrix->is_initial_sync_finished()) { + load_sprite.setPosition(body_pos.x + body_size.x * 0.5f, body_pos.y + body_size.y * 0.5f); + load_sprite.setRotation(load_sprite_timer.getElapsedTime().asSeconds() * 400.0); + window.draw(load_sprite); + } + window.display(); + if(matrix_chat_page->should_clear_data) { + matrix_chat_page->should_clear_data = false; + cleanup_tasks(); + + while(!matrix->is_initial_sync_finished()) { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + + current_room = matrix->get_room_by_id(current_room->id); + if(current_room) { + chat_page(matrix_chat_page, current_room); + return; + } else { + go_to_previous_page = true; + } + } + if(go_to_previous_page) { go_to_previous_page = false; goto chat_page_end; @@ -4168,21 +4187,7 @@ namespace QuickMedia { } chat_page_end: - set_read_marker_future.cancel(); - previous_messages_future.cancel(); - fetch_message_future.cancel(); - typing_state_queue.close(); - program_kill_in_thread(typing_state_thread.get_id()); - if(typing_state_thread.joinable()) - typing_state_thread.join(); - post_task_queue.close(); - program_kill_in_thread(post_thread.get_id()); - if(post_thread.joinable()) - post_thread.join(); - - for(auto &body_item : tabs[PINNED_TAB_INDEX].body->items) { - delete (PinnedEventData*)body_item->userdata; - } + cleanup_tasks(); } void Program::after_matrix_login_page() { @@ -4209,13 +4214,27 @@ namespace QuickMedia { tabs.push_back(Tab{std::move(rooms_tags_body), std::move(matrix_rooms_tag_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); tabs.push_back(Tab{std::move(invites_body), std::move(matrix_invites_page), create_search_bar("Search...", SEARCH_DELAY_FILTER)}); - 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); - - sf::Clock timer; sf::Event event; - while(window.isOpen() && !matrix->is_initial_sync_finished()) { + std::string sync_err_msg; +#if 0 + while(window.isOpen()) { + if(matrix->is_initial_sync_finished()) + break; + else if(matrix->did_initial_sync_fail(sync_err_msg)) { + show_notification("QuickMedia", "Initial sync failed, reason: " + sync_err_msg, Urgency::CRITICAL); + matrix->stop_sync(); + matrix->logout(); + // TODO: Instead of doing this, exit this current function and navigate to chat login page instead. + //delete current_plugin; + //current_plugin = new Matrix(); + current_page = PageType::CHAT_LOGIN; + chat_login_page(); + if(current_page == PageType::CHAT) + after_matrix_login_page(); + exit(0); + break; + } + while(window.pollEvent(event)) { if(event.type == sf::Event::Closed) window.close(); @@ -4228,15 +4247,17 @@ namespace QuickMedia { window.close(); } } + 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); + load_sprite.setRotation(load_sprite_timer.getElapsedTime().asSeconds() * 400.0); window.draw(load_sprite); window.display(); } - +#endif while(window.isOpen()) { page_loop(tabs); } + matrix->stop_sync(); } } |