mirror of
https://github.com/matrix-construct/construct
synced 2024-12-25 23:14:13 +01:00
ircd:Ⓜ️:room::message: Add interface to extract rich reply fallbacks.
This commit is contained in:
parent
504e0a1883
commit
35199dffb3
3 changed files with 168 additions and 0 deletions
|
@ -37,5 +37,23 @@ struct ircd::m::room::message
|
|||
json::property<name::formatted_body, json::string>
|
||||
>
|
||||
{
|
||||
/// The event ID of the message being replied to; empty if malformed or
|
||||
/// not a reply. If malformed, the message is not considered a reply.
|
||||
id::event reply_to_event() const noexcept;
|
||||
|
||||
/// The user who sent the message being replied to; empty if not a reply
|
||||
/// or the username was missing or malformed.
|
||||
id::user reply_to_user() const noexcept;
|
||||
|
||||
/// The message being replied to, cut to quoted content, which may include
|
||||
/// multiple pseudo-newlines and leading '>' interrupting the text; caller
|
||||
/// must clean that up if required. Empty if not a reply or malformed.
|
||||
string_view reply_to_body() const noexcept;
|
||||
|
||||
/// C2S v1.3 11.3.1 message body stripped of any reply fallback. This is
|
||||
/// the proper way to read the message rather than reading "body" direct;
|
||||
/// returns "body" if not reply.
|
||||
string_view body() const noexcept;
|
||||
|
||||
using super_type::tuple;
|
||||
};
|
||||
|
|
|
@ -126,6 +126,7 @@ libircd_matrix_la_SOURCES += room_members.cc
|
|||
libircd_matrix_la_SOURCES += room_origins.cc
|
||||
libircd_matrix_la_SOURCES += room_type.cc
|
||||
libircd_matrix_la_SOURCES += room_content.cc
|
||||
libircd_matrix_la_SOURCES += room_message.cc
|
||||
libircd_matrix_la_SOURCES += room_power.cc
|
||||
libircd_matrix_la_SOURCES += room_state.cc
|
||||
libircd_matrix_la_SOURCES += room_state_history.cc
|
||||
|
|
149
matrix/room_message.cc
Normal file
149
matrix/room_message.cc
Normal file
|
@ -0,0 +1,149 @@
|
|||
// The Construct
|
||||
//
|
||||
// Copyright (C) The Construct Developers, Authors & Contributors
|
||||
// Copyright (C) 2016-2022 Jason Volk <jason@zemos.net>
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice is present in all copies. The
|
||||
// full license for this software is available in the LICENSE file.
|
||||
|
||||
ircd::string_view
|
||||
ircd::m::room::message::body()
|
||||
const noexcept
|
||||
{
|
||||
const auto reply_to_body
|
||||
{
|
||||
this->reply_to_body()
|
||||
};
|
||||
|
||||
string_view body
|
||||
{
|
||||
json::get<"body"_>(*this)
|
||||
};
|
||||
|
||||
if(reply_to_body)
|
||||
{
|
||||
body = string_view
|
||||
{
|
||||
reply_to_body.end(), body.end()
|
||||
};
|
||||
|
||||
body = lstrip(body, "\\n", 2);
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::m::room::message::reply_to_body()
|
||||
const noexcept
|
||||
{
|
||||
const auto reply_to_user
|
||||
{
|
||||
this->reply_to_user()
|
||||
};
|
||||
|
||||
if(likely(!reply_to_user))
|
||||
return {};
|
||||
|
||||
string_view body
|
||||
{
|
||||
json::get<"body"_>(*this)
|
||||
};
|
||||
|
||||
body = string_view
|
||||
{
|
||||
reply_to_user.end(), body.end()
|
||||
};
|
||||
|
||||
body = lstrip(body, '>', 1);
|
||||
body = lstrip(body, ' ', 1);
|
||||
body = string_view
|
||||
{
|
||||
body.begin(), token(body, "\\n", 0).end()
|
||||
};
|
||||
|
||||
tokens(body, "\\n", [&body]
|
||||
(const string_view &line) noexcept
|
||||
{
|
||||
if(!startswith(line, '>'))
|
||||
return false;
|
||||
|
||||
body = string_view
|
||||
{
|
||||
body.begin(), line.end()
|
||||
};
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
ircd::m::user::id
|
||||
ircd::m::room::message::reply_to_user()
|
||||
const noexcept
|
||||
{
|
||||
string_view body
|
||||
{
|
||||
json::get<"body"_>(*this)
|
||||
};
|
||||
|
||||
if(!startswith(body, '>'))
|
||||
return {};
|
||||
|
||||
body = lstrip(body, '>', 1);
|
||||
body = lstrip(body, ' ', 1);
|
||||
body = lstrip(body, '*', 1);
|
||||
body = lstrip(body, ' ', 1);
|
||||
const string_view ret
|
||||
{
|
||||
between(body, '<', '>')
|
||||
};
|
||||
|
||||
if(!valid(m::id::USER, ret))
|
||||
return {};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ircd::m::event::id
|
||||
ircd::m::room::message::reply_to_event()
|
||||
const noexcept try
|
||||
{
|
||||
const json::object &m_relates_to
|
||||
{
|
||||
json::get<"m.relates_to"_>(*this)
|
||||
};
|
||||
|
||||
if(!m_relates_to || !json::type(m_relates_to, json::OBJECT))
|
||||
return {};
|
||||
|
||||
const json::object &m_in_reply_to
|
||||
{
|
||||
m_relates_to["m.in_reply_to"]
|
||||
};
|
||||
|
||||
const auto &event_id
|
||||
{
|
||||
json::type(m_in_reply_to, json::OBJECT)?
|
||||
m_in_reply_to.get<json::string>("event_id"):
|
||||
m_relates_to.get<json::string>("event_id")
|
||||
};
|
||||
|
||||
if(!event_id || !valid(m::id::EVENT, event_id))
|
||||
return {};
|
||||
|
||||
return event_id;
|
||||
}
|
||||
catch(const std::exception &e)
|
||||
{
|
||||
log::error
|
||||
{
|
||||
log, "Failed to extract m.relates_to m.in_reply_to event_id :%s",
|
||||
e.what(),
|
||||
};
|
||||
|
||||
return {};
|
||||
}
|
Loading…
Reference in a new issue