Add read support for room access options (#324)

- Join rules
- Guest access
This commit is contained in:
twahm 2018-05-12 17:31:58 -05:00 committed by mujx
parent 18061f0600
commit 4bd43780d9
4 changed files with 134 additions and 13 deletions

View file

@ -22,7 +22,9 @@
#include <QImage> #include <QImage>
#include <json.hpp> #include <json.hpp>
#include <lmdb++.h> #include <lmdb++.h>
#include <mtx/events/join_rules.hpp>
#include <mtx/responses.hpp> #include <mtx/responses.hpp>
using mtx::events::state::JoinRule;
struct RoomMember struct RoomMember
{ {
@ -74,15 +76,20 @@ struct RoomInfo
bool is_invite = false; bool is_invite = false;
//! Total number of members in the room. //! Total number of members in the room.
int16_t member_count = 0; int16_t member_count = 0;
//! Who can access to the room.
JoinRule join_rule = JoinRule::Public;
bool guest_access = false;
}; };
inline void inline void
to_json(json &j, const RoomInfo &info) to_json(json &j, const RoomInfo &info)
{ {
j["name"] = info.name; j["name"] = info.name;
j["topic"] = info.topic; j["topic"] = info.topic;
j["avatar_url"] = info.avatar_url; j["avatar_url"] = info.avatar_url;
j["is_invite"] = info.is_invite; j["is_invite"] = info.is_invite;
j["join_rule"] = info.join_rule;
j["guest_access"] = info.guest_access;
if (info.member_count != 0) if (info.member_count != 0)
j["member_count"] = info.member_count; j["member_count"] = info.member_count;
@ -91,10 +98,12 @@ to_json(json &j, const RoomInfo &info)
inline void inline void
from_json(const json &j, RoomInfo &info) from_json(const json &j, RoomInfo &info)
{ {
info.name = j.at("name"); info.name = j.at("name");
info.topic = j.at("topic"); info.topic = j.at("topic");
info.avatar_url = j.at("avatar_url"); info.avatar_url = j.at("avatar_url");
info.is_invite = j.at("is_invite"); info.is_invite = j.at("is_invite");
info.join_rule = j.at("join_rule");
info.guest_access = j.at("guest_access");
if (j.count("member_count")) if (j.count("member_count"))
info.member_count = j.at("member_count"); info.member_count = j.at("member_count");
@ -164,6 +173,9 @@ public:
//! Calculate & return the name of the room. //! Calculate & return the name of the room.
QString getRoomName(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb); QString getRoomName(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb);
//! Get room join rules
JoinRule getRoomJoinRule(lmdb::txn &txn, lmdb::dbi &statesdb);
bool getRoomGuestAccess(lmdb::txn &txn, lmdb::dbi &statesdb);
//! Retrieve the topic of the room if any. //! Retrieve the topic of the room if any.
QString getRoomTopic(lmdb::txn &txn, lmdb::dbi &statesdb); QString getRoomTopic(lmdb::txn &txn, lmdb::dbi &statesdb);
//! Retrieve the room avatar's url if any. //! Retrieve the room avatar's url if any.

View file

@ -11,6 +11,7 @@ class Avatar;
class QPixmap; class QPixmap;
class QLayout; class QLayout;
class QLabel; class QLabel;
class QComboBox;
template<class T> template<class T>
class QSharedPointer; class QSharedPointer;
@ -54,6 +55,9 @@ signals:
protected: protected:
void paintEvent(QPaintEvent *event) override; void paintEvent(QPaintEvent *event) override;
private slots:
void save_and_close();
private: private:
static constexpr int AvatarSize = 64; static constexpr int AvatarSize = 64;
@ -66,6 +70,8 @@ private:
RoomInfo info_; RoomInfo info_;
QString room_id_; QString room_id_;
QImage avatarImg_; QImage avatarImg_;
QComboBox *accessCombo;
}; };
} // dialogs } // dialogs

View file

@ -30,7 +30,7 @@
//! Should be changed when a breaking change occurs in the cache format. //! Should be changed when a breaking change occurs in the cache format.
//! This will reset client's data. //! This will reset client's data.
static const std::string CURRENT_CACHE_FORMAT_VERSION("2018.04.21"); static const std::string CURRENT_CACHE_FORMAT_VERSION("2018.05.11");
static const lmdb::val NEXT_BATCH_KEY("next_batch"); static const lmdb::val NEXT_BATCH_KEY("next_batch");
static const lmdb::val CACHE_FORMAT_VERSION_KEY("cache_format_version"); static const lmdb::val CACHE_FORMAT_VERSION_KEY("cache_format_version");
@ -550,7 +550,8 @@ Cache::roomsWithStateUpdates(const mtx::responses::Sync &res)
RoomInfo RoomInfo
Cache::singleRoomInfo(const std::string &room_id) Cache::singleRoomInfo(const std::string &room_id)
{ {
auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY); auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY);
auto statesdb = getStatesDb(txn, room_id);
lmdb::val data; lmdb::val data;
@ -559,6 +560,8 @@ Cache::singleRoomInfo(const std::string &room_id)
try { try {
RoomInfo tmp = json::parse(std::string(data.data(), data.size())); RoomInfo tmp = json::parse(std::string(data.data(), data.size()));
tmp.member_count = getMembersDb(txn, room_id).size(txn); tmp.member_count = getMembersDb(txn, room_id).size(txn);
tmp.join_rule = getRoomJoinRule(txn, statesdb);
tmp.guest_access = getRoomGuestAccess(txn, statesdb);
txn.commit(); txn.commit();
@ -584,12 +587,15 @@ Cache::getRoomInfo(const std::vector<std::string> &rooms)
for (const auto &room : rooms) { for (const auto &room : rooms) {
lmdb::val data; lmdb::val data;
auto statesdb = getStatesDb(txn, room);
// Check if the room is joined. // Check if the room is joined.
if (lmdb::dbi_get(txn, roomsDb_, lmdb::val(room), data)) { if (lmdb::dbi_get(txn, roomsDb_, lmdb::val(room), data)) {
try { try {
RoomInfo tmp = json::parse(std::string(data.data(), data.size())); RoomInfo tmp = json::parse(std::string(data.data(), data.size()));
tmp.member_count = getMembersDb(txn, room).size(txn); tmp.member_count = getMembersDb(txn, room).size(txn);
tmp.join_rule = getRoomJoinRule(txn, statesdb);
tmp.guest_access = getRoomGuestAccess(txn, statesdb);
room_info.emplace(QString::fromStdString(room), std::move(tmp)); room_info.emplace(QString::fromStdString(room), std::move(tmp));
} catch (const json::exception &e) { } catch (const json::exception &e) {
@ -805,6 +811,50 @@ Cache::getRoomName(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb)
return "Empty Room"; return "Empty Room";
} }
JoinRule
Cache::getRoomJoinRule(lmdb::txn &txn, lmdb::dbi &statesdb)
{
using namespace mtx::events;
using namespace mtx::events::state;
lmdb::val event;
bool res = lmdb::dbi_get(
txn, statesdb, lmdb::val(to_string(mtx::events::EventType::RoomJoinRules)), event);
if (res) {
try {
StateEvent<JoinRules> msg =
json::parse(std::string(event.data(), event.size()));
return msg.content.join_rule;
} catch (const json::exception &e) {
qWarning() << e.what();
}
}
return JoinRule::Knock;
}
bool
Cache::getRoomGuestAccess(lmdb::txn &txn, lmdb::dbi &statesdb)
{
using namespace mtx::events;
using namespace mtx::events::state;
lmdb::val event;
bool res = lmdb::dbi_get(
txn, statesdb, lmdb::val(to_string(mtx::events::EventType::RoomGuestAccess)), event);
if (res) {
try {
StateEvent<GuestAccess> msg =
json::parse(std::string(event.data(), event.size()));
return msg.content.guest_access == AccessState::CanJoin;
} catch (const json::exception &e) {
qWarning() << e.what();
}
}
return false;
}
QString QString
Cache::getRoomTopic(lmdb::txn &txn, lmdb::dbi &statesdb) Cache::getRoomTopic(lmdb::txn &txn, lmdb::dbi &statesdb)
{ {

View file

@ -38,8 +38,7 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent)
setMaximumWidth(385); setMaximumWidth(385);
try { try {
auto res = cache::client()->getRoomInfo({room_id_.toStdString()}); info_ = cache::client()->singleRoomInfo(room_id_.toStdString());
info_ = res[room_id_];
setAvatar(QImage::fromData(cache::client()->image(info_.avatar_url))); setAvatar(QImage::fromData(cache::client()->image(info_.avatar_url)));
} catch (const lmdb::error &e) { } catch (const lmdb::error &e) {
@ -75,13 +74,67 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent)
notifOptionLayout_->addWidget(notifLabel); notifOptionLayout_->addWidget(notifLabel);
notifOptionLayout_->addWidget(notifCombo, 0, Qt::AlignBottom | Qt::AlignRight); notifOptionLayout_->addWidget(notifCombo, 0, Qt::AlignBottom | Qt::AlignRight);
auto accessOptionLayout = new QHBoxLayout();
accessOptionLayout->setMargin(5);
auto accessLabel = new QLabel(tr("Room access"), this);
accessCombo = new QComboBox(this);
accessCombo->addItem(tr("Anyone and guests"));
accessCombo->addItem(tr("Anyone"));
accessCombo->addItem(tr("Invited users"));
accessCombo->setDisabled(true);
accessLabel->setStyleSheet("font-size: 15px;");
if(info_.join_rule == JoinRule::Public)
{
if(info_.guest_access)
{
accessCombo->setCurrentIndex(0);
}
else
{
accessCombo->setCurrentIndex(1);
}
}
else
{
accessCombo->setCurrentIndex(2);
}
accessOptionLayout->addWidget(accessLabel);
accessOptionLayout->addWidget(accessCombo);
layout->addWidget(new TopSection(info_, avatarImg_, this)); layout->addWidget(new TopSection(info_, avatarImg_, this));
layout->addLayout(notifOptionLayout_); layout->addLayout(notifOptionLayout_);
layout->addLayout(notifOptionLayout_); layout->addLayout(notifOptionLayout_);
layout->addLayout(accessOptionLayout);
layout->addLayout(btnLayout); layout->addLayout(btnLayout);
connect(cancelBtn_, &FlatButton::clicked, this, &RoomSettings::closing); connect(cancelBtn_, &FlatButton::clicked, this, &RoomSettings::closing);
connect(saveBtn_, &FlatButton::clicked, this, [this]() { emit closing(); }); connect(saveBtn_, &FlatButton::clicked, this, &RoomSettings::save_and_close);
}
void
RoomSettings::save_and_close() {
// TODO: Save access changes to the room
if (accessCombo->currentIndex()<2) {
if(info_.join_rule != JoinRule::Public) {
// Make join_rule Public
}
if(accessCombo->currentIndex()==0) {
if(!info_.guest_access) {
// Make guest_access CanJoin
}
}
}
else {
if(info_.join_rule != JoinRule::Invite) {
// Make join_rule invite
}
if(info_.guest_access) {
// Make guest_access forbidden
}
}
closing();
} }
void void