From 502299919ae84e99920f07c9259ec90bc5cfb397 Mon Sep 17 00:00:00 2001 From: Brendan Coles Date: Sat, 11 Apr 2020 08:23:03 +0000 Subject: [PATCH] IRCClient: Add channel member context menus for common CTCP requests Add menu items for CTCP: USERINFO, FINGER, TIME, VERSION, CLIENTINFO --- Applications/IRCClient/IRCClient.cpp | 15 +++++++++++ Applications/IRCClient/IRCClient.h | 2 ++ Applications/IRCClient/IRCWindow.cpp | 37 ++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/Applications/IRCClient/IRCClient.cpp b/Applications/IRCClient/IRCClient.cpp index 650d7c09e2..4963e28aad 100644 --- a/Applications/IRCClient/IRCClient.cpp +++ b/Applications/IRCClient/IRCClient.cpp @@ -1006,6 +1006,11 @@ void IRCClient::handle_whois_action(const String& nick) send_whois(nick); } +void IRCClient::handle_ctcp_user_action(const String& nick, const String& message) +{ + send_ctcp_request(nick, message); +} + void IRCClient::handle_open_query_action(const String& nick) { ensure_query(nick); @@ -1104,6 +1109,16 @@ void IRCClient::send_ctcp_response(const StringView& peer, const StringView& pay send_notice(peer, message); } +void IRCClient::send_ctcp_request(const StringView& peer, const StringView& payload) +{ + StringBuilder builder; + builder.append(0x01); + builder.append(payload); + builder.append(0x01); + auto message = builder.to_string(); + send_privmsg(peer, message); +} + void IRCClient::handle_ctcp_request(const StringView& peer, const StringView& payload) { dbg() << "handle_ctcp_request: " << payload; diff --git a/Applications/IRCClient/IRCClient.h b/Applications/IRCClient/IRCClient.h index 90a3282921..c8fb15c9e4 100644 --- a/Applications/IRCClient/IRCClient.h +++ b/Applications/IRCClient/IRCClient.h @@ -113,6 +113,7 @@ public: void handle_list_channels_action(); void handle_whois_action(const String& nick); + void handle_ctcp_user_action(const String& nick, const String& message); void handle_open_query_action(const String&); void handle_close_query_action(const String&); void handle_join_action(const String& channel_name); @@ -200,6 +201,7 @@ private: void handle_user_command(const String&); void handle_ctcp_request(const StringView& peer, const StringView& payload); void handle_ctcp_response(const StringView& peer, const StringView& payload); + void send_ctcp_request(const StringView& peer, const StringView& payload); void send_ctcp_response(const StringView& peer, const StringView& payload); void on_socket_connected(); diff --git a/Applications/IRCClient/IRCWindow.cpp b/Applications/IRCClient/IRCWindow.cpp index 443c5f09a0..fc41819064 100644 --- a/Applications/IRCClient/IRCWindow.cpp +++ b/Applications/IRCClient/IRCWindow.cpp @@ -137,6 +137,43 @@ IRCWindow::IRCWindow(IRCClient& client, void* owner, Type type, const String& na m_context_menu->add_separator(); + m_context_menu->add_action(GUI::Action::create("User info", [&](const GUI::Action&) { + auto nick = channel().member_model()->nick_at(member_view.selection().first()); + if (nick.is_empty()) + return; + m_client.handle_ctcp_user_action(m_client.nick_without_prefix(nick.characters()), "USERINFO"); + })); + + m_context_menu->add_action(GUI::Action::create("Finger", [&](const GUI::Action&) { + auto nick = channel().member_model()->nick_at(member_view.selection().first()); + if (nick.is_empty()) + return; + m_client.handle_ctcp_user_action(m_client.nick_without_prefix(nick.characters()), "FINGER"); + })); + + m_context_menu->add_action(GUI::Action::create("Time", [&](const GUI::Action&) { + auto nick = channel().member_model()->nick_at(member_view.selection().first()); + if (nick.is_empty()) + return; + m_client.handle_ctcp_user_action(m_client.nick_without_prefix(nick.characters()), "TIME"); + })); + + m_context_menu->add_action(GUI::Action::create("Version", [&](const GUI::Action&) { + auto nick = channel().member_model()->nick_at(member_view.selection().first()); + if (nick.is_empty()) + return; + m_client.handle_ctcp_user_action(m_client.nick_without_prefix(nick.characters()), "VERSION"); + })); + + m_context_menu->add_action(GUI::Action::create("Client info", [&](const GUI::Action&) { + auto nick = channel().member_model()->nick_at(member_view.selection().first()); + if (nick.is_empty()) + return; + m_client.handle_ctcp_user_action(m_client.nick_without_prefix(nick.characters()), "CLIENTINFO"); + })); + + m_context_menu->add_separator(); + m_context_menu->add_action(GUI::Action::create("Kick", [&](const GUI::Action&) { auto nick = channel().member_model()->nick_at(member_view.selection().first()); if (nick.is_empty())