summaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/chatinput.cpp10
-rw-r--r--src/components/chatinput.hpp3
-rw-r--r--src/components/chatlist.cpp17
-rw-r--r--src/components/chatlist.hpp1
-rw-r--r--src/components/chatwindow.cpp55
-rw-r--r--src/components/chatwindow.hpp7
6 files changed, 85 insertions, 8 deletions
diff --git a/src/components/chatinput.cpp b/src/components/chatinput.cpp
index 28ed1ea..8ad0c3f 100644
--- a/src/components/chatinput.cpp
+++ b/src/components/chatinput.cpp
@@ -565,6 +565,16 @@ void ChatInput::StopReplying() {
m_input.Get().get_style_context()->remove_class("replying");
}
+void ChatInput::StartEditing(const Message &message) {
+ m_input.Get().grab_focus();
+ m_input.Get().get_style_context()->add_class("editing");
+ GetBuffer()->set_text(message.Content);
+}
+
+void ChatInput::StopEditing() {
+ m_input.Get().get_style_context()->remove_class("editing");
+}
+
bool ChatInput::AddFileAsImageAttachment(const Glib::RefPtr<Gio::File> &file) {
try {
const auto read_stream = file->read();
diff --git a/src/components/chatinput.hpp b/src/components/chatinput.hpp
index bc6a45d..a7ee27f 100644
--- a/src/components/chatinput.hpp
+++ b/src/components/chatinput.hpp
@@ -139,6 +139,9 @@ public:
void StartReplying();
void StopReplying();
+ void StartEditing(const Message &message);
+ void StopEditing();
+
private:
bool AddFileAsImageAttachment(const Glib::RefPtr<Gio::File> &file);
bool CanAttachFiles();
diff --git a/src/components/chatlist.cpp b/src/components/chatlist.cpp
index 93fb46f..28981b2 100644
--- a/src/components/chatlist.cpp
+++ b/src/components/chatlist.cpp
@@ -253,6 +253,23 @@ void ChatList::ActuallyRemoveMessage(Snowflake id) {
RemoveMessageAndHeader(it->second);
}
+std::optional<Snowflake> ChatList::GetLastSentMessage() {
+ const auto &discord = Abaddon::Get().GetDiscordClient();
+ const auto self_id = discord.GetUserData().ID;
+
+ std::map<Snowflake, Gtk::Widget *> ordered(m_id_to_widget.begin(), m_id_to_widget.end());
+
+ for (auto it = ordered.crbegin(); it != ordered.crend(); it++) {
+ const auto *widget = dynamic_cast<ChatMessageItemContainer*>(it->second);
+ if (widget == nullptr) continue;
+ const auto msg = discord.GetMessage(widget->ID);
+ if (!msg.has_value()) continue;
+ if (msg->Author.ID == self_id) return msg->ID;
+ }
+
+ return std::nullopt;
+}
+
void ChatList::SetupMenu() {
m_menu_copy_id = Gtk::manage(new Gtk::MenuItem("Copy ID"));
m_menu_copy_id->signal_activate().connect([this] {
diff --git a/src/components/chatlist.hpp b/src/components/chatlist.hpp
index 0248d7f..5d4ec4a 100644
--- a/src/components/chatlist.hpp
+++ b/src/components/chatlist.hpp
@@ -23,6 +23,7 @@ public:
void SetSeparateAll(bool separate);
void SetUsePinnedMenu(); // i think i need a better way to do menus
void ActuallyRemoveMessage(Snowflake id); // perhaps not the best method name
+ std::optional<Snowflake> GetLastSentMessage();
private:
void SetupMenu();
diff --git a/src/components/chatwindow.cpp b/src/components/chatwindow.cpp
index e51d491..864d0c9 100644
--- a/src/components/chatwindow.cpp
+++ b/src/components/chatwindow.cpp
@@ -50,8 +50,8 @@ ChatWindow::ChatWindow() {
m_input->signal_submit().connect(sigc::mem_fun(*this, &ChatWindow::OnInputSubmit));
m_input->signal_escape().connect([this]() {
- if (m_is_replying)
- StopReplying();
+ if (m_is_replying) StopReplying();
+ if (m_is_editing) StopEditing();
});
m_input->signal_key_press_event().connect(sigc::mem_fun(*this, &ChatWindow::OnKeyPressEvent), false);
m_input->show();
@@ -132,8 +132,8 @@ void ChatWindow::SetActiveChannel(Snowflake id) {
m_input->SetActiveChannel(id);
m_input_indicator->SetActiveChannel(id);
m_rate_limit_indicator->SetActiveChannel(id);
- if (m_is_replying)
- StopReplying();
+ if (m_is_replying) StopReplying();
+ if (m_is_editing) StopEditing();
#ifdef WITH_LIBHANDY
m_tab_switcher->ReplaceActiveTab(id);
@@ -274,15 +274,31 @@ bool ChatWindow::OnInputSubmit(ChatSubmitParams data) {
data.ChannelID = m_active_channel;
data.InReplyToID = m_replying_to;
+ data.EditingID = m_editing_id;
if (m_active_channel.IsValid())
m_signal_action_chat_submit.emit(data); // m_replying_to is checked for invalid in the handler
- if (m_is_replying)
- StopReplying();
+
+ if (m_is_replying) StopReplying();
+ if (m_is_editing) StopEditing();
return true;
}
+bool ChatWindow::ProcessKeyEvent(GdkEventKey *e) {
+ if (e->type != GDK_KEY_PRESS) return false;
+ if (e->keyval == GDK_KEY_Up) {
+ const auto edit_id = m_chat->GetLastSentMessage();
+ if (edit_id.has_value()) {
+ StartEditing(*edit_id);
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
bool ChatWindow::OnKeyPressEvent(GdkEventKey *e) {
if (m_completer.ProcessKeyPress(e))
return true;
@@ -290,6 +306,9 @@ bool ChatWindow::OnKeyPressEvent(GdkEventKey *e) {
if (m_input->ProcessKeyPress(e))
return true;
+ if (ProcessKeyEvent(e))
+ return true;
+
return false;
}
@@ -300,10 +319,11 @@ void ChatWindow::StartReplying(Snowflake message_id) {
m_replying_to = message_id;
m_is_replying = true;
m_input->StartReplying();
- if (author.has_value())
+ if (author.has_value()) {
m_input_indicator->SetCustomMarkup("Replying to " + author->GetUsernameEscapedBold());
- else
+ } else {
m_input_indicator->SetCustomMarkup("Replying...");
+ }
}
void ChatWindow::StopReplying() {
@@ -313,6 +333,25 @@ void ChatWindow::StopReplying() {
m_input_indicator->ClearCustom();
}
+void ChatWindow::StartEditing(Snowflake message_id) {
+ const auto message = Abaddon::Get().GetDiscordClient().GetMessage(message_id);
+ if (!message.has_value()) {
+ spdlog::get("ui")->warn("ChatWindow::StartEditing message is nullopt");
+ return;
+ }
+ m_is_editing = true;
+ m_editing_id = message_id;
+ m_input->StartEditing(*message);
+ m_input_indicator->SetCustomMarkup("Editing...");
+}
+
+void ChatWindow::StopEditing() {
+ m_is_editing = false;
+ m_editing_id = Snowflake::Invalid;
+ m_input->StopEditing();
+ m_input_indicator->ClearCustom();
+}
+
void ChatWindow::OnScrollEdgeOvershot(Gtk::PositionType pos) {
if (pos == Gtk::POS_TOP)
m_signal_action_chat_load_history.emit(m_active_channel);
diff --git a/src/components/chatwindow.hpp b/src/components/chatwindow.hpp
index e1bb57a..b3c9d41 100644
--- a/src/components/chatwindow.hpp
+++ b/src/components/chatwindow.hpp
@@ -37,6 +37,9 @@ public:
void SetTopic(const std::string &text);
void AddAttachment(const Glib::RefPtr<Gio::File> &file);
+ void StartEditing(Snowflake message_id);
+ void StopEditing();
+
#ifdef WITH_LIBHANDY
void OpenNewTab(Snowflake id);
TabsState GetTabsState();
@@ -55,10 +58,14 @@ protected:
void StartReplying(Snowflake message_id);
void StopReplying();
+ bool m_is_editing = false;
+ Snowflake m_editing_id;
+
Snowflake m_active_channel;
bool OnInputSubmit(ChatSubmitParams data);
+ bool ProcessKeyEvent(GdkEventKey *e);
bool OnKeyPressEvent(GdkEventKey *e);
void OnScrollEdgeOvershot(Gtk::PositionType pos);