aboutsummaryrefslogtreecommitdiff
path: root/include/QuickMedia.hpp
blob: 45c499a73ae6408622342b2924bd2b3f9260d7c9 (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
#pragma once

#include "Body.hpp"
#include "SearchBar.hpp"
#include "Page.hpp"
#include "Storage.hpp"
#include "Tab.hpp"
#include <vector>
#include <memory>
#include <SFML/Graphics/Font.hpp>
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Graphics/Shader.hpp>
#include <json/value.h>
#include <unordered_set>
#include <future>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <stack>
#include <deque>
#include <X11/Xlib.h>
#include <X11/Xatom.h>

namespace QuickMedia {
    class Matrix;
    class FileManager;
    class MangaImagesPage;
    class ImageBoardThreadPage;

    enum class ImageViewMode {
        SINGLE,
        SCROLL
    };

    struct CopyOp {
        Path source;
        Path destination;
    };
    
    class Program {
    public:
        Program();
        ~Program();
        int run(int argc, char **argv);

        bool is_tor_enabled();
        std::unique_ptr<Body> create_body();
        std::unique_ptr<SearchBar> create_search_bar(const std::string &placeholder, int search_delay);

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

        void select_file(const std::string &filepath);
    private:
        void base_event_handler(sf::Event &event, PageType previous_page, Body *body, SearchBar *search_bar, bool handle_key_press = true, bool handle_searchbar = true);
        void page_loop(std::vector<Tab> tabs);
        void video_content_page(Page *page, std::string video_url, std::string video_title);
        // 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);
        void image_board_thread_page(ImageBoardThreadPage *thread_page, Body *thread_body);
        void chat_login_page();
        void chat_page();

        enum class LoadImageResult {
            OK,
            FAILED,
            DOWNLOAD_IN_PROGRESS
        };

        LoadImageResult load_image_by_index(int image_index, sf::Texture &image_texture, sf::String &error_message);
        void download_chapter_images_if_needed(MangaImagesPage *images_page);
        void select_episode(BodyItem *item, bool start_from_beginning);

        // Returns PageType::EXIT if empty
        PageType pop_page_stack();

        void manga_get_watch_history(const char *plugin_name, BodyItems &history_items);
        void youtube_get_watch_history(BodyItems &history_items);
        Json::Value load_video_history_json();
        Json::Value load_recommended_json();

        void save_recommendations_from_related_videos(const std::string &video_url, const std::string &video_title, const Body *related_media_body);
    private:
        enum class UpscaleImageAction {
            NO,
            LOW_RESOLUTION,
            FORCE
        };

        Display *disp;
        sf::RenderWindow window;
        Matrix *matrix = nullptr;
        int monitor_hz;
        sf::Vector2f window_size;
        std::unique_ptr<sf::Font> font;
        std::unique_ptr<sf::Font> bold_font;
        std::unique_ptr<sf::Font> cjk_font;
        const char *plugin_name = nullptr;
        sf::Texture plugin_logo;
        sf::Texture loading_icon;
        PageType current_page;
        std::stack<PageType> page_stack;
        int image_index;
        Path content_storage_file;
        Path content_cache_dir;
        std::string manga_id_base64;
        Json::Value content_storage_json;
        std::unordered_set<std::string> watched_videos;
        std::future<BodyItems> search_suggestion_future;
        std::future<std::string> autocomplete_future;
        std::future<void> image_download_future;
        std::thread image_upscale_thead;
        std::mutex image_upscale_mutex;
        std::deque<CopyOp> images_to_upscale;
        std::vector<char> image_upscale_status;
        std::condition_variable image_upscale_cv;
        std::string downloading_chapter_url;
        bool image_download_cancel = false;
        int exit_code = 0;
        std::string resources_root;
        sf::Shader circle_mask_shader;
        bool use_tor = false;
        bool no_video = false;
        bool use_system_mpv_config = false;
        UpscaleImageAction upscale_image_action = UpscaleImageAction::NO;
        // TODO: Save this to config file when switching modes
        ImageViewMode image_view_mode = ImageViewMode::SINGLE;
        std::vector<std::string> selected_files;
        bool fit_image_to_window = false;
    };
}