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 <QPainter>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
#include <QSharedPointer>
|
#include <QSharedPointer>
|
||||||
|
#include <QShowEvent>
|
||||||
#include <QStyleOption>
|
#include <QStyleOption>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
@ -17,6 +18,7 @@
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
#include "ui/Avatar.h"
|
#include "ui/Avatar.h"
|
||||||
#include "ui/FlatButton.h"
|
#include "ui/FlatButton.h"
|
||||||
|
#include "ui/LoadingIndicator.h"
|
||||||
#include "ui/Painter.h"
|
#include "ui/Painter.h"
|
||||||
#include "ui/TextField.h"
|
#include "ui/TextField.h"
|
||||||
#include "ui/Theme.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 and guests"));
|
||||||
accessCombo->addItem(tr("Anyone"));
|
accessCombo->addItem(tr("Anyone"));
|
||||||
accessCombo->addItem(tr("Invited users"));
|
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_.join_rule == JoinRule::Public) {
|
||||||
if (info_.guest_access) {
|
if (info_.guest_access) {
|
||||||
|
@ -321,6 +355,20 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent)
|
||||||
|
|
||||||
setupEditButton();
|
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->addWidget(avatar_, Qt::AlignCenter | Qt::AlignTop);
|
||||||
layout->addLayout(textLayout);
|
layout->addLayout(textLayout);
|
||||||
layout->addLayout(btnLayout_);
|
layout->addLayout(btnLayout_);
|
||||||
|
@ -329,6 +377,8 @@ RoomSettings::RoomSettings(const QString &room_id, QWidget *parent)
|
||||||
layout->addLayout(accessOptionLayout);
|
layout->addLayout(accessOptionLayout);
|
||||||
layout->addLayout(encryptionOptionLayout);
|
layout->addLayout(encryptionOptionLayout);
|
||||||
layout->addLayout(keyRequestsLayout);
|
layout->addLayout(keyRequestsLayout);
|
||||||
|
layout->addWidget(errorLabel_);
|
||||||
|
layout->addLayout(spinnerLayout);
|
||||||
layout->addStretch(1);
|
layout->addStretch(1);
|
||||||
|
|
||||||
connect(this, &RoomSettings::enableEncryptionError, this, [this](const QString &msg) {
|
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);
|
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
|
void
|
||||||
|
@ -346,16 +411,7 @@ RoomSettings::setupEditButton()
|
||||||
btnLayout_->setSpacing(BUTTON_SPACING);
|
btnLayout_->setSpacing(BUTTON_SPACING);
|
||||||
btnLayout_->setMargin(0);
|
btnLayout_->setMargin(0);
|
||||||
|
|
||||||
try {
|
if (!canChangeNameAndTopic(room_id_.toStdString(), utils::localUser().toStdString()))
|
||||||
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_)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QIcon editIcon;
|
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
|
void
|
||||||
RoomSettings::enableEncryption()
|
RoomSettings::enableEncryption()
|
||||||
{
|
{
|
||||||
|
@ -443,6 +475,15 @@ RoomSettings::enableEncryption()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RoomSettings::showEvent(QShowEvent *event)
|
||||||
|
{
|
||||||
|
resetErrorLabel();
|
||||||
|
stopLoadingSpinner();
|
||||||
|
|
||||||
|
QWidget::showEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
RoomSettings::paintEvent(QPaintEvent *)
|
RoomSettings::paintEvent(QPaintEvent *)
|
||||||
{
|
{
|
||||||
|
@ -451,3 +492,97 @@ RoomSettings::paintEvent(QPaintEvent *)
|
||||||
QPainter p(this);
|
QPainter p(this);
|
||||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &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 FlatButton;
|
||||||
class QComboBox;
|
class QComboBox;
|
||||||
class QHBoxLayout;
|
class QHBoxLayout;
|
||||||
|
class QShowEvent;
|
||||||
|
class LoadingIndicator;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class QLayout;
|
class QLayout;
|
||||||
|
@ -60,15 +62,24 @@ public:
|
||||||
signals:
|
signals:
|
||||||
void closing();
|
void closing();
|
||||||
void enableEncryptionError(const QString &msg);
|
void enableEncryptionError(const QString &msg);
|
||||||
|
void showErrorMessage(const QString &msg);
|
||||||
|
void accessRulesUpdated();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *event) override;
|
void paintEvent(QPaintEvent *event) override;
|
||||||
|
void showEvent(QShowEvent *event) override;
|
||||||
private slots:
|
|
||||||
void saveSettings();
|
|
||||||
|
|
||||||
private:
|
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 setAvatar(const QImage &img) { avatarImg_ = img; }
|
||||||
void setupEditButton();
|
void setupEditButton();
|
||||||
|
@ -78,8 +89,6 @@ private:
|
||||||
|
|
||||||
Avatar *avatar_;
|
Avatar *avatar_;
|
||||||
|
|
||||||
//! Whether the user would be able to change the name or the topic of the room.
|
|
||||||
bool hasEditRights_ = true;
|
|
||||||
bool usesEncryption_ = false;
|
bool usesEncryption_ = false;
|
||||||
QHBoxLayout *btnLayout_;
|
QHBoxLayout *btnLayout_;
|
||||||
|
|
||||||
|
@ -89,6 +98,9 @@ private:
|
||||||
QString room_id_;
|
QString room_id_;
|
||||||
QImage avatarImg_;
|
QImage avatarImg_;
|
||||||
|
|
||||||
|
QLabel *errorLabel_;
|
||||||
|
LoadingIndicator *spinner_;
|
||||||
|
|
||||||
QComboBox *accessCombo;
|
QComboBox *accessCombo;
|
||||||
Toggle *encryptionToggle_;
|
Toggle *encryptionToggle_;
|
||||||
Toggle *keyRequestsToggle_;
|
Toggle *keyRequestsToggle_;
|
||||||
|
|
Loading…
Reference in a new issue