aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2020-10-01 11:44:23 +0200
committerdec05eba <dec05eba@protonmail.com>2020-10-01 11:45:21 +0200
commita1ff5cb86eaa32e6e4ee194e87d8036c74be8dc9 (patch)
treef537bd25c20ecd32467ae2af558e74f6ea2ef70b /src
parentcb60c5304db0b25d6ce2460fded4cd42a1dcf0dc (diff)
Matrix: add url selection, open youtube with quickmedia and other urls with browser
Diffstat (limited to 'src')
-rw-r--r--src/Program.c2
-rw-r--r--src/QuickMedia.cpp97
2 files changed, 93 insertions, 6 deletions
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 <assert.h>
+#include <cmath>
+#include <string.h>
+#include <signal.h>
+#include <regex>
+
#include <SFML/Graphics/RectangleShape.hpp>
#include <SFML/Window/Clipboard.hpp>
#include <SFML/Graphics/Sprite.hpp>
@@ -27,10 +33,6 @@
#include <SFML/Window/Event.hpp>
#include <json/reader.h>
#include <json/writer.h>
-#include <assert.h>
-#include <cmath>
-#include <string.h>
-#include <signal.h>
#include <X11/keysym.h>
#include <X11/extensions/Xrandr.h>
#include <SFML/OpenGL.hpp>
@@ -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));