add CAP LS 302 support and max-lines support for draft/multiline messages
This commit is contained in:
committed by
mathieui
parent
b250237e01
commit
bf958d0e34
+38
-15
@@ -2,6 +2,7 @@
|
||||
#include <utility>
|
||||
#include <xmpp/biboumi_component.hpp>
|
||||
#include <network/poller.hpp>
|
||||
#include <utils/chunk.hpp>
|
||||
#include <utils/empty_if_fixed_server.hpp>
|
||||
#include <utils/encoding.hpp>
|
||||
#include <utils/tolower.hpp>
|
||||
@@ -12,6 +13,7 @@
|
||||
#include <utils/split.hpp>
|
||||
#include <xmpp/jid.hpp>
|
||||
#include <database/database.hpp>
|
||||
#include <irc/parse_caps.hpp>
|
||||
#include "result_set_management.hpp"
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
@@ -242,9 +244,27 @@ void Bridge::send_channel_message(const Iid& iid, const std::string& body, std::
|
||||
if (id.empty())
|
||||
id = utils::gen_uuid();
|
||||
|
||||
std::vector<IrcMessage> messages;
|
||||
for (const std::string& line: lines)
|
||||
{
|
||||
// A message with a lot of lines may need to be split, even if the
|
||||
// server supports draft/multiline, as we may not be allowed to send
|
||||
// that many lines all at once. As such check max-lines
|
||||
// https://ircv3.net/specs/extensions/multiline#capabilities
|
||||
std::vector<std::vector<std::string>> lines_chunked = {lines};
|
||||
auto cap_value = irc->get_capability_value("draft/multiline");
|
||||
if (cap_value) {
|
||||
auto cap_value_parsed = parse_cap_keyval(cap_value.value());
|
||||
if (cap_value_parsed.contains("max-lines") &&
|
||||
cap_value_parsed.at("max-lines").has_value()) {
|
||||
std::stringstream max_lines_string(
|
||||
cap_value_parsed.at("max-lines").value());
|
||||
size_t size;
|
||||
max_lines_string >> size;
|
||||
if (size > 0)
|
||||
lines_chunked = utils::chunk(lines, size);
|
||||
}
|
||||
}
|
||||
for (const auto &lines : lines_chunked) {
|
||||
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 -
|
||||
@@ -264,18 +284,21 @@ void Bridge::send_channel_message(const Iid& iid, const std::string& body, std::
|
||||
}
|
||||
}
|
||||
|
||||
MessageCallback mirror_to_all_resources = [this, iid, uuid, id, nodes_to_reflect, body](const IrcClient* irc, const IrcMessage&) {
|
||||
for (const auto& resource: this->resources_in_chan[iid.to_tuple()])
|
||||
{
|
||||
auto stanza = this->xmpp.make_muc_message(std::to_string(iid), irc->get_own_nick(), this->make_xmpp_body(body),
|
||||
this->user_jid + "/"
|
||||
+ resource, uuid, id);
|
||||
for (const auto& node: nodes_to_reflect)
|
||||
stanza.add_child(node);
|
||||
this->xmpp.send_stanza(stanza);
|
||||
}
|
||||
};
|
||||
irc->send_batch(uuid, "draft/multiline", {iid.get_local()}, messages, std::move(mirror_to_all_resources));
|
||||
MessageCallback mirror_to_all_resources = [this, iid, uuid, id, nodes_to_reflect, body](const IrcClient* irc, const IrcMessage&) {
|
||||
for (const auto& resource: this->resources_in_chan[iid.to_tuple()])
|
||||
{
|
||||
auto stanza = this->xmpp.make_muc_message(std::to_string(iid), irc->get_own_nick(), this->make_xmpp_body(body),
|
||||
this->user_jid + "/"
|
||||
+ resource, uuid, id);
|
||||
for (const auto& node: nodes_to_reflect)
|
||||
stanza.add_child(node);
|
||||
this->xmpp.send_stanza(stanza);
|
||||
}
|
||||
};
|
||||
irc->send_batch(uuid, "draft/multiline", {iid.get_local()}, messages, std::move(mirror_to_all_resources));
|
||||
id = utils::gen_uuid();
|
||||
uuid = utils::gen_uuid();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user