mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-25 20:48:52 +03:00
Allow user to configure join rules for a room
This commit is contained in:
parent
509d3eb8b4
commit
aec5587947
2 changed files with 188 additions and 41 deletions
|
@ -5,6 +5,7 @@
|
|||
#include <QPainter>
|
||||
#include <QPixmap>
|
||||
#include <QSharedPointer>
|
||||
#include <QShowEvent>
|
||||
#include <QStyleOption>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
|
@ -17,6 +18,7 @@
|
|||
#include "Utils.h"
|
||||
#include "ui/Avatar.h"
|
||||
#include "ui/FlatButton.h"
|
||||
#include "ui/LoadingIndicator.h"
|
||||
#include "ui/Painter.h"
|
||||
#include "ui/TextField.h"
|
||||
#include "ui/Theme.h"
|
||||
|
@ -207,7 +209,39 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent)
|
|||
accessCombo->addItem(tr("Anyone and guests"));
|
||||
accessCombo->addItem(tr("Anyone"));
|
||||
accessCombo->addItem(tr("Invited users"));
|
||||
accessCombo->setDisabled(true);
|
||||
accessCombo->setDisabled(
|
||||
!canChangeJoinRules(room_id_.toStdString(), utils::localUser().toStdString()));
|
||||
connect(accessCombo, QOverload<int>::of(&QComboBox::activated), [this](int index) {
|
||||
using namespace mtx::events::state;
|
||||
|
||||
auto guest_access = [](int index) -> state::GuestAccess {
|
||||
state::GuestAccess event;
|
||||
|
||||
if (index == 0)
|
||||
event.guest_access = state::AccessState::CanJoin;
|
||||
else
|
||||
event.guest_access = state::AccessState::Forbidden;
|
||||
|
||||
return event;
|
||||
}(index);
|
||||
|
||||
auto join_rule = [](int index) -> state::JoinRules {
|
||||
state::JoinRules event;
|
||||
|
||||
switch (index) {
|
||||
case 0:
|
||||
case 1:
|
||||
event.join_rule = JoinRule::Public;
|
||||
break;
|
||||
default:
|
||||
event.join_rule = JoinRule::Invite;
|
||||
}
|
||||
|
||||
return event;
|
||||
}(index);
|
||||
|
||||
updateAccessRules(room_id_.toStdString(), join_rule, guest_access);
|
||||
});
|
||||
|
||||
if (info_.join_rule == JoinRule::Public) {
|
||||
if (info_.guest_access) {
|
||||
|
@ -321,6 +355,20 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent)
|
|||
|
||||
setupEditButton();
|
||||
|
||||
errorLabel_ = new QLabel(this);
|
||||
errorLabel_->setAlignment(Qt::AlignCenter);
|
||||
errorLabel_->hide();
|
||||
|
||||
spinner_ = new LoadingIndicator(this);
|
||||
spinner_->setFixedHeight(30);
|
||||
spinner_->setFixedWidth(30);
|
||||
spinner_->hide();
|
||||
auto spinnerLayout = new QVBoxLayout;
|
||||
spinnerLayout->addWidget(spinner_);
|
||||
spinnerLayout->setAlignment(Qt::AlignCenter);
|
||||
spinnerLayout->setMargin(0);
|
||||
spinnerLayout->setSpacing(0);
|
||||
|
||||
layout->addWidget(avatar_, Qt::AlignCenter | Qt::AlignTop);
|
||||
layout->addLayout(textLayout);
|
||||
layout->addLayout(btnLayout_);
|
||||
|
@ -329,6 +377,8 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent)
|
|||
layout->addLayout(accessOptionLayout);
|
||||
layout->addLayout(encryptionOptionLayout);
|
||||
layout->addLayout(keyRequestsLayout);
|
||||
layout->addWidget(errorLabel_);
|
||||
layout->addLayout(spinnerLayout);
|
||||
layout->addStretch(1);
|
||||
|
||||
connect(this, &RoomSettings::enableEncryptionError, this, [this](const QString &msg) {
|
||||
|
@ -337,6 +387,21 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent)
|
|||
|
||||
emit ChatPage::instance()->showNotification(msg);
|
||||
});
|
||||
|
||||
connect(this, &RoomSettings::showErrorMessage, this, [this](const QString &msg) {
|
||||
if (!errorLabel_)
|
||||
return;
|
||||
|
||||
stopLoadingSpinner();
|
||||
|
||||
errorLabel_->show();
|
||||
errorLabel_->setText(msg);
|
||||
});
|
||||
|
||||
connect(this, &RoomSettings::accessRulesUpdated, this, [this]() {
|
||||
stopLoadingSpinner();
|
||||
resetErrorLabel();
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -346,16 +411,7 @@ RoomSettings::setupEditButton()
|
|||
btnLayout_->setSpacing(BUTTON_SPACING);
|
||||
btnLayout_->setMargin(0);
|
||||
|
||||
try {
|
||||
auto userId = utils::localUser().toStdString();
|
||||
|
||||
hasEditRights_ = cache::client()->hasEnoughPowerLevel(
|
||||
{EventType::RoomName, EventType::RoomTopic}, room_id_.toStdString(), userId);
|
||||
} catch (const lmdb::error &e) {
|
||||
nhlog::db()->warn("lmdb error: {}", e.what());
|
||||
}
|
||||
|
||||
if (!hasEditRights_)
|
||||
if (!canChangeNameAndTopic(room_id_.toStdString(), utils::localUser().toStdString()))
|
||||
return;
|
||||
|
||||
QIcon editIcon;
|
||||
|
@ -397,30 +453,6 @@ RoomSettings::retrieveRoomInfo()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
RoomSettings::saveSettings()
|
||||
{
|
||||
// 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
|
||||
RoomSettings::enableEncryption()
|
||||
{
|
||||
|
@ -443,6 +475,15 @@ RoomSettings::enableEncryption()
|
|||
});
|
||||
}
|
||||
|
||||
void
|
||||
RoomSettings::showEvent(QShowEvent *event)
|
||||
{
|
||||
resetErrorLabel();
|
||||
stopLoadingSpinner();
|
||||
|
||||
QWidget::showEvent(event);
|
||||
}
|
||||
|
||||
void
|
||||
RoomSettings::paintEvent(QPaintEvent *)
|
||||
{
|
||||
|
@ -451,3 +492,97 @@ RoomSettings::paintEvent(QPaintEvent *)
|
|||
QPainter p(this);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
}
|
||||
|
||||
bool
|
||||
RoomSettings::canChangeJoinRules(const std::string &room_id, const std::string &user_id) const
|
||||
{
|
||||
try {
|
||||
return cache::client()->hasEnoughPowerLevel(
|
||||
{EventType::RoomJoinRules}, room_id, user_id);
|
||||
} catch (const lmdb::error &e) {
|
||||
nhlog::db()->warn("lmdb error: {}", e.what());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
RoomSettings::canChangeNameAndTopic(const std::string &room_id, const std::string &user_id) const
|
||||
{
|
||||
try {
|
||||
return cache::client()->hasEnoughPowerLevel(
|
||||
{EventType::RoomName, EventType::RoomTopic}, room_id, user_id);
|
||||
} catch (const lmdb::error &e) {
|
||||
nhlog::db()->warn("lmdb error: {}", e.what());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
RoomSettings::updateAccessRules(const std::string &room_id,
|
||||
const mtx::events::state::JoinRules &join_rule,
|
||||
const mtx::events::state::GuestAccess &guest_access)
|
||||
{
|
||||
startLoadingSpinner();
|
||||
resetErrorLabel();
|
||||
|
||||
http::client()->send_state_event<state::JoinRules, EventType::RoomJoinRules>(
|
||||
room_id,
|
||||
join_rule,
|
||||
[this, room_id, guest_access](const mtx::responses::EventId &,
|
||||
mtx::http::RequestErr err) {
|
||||
if (err) {
|
||||
nhlog::net()->warn("failed to send m.room.join_rule: {} {}",
|
||||
static_cast<int>(err->status_code),
|
||||
err->matrix_error.error);
|
||||
emit showErrorMessage(QString::fromStdString(err->matrix_error.error));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
http::client()->send_state_event<state::GuestAccess, EventType::RoomGuestAccess>(
|
||||
room_id,
|
||||
guest_access,
|
||||
[this](const mtx::responses::EventId &, mtx::http::RequestErr err) {
|
||||
if (err) {
|
||||
nhlog::net()->warn("failed to send m.room.guest_access: {} {}",
|
||||
static_cast<int>(err->status_code),
|
||||
err->matrix_error.error);
|
||||
emit showErrorMessage(
|
||||
QString::fromStdString(err->matrix_error.error));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
emit accessRulesUpdated();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void
|
||||
RoomSettings::stopLoadingSpinner()
|
||||
{
|
||||
if (spinner_) {
|
||||
spinner_->stop();
|
||||
spinner_->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RoomSettings::startLoadingSpinner()
|
||||
{
|
||||
if (spinner_) {
|
||||
spinner_->start();
|
||||
spinner_->show();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RoomSettings::resetErrorLabel()
|
||||
{
|
||||
if (errorLabel_) {
|
||||
errorLabel_->hide();
|
||||
errorLabel_->clear();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ class Avatar;
|
|||
class FlatButton;
|
||||
class QComboBox;
|
||||
class QHBoxLayout;
|
||||
class QShowEvent;
|
||||
class LoadingIndicator;
|
||||
class QLabel;
|
||||
class QLabel;
|
||||
class QLayout;
|
||||
|
@ -60,15 +62,24 @@ public:
|
|||
signals:
|
||||
void closing();
|
||||
void enableEncryptionError(const QString &msg);
|
||||
void showErrorMessage(const QString &msg);
|
||||
void accessRulesUpdated();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
private slots:
|
||||
void saveSettings();
|
||||
void showEvent(QShowEvent *event) override;
|
||||
|
||||
private:
|
||||
static constexpr int AvatarSize = 64;
|
||||
//! Whether the user has enough power level to send m.room.join_rules events.
|
||||
bool canChangeJoinRules(const std::string &room_id, const std::string &user_id) const;
|
||||
//! Whether the user has enough power level to send m.room.name & m.room.topic events.
|
||||
bool canChangeNameAndTopic(const std::string &room_id, const std::string &user_id) const;
|
||||
void updateAccessRules(const std::string &room_id,
|
||||
const mtx::events::state::JoinRules &,
|
||||
const mtx::events::state::GuestAccess &);
|
||||
void stopLoadingSpinner();
|
||||
void startLoadingSpinner();
|
||||
void resetErrorLabel();
|
||||
|
||||
void setAvatar(const QImage &img) { avatarImg_ = img; }
|
||||
void setupEditButton();
|
||||
|
@ -78,8 +89,6 @@ private:
|
|||
|
||||
Avatar *avatar_;
|
||||
|
||||
//! Whether the user would be able to change the name or the topic of the room.
|
||||
bool hasEditRights_ = true;
|
||||
bool usesEncryption_ = false;
|
||||
QHBoxLayout *btnLayout_;
|
||||
|
||||
|
@ -89,6 +98,9 @@ private:
|
|||
QString room_id_;
|
||||
QImage avatarImg_;
|
||||
|
||||
QLabel *errorLabel_;
|
||||
LoadingIndicator *spinner_;
|
||||
|
||||
QComboBox *accessCombo;
|
||||
Toggle *encryptionToggle_;
|
||||
Toggle *keyRequestsToggle_;
|
||||
|
|
Loading…
Reference in a new issue