aboutsummaryrefslogtreecommitdiff
path: root/src/QuickMedia.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/QuickMedia.cpp')
-rw-r--r--src/QuickMedia.cpp108
1 files changed, 85 insertions, 23 deletions
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index 8a7cbf6..c3e61fe 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -678,7 +678,7 @@ namespace QuickMedia {
if(!timestamp.isNumeric())
continue;
- auto body_item = std::make_unique<BodyItem>(std::move(title_str));
+ auto body_item = BodyItem::create(std::move(title_str));
body_item->url = "https://www.youtube.com/watch?v=" + video_id_str;
body_item->thumbnail_url = "https://img.youtube.com/vi/" + video_id_str + "/hqdefault.jpg";
body_item->set_description(timestamp_to_relative_time_str(std::max(0l, time_now - timestamp.asInt64())));
@@ -746,7 +746,7 @@ namespace QuickMedia {
if(!recommended_title_json.isString())
continue;
- auto body_item = std::make_unique<BodyItem>(recommended_title_json.asString());
+ auto body_item = BodyItem::create(recommended_title_json.asString());
body_item->url = "https://www.youtube.com/watch?v=" + recommended_item_id;
body_item->thumbnail_url = "https://img.youtube.com/vi/" + recommended_item_id + "/hqdefault.jpg";
body_items.push_back(std::move(body_item));
@@ -837,7 +837,7 @@ namespace QuickMedia {
const Json::Value &manga_name = body["name"];
if(!filename.empty() && manga_name.isString()) {
// TODO: Add thumbnail
- auto body_item = std::make_unique<BodyItem>(manga_name.asString());
+ auto body_item = BodyItem::create(manga_name.asString());
if(plugin->name == "manganelo")
body_item->url = "https://manganelo.com/manga/" + base64_decode(filename.string());
else if(plugin->name == "mangadex")
@@ -3343,14 +3343,23 @@ namespace QuickMedia {
// get_all_room_messages is not needed here because its done in the loop, where the initial timeout is 0ms
+ enum class ChatState {
+ NAVIGATING,
+ TYPING_MESSAGE,
+ REPLYING
+ };
+
Page new_page = Page::CHAT;
- bool typing_message = false;
+ ChatState chat_state = ChatState::NAVIGATING;
+
+ std::shared_ptr<BodyItem> replying_to_message;
+ sf::Text replying_to_text("Replying to:", *font, 18);
sf::Sprite logo_sprite(plugin_logo);
Entry chat_input("Press ctrl+m to begin writing a message...", font.get(), cjk_font.get());
chat_input.set_editable(false);
- chat_input.on_submit_callback = [matrix, &chat_input, &tabs, &selected_tab, &current_room_id, &new_page, &typing_message](const sf::String &text) {
+ chat_input.on_submit_callback = [matrix, &chat_input, &tabs, &selected_tab, &current_room_id, &new_page, &chat_state, &replying_to_message](const sf::String &text) mutable {
if(tabs[selected_tab].type == ChatTabType::MESSAGES) {
if(text.isEmpty())
return false;
@@ -3361,12 +3370,12 @@ namespace QuickMedia {
if(command == "/upload") {
new_page = Page::FILE_MANAGER;
chat_input.set_editable(false);
- typing_message = false;
+ chat_state = ChatState::NAVIGATING;
return true;
} else if(command == "/logout") {
new_page = Page::CHAT_LOGIN;
chat_input.set_editable(false);
- typing_message = false;
+ chat_state = ChatState::NAVIGATING;
return true;
} else {
fprintf(stderr, "Error: invalid command: %s, expected /upload\n", command.c_str());
@@ -3374,14 +3383,29 @@ namespace QuickMedia {
}
}
- // TODO: Make asynchronous
- if(matrix->post_message(current_room_id, text) == PluginResult::OK) {
- chat_input.set_editable(false);
- typing_message = false;
- return true;
- } else {
- show_notification("QuickMedia", "Failed to post matrix message", Urgency::CRITICAL);
- return false;
+ tabs[selected_tab].body->select_last_item();
+
+ if(chat_state == ChatState::TYPING_MESSAGE) {
+ // TODO: Make asynchronous
+ if(matrix->post_message(current_room_id, text) == PluginResult::OK) {
+ chat_input.set_editable(false);
+ chat_state = ChatState::NAVIGATING;
+ return true;
+ } else {
+ show_notification("QuickMedia", "Failed to post matrix message", Urgency::CRITICAL);
+ return false;
+ }
+ } else if(chat_state == ChatState::REPLYING) {
+ // TODO: Make asynchronous
+ if(matrix->post_reply(current_room_id, text, replying_to_message->userdata) == PluginResult::OK) {
+ chat_input.set_editable(false);
+ chat_state = ChatState::NAVIGATING;
+ replying_to_message = nullptr;
+ return true;
+ } else {
+ show_notification("QuickMedia", "Failed to post matrix reply", Urgency::CRITICAL);
+ return false;
+ }
}
}
return false;
@@ -3437,6 +3461,7 @@ namespace QuickMedia {
sf::Clock frame_timer;
float prev_chat_height = chat_input.get_height();
+ float chat_input_height_full = 0.0f;
while (current_page == Page::CHAT) {
sf::Int32 frame_time_ms = frame_timer.restart().asMilliseconds();
@@ -3444,7 +3469,7 @@ namespace QuickMedia {
base_event_handler(event, Page::EXIT, false, false, false);
if(event.type == sf::Event::Resized || event.type == sf::Event::GainedFocus) {
redraw = true;
- } else if(event.type == sf::Event::KeyPressed && !typing_message) {
+ } else if(event.type == sf::Event::KeyPressed && chat_state == ChatState::NAVIGATING) {
if(event.key.code == sf::Keyboard::Up || event.key.code == sf::Keyboard::PageUp || event.key.code == sf::Keyboard::Home) {
bool hit_top = false;
switch(event.key.code) {
@@ -3516,15 +3541,25 @@ namespace QuickMedia {
current_page = Page::VIDEO_CONTENT;
video_content_page();
redraw = true;
+ } else if(tabs[selected_tab].type == ChatTabType::MESSAGES && event.key.control && event.key.code == sf::Keyboard::R) {
+ std::shared_ptr<BodyItem> selected = tabs[selected_tab].body->get_selected_shared();
+ if(selected) {
+ chat_state = ChatState::REPLYING;
+ replying_to_message = selected;
+ chat_input.set_editable(true);
+ } else {
+ // TODO: Show inline notification
+ show_notification("QuickMedia", "No message selected for replying");
+ }
}
}
- if(!typing_message && tabs[selected_tab].type == ChatTabType::MESSAGES && event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::M && event.key.control) {
+ if(chat_state == ChatState::NAVIGATING && tabs[selected_tab].type == ChatTabType::MESSAGES && event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::M && event.key.control) {
chat_input.set_editable(true);
- typing_message = true;
+ chat_state = ChatState::TYPING_MESSAGE;
}
- if(typing_message && tabs[selected_tab].type == ChatTabType::MESSAGES) {
+ if((chat_state == ChatState::TYPING_MESSAGE || chat_state == ChatState::REPLYING) && tabs[selected_tab].type == ChatTabType::MESSAGES) {
if(event.type == sf::Event::TextEntered) {
//chat_input.onTextEntered(event.text.unicode);
// TODO: Also show typing event when ctrl+v pasting?
@@ -3538,7 +3573,8 @@ namespace QuickMedia {
}
} else if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape) {
chat_input.set_editable(false);
- typing_message = false;
+ chat_state = ChatState::NAVIGATING;
+ replying_to_message = nullptr;
}
//chat_input.on_event(event);
chat_input.process_event(event);
@@ -3649,7 +3685,8 @@ namespace QuickMedia {
body_padding_horizontal = 0.0f;
}
- chat_input_shade.setSize(sf::Vector2f(window_size.x, chat_input.get_height() + chat_input_padding_y * 2.0f));
+ chat_input_height_full = chat_input.get_height() + chat_input_padding_y * 2.0f;
+ chat_input_shade.setSize(sf::Vector2f(window_size.x, chat_input_height_full));
chat_input_shade.setPosition(0.0f, window_size.y - chat_input_shade.getSize().y);
body_pos = sf::Vector2f(body_padding_horizontal, body_padding_vertical + tab_shade_height);
@@ -3675,7 +3712,7 @@ namespace QuickMedia {
BodyItems result_items;
if(matrix->sync() == PluginResult::OK) {
fprintf(stderr, "Synced matrix\n");
- if(matrix->get_new_room_messages(sync_future_room_id, result_items) == PluginResult::OK) {
+ if(matrix->get_new_room_messages(sync_future_room_id, result_items) != PluginResult::OK) {
fprintf(stderr, "Failed to get new matrix messages in room: %s\n", sync_future_room_id.c_str());
}
} else {
@@ -3691,7 +3728,7 @@ namespace QuickMedia {
// Ignore finished sync if it happened in another room. When we navigate back to the room we will get the messages again
if(sync_future_room_id == current_room_id) {
int num_items = tabs[MESSAGES_TAB_INDEX].body->items.size();
- bool scroll_to_end = (num_items > 0 && tabs[MESSAGES_TAB_INDEX].body->get_selected_item() == num_items - 1);
+ bool scroll_to_end = (num_items == 0 || (num_items > 0 && tabs[MESSAGES_TAB_INDEX].body->get_selected_item() == num_items - 1));
tabs[MESSAGES_TAB_INDEX].body->append_items(std::move(new_body_items));
if(scroll_to_end)
tabs[MESSAGES_TAB_INDEX].body->select_last_item();
@@ -3762,6 +3799,31 @@ namespace QuickMedia {
window.draw(gradient_points, 4, sf::Quads); // Note: sf::Quads doesn't work with egl
}
+ if(chat_state == ChatState::REPLYING) {
+ const float margin = 5.0f;
+ const float replying_to_text_height = replying_to_text.getLocalBounds().height + margin;
+
+ const float item_height = std::min(body_size.y - replying_to_text_height - margin, tabs[MESSAGES_TAB_INDEX].body->get_item_height(replying_to_message.get()) + margin);
+
+ sf::RectangleShape overlay(sf::Vector2f(window_size.x, window_size.y - tab_shade_height - chat_input_height_full));
+ overlay.setPosition(0.0f, tab_shade_height);
+ overlay.setFillColor(sf::Color(0, 0, 0, 240));
+ window.draw(overlay);
+
+ sf::Vector2f body_item_pos(body_pos.x, window_size.y - chat_input_height_full - item_height);
+ sf::Vector2f body_item_size(body_size.x, item_height);
+
+ sf::RectangleShape item_background(sf::Vector2f(window_size.x, body_item_size.y + replying_to_text_height + margin));
+ item_background.setPosition(sf::Vector2f(0.0f, body_item_pos.y - replying_to_text_height - margin));
+ item_background.setFillColor(back_color);
+ window.draw(item_background);
+
+ replying_to_text.setPosition(body_item_pos.x, body_item_pos.y - replying_to_text_height);
+ window.draw(replying_to_text);
+
+ tabs[MESSAGES_TAB_INDEX].body->draw_item(window, replying_to_message.get(), body_item_pos, body_item_size);
+ }
+
if(tabs[selected_tab].type == ChatTabType::MESSAGES && !tabs[selected_tab].body->is_last_item_fully_visible()) {
window.draw(more_messages_below_rect);
}