Page MenuHomePhorge

No OneTemporary

Size
31 KB
Referenced Files
None
Subscribers
None
diff --git a/README.md b/README.md
index 8d48eb3..9500b4d 100644
--- a/README.md
+++ b/README.md
@@ -1,144 +1,144 @@
# libkazv
libkazv is a matrix client sdk built upon [lager](https://github.com/arximboldi/lager)
and the value-oriented design it enables.
# Functionalities
libkazv support the following functionalities:
- Logging in
- Receiving room states
- Receiving room messages
- Receiving account data
- Receiving presence
- Sending messages
- Send room state events
- Create rooms
+- Room invites
These functionalities are currently not supported:
- Join rooms
-- Room invites
- Typing notifications
- Receipts and fully-read markers
- Setting presence
- Content repository
- Send-to-device messages
- Device management
- Direct messages
- Redactions
- Room history visibility
- Registering
- VoIP
- E2EE
- Room tagging
- Searching
- Room previews
- Mentions
These functionalities may be implemented, but in a low priority:
- Push notifications
- Third-party invites
- Guest access
- Server administration
- Event context
- Ignoring users
- Reporting content
- Third party networks
- Server notices
- Moderation policy lists
libkazv is not planning to support these functionalities:
- Single Sign On
# Build and Use
## Dependencies
libkazv depends on [lager](https://github.com/arximboldi/lager),
[immer](https://github.com/arximboldi/immer),
[zug](https://github.com/arximboldi/zug),
[boost](https://boost.org),
[nlohmann_json](https://github.com/nlohmann/json),
[cereal](https://github.com/USCiLab/cereal).
kazvjob also depends on [cpr](https://github.com/whoshuu/cpr).
Tests also depend on [Catch2](https://github.com/catchorg/Catch2).
Examples also depend on [libhttpserver](https://github.com/etr/libhttpserver).
All the dependencies mentioned, except for boost and libhttpserver,
are automatically fetched by cmake `FetchContent`.
## Process
You can build libkazv through the standard CMake process:
```
mkdir -pv build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/path/to/prefix
make install
```
libkazv offers the following CMake options:
- `libkazv_BUILD_TESTS`: boolean value to specify whether to build tests
- `libkazv_BUILD_EXAMPLES`: boolean value to specify whether to build examples
- `libkazv_OUTPUT_LEVEL`: integral value from 0 to 100 to determine what kinds
of logs are shown. Setting to 100 makes libkazv output the most debug
information.
- `libkazv_INSTALL_HEADERS`: boolean value to determine whether to install
libkazv's headers. This is by default set to OFF when libkazv is built
as a subproject.
libkazv can be incorporated into your project using CMake `FetchContent()`.
It has two libraries you can link to:
- `libkazv::kazv` is the one that contains API call definitions
and client logic. It does not, however, define how the jobs are
fetched.
- `libkazv::kazvjob` is a tiny library that provides async
and network fetching functionalities. There is one class
`CprJobHandler` that implements `JobInterface` in `kazv`.
You can link your program to `kazvjob` or make up another
job handler using what you choose as async and network
libraries. To switch from one job handler to another,
you only need to change one or two lines in your program.
# Acknowledgement
libkazv uses [gtad](https://github.com/KitsuneRal/gtad) to generate the API
definitions it needed. The source of the Matrix API is
[https://github.com/matrix-org/matrix-doc](https://github.com/matrix-org/matrix-doc)
. The gtad configuration files and json/query serializing used in libkazv are
adapted from the ones in [libQuotient](https://github.com/quotient-im/libQuotient).
libQuotient is released under GNU LGPL v2.1. The changes in said files
in libkazv compared to libQuotient's are:
- Get rid of the `avoidCopy` and `moveOnly` markers
- Use data types from `immer` and `std` instead of Qt
- Use `nlohmann::json` instead of Qt's JSON library
# License
Copyright (C) 2020 Tusooa Zhu
libkazv is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
libkazv is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with libkazv. If not, see <https://www.gnu.org/licenses/>.
diff --git a/src/client/actions/membership.cpp b/src/client/actions/membership.cpp
index 77d294d..f757fce 100644
--- a/src/client/actions/membership.cpp
+++ b/src/client/actions/membership.cpp
@@ -1,118 +1,142 @@
/*
* Copyright (C) 2020 Tusooa Zhu <tusooa@vista.aero>
*
* This file is part of libkazv.
*
* libkazv is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* libkazv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with libkazv. If not, see <https://www.gnu.org/licenses/>.
*/
-#include "client/client.hpp"
-
#include "csapi/create_room.hpp"
+#include "csapi/inviting.hpp"
#include "debug.hpp"
+#include "client/client.hpp"
+#include "client/util.hpp"
#include "client/cursorutil.hpp"
+
#include "membership.hpp"
namespace Kazv
{
static std::string visibilityToStr(CreateRoomAction::Visibility v)
{
using V = CreateRoomAction::Visibility;
switch (v) {
case V::Private:
return "private";
case V::Public:
return "public";
default:
// should not happen
return "";
}
}
static std::string presetToStr(CreateRoomAction::Preset p)
{
using P = CreateRoomAction::Preset;
switch (p) {
case P::PrivateChat:
return "private_chat";
case P::PublicChat:
return "public_chat";
case P::TrustedPrivateChat:
return "trusted_private_chat";
default:
// should not happen
return "";
}
}
ClientResult updateClient(Client m, CreateRoomAction a)
{
return {
m,
[=](auto &&ctx) {
auto visibility = visibilityToStr(a.visibility);
auto preset = a.preset
? presetToStr(a.preset.value())
: ""s;
using StateEvT = Kazv::CreateRoomJob::StateEvent;
auto initialState = intoImmer(
immer::array<StateEvT>{},
zug::map(
[](Event e) {
return StateEvT{e.type(), e.stateKey(), e.content()};
}),
a.initialState);
auto job = m.job<CreateRoomJob>().make(
visibility,
a.roomAliasName,
a.name,
a.topic,
a.invite,
DEFVAL, // invite3pid, not supported yet
a.roomVersion,
a.creationContent,
initialState,
preset,
a.isDirect,
a.powerLevelContentOverride);
auto &jobHandler = lager::get<JobInterface &>(ctx);
jobHandler.fetch(
job,
[=](BaseJob::Response r) {
if (!CreateRoomJob::success(r)) {
dbgClient << "Create room failed" << std::endl;
if (BaseJob::isBodyJson(r.body)) {
dbgClient << jsonBody(r).get().dump() << std::endl;
ctx.dispatch(Error::SetErrorAction{
Error::JsonError{json{
{"action", "CreateRoomAction"},
{"reason", "Request to remote host failed"},
{"original", jsonBody(r).get()}
}}
});
} else {
dbgClient << std::get<BaseJob::BytesBody>(r.body) << std::endl;
}
}
// if success, nothing to do
});
}
};
}
+
+ ClientResult updateClient(Client m, InviteToRoomAction a)
+ {
+ return {
+ m,
+ [=](auto &&ctx) {
+ auto job = m.job<InviteUserJob>().make(a.roomId, a.userId);
+
+ auto &jobHandler = getJobHandler(ctx);
+ jobHandler.fetch(
+ job,
+ [=](BaseJob::Response r) {
+ if (! InviteUserJob::success(r)) {
+ // Error
+ dbgClient << "Error inviting user" << std::endl;
+ return;
+ }
+ dbgClient << "Inviting user successful" << std::endl;
+ });
+ }
+ };
+ }
};
diff --git a/src/client/actions/membership.hpp b/src/client/actions/membership.hpp
index 411d708..a5b97b5 100644
--- a/src/client/actions/membership.hpp
+++ b/src/client/actions/membership.hpp
@@ -1,27 +1,28 @@
/*
* Copyright (C) 2020 Tusooa Zhu <tusooa@vista.aero>
*
* This file is part of libkazv.
*
* libkazv is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* libkazv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with libkazv. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "client/client.hpp"
namespace Kazv
{
ClientResult updateClient(Client m, CreateRoomAction a);
+ ClientResult updateClient(Client m, InviteToRoomAction a);
}
diff --git a/src/client/client.hpp b/src/client/client.hpp
index 6b1d70e..47dd57a 100644
--- a/src/client/client.hpp
+++ b/src/client/client.hpp
@@ -1,237 +1,244 @@
/*
* Copyright (C) 2020 Tusooa Zhu
*
* This file is part of libkazv.
*
* libkazv is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* libkazv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with libkazv. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <tuple>
#include <variant>
#include <string>
#include <optional>
#include <lager/context.hpp>
#include <boost/hana.hpp>
#ifndef NDEBUG
#include <lager/debug/cereal/struct.hpp>
#endif
#include "clientfwd.hpp"
#include "csapi/sync.hpp"
#include "job/jobinterface.hpp"
#include "eventemitter/eventinterface.hpp"
#include "error.hpp"
#include "room/room.hpp"
namespace Kazv
{
inline const std::string DEFTXNID{"0"};
enum RoomVisibility
{
Private,
Public,
};
enum CreateRoomPreset
{
PrivateChat,
PublicChat,
TrustedPrivateChat,
};
struct Client
{
std::string serverUrl;
std::string userId;
std::string token;
std::string deviceId;
bool loggedIn;
Error error;
std::string syncToken;
RoomList roomList;
immer::map<std::string /* sender */, Event> presence;
immer::map<std::string /* type */, Event> accountData;
std::string nextTxnId{DEFTXNID};
// helpers
template<class Job>
struct MakeJobT
{
template<class ...Args>
constexpr auto make(Args &&...args) const {
if constexpr (Job::needsAuth()) {
return Job(
serverUrl,
token,
std::forward<Args>(args)...);
} else {
return Job(
serverUrl,
std::forward<Args>(args)...);
}
}
std::string serverUrl;
std::string token;
};
template<class Job>
constexpr auto job() const {
return MakeJobT<Job>{serverUrl, token};
}
using Action = ClientAction;
using Effect = ClientEffect;
using Result = ClientResult;
static Result update(Client m, Action a);
};
// actions:
struct LoginAction {
std::string serverUrl;
std::string username;
std::string password;
std::optional<std::string> deviceName;
};
struct LoadUserInfoAction {
std::string serverUrl;
std::string userId;
std::string token;
std::string deviceId;
bool loggedIn;
};
struct LogoutAction {};
struct SyncAction {};
struct LoadSyncResultAction
{
std::string syncToken;
std::optional<SyncJob::Rooms> rooms;
std::optional<EventBatch> presence;
std::optional<EventBatch> accountData;
JsonWrap toDevice;
JsonWrap deviceLists;
immer::map<std::string, int> deviceOneTimeKeysCount;
};
struct PaginateTimelineAction
{
std::string roomId;
std::optional<int> limit;
};
struct LoadPaginateTimelineResultAction
{
std::string roomId;
EventList events;
std::string paginateBackToken;
};
struct SendMessageAction
{
std::string roomId;
Event event;
};
struct SendStateEventAction
{
std::string roomId;
Event event;
};
struct CreateRoomAction
{
using Visibility = RoomVisibility;
using Preset = CreateRoomPreset;
Visibility visibility;
std::string roomAliasName;
std::string name;
std::string topic;
immer::array<std::string> invite;
//immer::array<Invite3pid> invite3pid;
std::string roomVersion;
JsonWrap creationContent;
immer::array<Event> initialState;
std::optional<Preset> preset;
std::optional<bool> isDirect;
JsonWrap powerLevelContentOverride;
};
struct GetRoomStatesAction
{
std::string roomId;
};
struct LoadRoomStatesAction
{
std::string roomId;
EventList events;
};
+ struct InviteToRoomAction
+ {
+ std::string roomId;
+ std::string userId;
+ };
+
inline bool operator==(Client a, Client b)
{
return a.serverUrl == b.serverUrl
&& a.userId == b.userId
&& a.token == b.token
&& a.deviceId == b.deviceId
&& a.loggedIn == b.loggedIn
&& a.error == b.error
&& a.syncToken == b.syncToken
&& a.roomList == b.roomList
&& a.presence == b.presence
&& a.accountData == b.accountData
&& a.nextTxnId == b.nextTxnId;
}
#ifndef NDEBUG
LAGER_CEREAL_STRUCT(LoginAction);
LAGER_CEREAL_STRUCT(LoadUserInfoAction);
LAGER_CEREAL_STRUCT(LogoutAction);
LAGER_CEREAL_STRUCT(SyncAction);
LAGER_CEREAL_STRUCT(LoadSyncResultAction);
LAGER_CEREAL_STRUCT(PaginateTimelineAction);
LAGER_CEREAL_STRUCT(LoadPaginateTimelineResultAction);
LAGER_CEREAL_STRUCT(SendMessageAction);
LAGER_CEREAL_STRUCT(SendStateEventAction);
LAGER_CEREAL_STRUCT(CreateRoomAction);
LAGER_CEREAL_STRUCT(GetRoomStatesAction);
LAGER_CEREAL_STRUCT(LoadRoomStatesAction);
+ LAGER_CEREAL_STRUCT(InviteToRoomAction);
#endif
template<class Archive>
void serialize(Archive &ar, Client &m, std::uint32_t const /*version*/)
{
ar(m.serverUrl, m.userId, m.token, m.deviceId, m.loggedIn,
m.error,
m.syncToken,
m.roomList,
m.presence,
m.accountData,
m.nextTxnId);
}
}
CEREAL_CLASS_VERSION(Kazv::Client, 0);
diff --git a/src/client/clientfwd.hpp b/src/client/clientfwd.hpp
index 415a3aa..a50e39b 100644
--- a/src/client/clientfwd.hpp
+++ b/src/client/clientfwd.hpp
@@ -1,69 +1,71 @@
/*
* Copyright (C) 2020 Tusooa Zhu
*
* This file is part of libkazv.
*
* libkazv is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* libkazv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with libkazv. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <tuple>
#include <variant>
#include <lager/context.hpp>
#include "error.hpp"
#include "room/room.hpp"
namespace Kazv
{
class JobInterface;
class EventInterface;
struct LoginAction;
struct LogoutAction;
struct LoadUserInfoAction;
struct SyncAction;
struct LoadSyncResultAction;
struct PaginateTimelineAction;
struct LoadPaginateTimelineResultAction;
struct SendMessageAction;
struct SendStateEventAction;
struct CreateRoomAction;
struct GetRoomStatesAction;
struct LoadRoomStatesAction;
+ struct InviteToRoomAction;
struct Client;
using ClientAction = std::variant<
LoginAction,
LogoutAction,
LoadUserInfoAction,
SyncAction,
Error::Action,
LoadSyncResultAction,
PaginateTimelineAction,
LoadPaginateTimelineResultAction,
SendMessageAction,
SendStateEventAction,
CreateRoomAction,
GetRoomStatesAction,
LoadRoomStatesAction,
+ InviteToRoomAction,
RoomList::Action>;
using ClientEffect = lager::effect<ClientAction, lager::deps<JobInterface &, EventInterface &>>;
using ClientResult = std::pair<Client, ClientEffect>;
}
diff --git a/src/client/room/roomwrap.hpp b/src/client/room/roomwrap.hpp
index b4a1f7c..c1688a3 100644
--- a/src/client/room/roomwrap.hpp
+++ b/src/client/room/roomwrap.hpp
@@ -1,185 +1,190 @@
/*
* Copyright (C) 2020 Tusooa Zhu
*
* This file is part of libkazv.
*
* libkazv is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* libkazv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with libkazv. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <lager/reader.hpp>
#include <lager/with.hpp>
#include <lager/lenses/optional.hpp>
#include <zug/transducer/map.hpp>
#include <zug/transducer/filter.hpp>
#include <zug/sequence.hpp>
#include <immer/flex_vector_transient.hpp>
#include "room.hpp"
#include "client/cursorutil.hpp"
namespace Kazv
{
class RoomWrap
{
public:
inline RoomWrap(lager::reader<Room> room, lager::context<ClientAction> ctx)
: m_room(room)
, m_ctx(ctx) {}
/* lager::reader<MapT<KeyOfState, Event>> */
inline auto stateEvents() const {
return m_room
[&Room::stateEvents];
}
/* lager::reader<RangeT<Event>> */
inline auto timelineEvents() const {
return m_room
.xform(zug::map([](auto r) {
auto messages = r.messages;
auto timeline = r.timeline;
return intoImmer(
immer::flex_vector<Event>{},
zug::map([=](auto eventId) {
return messages[eventId];
}),
timeline);
}));
}
/* lager::reader<std::string> */
inline auto name() const {
using namespace lager::lenses;
return stateEvents()
[KeyOfState{"m.room.name", ""}]
[or_default]
.xform(zug::map([](Event ev) {
auto content = ev.content().get();
return
content.contains("name")
? std::string(content["name"])
// TODO: use heroes to generate a name
: "<no name>";
}));
}
/* lager::reader<RangeT<std::string>> */
inline auto members() const {
using MemberNode = std::pair<std::string, Kazv::Event>;
auto memberNameTransducer =
zug::filter(
[](auto val) {
auto [k, v] = val;
auto [type, stateKey] = k;
return type == "m.room.member"s;
})
| zug::map(
[](auto val) {
auto [k, v] = val;
auto [type, stateKey] = k;
return MemberNode{stateKey, v};
})
| zug::filter(
[](auto val) {
auto [stateKey, ev] = val;
return ev.content().get()
.at("membership"s) == "join"s;
})
| zug::map(
[](auto val) {
auto [stateKey, ev] = val;
return stateKey;
});
return m_room
[&Room::stateEvents]
.xform(zug::map(
[=](auto eventMap) {
return intoImmer(
immer::flex_vector<std::string>{},
memberNameTransducer,
eventMap);
}));
}
lager::reader<bool> encrypted() const;
/*lager::reader<std::string>*/
KAZV_WRAP_ATTR(Room, m_room, roomId);
inline void sendMessage(Event msg) const {
using namespace CursorOp;
m_ctx.dispatch(SendMessageAction{+roomId(), msg});
}
inline void sendTextMessage(std::string text) const {
json j{
{"type", "m.room.message"},
{"content", {
{"msgtype", "m.text"},
{"body", text}
}
}
};
Event e{j};
sendMessage(e);
}
inline void sendStateEvent(Event state) const {
using namespace CursorOp;
m_ctx.dispatch(SendStateEventAction{+roomId(), state});
}
inline void setName(std::string name) const {
json j{
{"type", "m.room.name"},
{"content", {
{"name", name}
}
}
};
Event e{j};
sendStateEvent(e);
}
// lager::reader<std::string>
inline auto topic() const {
using namespace lager::lenses;
return stateEvents()
[KeyOfState{"m.room.topic", ""}]
[or_default]
.xform(eventContent
| jsonAtOr("topic"s, ""s));
}
inline void setTopic(std::string topic) const {
json j{
{"type", "m.room.topic"},
{"content", {
{"topic", topic}
}
}
};
Event e{j};
sendStateEvent(e);
}
+ inline void invite(std::string userId) const {
+ using namespace CursorOp;
+ m_ctx.dispatch(InviteToRoomAction{+roomId(), userId});
+ }
+
private:
lager::reader<Room> m_room;
lager::context<ClientAction> m_ctx;
};
}
diff --git a/src/examples/basic/commands.cpp b/src/examples/basic/commands.cpp
index a93591f..3ceb08d 100644
--- a/src/examples/basic/commands.cpp
+++ b/src/examples/basic/commands.cpp
@@ -1,140 +1,148 @@
/*
* Copyright (C) 2020 Tusooa Zhu
*
* This file is part of libkazv.
*
* libkazv is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* libkazv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with libkazv. If not, see <https://www.gnu.org/licenses/>.
*/
#include <regex>
#include <tuple>
#include <cereal/archives/json.hpp>
#include <lager/lenses/optional.hpp>
#include <zug/into.hpp>
#include <zug/compose.hpp>
#include <immer/flex_vector_transient.hpp>
#include <immer/flex_vector.hpp>
#include <client/clientwrap.hpp>
#include "commands.hpp"
using namespace std::string_literals;
static std::regex roomMsgsRegex("room msgs (.+)");
static std::regex roomStatesRegex("room states (.+)");
static std::regex roomMemsRegex("room mems (.+)");
static std::regex roomSendRegex("room send ([^\\s]+) (.+)");
static std::regex roomNameRegex("room name ([^\\s]+) (.+)");
static std::regex roomTopicRegex("room topic ([^\\s]+) (.+)");
static std::regex roomNewRegex("room new (.+)");
+static std::regex roomInviteRegex("room invite ([^\\s]+) (.+)");
void parse(std::string l, Kazv::ClientWrap c)
{
using namespace Kazv::CursorOp;
std::smatch m;
if (l == "rooms") {
auto roomIds = +c.roomIds();
std::cout << "Room Id\tRoom Name\n";
for (auto id : roomIds) {
auto roomName = c.room(id).name().make().get();
std::cout << id << "\t" << roomName << "\n";
}
} else if (std::regex_match(l, m, roomMsgsRegex)) {
auto roomId = m[1].str();
auto room = c.room(roomId);
auto msgs = +room.timelineEvents();
std::cout << "Messages in " << roomId << ":\n";
for (auto msg : msgs) {
std::cout << "Event "
<< msg.id() << " from "
<< msg.sender() << " at "
<< msg.originServerTs() << " typed "
<< msg.type() << "\n";
{
cereal::JSONOutputArchive archive( std::cout );
archive(msg.content());
}
std::cout << std::endl;
}
} else if (std::regex_match(l, m, roomMemsRegex)) {
auto roomId = m[1].str();
auto room = c.room(roomId);
auto members = +room.members();
std::cout << "Members in " << roomId << ":\n";
for (auto userId : members) {
std::cout << userId << std::endl;
}
} else if (std::regex_match(l, m, roomStatesRegex)) {
auto roomId = m[1].str();
auto room = c.room(roomId);
auto states = +room.stateEvents();
std::cout << "States in " << roomId << ":\n";
for (auto [k, st] : states) {
auto [type, stateKey] = k;
std::cout << "State typed "
<< type << " with stateKey "
<< stateKey << "\n";
{
cereal::JSONOutputArchive archive( std::cout );
archive(st);
}
std::cout << std::endl;
}
} else if (std::regex_match(l, m, roomSendRegex)) {
auto roomId = m[1].str();
auto text = m[2].str();
auto room = c.room(roomId);
room.sendTextMessage(text);
} else if (std::regex_match(l, m, roomNameRegex)) {
auto roomId = m[1].str();
auto text = m[2].str();
auto room = c.room(roomId);
room.setName(text);
} else if (std::regex_match(l, m, roomTopicRegex)) {
auto roomId = m[1].str();
auto text = m[2].str();
auto room = c.room(roomId);
room.setTopic(text);
} else if (std::regex_match(l, m, roomNewRegex)) {
auto name = m[1].str();
c.createRoom(Kazv::RoomVisibility::Private, name);
+ } else if (std::regex_match(l, m, roomInviteRegex)) {
+ auto roomId = m[1].str();
+ auto userId = m[2].str();
+ auto room = c.room(roomId);
+
+ room.invite(userId);
} else {
// no valid action, display help
std::cout << "Commands:\n"
<< "rooms -- List rooms\n"
<< "room msgs <roomId> -- List room messages\n"
<< "room states <roomId> -- List room states\n"
<< "room mems <roomId> -- List room members\n"
<< "room send <roomId> <message text> -- Send a text message\n"
<< "room name <roomId> <new name> -- Set room name\n"
<< "room topic <roomId> <new topic> -- Set room topic\n"
<< "room new <name> -- Create new room\n"
+ << "room invite <roomId> <userId> -- Invite user to room\n"
<< "\n";
}
}

File Metadata

Mime Type
text/x-diff
Expires
Sun, Jan 19, 10:12 AM (3 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
55096
Default Alt Text
(31 KB)

Event Timeline