summary refs log tree commit diff
diff options
context:
space:
mode:
authorKonstantinos Sideris <sideris.konstantin@gmail.com>2018-05-16 23:30:50 +0300
committerKonstantinos Sideris <sideris.konstantin@gmail.com>2018-05-16 23:30:50 +0300
commit791a9d0a4d04a6340e04a303d5e055acfd8ed53a (patch)
tree130969532fa174118224861a20029c4282fc7e92
parentAdd menu to modify the name & topic of the room (diff)
downloadnheko-791a9d0a4d04a6340e04a303d5e055acfd8ed53a.tar.xz
Hide the edit menu when the user doesn't have enough power
-rw-r--r--cmake/MatrixStructs.cmake2
-rw-r--r--include/Cache.h6
-rw-r--r--include/dialogs/RoomSettings.hpp6
-rw-r--r--src/Cache.cc39
-rw-r--r--src/dialogs/RoomSettings.cpp60
5 files changed, 93 insertions, 20 deletions
diff --git a/cmake/MatrixStructs.cmake b/cmake/MatrixStructs.cmake
index cf8e4710..b010ad20 100644
--- a/cmake/MatrixStructs.cmake
+++ b/cmake/MatrixStructs.cmake
@@ -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}
diff --git a/include/Cache.h b/include/Cache.h
index 20f277a9..d2574b76 100644
--- a/include/Cache.h
+++ b/include/Cache.h
@@ -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);
diff --git a/include/dialogs/RoomSettings.hpp b/include/dialogs/RoomSettings.hpp
index f4145060..1434eee6 100644
--- a/include/dialogs/RoomSettings.hpp
+++ b/include/dialogs/RoomSettings.hpp
@@ -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_;
diff --git a/src/Cache.cc b/src/Cache.cc
index 31e86a69..c055ab05 100644
--- a/src/Cache.cc
+++ b/src/Cache.cc
@@ -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;
 
diff --git a/src/dialogs/RoomSettings.cpp b/src/dialogs/RoomSettings.cpp
index 4a7ea4fc..294969d0 100644
--- a/src/dialogs/RoomSettings.cpp
+++ b/src/dialogs/RoomSettings.cpp
@@ -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