show pending/failed messages

css changes:
- added .failed
- added .pending
This commit is contained in:
ouwou
2021-04-03 02:40:37 -04:00
parent 88c91495c3
commit 77b43f0f24
16 changed files with 175 additions and 33 deletions

View File

@@ -51,6 +51,9 @@ ChatMessageItemContainer *ChatMessageItemContainer::FromMessage(Snowflake id) {
container->ID = data->ID;
container->ChannelID = data->ChannelID;
if (data->Nonce.has_value())
container->Nonce = *data->Nonce;
if (data->Content.size() > 0 || data->Type != MessageType::DEFAULT) {
container->m_text_component = container->CreateTextComponent(&*data);
container->AttachEventHandlers(*container->m_text_component);
@@ -139,6 +142,11 @@ void ChatMessageItemContainer::UpdateReactions() {
}
}
void ChatMessageItemContainer::SetFailed() {
m_text_component->get_style_context()->remove_class("pending");
m_text_component->get_style_context()->add_class("failed");
}
void ChatMessageItemContainer::UpdateAttributes() {
const auto data = Abaddon::Get().GetDiscordClient().GetMessage(ID);
if (!data.has_value()) return;
@@ -176,6 +184,8 @@ void ChatMessageItemContainer::AddClickHandler(Gtk::Widget *widget, std::string
Gtk::TextView *ChatMessageItemContainer::CreateTextComponent(const Message *data) {
auto *tv = Gtk::manage(new Gtk::TextView);
if (data->IsPending)
tv->get_style_context()->add_class("pending");
tv->get_style_context()->add_class("message-text");
tv->set_can_focus(false);
tv->set_editable(false);

View File

@@ -7,6 +7,8 @@ public:
Snowflake ID;
Snowflake ChannelID;
std::string Nonce;
ChatMessageItemContainer();
static ChatMessageItemContainer *FromMessage(Snowflake id);
@@ -14,6 +16,7 @@ public:
void UpdateAttributes();
void UpdateContent();
void UpdateReactions();
void SetFailed();
protected:
void AddClickHandler(Gtk::Widget *widget, std::string);

View File

@@ -5,6 +5,8 @@
#include "chatinput.hpp"
ChatWindow::ChatWindow() {
Abaddon::Get().GetDiscordClient().signal_message_send_fail().connect(sigc::mem_fun(*this, &ChatWindow::OnMessageSendFail));
m_main = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL));
m_list = Gtk::manage(new Gtk::ListBox);
m_scroll = Gtk::manage(new Gtk::ScrolledWindow);
@@ -197,6 +199,19 @@ ChatMessageItemContainer *ChatWindow::CreateMessageComponent(Snowflake id) {
return container;
}
void ChatWindow::RemoveMessageAndHeader(Gtk::Widget *widget) {
ChatMessageHeader *header = dynamic_cast<ChatMessageHeader *>(widget->get_ancestor(Gtk::ListBoxRow::get_type()));
if (header != nullptr) {
if (header->GetChildContent().size() == 1) {
m_num_rows--;
delete header;
} else
delete widget;
} else
delete widget;
m_num_messages--;
}
constexpr static int MaxMessagesForCull = 50; // this has to be 50 cuz that magic number is used in a couple other places and i dont feel like replacing them
void ChatWindow::ProcessNewMessage(Snowflake id, bool prepend) {
const auto &client = Abaddon::Get().GetDiscordClient();
@@ -204,6 +219,16 @@ void ChatWindow::ProcessNewMessage(Snowflake id, bool prepend) {
const auto data = client.GetMessage(id);
if (!data.has_value()) return;
if (!data->IsPending && data->Nonce.has_value() && data->Author.ID == client.GetUserData().ID) {
for (auto [id, widget] : m_id_to_widget) {
if (dynamic_cast<ChatMessageItemContainer *>(widget)->Nonce == *data->Nonce) {
RemoveMessageAndHeader(widget);
m_id_to_widget.erase(id);
break;
}
}
}
ChatMessageHeader *last_row = nullptr;
bool should_attach = false;
if (m_num_rows > 0) {
@@ -222,17 +247,8 @@ void ChatWindow::ProcessNewMessage(Snowflake id, bool prepend) {
if (m_should_scroll_to_bottom && !prepend)
while (m_num_messages > MaxMessagesForCull) {
auto first_it = m_id_to_widget.begin();
ChatMessageHeader *header = dynamic_cast<ChatMessageHeader *>(first_it->second->get_ancestor(Gtk::ListBoxRow::get_type()));
if (header != nullptr) {
if (header->GetChildContent().size() == 1)
delete header;
else
delete first_it->second;
} else
delete first_it->second;
RemoveMessageAndHeader(first_it->second);
m_id_to_widget.erase(first_it);
m_num_rows--;
m_num_messages--;
}
ChatMessageHeader *header;
@@ -261,22 +277,24 @@ void ChatWindow::ProcessNewMessage(Snowflake id, bool prepend) {
header->AddContent(content, prepend);
m_id_to_widget[id] = content;
content->signal_action_delete().connect([this, id] {
m_signal_action_message_delete.emit(m_active_channel, id);
});
content->signal_action_edit().connect([this, id] {
m_signal_action_message_edit.emit(m_active_channel, id);
});
content->signal_action_reaction_add().connect([this, id](const Glib::ustring &param) {
m_signal_action_reaction_add.emit(id, param);
});
content->signal_action_reaction_remove().connect([this, id](const Glib::ustring &param) {
m_signal_action_reaction_remove.emit(id, param);
});
content->signal_action_channel_click().connect([this](const Snowflake &id) {
m_signal_action_channel_click.emit(id);
});
content->signal_action_reply_to().connect(sigc::mem_fun(*this, &ChatWindow::StartReplying));
if (!data->IsPending) {
content->signal_action_delete().connect([this, id] {
m_signal_action_message_delete.emit(m_active_channel, id);
});
content->signal_action_edit().connect([this, id] {
m_signal_action_message_edit.emit(m_active_channel, id);
});
content->signal_action_reaction_add().connect([this, id](const Glib::ustring &param) {
m_signal_action_reaction_add.emit(id, param);
});
content->signal_action_reaction_remove().connect([this, id](const Glib::ustring &param) {
m_signal_action_reaction_remove.emit(id, param);
});
content->signal_action_channel_click().connect([this](const Snowflake &id) {
m_signal_action_channel_click.emit(id);
});
content->signal_action_reply_to().connect(sigc::mem_fun(*this, &ChatWindow::StartReplying));
}
}
header->set_margin_left(5);
@@ -321,6 +339,15 @@ void ChatWindow::ScrollToBottom() {
x->set_value(x->get_upper());
}
void ChatWindow::OnMessageSendFail(const std::string &nonce) {
for (auto [id, widget] : m_id_to_widget) {
if (auto *container = dynamic_cast<ChatMessageItemContainer *>(widget); container->Nonce == nonce) {
container->SetFailed();
break;
}
}
}
ChatWindow::type_signal_action_message_delete ChatWindow::signal_action_message_delete() {
return m_signal_action_message_delete;
}

View File

@@ -47,9 +47,13 @@ protected:
bool OnKeyPressEvent(GdkEventKey *e);
void OnScrollEdgeOvershot(Gtk::PositionType pos);
void RemoveMessageAndHeader(Gtk::Widget *widget);
void ScrollToBottom();
bool m_should_scroll_to_bottom = true;
void OnMessageSendFail(const std::string &nonce);
Gtk::Box *m_main;
Gtk::ListBox *m_list;
Gtk::ScrolledWindow *m_scroll;