Hide the edit menu when the user doesn't have enough power

This commit is contained in:
Konstantinos Sideris 2018-05-16 23:30:50 +03:00
parent 340c9ab9de
commit 791a9d0a4d
5 changed files with 93 additions and 20 deletions

View File

@ -21,7 +21,7 @@ ExternalProject_Add(
MatrixStructs
GIT_REPOSITORY https://github.com/mujx/matrix-structs
GIT_TAG 55a1a5aad0ead3cc45475fc1aed1bf54a56e352c
GIT_TAG ddba5a597be4bafd20e1dd37e5e7b7dc798b0997
BUILD_IN_SOURCE 1
SOURCE_DIR ${MATRIX_STRUCTS_ROOT}

View File

@ -206,6 +206,12 @@ public:
bool isFormatValid();
void setCurrentFormat();
//! Check if the given user has power leve greater than than
//! lowest power level of the given events.
bool hasEnoughPowerLevel(const std::vector<mtx::events::EventType> &eventTypes,
const std::string &room_id,
const std::string &user_id);
//! Retrieves the saved room avatar.
QImage getRoomAvatar(const QString &id);
QImage getRoomAvatar(const std::string &id);

View File

@ -7,6 +7,7 @@
class FlatButton;
class TextField;
class QHBoxLayout;
class Avatar;
class QPixmap;
class QLayout;
@ -91,6 +92,11 @@ private:
static constexpr int AvatarSize = 64;
void setAvatar(const QImage &img) { avatarImg_ = img; }
void setupEditButton();
//! Whether the user would be able to change the name or the topic of the room.
bool hasEditRights_ = true;
QHBoxLayout *editLayout_;
// Button section
FlatButton *saveBtn_;

View File

@ -15,6 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <limits>
#include <stdexcept>
#include <QByteArray>
@ -1223,6 +1224,44 @@ Cache::isNotificationSent(const std::string &event_id)
return res;
}
bool
Cache::hasEnoughPowerLevel(const std::vector<mtx::events::EventType> &eventTypes,
const std::string &room_id,
const std::string &user_id)
{
using namespace mtx::events;
using namespace mtx::events::state;
auto txn = lmdb::txn::begin(env_);
auto db = getStatesDb(txn, room_id);
uint16_t min_event_level = std::numeric_limits<uint16_t>::max();
uint16_t user_level = std::numeric_limits<uint16_t>::min();
lmdb::val event;
bool res = lmdb::dbi_get(txn, db, lmdb::val(to_string(EventType::RoomPowerLevels)), event);
if (res) {
try {
StateEvent<PowerLevels> msg =
json::parse(std::string(event.data(), event.size()));
user_level = msg.content.user_level(user_id);
for (const auto &ty : eventTypes)
min_event_level =
std::min(min_event_level,
(uint16_t)msg.content.state_level(to_string(ty)));
} catch (const json::exception &e) {
qWarning() << "hasEnoughPowerLevel: " << e.what();
}
}
txn.commit();
return user_level >= min_event_level;
}
QHash<QString, QString> Cache::DisplayNames;
QHash<QString, QString> Cache::AvatarUrls;

View File

@ -11,11 +11,13 @@
#include <QLabel>
#include <QPainter>
#include <QPixmap>
#include <QSettings>
#include <QSharedPointer>
#include <QStyleOption>
#include <QVBoxLayout>
using namespace dialogs;
using namespace mtx::events;
EditModal::EditModal(const QString &roomId, QWidget *parent)
: QWidget(parent)
@ -86,7 +88,7 @@ EditModal::EditModal(const QString &roomId, QWidget *parent)
&StateEventProxy::stateEventSent,
this,
[this, proxy, newName]() {
proxy->deleteLater();
Q_UNUSED(proxy);
errorField_->hide();
emit nameChanged(newName);
close();
@ -96,7 +98,7 @@ EditModal::EditModal(const QString &roomId, QWidget *parent)
&StateEventProxy::stateEventError,
this,
[this, proxy, newName](const QString &msg) {
proxy->deleteLater();
Q_UNUSED(proxy);
errorField_->setText(msg);
errorField_->show();
});
@ -113,7 +115,7 @@ EditModal::EditModal(const QString &roomId, QWidget *parent)
&StateEventProxy::stateEventSent,
this,
[this, proxy, newTopic]() {
proxy->deleteLater();
Q_UNUSED(proxy);
errorField_->hide();
close();
});
@ -122,7 +124,7 @@ EditModal::EditModal(const QString &roomId, QWidget *parent)
&StateEventProxy::stateEventError,
this,
[this, proxy, newTopic](const QString &msg) {
proxy->deleteLater();
Q_UNUSED(proxy);
errorField_->setText(msg);
errorField_->show();
});
@ -242,9 +244,43 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent)
auto menuLabel = new QLabel("Room Settings", this);
menuLabel->setFont(font);
topSection_ = new TopSection(info_, avatarImg_, this);
editLayout_ = new QHBoxLayout;
editLayout_->setMargin(0);
editLayout_->addWidget(topSection_);
setupEditButton();
layout->addWidget(menuLabel);
layout->addLayout(editLayout_);
layout->addLayout(notifOptionLayout_);
layout->addLayout(accessOptionLayout);
layout->addLayout(btnLayout);
connect(cancelBtn_, &QPushButton::clicked, this, &RoomSettings::closing);
connect(saveBtn_, &QPushButton::clicked, this, &RoomSettings::saveSettings);
}
void
RoomSettings::setupEditButton()
{
try {
QSettings settings;
auto userId = settings.value("auth/user_id").toString().toStdString();
hasEditRights_ = cache::client()->hasEnoughPowerLevel(
{EventType::RoomName, EventType::RoomTopic}, room_id_.toStdString(), userId);
} catch (const lmdb::error &e) {
qWarning() << "lmdb error" << e.what();
}
constexpr int buttonSize = 36;
constexpr int iconSize = buttonSize / 2;
if (!hasEditRights_)
return;
QIcon editIcon;
editIcon.addFile(":/icons/icons/ui/edit.svg");
editFieldsBtn_ = new FlatButton(this);
@ -264,21 +300,7 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent)
});
});
topSection_ = new TopSection(info_, avatarImg_, this);
auto editLayout = new QHBoxLayout;
editLayout->setMargin(0);
editLayout->addWidget(topSection_);
editLayout->addWidget(editFieldsBtn_, 0, Qt::AlignRight | Qt::AlignTop);
layout->addWidget(menuLabel);
layout->addLayout(editLayout);
layout->addLayout(notifOptionLayout_);
layout->addLayout(accessOptionLayout);
layout->addLayout(btnLayout);
connect(cancelBtn_, &QPushButton::clicked, this, &RoomSettings::closing);
connect(saveBtn_, &QPushButton::clicked, this, &RoomSettings::saveSettings);
editLayout_->addWidget(editFieldsBtn_, 0, Qt::AlignRight | Qt::AlignTop);
}
void