From a1ff5cb86eaa32e6e4ee194e87d8036c74be8dc9 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Thu, 1 Oct 2020 11:44:23 +0200 Subject: Matrix: add url selection, open youtube with quickmedia and other urls with browser --- src/Program.c | 2 ++ src/QuickMedia.cpp | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 93 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Program.c b/src/Program.c index c6bff50..0ad19f2 100644 --- a/src/Program.c +++ b/src/Program.c @@ -168,6 +168,8 @@ int exec_program_async(const char **args, pid_t *result_process_id) { setsid(); signal(SIGHUP, SIG_IGN); + // TODO: Still creates zombie??? find a fix! + // Daemonize child to make the parent the init process which will reap the zombie child pid_t second_child = fork(); if(second_child == 0) { // child diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 15ae39c..4234d1c 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -20,6 +20,12 @@ #include "../include/base64_url.hpp" #include "../include/Entry.hpp" +#include +#include +#include +#include +#include + #include #include #include @@ -27,10 +33,6 @@ #include #include #include -#include -#include -#include -#include #include #include #include @@ -3381,7 +3383,8 @@ namespace QuickMedia { NAVIGATING, TYPING_MESSAGE, REPLYING, - EDITING + EDITING, + URL_SELECTION }; Page new_page = Page::CHAT; @@ -3514,6 +3517,35 @@ namespace QuickMedia { float prev_chat_height = chat_input.get_height(); float chat_input_height_full = 0.0f; + std::regex url_extract_regex("(http(s?):\\/\\/)?([a-zA-Z0-9\\-_]+\\.)+[a-zA-Z]+[^\\s.,]+"); + + Body url_selection_body(this, font.get(), bold_font.get(), cjk_font.get()); + + auto launch_url = [this, &redraw](const std::string &url) mutable { + if(url.empty()) + return; + + std::string video_id; + if(youtube_url_extract_id(url, video_id)) { + page_stack.push(Page::CHAT); + watched_videos.clear(); + content_url = url; + current_page = Page::VIDEO_CONTENT; + video_content_page(); + redraw = true; + } else { + if(!is_program_executable_by_name("xdg-open")) { + show_notification("Nyaa.si", "xdg-utils which provides xdg-open needs to be installed to download torrents", Urgency::CRITICAL); + return; + } + std::string url_modified = url; + if(strncmp(url.c_str(), "http://", 7) != 0 && strncmp(url.c_str(), "https://", 8) != 0) + url_modified = "https://" + url; + const char *args[] = { "xdg-open", url_modified.c_str(), nullptr }; + exec_program_async(args, nullptr); + } + }; + while (current_page == Page::CHAT) { sf::Int32 frame_time_ms = frame_timer.restart().asMilliseconds(); while (window.pollEvent(event)) { @@ -3638,6 +3670,56 @@ namespace QuickMedia { show_notification("QuickMedia", "No message selected for deletion"); } } + + if(tabs[selected_tab].type == ChatTabType::MESSAGES && event.key.code == sf::Keyboard::Enter) { + BodyItem *selected = tabs[selected_tab].body->get_selected(); + if(selected) { + // TODO: Change this when messages are not stored in the description + const std::string &message_str = selected->get_description(); + auto urls_begin = std::sregex_iterator(message_str.begin(), message_str.end(), url_extract_regex); + auto urls_end = std::sregex_iterator(); + size_t num_urls = std::distance(urls_begin, urls_end); + if(num_urls == 1) { + launch_url(urls_begin->str()); + } else if(num_urls > 1) { + chat_state = ChatState::URL_SELECTION; + url_selection_body.clear_items(); + for(auto it = urls_begin; it != urls_end; ++it) { + auto body_item = BodyItem::create(it->str()); + url_selection_body.items.push_back(std::move(body_item)); + } + } + } + } + } else if(event.type == sf::Event::KeyPressed && chat_state == ChatState::URL_SELECTION) { + if(event.key.code == sf::Keyboard::Up) { + url_selection_body.select_previous_item(); + } else if(event.key.code == sf::Keyboard::Down) { + url_selection_body.select_next_item(); + } else if(event.key.code == sf::Keyboard::PageUp) { + url_selection_body.select_previous_page(); + } else if(event.key.code == sf::Keyboard::PageDown) { + url_selection_body.select_next_page(); + } else if(event.key.code == sf::Keyboard::Home) { + url_selection_body.select_first_item(); + } else if(event.key.code == sf::Keyboard::End) { + url_selection_body.select_last_item(); + } else if(event.key.code == sf::Keyboard::Left) { + // TODO: Clear url_selection_body? + selected_tab = std::max(0, selected_tab - 1); + chat_state = ChatState::NAVIGATING; + } else if(event.key.code == sf::Keyboard::Right) { + selected_tab = std::min((int)tabs.size() - 1, selected_tab + 1); + chat_state = ChatState::NAVIGATING; + } else if(event.key.code == sf::Keyboard::Escape) { + url_selection_body.clear_items(); + chat_state = ChatState::NAVIGATING; + } else if(event.key.code == sf::Keyboard::Enter) { + BodyItem *selected_item = url_selection_body.get_selected(); + if(!selected_item) + continue; + launch_url(selected_item->get_title()); + } } if(chat_state == ChatState::NAVIGATING && tabs[selected_tab].type == ChatTabType::MESSAGES && event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::M && event.key.control) { @@ -3855,7 +3937,10 @@ namespace QuickMedia { const float width_per_tab = window_size.x / tabs.size(); tab_background.setSize(sf::Vector2f(std::floor(width_per_tab - tab_margin_x * 2.0f), tab_height)); - tabs[selected_tab].body->draw(window, body_pos, body_size); + if(chat_state == ChatState::URL_SELECTION) + url_selection_body.draw(window, body_pos, body_size); + else + tabs[selected_tab].body->draw(window, body_pos, body_size); const float tab_y = tab_spacer_height + std::floor(tab_vertical_offset + tab_height * 0.5f - (tab_text_size + 5.0f) * 0.5f); tab_shade.setSize(sf::Vector2f(window_size.x, tab_shade_height)); -- cgit v1.2.3