aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO2
-rw-r--r--include/QuickMedia.hpp2
-rw-r--r--plugins/MangaCombined.hpp2
-rw-r--r--plugins/MangaGeneric.hpp2
-rw-r--r--plugins/Mangadex.hpp2
-rw-r--r--plugins/Manganelo.hpp2
-rw-r--r--plugins/MediaGeneric.hpp2
-rw-r--r--plugins/Youtube.hpp2
-rw-r--r--src/Body.cpp8
-rw-r--r--src/QuickMedia.cpp13
-rw-r--r--src/plugins/Fourchan.cpp112
11 files changed, 92 insertions, 57 deletions
diff --git a/TODO b/TODO
index 56617f6..ea94360 100644
--- a/TODO
+++ b/TODO
@@ -9,7 +9,7 @@ Add greentext support for 4chan quotes.
Add support for special formatting for posts by admins on imageboards.
For image boards, track (You)'s and show notification when somebody replies to your post.
Go to next chapter when reaching the end of the chapter in image endless mode.
-Some text is not visible on 4chan, such as code blocks.
+Make code blocks on matrix and 4chan use monospace and have a background of a different color, also syntax coloring?
Add login page for mangadex instead of having to manually add remember_me token to config file.
Allow deleting watch history with delete key (and show confirmation).
Add navigation to nyaa.si submitter torrents.
diff --git a/include/QuickMedia.hpp b/include/QuickMedia.hpp
index cb7e421..c01b4b8 100644
--- a/include/QuickMedia.hpp
+++ b/include/QuickMedia.hpp
@@ -100,7 +100,7 @@ namespace QuickMedia {
Json::Value load_recommended_json();
private:
void init(Window parent_window);
- void load_plugin_by_name(std::vector<Tab> &tabs, const char *start_dir);
+ void load_plugin_by_name(std::vector<Tab> &tabs, const char *start_dir, int &start_tab_index);
// Returns true if the window was closed
bool handle_window_close();
void base_event_handler(sf::Event &event, PageType previous_page, Body *body, SearchBar *search_bar, bool handle_key_press = true, bool handle_searchbar = true);
diff --git a/plugins/MangaCombined.hpp b/plugins/MangaCombined.hpp
index 56843c2..8d310f8 100644
--- a/plugins/MangaCombined.hpp
+++ b/plugins/MangaCombined.hpp
@@ -16,7 +16,7 @@ namespace QuickMedia {
class MangaCombinedSearchPage : public Page {
public:
MangaCombinedSearchPage(Program *program, std::vector<MangaPlugin> search_pages);
- const char* get_title() const override { return "All"; }
+ const char* get_title() const override { return "Search"; }
bool search_is_filter() override { return false; }
SearchResult search(const std::string &str, BodyItems &result_items) override;
PluginResult get_page(const std::string &str, int page, BodyItems &result_items) override;
diff --git a/plugins/MangaGeneric.hpp b/plugins/MangaGeneric.hpp
index 2dca919..e313c97 100644
--- a/plugins/MangaGeneric.hpp
+++ b/plugins/MangaGeneric.hpp
@@ -95,7 +95,7 @@ namespace QuickMedia {
class MangaGenericSearchPage : public Page {
public:
MangaGenericSearchPage(Program *program, const char *service_name, const char *website_url, bool fail_on_http_error = true);
- const char* get_title() const override { return "All"; }
+ const char* get_title() const override { return "Search"; }
bool search_is_filter() override { return false; }
SearchResult search(const std::string &str, BodyItems &result_items) override;
PluginResult get_page(const std::string &url, BodyItems &result_items);
diff --git a/plugins/Mangadex.hpp b/plugins/Mangadex.hpp
index 1befa1a..8e32aab 100644
--- a/plugins/Mangadex.hpp
+++ b/plugins/Mangadex.hpp
@@ -7,7 +7,7 @@ namespace QuickMedia {
class MangadexSearchPage : public Page {
public:
MangadexSearchPage(Program *program) : Page(program) {}
- const char* get_title() const override { return "All"; }
+ const char* get_title() const override { return "Search"; }
bool search_is_filter() override { return false; }
SearchResult search(const std::string &str, BodyItems &result_items) override;
PluginResult get_page(const std::string &str, int page, BodyItems &result_items) override;
diff --git a/plugins/Manganelo.hpp b/plugins/Manganelo.hpp
index 8e6c2cd..7cf3420 100644
--- a/plugins/Manganelo.hpp
+++ b/plugins/Manganelo.hpp
@@ -6,7 +6,7 @@ namespace QuickMedia {
class ManganeloSearchPage : public Page {
public:
ManganeloSearchPage(Program *program) : Page(program) {}
- const char* get_title() const override { return "All"; }
+ const char* get_title() const override { return "Search"; }
bool search_is_filter() override { return false; }
SearchResult search(const std::string &str, BodyItems &result_items) override;
PluginResult submit(const std::string &title, const std::string &url, std::vector<Tab> &result_tabs) override;
diff --git a/plugins/MediaGeneric.hpp b/plugins/MediaGeneric.hpp
index f7ff019..c7ce00b 100644
--- a/plugins/MediaGeneric.hpp
+++ b/plugins/MediaGeneric.hpp
@@ -35,7 +35,7 @@ namespace QuickMedia {
class MediaGenericSearchPage : public Page {
public:
MediaGenericSearchPage(Program *program, const char *website_url, sf::Vector2i thumbnail_max_size);
- const char* get_title() const override { return "All"; }
+ const char* get_title() const override { return "Search"; }
bool search_is_filter() override { return false; }
SearchResult search(const std::string &str, BodyItems &result_items) override;
PluginResult get_page(const std::string &str, int page, BodyItems &result_items) override;
diff --git a/plugins/Youtube.hpp b/plugins/Youtube.hpp
index 4be5339..dc3f0e7 100644
--- a/plugins/Youtube.hpp
+++ b/plugins/Youtube.hpp
@@ -8,7 +8,7 @@ namespace QuickMedia {
class YoutubeSearchPage : public Page {
public:
YoutubeSearchPage(Program *program) : Page(program) {}
- const char* get_title() const override { return "All"; }
+ const char* get_title() const override { return "Search"; }
bool search_is_filter() override { return false; }
SearchResult search(const std::string &str, BodyItems &result_items) override;
PluginResult get_page(const std::string &str, int page, BodyItems &result_items) override;
diff --git a/src/Body.cpp b/src/Body.cpp
index aa8d1d6..1470708 100644
--- a/src/Body.cpp
+++ b/src/Body.cpp
@@ -658,9 +658,9 @@ namespace QuickMedia {
const bool merge_with_previous = body_item_merge_handler && body_item_merge_handler(prev_body_item, item.get());
item->last_drawn_time = elapsed_time_sec;
- float extra_page_scroll = page_scroll;
+ //float extra_page_scroll = page_scroll;
float item_height = get_item_height(item.get(), size.x, true, true, merge_with_previous, i);
- prev_pos.y += (page_scroll - extra_page_scroll);
+ //prev_pos.y += (page_scroll - extra_page_scroll);
float item_height_with_merge = item_height;
item_height_with_merge += spacing_y;
prev_pos.y -= item_height_with_merge;
@@ -1255,8 +1255,8 @@ namespace QuickMedia {
item_height = std::max(item_height, image_height);
item_height += (padding_y * 2.0f);
- if(attach_side == AttachSide::TOP && item_index != -1 && item_index < selected_item && item->calculated_height >= 0.0f)
- page_scroll += (item_height - item->calculated_height);
+ //if(attach_side == AttachSide::TOP && item_index != -1 && item_index < selected_item && item->calculated_height >= 0.0f)
+ // page_scroll += (item_height - item->calculated_height);
item->calculated_height = item_height;
return item_height;
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index 247221e..4ed11b2 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -595,8 +595,10 @@ namespace QuickMedia {
return -1;
}
+ int start_tab_index = 0;
+
init(parent_window);
- load_plugin_by_name(tabs, start_dir);
+ load_plugin_by_name(tabs, start_dir, start_tab_index);
while(!tabs.empty() || matrix) {
if(matrix) {
@@ -611,12 +613,12 @@ namespace QuickMedia {
return exit_code;
}
- page_loop(tabs);
+ page_loop(tabs, start_tab_index);
tabs.clear();
if(strcmp(plugin_name, "launcher") == 0) {
plugin_name = pipe_selected_text.c_str();
- load_plugin_by_name(tabs, start_dir);
+ load_plugin_by_name(tabs, start_dir, start_tab_index);
}
}
@@ -893,7 +895,7 @@ namespace QuickMedia {
.related_media_thumbnail_handler({{"//img", "src", "/thumb-"}});
}
- void Program::load_plugin_by_name(std::vector<Tab> &tabs, const char *start_dir) {
+ void Program::load_plugin_by_name(std::vector<Tab> &tabs, const char *start_dir, int &start_tab_index) {
if(!plugin_name || plugin_name[0] == '\0')
return;
@@ -1012,6 +1014,8 @@ namespace QuickMedia {
PipePage::load_body_items_from_stdin(pipe_body->items);
tabs.push_back(Tab{std::move(pipe_body), std::make_unique<PipePage>(this), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
} else if(strcmp(plugin_name, "youtube") == 0) {
+ start_tab_index = 1;
+ tabs.push_back(Tab{create_body(), std::make_unique<YoutubeSubscriptionsPage>(this), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
tabs.push_back(Tab{create_body(), std::make_unique<YoutubeSearchPage>(this), create_search_bar("Search...", 350)});
auto history_body = create_body();
@@ -1022,7 +1026,6 @@ namespace QuickMedia {
auto recommended_search_bar = create_search_bar("Search...", SEARCH_DELAY_FILTER);
auto recommended_page = std::make_unique<RecommendedPage>(this, tabs.front().page.get(), recommended_search_bar.get(), plugin_name);
tabs.push_back(Tab{create_body(), std::move(recommended_page), std::move(recommended_search_bar)});
- tabs.push_back(Tab{create_body(), std::make_unique<YoutubeSubscriptionsPage>(this), create_search_bar("Search...", SEARCH_DELAY_FILTER)});
} else if(strcmp(plugin_name, "pornhub") == 0) {
auto search_page = std::make_unique<MediaGenericSearchPage>(this, "https://www.pornhub.com/", sf::Vector2i(320/1.5f, 180/1.5f));
add_pornhub_handlers(search_page.get());
diff --git a/src/plugins/Fourchan.cpp b/src/plugins/Fourchan.cpp
index c91bd0d..7cad54f 100644
--- a/src/plugins/Fourchan.cpp
+++ b/src/plugins/Fourchan.cpp
@@ -43,7 +43,7 @@ namespace QuickMedia {
};
DataView text; // Set when type is TEXT, QUOTE or QUOTELINK
- int64_t quote_postnumber; // Set when type is QUOTELINK
+ int64_t quote_postnumber = 0; // Set when type is QUOTELINK
Type type;
};
@@ -63,58 +63,90 @@ namespace QuickMedia {
return nullptr;
}
+ static void lstrip_newline(const char *str, size_t size, const char **output_str, size_t *output_size) {
+ size_t i = 0;
+ while(i < size && str[i] == '\n') {
+ ++i;
+ }
+ *output_str = str + i;
+ *output_size = size - i;
+ }
+
+ static void rstrip_newline(const char *str, size_t size, size_t *output_size) {
+ ssize_t i = size - 1;
+ while(i >= 0 && str[i] == '\n') {
+ --i;
+ }
+ *output_size = i + 1;
+ }
+
+ static void strip_newline(const char *str, size_t size, const char **output_str, size_t *output_size) {
+ lstrip_newline(str, size, output_str, output_size);
+ rstrip_newline(*output_str, *output_size, output_size);
+ }
+
using CommentPieceCallback = std::function<void(const CommentPiece&)>;
- static void extract_comment_pieces(TidyDoc doc, TidyNode node, CommentPieceCallback callback) {
+ static int extract_comment_pieces(TidyDoc doc, TidyNode node, CommentPieceCallback &callback) {
for(TidyNode child = tidyGetChild(node); child; child = tidyGetNext(child)) {
const char *node_name = tidyNodeGetName(child);
- if(node_name && strcmp(node_name, "wbr") == 0) {
- CommentPiece comment_piece;
- comment_piece.type = CommentPiece::Type::LINE_CONTINUE;
- comment_piece.text = { (char*)"", 0 };
- callback(comment_piece);
- continue;
- }
- TidyNodeType node_type = tidyNodeGetType(child);
- if(node_type == TidyNode_Start && node_name) {
- TidyNode text_node = tidyGetChild(child);
- //fprintf(stderr, "Child node name: %s, child text type: %d\n", node_name, tidyNodeGetType(text_node));
- if(tidyNodeGetType(text_node) == TidyNode_Text) {
- TidyBuffer tidy_buffer;
- tidyBufInit(&tidy_buffer);
- if(tidyNodeGetText(doc, text_node, &tidy_buffer)) {
+ if(node_name) {
+ if(strcmp(node_name, "br") == 0) {
+ CommentPiece comment_piece;
+ comment_piece.type = CommentPiece::Type::TEXT;
+ // Warning: Cast from const char* to char* ...
+ comment_piece.text = { (char*)"\n", 1 };
+ callback(comment_piece);
+ /*} else if(strcmp(node_name, "span") == 0) {
+ const char *span_class = get_attribute_value(child, "class");
+ //fprintf(stderr, "span class: %s\n", span_class);
+ if(span_class && strcmp(span_class, "quote") == 0) {
CommentPiece comment_piece;
- comment_piece.type = CommentPiece::Type::TEXT;
- comment_piece.text = { (char*)tidy_buffer.bp, tidy_buffer.size };
- if(strcmp(node_name, "span") == 0) {
- const char *span_class = get_attribute_value(child, "class");
- //fprintf(stderr, "span class: %s\n", span_class);
- if(span_class && strcmp(span_class, "quote") == 0)
- comment_piece.type = CommentPiece::Type::QUOTE;
- } else if(strcmp(node_name, "a") == 0) {
- const char *a_class = get_attribute_value(child, "class");
- const char *a_href = get_attribute_value(child, "href");
- //fprintf(stderr, "a class: %s, href: %s\n", a_class, a_href);
- if(a_class && a_href && strcmp(a_class, "quotelink") == 0 && strncmp(a_href, "#p", 2) == 0) {
- comment_piece.type = CommentPiece::Type::QUOTELINK;
- comment_piece.quote_postnumber = strtoll(a_href + 2, nullptr, 10);
- }
- }
+ comment_piece.type = CommentPiece::Type::QUOTE;
+ // Warning: Cast from const char* to char* ...
+ comment_piece.text = { (char*)"\n", 1 };
callback(comment_piece);
- }
- tidyBufFree(&tidy_buffer);
+ }*/
}
- } else if(node_type == TidyNode_Text) {
+ }
+
+ if(tidyNodeGetType(child) == TidyNode_Text) {
TidyBuffer tidy_buffer;
tidyBufInit(&tidy_buffer);
if(tidyNodeGetText(doc, child, &tidy_buffer)) {
+ const char *inner_text = (const char*)tidy_buffer.bp;
+ size_t inner_text_size = tidy_buffer.size;
+ strip_newline(inner_text, inner_text_size, &inner_text, &inner_text_size);
+
+ const char *node_name = tidyNodeGetName(node);
+ if(node_name && strcmp(node_name, "a") == 0) {
+ const char *a_class = get_attribute_value(node, "class");
+ const char *a_href = get_attribute_value(node, "href");
+ if(a_class && a_href && strcmp(a_class, "quotelink") == 0 && strncmp(a_href, "#p", 2) == 0) {
+ CommentPiece comment_piece;
+ comment_piece.type = CommentPiece::Type::QUOTELINK;
+ comment_piece.quote_postnumber = strtoll(a_href + 2, nullptr, 10);
+ // Warning: Cast from const char* to char* ...
+ comment_piece.text = { (char*)inner_text, inner_text_size };
+ callback(comment_piece);
+ tidyBufFree(&tidy_buffer);
+ continue;
+ }
+ }
+
CommentPiece comment_piece;
comment_piece.type = CommentPiece::Type::TEXT;
- comment_piece.text = { (char*)tidy_buffer.bp, tidy_buffer.size };
+ // Warning: Cast from const char* to char* ...
+ comment_piece.text = { (char*)inner_text, inner_text_size };
callback(comment_piece);
}
tidyBufFree(&tidy_buffer);
+ } else {
+ int res = extract_comment_pieces(doc, child, callback);
+ if(res != 0)
+ return res;
}
}
+ return 0;
}
static void extract_comment_pieces(const char *html_source, size_t size, CommentPieceCallback callback) {
@@ -129,7 +161,7 @@ namespace QuickMedia {
comment_piece.text = { (char*)html_source, size };
callback(comment_piece);
} else {
- extract_comment_pieces(doc, tidyGetBody(doc), std::move(callback));
+ extract_comment_pieces(doc, tidyGetRoot(doc), callback);
}
tidyRelease(doc);
}
@@ -241,8 +273,8 @@ namespace QuickMedia {
comment_text.append(cp.text.data, cp.text.size);
break;
case CommentPiece::Type::QUOTE:
- comment_text += '>';
- comment_text.append(cp.text.data, cp.text.size);
+ //comment_text += '>';
+ //comment_text.append(cp.text.data, cp.text.size);
//comment_text += '\n';
break;
case CommentPiece::Type::QUOTELINK: {