aboutsummaryrefslogtreecommitdiff
path: root/include/QuickMedia.hpp
blob: 0a0b509f268d80f46f01610661cfabd1565d45f9 (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
#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 <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;
        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;
        bool use_tor = false;
        bool no_video = false;
        bool use_system_mpv_config = false;
        UpscaleImageAction upscale_image_action = UpscaleImageAction::NO;
        bool running = false;
        // 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;
    };
}