summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/abaddon.cpp18
-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
-rw-r--r--src/dialogs/editmessage.cpp45
-rw-r--r--src/dialogs/editmessage.hpp20
-rw-r--r--src/discord/chatsubmitparams.hpp1
-rw-r--r--src/windows/mainwindow.cpp4
-rw-r--r--src/windows/mainwindow.hpp1
12 files changed, 98 insertions, 84 deletions
diff --git a/src/abaddon.cpp b/src/abaddon.cpp
index 921549b..2be54ba 100644
--- a/src/abaddon.cpp
+++ b/src/abaddon.cpp
@@ -8,7 +8,6 @@
#include "audio/manager.hpp"
#include "discord/discord.hpp"
#include "dialogs/token.hpp"
-#include "dialogs/editmessage.hpp"
#include "dialogs/confirm.hpp"
#include "dialogs/setstatus.hpp"
#include "dialogs/friendpicker.hpp"
@@ -948,19 +947,15 @@ void Abaddon::ActionChatInputSubmit(ChatSubmitParams data) {
if (!m_discord.HasChannelPermission(m_discord.GetUserData().ID, data.ChannelID, Permission::VIEW_CHANNEL)) return;
- m_discord.SendChatMessage(data, NOOP_CALLBACK);
+ if (data.EditingID.IsValid()) {
+ m_discord.EditMessage(data.ChannelID, data.EditingID, data.Message);
+ } else {
+ m_discord.SendChatMessage(data, NOOP_CALLBACK);
+ }
}
void Abaddon::ActionChatEditMessage(Snowflake channel_id, Snowflake id) {
- const auto msg = m_discord.GetMessage(id);
- if (!msg.has_value()) return;
- EditMessageDialog dlg(*m_main_window);
- dlg.SetContent(msg->Content);
- auto response = dlg.run();
- if (response == Gtk::RESPONSE_OK) {
- auto new_content = dlg.GetContent();
- m_discord.EditMessage(channel_id, id, new_content);
- }
+ m_main_window->EditMessage(id);
}
void Abaddon::ActionInsertMention(Snowflake id) {
@@ -1156,6 +1151,7 @@ int main(int argc, char **argv) {
#endif
spdlog::cfg::load_env_levels();
+ auto log_ui = spdlog::stdout_color_mt("ui");
auto log_audio = spdlog::stdout_color_mt("audio");
auto log_voice = spdlog::stdout_color_mt("voice");
auto log_discord = spdlog::stdout_color_mt("discord");
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);
diff --git a/src/dialogs/editmessage.cpp b/src/dialogs/editmessage.cpp
deleted file mode 100644
index b4308a0..0000000
--- a/src/dialogs/editmessage.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-#include "editmessage.hpp"
-
-EditMessageDialog::EditMessageDialog(Gtk::Window &parent)
- : Gtk::Dialog("Edit Message", parent, true)
- , m_layout(Gtk::ORIENTATION_VERTICAL)
- , m_ok("OK")
- , m_cancel("Cancel")
- , m_bbox(Gtk::ORIENTATION_HORIZONTAL) {
- set_default_size(300, 50);
- get_style_context()->add_class("app-window");
- get_style_context()->add_class("app-popup");
-
- m_ok.signal_clicked().connect([&]() {
- m_content = m_text.get_buffer()->get_text();
- response(Gtk::RESPONSE_OK);
- });
-
- m_cancel.signal_clicked().connect([&]() {
- response(Gtk::RESPONSE_CANCEL);
- });
-
- m_bbox.pack_start(m_ok, Gtk::PACK_SHRINK);
- m_bbox.pack_start(m_cancel, Gtk::PACK_SHRINK);
- m_bbox.set_layout(Gtk::BUTTONBOX_END);
-
- m_text.set_hexpand(true);
-
- m_scroll.set_hexpand(true);
- m_scroll.set_vexpand(true);
- m_scroll.add(m_text);
-
- m_layout.add(m_scroll);
- m_layout.add(m_bbox);
- get_content_area()->add(m_layout);
-
- show_all_children();
-}
-
-Glib::ustring EditMessageDialog::GetContent() {
- return m_content;
-}
-
-void EditMessageDialog::SetContent(const Glib::ustring &str) {
- m_text.get_buffer()->set_text(str);
-}
diff --git a/src/dialogs/editmessage.hpp b/src/dialogs/editmessage.hpp
deleted file mode 100644
index 38ebedb..0000000
--- a/src/dialogs/editmessage.hpp
+++ /dev/null
@@ -1,20 +0,0 @@
-#pragma once
-#include <string>
-
-class EditMessageDialog : public Gtk::Dialog {
-public:
- EditMessageDialog(Gtk::Window &parent);
- Glib::ustring GetContent();
- void SetContent(const Glib::ustring &str);
-
-protected:
- Gtk::Box m_layout;
- Gtk::Button m_ok;
- Gtk::Button m_cancel;
- Gtk::ButtonBox m_bbox;
- Gtk::ScrolledWindow m_scroll;
- Gtk::TextView m_text;
-
-private:
- Glib::ustring m_content;
-};
diff --git a/src/discord/chatsubmitparams.hpp b/src/discord/chatsubmitparams.hpp
index 24c6f50..e195189 100644
--- a/src/discord/chatsubmitparams.hpp
+++ b/src/discord/chatsubmitparams.hpp
@@ -20,6 +20,7 @@ struct ChatSubmitParams {
bool Silent = false;
Snowflake ChannelID;
Snowflake InReplyToID;
+ Snowflake EditingID;
Glib::ustring Message;
std::vector<Attachment> Attachments;
};
diff --git a/src/windows/mainwindow.cpp b/src/windows/mainwindow.cpp
index 0b21567..8e030ed 100644
--- a/src/windows/mainwindow.cpp
+++ b/src/windows/mainwindow.cpp
@@ -168,6 +168,10 @@ void MainWindow::ToggleMenuVisibility() {
m_menu_bar.set_visible(!m_menu_bar.get_visible());
}
+void MainWindow::EditMessage(Snowflake message_id) {
+ m_chat.StartEditing(message_id);
+}
+
#ifdef WITH_LIBHANDY
void MainWindow::GoBack() {
m_chat.GoBack();
diff --git a/src/windows/mainwindow.hpp b/src/windows/mainwindow.hpp
index 604043c..ce2e636 100644
--- a/src/windows/mainwindow.hpp
+++ b/src/windows/mainwindow.hpp
@@ -29,6 +29,7 @@ public:
void UpdateChatReactionRemove(Snowflake id, const Glib::ustring &param);
void UpdateMenus();
void ToggleMenuVisibility();
+ void EditMessage(Snowflake message_id);
#ifdef WITH_LIBHANDY
void GoBack();