diff --git a/include/ircd/m/receipt.h b/include/ircd/m/receipt.h index 76a089ae9..7603e67d9 100644 --- a/include/ircd/m/receipt.h +++ b/include/ircd/m/receipt.h @@ -11,10 +11,11 @@ #pragma once #define HAVE_IRCD_M_RECEIPT_H -namespace ircd::m +namespace ircd::m::receipt { - -} + id::event::buf read(const id::room &, const id::user &, const id::event &, const time_t &); + id::event::buf read(const id::room &, const id::user &, const id::event &); // now +}; struct ircd::m::edu::m_receipt { diff --git a/ircd/m/m.cc b/ircd/m/m.cc index 748bcce40..63dd36581 100644 --- a/ircd/m/m.cc +++ b/ircd/m/m.cc @@ -525,6 +525,35 @@ ircd::m::keys::init::signing() self::public_key_b64); } +/////////////////////////////////////////////////////////////////////////////// +// +// m/receipt.h +// + +ircd::m::event::id::buf +ircd::m::receipt::read(const id::room &room_id, + const id::user &user_id, + const id::event &event_id) +{ + return read(room_id, user_id, event_id, ircd::time()); +} + +ircd::m::event::id::buf +ircd::m::receipt::read(const id::room &room_id, + const id::user &user_id, + const id::event &event_id, + const time_t &ms) +{ + using prototype = event::id::buf (const id::room &, const id::user &, const id::event &, const time_t &); + + static import function + { + "m_receipt", "receipt_m_read" + }; + + return function(room_id, user_id, event_id, ms); +} + /////////////////////////////////////////////////////////////////////////////// // // m/typing.h @@ -543,7 +572,6 @@ ircd::m::typing::set(const m::typing &object) return function(object); } - /////////////////////////////////////////////////////////////////////////////// // // m/presence.h diff --git a/modules/client/rooms/read_markers.cc b/modules/client/rooms/read_markers.cc index f37139abc..ee4ecdbdc 100644 --- a/modules/client/rooms/read_markers.cc +++ b/modules/client/rooms/read_markers.cc @@ -17,6 +17,18 @@ post__read_markers(client &client, const resource::request &request, const m::room::id &room_id) { + const string_view m_fully_read + { + unquote(request["m.fully_read"]) + }; + + const string_view m_read + { + unquote(request["m.read"]) + }; + + m::receipt::read(room_id, request.user_id, m_read?: m_fully_read); + return resource::response { client, http::OK diff --git a/modules/m_receipt.cc b/modules/m_receipt.cc index 8b726bdff..2ed2997d6 100644 --- a/modules/m_receipt.cc +++ b/modules/m_receipt.cc @@ -20,6 +20,52 @@ static void handle_m_receipt_m_read(const m::room::id &, const m::user::id &, co static void handle_m_receipt_m_read(const m::room::id &, const json::object &); static void handle_m_receipt(const m::room::id &, const json::object &); static void handle_edu_m_receipt(const m::event &); +extern "C" m::event::id::buf receipt_m_read(const m::room::id &, const m::user::id &, const m::event::id &, const time_t &); + +m::event::id::buf +receipt_m_read(const m::room::id &room_id, + const m::user::id &user_id, + const m::event::id &event_id, + const time_t &ms) +{ + const json::value event_ids[] + { + { event_id } + }; + + const json::members m_read + { + { "data", + { + { "ts", ms } + }}, + { "event_ids", { event_ids, 1 } }, + }; + + json::iov event, content; + const json::iov::push push[] + { + { event, { "type", "m.receipt" } }, + { event, { "room_id", room_id } }, + { content, { room_id, + { + { "m.read", + { + { user_id, m_read } + }} + }}} + }; + + m::vm::opts opts; + opts.hash = false; + opts.sign = false; + opts.event_id = false; + opts.origin = true; + opts.origin_server_ts = false; + opts.conforming = false; + + return m::vm::commit(event, content, opts); +} const m::hook _m_receipt_eval