aboutsummaryrefslogtreecommitdiff
path: root/plugins/Page.hpp
blob: 0d45b9e75b5e8eedc4737f2412df8d684b66ab24 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#pragma once

#include "Plugin.hpp"

#include "../include/Tab.hpp"
#include "../include/SearchBar.hpp"
#include "../include/Body.hpp"
#include "../include/MediaChapter.hpp"

namespace QuickMedia {
    constexpr int SEARCH_DELAY_FILTER = 50;

    // TODO: Remove to PageType when the other PageType is removed
    enum class PageTypez {
        REGULAR,
        MANGA_IMAGES,
        IMAGE_BOARD_THREAD,
        VIDEO,
        CHAT
    };

    class Page {
    public:
        Page(Program *program) : program(program) {}
        virtual ~Page() = default;

        virtual const char* get_title() const = 0;
        virtual bool search_is_filter() { return true; }
        // This show be overriden if search_is_filter is overriden to return false
        virtual SearchResult search(const std::string &str, BodyItems &result_items) { (void)str; (void)result_items; return SearchResult::ERR; }

        // Return empty |result_tabs| and PluginResult::OK to do nothing; which is useful for implementing custom actions on item submit
        virtual PluginResult submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) {
            (void)title;
            (void)url;
            (void)result_tabs;
            return PluginResult::ERR;
        }
        // Override and return false to make submit run in the main (ui) thread
        virtual bool submit_is_async() { return true; }
        virtual bool clear_search_after_submit() { return false; }
        // Note: If pagination is done by fetching the next page until we get to |page|, then the "current page" should be reset everytime |search| is called.
        // Note: the first page is 0
        virtual PluginResult get_page(const std::string &str, int page, BodyItems &result_items) { (void)str; (void)page; (void)result_items; return PluginResult::OK; }

        DownloadResult download_json(Json::Value &result, const std::string &url, std::vector<CommandArg> additional_args, bool use_browser_useragent = false, std::string *err_msg = nullptr);

        virtual PageTypez get_type() const { return PageTypez::REGULAR; }
        // Mutually exclusive with |get_type| when |get_type| is not PageTypez::REGULAR
        virtual bool is_single_page() const { return false; }
        virtual bool is_trackable() const { return false; }
        virtual bool is_lazy_fetch_page() const { return false; }
        // Note: If submit is done without any selection, then the search term is sent as the |title|, not |url|. Submit will only be sent if the input text is not empty or if an item is selected
        virtual bool allow_submit_no_selection() const { return false; }
        // This is used to delay loading of the page. For example if the page relies on an external factor to start loading
        virtual bool is_ready() { return true; }

        // This is called both when first navigating to page and when going back to page
        virtual void on_navigate_to_page(Body *body) { (void)body; }

        std::unique_ptr<Body> create_body(bool plain_text_list = false, bool prefer_card_view = false);
        std::unique_ptr<SearchBar> create_search_bar(const std::string &placeholder_text, int search_delay);

        bool load_manga_content_storage(const char *service_name, const std::string &manga_title, const std::string &manga_id);

        virtual sf::Vector2i get_thumbnail_max_size() { return sf::Vector2i(250, 141); };
    
        Program *program;
        std::shared_ptr<BodyItem> submit_body_item; // TODO: Remove this
    };

    enum class TrackResult {
        OK,
        ERR
    };

    class TrackablePage {
    public:
        TrackablePage(std::string content_title, std::string content_url) : content_title(std::move(content_title)), content_url(std::move(content_url)) {}
        virtual ~TrackablePage() = default;
        virtual TrackResult track(const std::string &str) = 0;

        const std::string content_title;
        const std::string content_url;
    };

    class LazyFetchPage : public Page {
    public:
        LazyFetchPage(Program *program) : Page(program) {}
        virtual bool search_is_filter() override { return true; }
        bool is_lazy_fetch_page() const override { return true; }
        virtual PluginResult lazy_fetch(BodyItems &result_items) = 0;
        // If this returns true then |lazy_fetch| is not meant to return results but async background load the page. This can be used to fetch API keys for example
        virtual bool lazy_fetch_is_loader() { return false; }
        virtual bool reload_on_page_change() { return false; }
    };

    class RelatedVideosPage : public Page {
    public:
        RelatedVideosPage(Program *program) : Page(program) {}
        const char* get_title() const override { return "Related videos"; }
    };

    class VideoPage : public Page {
    public:
        VideoPage(Program *program, std::string url) : Page(program), url(std::move(url)) {}
        virtual PageTypez get_type() const override { return PageTypez::VIDEO; }
        virtual bool autoplay_next_item() { return false; }
        virtual BodyItems get_related_media(const std::string &url) { (void)url; return {}; }
        virtual std::unique_ptr<Page> create_search_page(Program *program, int &search_delay) { (void)program; (void)search_delay; return nullptr; }
        virtual std::unique_ptr<Page> create_comments_page(Program *program) { (void)program; return nullptr; }
        // Return nullptr if the service doesn't support related videos page
        virtual std::unique_ptr<RelatedVideosPage> create_related_videos_page(Program *program) = 0;
        // Return nullptr if the service doesn't support channels page
        virtual std::unique_ptr<Page> create_channels_page(Program *program, const std::string &channel_url) = 0;
        virtual void set_url(std::string new_url) { url = std::move(new_url); }
        std::string get_url() { return url; }
        // Returns empty string for no timestamp or if the video doesn't support timestamps
        virtual std::string get_url_timestamp() { return ""; }
        // Falls back to |get_url| if this and |get_audio_url| returns empty strings
        virtual std::string get_video_url(int max_height, bool &has_embedded_audio) {
            (void)max_height;
            has_embedded_audio = true;
            return "";
        }
        // Only used if |get_video_url| sets |has_embedded_audio| to false
        virtual std::string get_audio_url() { return ""; }
        virtual std::string url_get_playable_url(const std::string &url) { return url; }
        virtual bool video_should_be_skipped(const std::string &url) { (void)url; return false; }
        virtual PluginResult load(std::string &title, std::string &channel_url, std::vector<MediaChapter> &chapters) { (void)title; (void)channel_url; (void)chapters; return PluginResult::OK; }
        virtual void mark_watched() {};
    protected:
        std::string url;
    };
}