mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-10-30 09:30:47 +03:00
Add read support for room access options (#324)
- Join rules - Guest access
This commit is contained in:
parent
18061f0600
commit
4bd43780d9
4 changed files with 134 additions and 13 deletions
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
54
src/Cache.cc
54
src/Cache.cc
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue