aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md6
-rw-r--r--plugins/Mangadex.hpp1
-rw-r--r--src/Body.cpp4
-rw-r--r--src/QuickMedia.cpp2
-rw-r--r--src/SearchBar.cpp6
-rw-r--r--src/Tabs.cpp16
-rw-r--r--src/plugins/Mangadex.cpp85
-rw-r--r--src/plugins/Matrix.cpp11
8 files changed, 103 insertions, 28 deletions
diff --git a/README.md b/README.md
index 5c7996b..49a6ec2 100644
--- a/README.md
+++ b/README.md
@@ -25,8 +25,8 @@ EXAMPLES:
If you are running arch linux then you can install QuickMedia from aur (https://aur.archlinux.org/packages/quickmedia-git/), otherwise you will need to first install [sibs](https://git.dec05eba.com/sibs/) and then run `./install.sh` as root.
## Controls
Press `Arrow up` / `Arrow down` or `Ctrl+K` / `Ctrl+J` to navigate the menu and also to scroll to the previous/next image when viewing manga in scroll mode. Alternatively you can use the mouse scroll to scroll to the previous/next manga in scroll mode.\
-Press `Arrow left` / `Arrow right` or `Ctrl+H` / `Ctrl+L` or `Tab` / `Shift+Tab` to switch tab. The alt key can also be used in grid mode to move tabs instead of moving selection left/right.\
-Press `Ctrl+1-9` to move to the numbered tab.\
+Press `Alt+Arrow left` / `Alt+Arrow right` or `Ctrl+Alt+H` / `Ctrl+Alt+L` or `Tab` / `Shift+Tab` to switch tab.\
+Press `Alt+1-9` to switch to the specified tab.\
Press `Page up` to scroll up and entire page or `Page down` to scroll down an entire page.\
Press `Home` to scroll to the top or `End` to scroll to the bottom.\
Press `Enter` (aka `Return`) to select the item.\
@@ -60,7 +60,7 @@ Press `U` in matrix or in a 4chan thread to bring up the file manager to choose
Press `Ctrl + V` to upload media to room in matrix if the clipboard contains a valid absolute filepath.\
Press `Ctrl + D` to remove the file that was previously selected with `U` in a 4chan thread.\
Press `Ctrl + I` to reverse image search the selected image on 4chan or matrix, or to select the url in the text to open in a browser.\
-Press `Ctrl+Alt+Arrow up` / `Ctrl+Alt+Arrow down` or `Ctrl+Alt+K` / `Ctrl+Alt+J` to view the room above/below the selected room in matrix.\
+Press `Alt+Arrow up` / `Alt+Arrow down` or `Ctrl+Alt+K` / `Ctrl+Alt+J` to view the room above/below the selected room in matrix.\
Press `Ctrl + S` to save the selected/displaying image/video/audio (does currently not work for manga pages).\
Press `Ctrl + Enter` to submit text, ignoring the selected item (when saving a file or selecting a server for matrix room directory).\
Press `Ctrl + Enter` to save the file to the selected directory with the selected name, when downloading a file.
diff --git a/plugins/Mangadex.hpp b/plugins/Mangadex.hpp
index bd4385b..7497b06 100644
--- a/plugins/Mangadex.hpp
+++ b/plugins/Mangadex.hpp
@@ -20,6 +20,7 @@ namespace QuickMedia {
ChapterImageUrls chapter_image_urls;
private:
+ PluginResult get_cover_urls(BodyItems &body_items);
SearchResult search(const std::string &str, int page, BodyItems &result_items);
bool get_rememberme_token(std::string &rememberme_token);
std::optional<std::string> rememberme_token;
diff --git a/src/Body.cpp b/src/Body.cpp
index 9843492..ce7f4f3 100644
--- a/src/Body.cpp
+++ b/src/Body.cpp
@@ -520,7 +520,7 @@ namespace QuickMedia {
if(!show_drop_shadow)
return;
- const sf::Color color(21, 25, 30);
+ const sf::Color color(0, 0, 0, 50);
const float height = 5.0f;
sf::Vertex gradient_points[4];
@@ -1201,7 +1201,7 @@ namespace QuickMedia {
const float text_height = (card_height - card_padding_y * 2.0f) - image_height - text_padding;
const float underflow_text = text_pos.y - scissor_y;
- const float underflow_height = underflow_text < 0.0f ? text_height + underflow_text : text_height;
+ const float underflow_height = underflow_text < 0.0f ? std::max(0.0f, text_height + underflow_text) : text_height;
sf::View new_view(sf::FloatRect(0.0f, 0.0f, window_size.x, underflow_height));
new_view.setViewport(sf::FloatRect(0.0f, std::max(text_pos.y, scissor_y) / (float)window_size.y, 1.0f, underflow_height / (float)window_size.y));
window.setView(new_view);
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index 0709a12..c4a5d72 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -5251,7 +5251,7 @@ namespace QuickMedia {
idle_active_handler();
}
- if(event.type == sf::Event::KeyPressed && event.key.control && event.key.alt && (chat_state == ChatState::NAVIGATING || chat_state == ChatState::URL_SELECTION)) {
+ if(event.type == sf::Event::KeyPressed && event.key.alt && (chat_state == ChatState::NAVIGATING || chat_state == ChatState::URL_SELECTION)) {
if(event.key.code == sf::Keyboard::Up || (event.key.control && event.key.code == sf::Keyboard::K)) {
matrix_chat_page->rooms_page->body->select_previous_item(true);
move_room = true;
diff --git a/src/SearchBar.cpp b/src/SearchBar.cpp
index 91ad2e8..bf58c34 100644
--- a/src/SearchBar.cpp
+++ b/src/SearchBar.cpp
@@ -106,9 +106,6 @@ namespace QuickMedia {
if(!editable)
return;
- if(sf::Keyboard::isKeyPressed(sf::Keyboard::LControl) || sf::Keyboard::isKeyPressed(sf::Keyboard::RControl))
- return;
-
if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Backspace)
backspace_pressed = true;
else if(event.type == sf::Event::KeyReleased && event.key.code == sf::Keyboard::Backspace)
@@ -125,6 +122,9 @@ namespace QuickMedia {
time_since_search_update.restart();
}
+ if(sf::Keyboard::isKeyPressed(sf::Keyboard::LAlt) || sf::Keyboard::isKeyPressed(sf::Keyboard::RAlt))
+ return;
+
if(event.type == sf::Event::TextEntered && event.text.unicode != 8 && event.text.unicode != 127) // 8 = backspace, 127 = del
onTextEntered(event.text.unicode);
else if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Backspace)
diff --git a/src/Tabs.cpp b/src/Tabs.cpp
index e1a0d86..390b088 100644
--- a/src/Tabs.cpp
+++ b/src/Tabs.cpp
@@ -62,17 +62,19 @@ namespace QuickMedia {
void Tabs::on_event(sf::Event &event) {
if(event.type == sf::Event::KeyPressed && !tabs.empty()) {
- if(((!tabs[selected_tab].body->can_move_left() || event.key.alt) && (event.key.code == sf::Keyboard::Left || (event.key.control && event.key.code == sf::Keyboard::H)))
- || (event.key.code == sf::Keyboard::Tab && event.key.shift))
- {
+ bool move_left = event.key.alt && (event.key.code == sf::Keyboard::Left || (event.key.control && event.key.code == sf::Keyboard::H));
+ move_left |= (event.key.code == sf::Keyboard::Tab && event.key.shift);
+
+ bool move_right = event.key.alt && (event.key.code == sf::Keyboard::Right || (event.key.control && event.key.code == sf::Keyboard::L));
+ move_right |= (event.key.code == sf::Keyboard::Tab && !event.key.shift);
+
+ if(move_left) {
if(selected_tab > 0)
move_selected_tab(selected_tab - 1);
- } else if(((!tabs[selected_tab].body->can_move_right() || event.key.alt) && (event.key.code == sf::Keyboard::Right || (event.key.control && event.key.code == sf::Keyboard::L)))
- || (event.key.code == sf::Keyboard::Tab && !event.key.shift))
- {
+ } else if(move_right) {
if(selected_tab < (int)tabs.size() - 1)
move_selected_tab(selected_tab + 1);
- } else if(event.key.control && event.key.code >= sf::Keyboard::Num1 && event.key.code <= sf::Keyboard::Num9) {
+ } else if(event.key.alt && event.key.code >= sf::Keyboard::Num1 && event.key.code <= sf::Keyboard::Num9) {
const int tab_target = event.key.code - sf::Keyboard::Num1;
if(tab_target < (int)tabs.size())
move_selected_tab(tab_target);
diff --git a/src/plugins/Mangadex.cpp b/src/plugins/Mangadex.cpp
index 0143d7f..4a10455 100644
--- a/src/plugins/Mangadex.cpp
+++ b/src/plugins/Mangadex.cpp
@@ -58,8 +58,88 @@ namespace QuickMedia {
return PluginResult::OK;
}
+ static std::shared_ptr<BodyItem> relationship_get_body_item(const Json::Value &json, BodyItems &body_items) {
+ for(const Json::Value &item_json : json) {
+ if(!item_json.isObject())
+ continue;
+
+ const Json::Value &type_json = item_json["type"];
+ if(!type_json.isString() || strcmp(type_json.asCString(), "manga") != 0)
+ continue;
+
+ const Json::Value &id_json = item_json["id"];
+ if(!id_json.isString())
+ continue;
+
+ std::string id_str = id_json.asString();
+ auto it = std::find_if(body_items.begin(), body_items.end(), [&id_str](const std::shared_ptr<BodyItem> &body_item) {
+ return body_item->url == id_str;
+ });
+
+ if(it == body_items.end())
+ continue;
+
+ return *it;
+ }
+ return nullptr;
+ }
+
+ PluginResult MangadexSearchPage::get_cover_urls(BodyItems &body_items) {
+ std::string url = "https://api.mangadex.org/cover?";
+ for(size_t i = 0; i < body_items.size(); ++i) {
+ if(i > 0)
+ url += "&";
+ url += "manga[]=" + body_items[i]->url;
+ }
+
+ Json::Value json_root;
+ if(download_json(json_root, url, {}, true) != DownloadResult::OK)
+ return PluginResult::NET_ERR;
+
+ if(!json_root.isObject())
+ return PluginResult::OK;
+
+ const Json::Value &results_json = json_root["results"];
+ if(!results_json.isArray())
+ return PluginResult::OK;
+
+ std::shared_ptr<BodyItem> body_item;
+ for(const Json::Value &result_item_json : results_json) {
+ if(!result_item_json.isObject())
+ continue;
+
+ const Json::Value &result_json = result_item_json["result"];
+ if(!result_json.isString() || strcmp(result_json.asCString(), "ok") != 0)
+ continue;
+
+ const Json::Value &relationships_json = result_item_json["relationships"];
+ if(!relationships_json.isArray())
+ continue;
+
+ body_item = relationship_get_body_item(relationships_json, body_items);
+ if(!body_item)
+ continue;
+
+ const Json::Value &data_json = result_item_json["data"];
+ if(!data_json.isObject())
+ continue;
+
+ const Json::Value &attributes_json = data_json["attributes"];
+ if(!attributes_json.isObject())
+ continue;
+
+ const Json::Value &filename_json = attributes_json["fileName"];
+ if(!filename_json.isString())
+ continue;
+
+ body_item->thumbnail_url = "https://uploads.mangadex.org/covers/" + body_item->url + "/" + filename_json.asString() + ".256.jpg";
+ }
+
+ return PluginResult::OK;
+ }
+
SearchResult MangadexSearchPage::search(const std::string &str, int page, BodyItems &result_items) {
- std::string url = "https://api.mangadex.org/manga?title=" + url_param_encode(str) + "&limit=100&offset=" + std::to_string(page * 100);
+ std::string url = "https://api.mangadex.org/manga?title=" + url_param_encode(str) + "&limit=20&offset=" + std::to_string(page * 20);
Json::Value json_root;
if(download_json(json_root, url, {}, true) != DownloadResult::OK)
@@ -108,6 +188,9 @@ namespace QuickMedia {
result_items.push_back(std::move(body_item));
}
+ // Intentionally ignore errors. This api shouldn't fail if we fail to get covers
+ get_cover_urls(result_items);
+
return SearchResult::OK;
}
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index 1e69bd7..6c7e4bd 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -2464,17 +2464,6 @@ namespace QuickMedia {
room_data->set_avatar_url(get_thumbnail_url(homeserver, thumbnail_url_extract_media_id(url_json.GetString())));
room_data->avatar_is_fallback = false;
- } else if(strcmp(type_json.GetString(), "m.room.avatar") == 0) {
- const rapidjson::Value &content_json = GetMember(event_item_json, "content");
- if(!content_json.IsObject())
- continue;
-
- const rapidjson::Value &url_json = GetMember(content_json, "url");
- if(!url_json.IsString() || strncmp(url_json.GetString(), "mxc://", 6) != 0)
- continue;
-
- room_data->set_avatar_url(get_thumbnail_url(homeserver, thumbnail_url_extract_media_id(url_json.GetString())));
- room_data->avatar_is_fallback = false;
} else if(strcmp(type_json.GetString(), "m.room.topic") == 0) {
const rapidjson::Value &content_json = GetMember(event_item_json, "content");
if(!content_json.IsObject())