diff --git a/modules/client/publicrooms.cc b/modules/client/publicrooms.cc index 31df929df..ad56d75af 100644 --- a/modules/client/publicrooms.cc +++ b/modules/client/publicrooms.cc @@ -102,6 +102,7 @@ post__publicrooms(client &client, response.buf, response.flusher(), size_t(flush_hiwat) }; + size_t count{0}; m::room::id::buf prev_batch_buf; m::room::id::buf next_batch_buf; const m::room::state publix @@ -113,60 +114,113 @@ post__publicrooms(client &client, { json::stack::member chunk_m{top, "chunk"}; json::stack::array chunk{chunk_m}; - - size_t count{0}; publix.test("ircd.room", since, [&](const m::event &event) { - if(!count) - prev_batch_buf = at<"state_key"_>(event); - + const m::room::id room_id{at<"state_key"_>(event)}; + const m::room::state state{room_id}; json::stack::object obj{chunk}; - json::stack::member + + if(!count && !empty(since)) + prev_batch_buf = room_id; //TODO: ??? + + // Aliases array { - obj, "aliases", json::empty_array - }; + json::stack::member aliases_m{obj, "aliases"}; + json::stack::array array{aliases_m}; + state.for_each("m.room.aliases", [&array] + (const m::event &event) + { + const json::array aliases + { + json::get<"content"_>(event).get("aliases") + }; + + for(const string_view &alias : aliases) + array.append(unquote(alias)); + }); + } + + state.get(std::nothrow, "m.room.avatar_url", "", [&obj] + (const m::event &event) + { + json::stack::member + { + obj, "avatar_url", unquote(json::get<"content"_>(event).get("url")) + }; + }); + + state.get(std::nothrow, "m.room.canonical_alias", "", [&obj] + (const m::event &event) + { + json::stack::member + { + obj, "canonical_alias", unquote(json::get<"content"_>(event).get("alias")) + }; + }); + + state.get(std::nothrow, "m.room.guest_access", "", [&obj] + (const m::event &event) + { + json::stack::member + { + obj, "guest_can_join", json::value + { + unquote(json::get<"content"_>(event).get("guest_access")) == "can_join" + } + }; + }); + + state.get(std::nothrow, "m.room.name", "", [&obj] + (const m::event &event) + { + json::stack::member + { + obj, "name", json::value + { + unquote(json::get<"content"_>(event).get("name")) + } + }; + }); + + // num_join_members + { + const m::room::members members{room_id}; + json::stack::member + { + obj, "num_joined_members", json::value + { + long(members.count("join")) + } + }; + } json::stack::member { - obj, "canonical_alias", string_view{} + obj, "room_id", room_id }; - json::stack::member + state.get(std::nothrow, "m.room.topic", "", [&obj] + (const m::event &event) { - obj, "name", string_view{} - }; + json::stack::member + { + obj, "topic", unquote(json::get<"content"_>(event).get("topic")) + }; + }); - json::stack::member + state.get(std::nothrow, "m.room.history_visibility", "", [&obj] + (const m::event &event) { - obj, "num_joined_members", json::value{1L} - }; + json::stack::member + { + obj, "world_readable", json::value + { + unquote(json::get<"content"_>(event).get("history_visibility")) == "world_readable" + } + }; + }); - json::stack::member - { - obj, "room_id", at<"state_key"_>(event) - }; - - json::stack::member - { - obj, "topic", string_view{} - }; - - json::stack::member - { - obj, "world_readable", json::value{true} - }; - - json::stack::member - { - obj, "guest_can_join", json::value{true} - }; - - json::stack::member - { - obj, "avatar_url", string_view{} - }; - - next_batch_buf = at<"state_key"_>(event); + next_batch_buf = room_id; return count >= limit; }); } @@ -179,15 +233,17 @@ post__publicrooms(client &client, } }; - json::stack::member - { - top, "prev_batch", prev_batch_buf - }; + if(prev_batch_buf) + json::stack::member + { + top, "prev_batch", prev_batch_buf + }; - json::stack::member - { - top, "next_batch", next_batch_buf - }; + if(count >= limit) + json::stack::member + { + top, "next_batch", next_batch_buf + }; return {}; }