From 87c7a3c659735dbe4bda63712372e3dbdf807c3b Mon Sep 17 00:00:00 2001 From: dec05eba Date: Fri, 2 Oct 2020 17:56:06 +0200 Subject: Matrix: do a HEAD request to selected url to determinate type before using mpv or xdg-open --- src/QuickMedia.cpp | 105 +++++++++++++++++++++++++++++++++------------------- src/VideoPlayer.cpp | 1 + 2 files changed, 68 insertions(+), 38 deletions(-) (limited to 'src') diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 80faa88..41c4cb1 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -3417,8 +3417,7 @@ namespace QuickMedia { return false; if(chat_state == ChatState::TYPING_MESSAGE && text[0] == '/') { - std::string command = text; - strip(command); + std::string command = strip(text); if(command == "/upload") { new_page = Page::FILE_MANAGER; chat_input.set_editable(false); @@ -3582,6 +3581,41 @@ namespace QuickMedia { } }; + // TODO: Remove this? it adds additional delay to launch. + // TODO: Make async + auto link_get_content_type = [this](const std::string &url) -> const char* { + std::vector additional_args = { + { "-I", "" } // HEAD request, to get content-type + }; + + std::string program_result; + if(download_to_string(url, program_result, std::move(additional_args), use_tor, true) != DownloadResult::OK) { + fprintf(stderr, "HEAD request to %s failed\n", url.c_str()); + return nullptr; + } + + const char *result = nullptr; + string_split(program_result, '\n', [&result](const char *str, size_t size) mutable -> bool { + if(size > 13 && strncasecmp(str, "content-type:", 13) == 0) { + std::string content_type_value(str + 13, size - 13); + content_type_value = strip(content_type_value); + if(strncasecmp(content_type_value.c_str(), "audio", 5) == 0) { + result = "audio"; + return false; + } else if(strncasecmp(content_type_value.c_str(), "video", 5) == 0) { + result = "video"; + return false; + } else if(strncasecmp(content_type_value.c_str(), "image", 5) == 0) { + result = "image"; + return false; + } + } + return true; + }); + + return result; + }; + bool is_window_focused = true; while (current_page == Page::CHAT) { @@ -3657,21 +3691,7 @@ namespace QuickMedia { } } - if(tabs[selected_tab].type == ChatTabType::MESSAGES && event.key.control && event.key.code == sf::Keyboard::P) { - BodyItem *selected_item = tabs[selected_tab].body->get_selected(); - if(!selected_item) - continue; - - if(selected_item->url.empty()) - continue; - - page_stack.push(Page::CHAT); - watched_videos.clear(); - content_url = selected_item->url; - current_page = Page::VIDEO_CONTENT; - video_content_page(); - redraw = true; - } else if(tabs[selected_tab].type == ChatTabType::MESSAGES && event.key.control && event.key.code == sf::Keyboard::R) { + if(tabs[selected_tab].type == ChatTabType::MESSAGES && event.key.control && event.key.code == sf::Keyboard::R) { std::shared_ptr selected = tabs[selected_tab].body->get_selected_shared(); if(selected) { chat_state = ChatState::REPLYING; @@ -3722,27 +3742,36 @@ namespace QuickMedia { BodyItem *selected = tabs[selected_tab].body->get_selected(); if(selected) { if(!selected->url.empty()) { - page_stack.push(Page::CHAT); - watched_videos.clear(); - content_url = selected->url; - current_page = Page::VIDEO_CONTENT; - video_content_page(); - redraw = true; - } else { - // 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)); - } + const char *content_type = link_get_content_type(selected->url); + if(content_type && (strcmp(content_type, "audio") == 0 || strcmp(content_type, "video") == 0 || strcmp(content_type, "image") == 0)) { + page_stack.push(Page::CHAT); + watched_videos.clear(); + content_url = selected->url; + current_page = Page::VIDEO_CONTENT; + video_content_page(); + redraw = true; + continue; + } + + launch_url(selected->url.c_str()); + continue; + } + + // TODO: If content type is a file, show file-manager prompt where it should be saved and asynchronously save it instead + + // 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)); } } } diff --git a/src/VideoPlayer.cpp b/src/VideoPlayer.cpp index c93b5e8..0b173dd 100644 --- a/src/VideoPlayer.cpp +++ b/src/VideoPlayer.cpp @@ -85,6 +85,7 @@ namespace QuickMedia { "--no-resume-playback", "--cursor-autohide=no", /* "--no-input-default-bindings", "--input-vo-keyboard=no", "--no-input-cursor", */ "--no-terminal", + "--profile=pseudo-gui", // For gui when playing audio, requires a version of mpv that isn't ancient "--ytdl-raw-options=sub-lang=\"en,eng,enUS,en-US\",write-sub=", input_conf.c_str(), wid_arg.c_str() -- cgit v1.2.3