From 25217db93f952c95d834e6f32dc2340a2054df0a Mon Sep 17 00:00:00 2001 From: dec05eba Date: Wed, 31 Mar 2021 15:17:27 +0200 Subject: Soundcloud: automatically fetch next page when reaching end of related music list --- TODO | 3 +-- include/QuickMedia.hpp | 2 +- src/QuickMedia.cpp | 46 ++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/TODO b/TODO index 6e6a578..0d19b85 100644 --- a/TODO +++ b/TODO @@ -159,5 +159,4 @@ Check what happens with xsrf_token if comments are not fetched for a long time. Add support for comments in live youtube videos, api is at: https://www.youtube.com/youtubei/v1/live_chat/get_live_chat?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8. Make video visible when reading comments (youtube). Convert nyaa.si/spotify/soundcloud date from ISO date string to local time. -When ui is scaled then the predicated thumbnail size will be wrong since its scaled in Body but not in the plugins where they are requested. -Automatically fetch the next page on soundcloud when playing music and reaching the bottom, to be able to play the music from the next page as well. \ No newline at end of file +When ui is scaled then the predicated thumbnail size will be wrong since its scaled in Body but not in the plugins where they are requested. \ No newline at end of file diff --git a/include/QuickMedia.hpp b/include/QuickMedia.hpp index ec16feb..3e8e7c7 100644 --- a/include/QuickMedia.hpp +++ b/include/QuickMedia.hpp @@ -100,7 +100,7 @@ namespace QuickMedia { void page_loop_render(sf::RenderWindow &window, std::vector &tabs, int selected_tab, TabAssociatedData &tab_associated_data, const Json::Value *json_chapters); using PageLoopSubmitHandler = std::function &new_tabs)>; void page_loop(std::vector &tabs, int start_tab_index = 0, PageLoopSubmitHandler after_submit_handler = nullptr); - void video_content_page(VideoPage *video_page, std::string video_title, bool download_if_streaming_fails, BodyItems &next_play_items, int play_index); + void video_content_page(Page *parent_page, VideoPage *video_page, std::string video_title, bool download_if_streaming_fails, BodyItems &next_play_items, int play_index, int *parent_body_page = nullptr, const std::string &parent_page_search = ""); // Returns -1 to go to previous chapter, 0 to stay on same chapter and 1 to go to next chapter int image_page(MangaImagesPage *images_page, Body *chapters_body); void image_continuous_page(MangaImagesPage *images_page); diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp index 06abf22..705e8ff 100644 --- a/src/QuickMedia.cpp +++ b/src/QuickMedia.cpp @@ -1186,7 +1186,7 @@ namespace QuickMedia { } else if(new_tabs.size() == 1 && new_tabs[0].page->get_type() == PageTypez::VIDEO) { current_page = PageType::VIDEO_CONTENT; int selected_index = tabs[selected_tab].body->get_selected_item(); - video_content_page(static_cast(new_tabs[0].page.get()), selected_item->get_title(), false, tabs[selected_tab].body->items, selected_index); + video_content_page(tabs[selected_tab].page.get(), static_cast(new_tabs[0].page.get()), selected_item->get_title(), false, tabs[selected_tab].body->items, selected_index, &tab_associated_data[selected_tab].fetched_page, tab_associated_data[selected_tab].update_search_text); } else if(new_tabs.size() == 1 && new_tabs[0].page->get_type() == PageTypez::CHAT) { body_set_selected_item(tabs[selected_tab].body.get(), selected_item.get()); current_page = PageType::CHAT; @@ -1726,7 +1726,7 @@ namespace QuickMedia { #define CLEANMASK(mask) ((mask) & (ShiftMask|ControlMask|Mod1Mask|Mod4Mask|Mod5Mask)) - void Program::video_content_page(VideoPage *video_page, std::string video_title, bool download_if_streaming_fails, BodyItems &next_play_items, int play_index) { + void Program::video_content_page(Page *parent_page, VideoPage *video_page, std::string video_title, bool download_if_streaming_fails, BodyItems &next_play_items, int play_index, int *parent_body_page, const std::string &parent_page_search) { sf::Clock time_watched_timer; bool added_recommendations = false; bool video_loaded = false; @@ -2027,8 +2027,8 @@ namespace QuickMedia { } else if(update_err == VideoPlayer::Error::EXITED && video_player->exit_status == 0 && !is_matrix) { std::string new_video_url; std::string new_video_title; + // Find video that hasn't been played before in this video session - // TODO: Remove duplicates for(auto it = related_videos.begin(), end = related_videos.end(); it != end; ++it) { if(watched_videos.find((*it)->url) == watched_videos.end() && !video_page->video_should_be_skipped((*it)->url)) { new_video_url = (*it)->url; @@ -2038,6 +2038,36 @@ namespace QuickMedia { } } + if(new_video_url.empty() && parent_page && parent_body_page) { + BodyItems new_body_items; + const int fetch_page = (*parent_body_page) + 1; + run_task_with_loading_screen([parent_page, parent_page_search, fetch_page, &new_body_items] { + if(parent_page->get_page(parent_page_search, fetch_page, new_body_items) != PluginResult::OK) { + fprintf(stderr, "Failed to get next page (page %d)\n", fetch_page); + return false; + } + return true; + }); + + fprintf(stderr, "Finished fetching page %d, num new messages: %zu\n", fetch_page, new_body_items.size()); + size_t num_new_messages = new_body_items.size(); + if(num_new_messages > 0) { + next_play_items.insert(next_play_items.end(), new_body_items.begin(), new_body_items.end()); + (*parent_body_page)++; + related_videos = std::move(new_body_items); + + // Find video that hasn't been played before in this video session + for(auto it = related_videos.begin(), end = related_videos.end(); it != end; ++it) { + if(watched_videos.find((*it)->url) == watched_videos.end() && !video_page->video_should_be_skipped((*it)->url)) { + new_video_url = (*it)->url; + new_video_title = (*it)->get_title(); + related_videos.erase(it); + break; + } + } + } + } + // If there are no videos to play, then dont play any... if(new_video_url.empty()) { show_notification("QuickMedia", "No more related videos to play"); @@ -2834,7 +2864,7 @@ namespace QuickMedia { thread_page->video_url = selected_item->attached_content_url; BodyItems next_items; // TODO: Use real title - video_content_page(thread_page, "", true, next_items, 0); + video_content_page(thread_page, thread_page, "", true, next_items, 0); redraw = true; } else { if(downloading_image && load_image_future.valid()) @@ -4131,7 +4161,7 @@ namespace QuickMedia { const float chat_input_padding_x = std::floor(10.0f * get_ui_scale()); const float chat_input_padding_y = std::floor(10.0f * get_ui_scale()); - auto launch_url = [this, &video_page, &redraw](const std::string &url) mutable { + auto launch_url = [this, matrix_chat_page, &video_page, &redraw](const std::string &url) mutable { if(url.empty()) return; @@ -4143,7 +4173,7 @@ namespace QuickMedia { video_page->url = url; BodyItems next_items; // TODO: Add title - video_content_page(video_page.get(), "", false, next_items, 0); + video_content_page(matrix_chat_page, video_page.get(), "", false, next_items, 0); redraw = true; } else { const char *launch_program = "xdg-open"; @@ -4201,7 +4231,7 @@ namespace QuickMedia { } }; - auto display_url_or_image = [this, &selected_tab, &redraw, &video_page, &launch_url, &chat_state, &url_selection_body](BodyItem *selected) { + auto display_url_or_image = [this, matrix_chat_page, &selected_tab, &redraw, &video_page, &launch_url, &chat_state, &url_selection_body](BodyItem *selected) { if(!selected) return false; @@ -4225,7 +4255,7 @@ namespace QuickMedia { video_page->url = selected->url; BodyItems next_items; // TODO: Add title - video_content_page(video_page.get(), "", message_type == MessageType::VIDEO || message_type == MessageType::AUDIO, next_items, 0); + video_content_page(matrix_chat_page, video_page.get(), "", message_type == MessageType::VIDEO || message_type == MessageType::AUDIO, next_items, 0); no_video = prev_no_video; redraw = true; return true; -- cgit v1.2.3