0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2025-02-18 17:50:16 +01:00

ircd:Ⓜ️:room: Add interface to room messages.

This commit is contained in:
Jason Volk 2022-08-13 20:06:18 -07:00
parent 2bf10c1234
commit 727749e9de
5 changed files with 161 additions and 9 deletions

View file

@ -0,0 +1,50 @@
// 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.
#pragma once
#define HAVE_IRCD_M_ROOM_MESSAGES_H
/// Rendering
///
struct ircd::m::room::messages
{
using closure = util::closure_bool
<
std::function, const message &, const uint64_t &, const event::idx &
>;
static const event::fetch::opts fopts;
room::type events;
private:
bool m_replace(event &, const event::idx &) const;
public:
bool for_each(const closure &) const;
messages(const m::room &,
const decltype(room::type::range) & = { -1UL, -1L });
messages(messages &&) = delete;
messages(const messages &) = delete;
};
inline
ircd::m::room::messages::messages(const m::room &room,
const decltype(room::type::range) &range)
:events
{
room.room_id,
"m.room.message",
range,
false,
}
{}

View file

@ -123,6 +123,7 @@ struct ircd::m::room
struct stats;
struct server_acl;
struct message;
struct messages;
struct bootstrap;
struct content;
@ -206,6 +207,7 @@ struct ircd::m::room
#include "stats.h"
#include "server_acl.h"
#include "message.h"
#include "messages.h"
#include "bootstrap.h"
inline

View file

@ -128,6 +128,7 @@ 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_messages.cc
libircd_matrix_la_SOURCES += room_power.cc
libircd_matrix_la_SOURCES += room_state.cc
libircd_matrix_la_SOURCES += room_state_history.cc

102
matrix/room_messages.cc Normal file
View file

@ -0,0 +1,102 @@
// 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.
decltype(ircd::m::room::messages::fopts)
ircd::m::room::messages::fopts
{
event::keys::include
{
"content",
},
};
bool
ircd::m::room::messages::for_each(const closure &closure)
const
{
event::fetch event
{
fopts
};
return events.for_each([this, &closure, &event]
(const string_view &type, const uint64_t &depth, event::idx event_idx)
{
assert(type == "m.room.message");
if(redacted(event_idx))
return true;
if(!seek(std::nothrow, event, event_idx))
return true;
room::message msg
{
json::get<"content"_>(event)
};
// Don't show messages which edit other messages, since we will or
// already have rendered it at the edited message, if we have it,
// otherwise ignored.
if(msg.replace_event())
return true;
// If the content was replaced msg has to be updated.
if(m_replace(event, event_idx))
msg = json::get<"content"_>(event);
return closure(msg, depth, event_idx);
});
}
bool
ircd::m::room::messages::m_replace(event &event,
const event::idx &event_idx)
const
{
// Find the latest edit of this; otherwise stick with the original.
const m::relates relates
{
.refs = event_idx,
.match_sender = true,
};
const event::idx replace_idx
{
relates.latest("m.replace")
};
if(!replace_idx)
return false;
const event::fetch replace
{
std::nothrow, replace_idx, fopts
};
if(!replace.valid)
return false;
const json::object replace_content
{
json::get<"content"_>(replace)
};
const json::object new_content
{
replace_content.get("m.new_content")
};
// XXX When m.new_content is undefined the edit does not take place.
if(!new_content && !replace_content.has("m.new_content"))
return false;
json::get<"content"_>(event) = new_content;
return true;
}

View file

@ -11504,7 +11504,7 @@ console_cmd__room__messages(opt &out, const string_view &line)
const auto limit
{
param.at("limit", 64U)?: -1U
param.at("limit", 48U)?: -1U
};
const int64_t start_depth
@ -11517,23 +11517,20 @@ console_cmd__room__messages(opt &out, const string_view &line)
param.at<int64_t>("end_depth", -1)
};
const m::room::type events
const m::room::messages messages
{
room_id,
"m.room.message",
{ start_depth, end_depth },
false,
room_id, { start_depth, end_depth },
};
size_t i(0);
m::event::fetch event;
events.for_each([&out, &event, &i, &limit]
(const string_view &type, const uint64_t &depth, const m::event::idx &event_idx)
messages.for_each([&out, &i, &limit, &event]
(const m::room::message &msg, const uint64_t &depth, m::event::idx event_idx)
{
assert(type == "m.room.message");
if(!seek(std::nothrow, event, event_idx))
return true;
json::get<"content"_>(event) = msg.source;
const m::pretty_opts opts
{
.event_idx = event_idx,