fix multiline private messages

This commit is contained in:
Luca Matei Pintilie
2026-01-10 19:02:48 +01:00
committed by mathieui
parent 6ed185a8a5
commit c15a057885
2 changed files with 47 additions and 8 deletions
+36 -7
View File
@@ -225,6 +225,7 @@ void Bridge::send_channel_message(const Iid& iid, const std::string& body, std::
return ;
if (irc->has_capability("draft/multiline")
&& lines.size() > 1
// /me and /mode cannot be multi lined
&& lines[0].substr(0, 5) != "/mode"
&& lines[0].substr(0, 4) != "/me ")
@@ -241,13 +242,6 @@ void Bridge::send_channel_message(const Iid& iid, const std::string& body, std::
if (id.empty())
id = utils::gen_uuid();
IrcChannel* channel = irc->get_channel(iid.get_local());
if (!channel->joined)
{
log_warning("Cannot send message to channel ", iid.get_local(), ", it is not joined");
return;
}
std::vector<IrcMessage> messages;
for (const std::string& line: lines)
{
@@ -467,6 +461,41 @@ void Bridge::send_private_message(const Iid& iid, const std::string& body, const
std::vector<std::string> lines = utils::split(body, '\n', true);
if (lines.empty())
return ;
if (irc->has_capability("draft/multiline")
&& lines.size() > 1
// /me and /mode cannot be multi lined
&& lines[0].substr(0, 5) != "/mode"
&& lines[0].substr(0, 4) != "/me ")
{
std::basic_string<char> uuid = utils::gen_uuid();
std::vector<IrcMessage> messages;
for (const std::string &line : lines) {
constexpr auto max_username_size = 10;
constexpr auto max_hostname_size = 63;
const auto line_size = 512 - 1 - ::strlen("batch=") - uuid.length() - 1 -
::strlen("draft/multiline-concat") - 1 -
irc->get_own_nick().size() - max_username_size -
max_hostname_size - ::strlen(":!@ PRIVMSG ") -
iid.get_local().length() - ::strlen(" :\r\n");
const auto privmsgs = cut(line, line_size);
bool first = true;
for (const auto &privmsg : privmsgs) {
if (first) {
messages.push_back(IrcMessage({}, std::string(), "PRIVMSG",
{iid.get_local(), privmsg}));
first = false;
} else
messages.push_back(IrcMessage({{"draft/multiline-concat", {}}},
std::string(), "PRIVMSG",
{iid.get_local(), privmsg}));
}
}
irc->send_batch(uuid, "draft/multiline", {iid.get_local()}, messages,
[](const IrcClient *, const IrcMessage &) {});
return;
}
for (const std::string& line: lines)
{
if (line.substr(0, 4) == "/me ")
@@ -52,5 +52,15 @@ scenario = (
["/message[@from='#foo%{irc_server_one}/{nick_one}'][@id='the-message-id'][@to='{jid_one}/{resource_one}'][@type='groupchat']/body[text()='a\nb\nc']"],
["/message[@from='#foo%{irc_server_one}/{nick_one}'][@id][@to='{jid_two}/{resource_one}'][@type='groupchat']/body[text()='a\nb\nc']"],
)
),
# Send a multi-line private message, to a in-room JID
send_stanza("<message from='{jid_one}/{resource_one}' to='#foo%{irc_server_one}/{nick_two}' type='chat'><body>a\nb\nc</body></message>"),
# Message is received with a server-wide JID
expect_stanza("/message[@from='{lower_nick_one}%{irc_server_one}'][@to='{jid_two}'][@type='chat']/body[text()='a\nb\nc']"),
# Send a multi-line private message, to a server-wide JID
send_stanza("<message from='{jid_one}/{resource_one}' to='{lower_nick_two}%{irc_server_one}' type='chat'><body>a\nb\nc</body></message>"),
# Message is received with a server-wide JID
expect_stanza("/message[@from='{lower_nick_one}%{irc_server_one}'][@to='{jid_two}'][@type='chat']/body[text()='a\nb\nc']"),
)