diff --git a/modules/client/rooms/receipt.cc b/modules/client/rooms/receipt.cc index e69fa7dfb..7ac6f5443 100644 --- a/modules/client/rooms/receipt.cc +++ b/modules/client/rooms/receipt.cc @@ -66,6 +66,30 @@ post__receipt(client &client, }; } +/// Does the user wish to not send receipts for events sent by its specific +/// sender? +static bool +user_ignoring_receipts_sender(const m::user::room &user_room, + const m::event::id &event_id) +{ + bool ret{false}; + m::get(std::nothrow, event_id, "sender", [&ret, &user_room] + (const string_view &sender) + { + ret = user_room.has("ircd.read.ignore", sender); + }); + + return ret; +} + +/// Does the user wish to not send receipts for events for this entire room? +static bool +user_ignoring_receipts_room(const m::user::room &user_room, + const m::room::id &room_id) +{ + return user_room.has("ircd.read.ignore", room_id); +} + m::event::id::buf commit__m_receipt_m_read(const m::room::id &room_id, const m::user::id &user_id, @@ -80,12 +104,14 @@ commit__m_receipt_m_read(const m::room::id &room_id, user_id }; - bool ignored{false}; - m::get(std::nothrow, event_id, "sender", [&ignored, &user_room] - (const string_view &sender) + // Check if receipts for the room are disabled first because we have the + // room_id on the stack, whereas the event sender requires column queries + // from the event_id. + const bool ignored { - ignored = user_room.has("ircd.read.ignore", sender); - }); + user_ignoring_receipts_room(user_room, room_id) || + user_ignoring_receipts_sender(user_room, event_id) + }; if(ignored) { diff --git a/modules/console.cc b/modules/console.cc index 99dad1c12..b2c81337d 100644 --- a/modules/console.cc +++ b/modules/console.cc @@ -4896,7 +4896,7 @@ console_cmd__user__read__ignore(opt &out, const string_view &line) { const params param{line, " ", { - "my_user_id", "target_user_id" + "my_user_id", "target_user|room_id" }}; const m::user my_user @@ -4904,20 +4904,37 @@ console_cmd__user__read__ignore(opt &out, const string_view &line) param.at(0) }; - const m::user::id target_user + string_view target { param.at(1) }; + char buf[m::id::MAX_SIZE]; + switch(m::sigil(target)) + { + case m::id::USER: + case m::id::ROOM: + break; + + case m::id::ROOM_ALIAS: + target = m::room_id(buf, target); + break; + + default: throw error + { + "Unsupported target MXID type for receipt ignores." + }; + } + const m::user::room user_room { my_user }; - if(user_room.has("ircd.read.ignore", target_user)) + if(user_room.has("ircd.read.ignore", target)) { out << "User " << my_user.user_id << " is already not sending" - << " receipts for messages from user " << target_user + << " receipts for messages from " << target << std::endl; return true; @@ -4925,11 +4942,11 @@ console_cmd__user__read__ignore(opt &out, const string_view &line) const auto eid { - send(user_room, m::me.user_id, "ircd.read.ignore", target_user, json::object{}) + send(user_room, m::me.user_id, "ircd.read.ignore", target, json::object{}) }; out << "User " << my_user.user_id << " will not send receipts for" - << " messages from user " << target_user + << " messages from " << target << " (" << eid << ")" << std::endl;