diff --git a/resources/qml/Root.qml b/resources/qml/Root.qml
index fc321136..063284c1 100644
--- a/resources/qml/Root.qml
+++ b/resources/qml/Root.qml
@@ -94,6 +94,22 @@ Pane {
}
+ Component {
+ id: allowedRoomSettingsComponent
+
+ AllowedRoomsSettingsDialog {
+ }
+
+ }
+
+ function showAllowedRoomsEditor(settings) {
+ var dialog = allowedRoomSettingsComponent.createObject(timelineRoot, {
+ "roomSettings": settings
+ });
+ dialog.show();
+ destroyOnClose(dialog);
+ }
+
Component {
id: roomMembersComponent
diff --git a/resources/qml/dialogs/AllowedRoomsSettingsDialog.qml b/resources/qml/dialogs/AllowedRoomsSettingsDialog.qml
new file mode 100644
index 00000000..60ac06de
--- /dev/null
+++ b/resources/qml/dialogs/AllowedRoomsSettingsDialog.qml
@@ -0,0 +1,178 @@
+// SPDX-FileCopyrightText: 2022 Nheko Contributors
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+import ".."
+import "../ui"
+import Qt.labs.platform 1.1 as Platform
+import QtQuick 2.15
+import QtQuick.Controls 2.3
+import QtQuick.Layouts 1.2
+import QtQuick.Window 2.13
+import im.nheko 1.0
+
+ApplicationWindow {
+ id: allowedDialog
+
+ property var roomSettings
+
+ minimumWidth: 340
+ minimumHeight: 450
+ width: 450
+ height: 680
+ palette: Nheko.colors
+ color: Nheko.colors.window
+ modality: Qt.NonModal
+ flags: Qt.Dialog | Qt.WindowCloseButtonHint | Qt.WindowTitleHint
+ title: qsTr("Allowed rooms settings")
+
+ Shortcut {
+ sequence: StandardKey.Cancel
+ onActivated: roomSettingsDialog.close()
+ }
+
+ ColumnLayout {
+ anchors.margins: Nheko.paddingMedium
+ anchors.fill: parent
+ spacing: 0
+
+
+ MatrixText {
+ text: qsTr("List of rooms that allow access to this room. Anyone who is in any of those rooms can join this room.")
+ font.pixelSize: Math.floor(fontMetrics.font.pixelSize * 1.1)
+ Layout.fillWidth: true
+ Layout.fillHeight: false
+ color: Nheko.colors.text
+ Layout.bottomMargin: Nheko.paddingMedium
+ }
+
+ ListView {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ id: view
+
+ clip: true
+
+ ScrollHelper {
+ flickable: parent
+ anchors.fill: parent
+ }
+
+ model: roomSettings.allowedRoomsModel
+ spacing: 4
+ cacheBuffer: 50
+
+ delegate: RowLayout {
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ ColumnLayout {
+ Layout.fillWidth: true
+ Text {
+ Layout.fillWidth: true
+ text: model.name
+ color: Nheko.colors.text
+ textFormat: Text.PlainText
+ }
+
+ Text {
+ Layout.fillWidth: true
+ text: model.isParent ? qsTr("Parent community") : qsTr("Other room")
+ color: Nheko.colors.buttonText
+ textFormat: Text.PlainText
+ }
+ }
+
+ ToggleButton {
+ checked: model.allowed
+ Layout.alignment: Qt.AlignRight
+ onCheckedChanged: model.allowed = checked
+ }
+ }
+ }
+
+ Column{
+ id: roomEntryCompleter
+ Layout.fillWidth: true
+
+ spacing: 1
+ z: 5
+
+ Completer {
+ id: roomCompleter
+
+ visible: roomEntry.text.length > 0
+ width: parent.width
+ roomId: allowedDialog.roomSettings.roomId
+ completerName: "room"
+ bottomToTop: true
+ fullWidth: true
+ avatarHeight: Nheko.avatarSize / 2
+ avatarWidth: Nheko.avatarSize / 2
+ centerRowContent: false
+ rowMargin: 2
+ rowSpacing: 2
+ }
+
+ MatrixTextField {
+ id: roomEntry
+
+ width: parent.width
+
+ placeholderText: qsTr("Enter additional rooms not in the list yet...")
+
+ //font.pixelSize: Math.ceil(quickSwitcher.textHeight * 0.6)
+ color: Nheko.colors.text
+ onTextEdited: {
+ roomCompleter.completer.searchString = text;
+ }
+ Keys.onPressed: {
+ if (event.key == Qt.Key_Up || event.key == Qt.Key_Backtab) {
+ event.accepted = true;
+ roomCompleter.up();
+ } else if (event.key == Qt.Key_Down || event.key == Qt.Key_Tab) {
+ event.accepted = true;
+ if (event.key == Qt.Key_Tab && (event.modifiers & Qt.ShiftModifier))
+ roomCompleter.up();
+ else
+ roomCompleter.down();
+ } else if (event.matches(StandardKey.InsertParagraphSeparator)) {
+ roomCompleter.finishCompletion();
+ event.accepted = true;
+ }
+ }
+ }
+
+ }
+
+ Connections {
+ function onCompletionSelected(id) {
+ console.log("selected: " + id);
+ roomSettings.allowedRoomsModel.addRoom(id);
+ roomEntry.clear();
+ }
+
+ function onCountChanged() {
+ if (roomCompleter.count > 0 && (roomCompleter.currentIndex < 0 || roomCompleter.currentIndex >= roomCompleter.count))
+ roomCompleter.currentIndex = 0;
+
+ }
+
+ target: roomCompleter
+ }
+
+ }
+
+ footer: DialogButtonBox {
+ id: dbb
+
+ standardButtons: DialogButtonBox.Ok | DialogButtonBox.Cancel
+ onAccepted: {
+ roomSettings.applyAllowedFromModel();
+ allowedDialog.close();
+ }
+ onRejected: allowedDialog.close()
+ }
+
+}
diff --git a/resources/qml/dialogs/RoomSettings.qml b/resources/qml/dialogs/RoomSettings.qml
index 137df6c4..33a6f6fa 100644
--- a/resources/qml/dialogs/RoomSettings.qml
+++ b/resources/qml/dialogs/RoomSettings.qml
@@ -288,32 +288,98 @@ ApplicationWindow {
}
Label {
- text: qsTr("Room access")
+ text: qsTr("Anyone can join")
Layout.fillWidth: true
color: Nheko.colors.text
}
- ComboBox {
+ ToggleButton {
+ id: publicRoomButton
+
enabled: roomSettings.canChangeJoinRules
- model: {
- let opts = [qsTr("Anyone and guests"), qsTr("Anyone"), qsTr("Invited users")];
- if (roomSettings.supportsKnocking)
- opts.push(qsTr("By knocking"));
+ checked: !roomSettings.privateAccess
+ Layout.alignment: Qt.AlignRight
+ }
- if (roomSettings.supportsRestricted)
- opts.push(qsTr("Restricted by membership in other rooms"));
-
- if (roomSettings.supportsKnockRestricted)
- opts.push(qsTr("Restricted by membership in other rooms or by knocking"));
-
- return opts;
- }
- currentIndex: roomSettings.accessJoinRules
- onActivated: {
- roomSettings.changeAccessRules(index);
- }
+ Label {
+ text: qsTr("Allow knocking")
+ Layout.fillWidth: true
+ color: Nheko.colors.text
+ visible: knockingButton.visible
+ }
+
+ ToggleButton {
+ id: knockingButton
+
+ visible: !publicRoomButton.checked
+ enabled: roomSettings.canChangeJoinRules && roomSettings.supportsKnocking
+ checked: roomSettings.knockingEnabled
+ onCheckedChanged: {
+ if (checked && !roomSettings.supportsKnockRestricted) restrictedButton.checked = false;
+ }
+ Layout.alignment: Qt.AlignRight
+ }
+
+ Label {
+ text: qsTr("Allow joining via other rooms")
+ Layout.fillWidth: true
+ color: Nheko.colors.text
+ visible: restrictedButton.visible
+ }
+
+ ToggleButton {
+ id: restrictedButton
+
+ visible: !publicRoomButton.checked
+ enabled: roomSettings.canChangeJoinRules && roomSettings.supportsRestricted
+ checked: roomSettings.restrictedEnabled
+ onCheckedChanged: {
+ if (checked && !roomSettings.supportsKnockRestricted) knockingButton.checked = false;
+ }
+ Layout.alignment: Qt.AlignRight
+ }
+
+ Label {
+ text: qsTr("Rooms to join via")
+ Layout.fillWidth: true
+ color: Nheko.colors.text
+ visible: allowedRoomsButton.visible
+ }
+
+ Button {
+ id: allowedRoomsButton
+
+ visible: restrictedButton.checked && restrictedButton.visible
+ enabled: roomSettings.canChangeJoinRules && roomSettings.supportsRestricted
+
+ text: qsTr("Change")
+ ToolTip.text: qsTr("Change the list of rooms users can join this room via. Usually this is the official community of this room.")
+ onClicked: timelineRoot.showAllowedRoomsEditor(roomSettings)
+ Layout.alignment: Qt.AlignRight
+ }
+
+ Label {
+ text: qsTr("Allow guests to join")
+ Layout.fillWidth: true
+ color: Nheko.colors.text
+ }
+
+ ToggleButton {
+ id: guestAccessButton
+
+ enabled: roomSettings.canChangeJoinRules
+ checked: roomSettings.guestAccess
+ Layout.alignment: Qt.AlignRight
+ }
+
+ Button {
+ visible: publicRoomButton.checked == roomSettings.privateAccess || knockingButton.checked != roomSettings.knockingEnabled || restrictedButton.checked != roomSettings.restrictedEnabled || guestAccessButton.checked != roomSettings.guestAccess || roomSettings.allowedRoomsModified
+ enabled: roomSettings.canChangeJoinRules
+
+ text: qsTr("Apply access rules")
+ onClicked: roomSettings.changeAccessRules(!publicRoomButton.checked, guestAccessButton.checked, knockingButton.checked, restrictedButton.checked)
+ Layout.columnSpan: 2
Layout.fillWidth: true
- WheelHandler{} // suppress scrolling changing values
}
Label {
diff --git a/resources/res.qrc b/resources/res.qrc
index c14ebd5f..27d9c081 100644
--- a/resources/res.qrc
+++ b/resources/res.qrc
@@ -166,6 +166,7 @@
qml/dialogs/ReadReceipts.qml
qml/dialogs/RoomDirectory.qml
qml/dialogs/RoomMembers.qml
+ qml/dialogs/AllowedRoomsSettingsDialog.qml
qml/dialogs/RoomSettings.qml
qml/dialogs/UserProfile.qml
qml/emoji/EmojiPicker.qml
diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
index 5b850999..63cf2844 100644
--- a/src/MainWindow.cpp
+++ b/src/MainWindow.cpp
@@ -148,6 +148,7 @@ MainWindow::registerQmlTypes()
qRegisterMetaType();
qRegisterMetaType();
qRegisterMetaType();
+ qRegisterMetaType();
qRegisterMetaType();
qRegisterMetaType>();
diff --git a/src/ui/RoomSettings.cpp b/src/ui/RoomSettings.cpp
index 2d124e1e..31ae863e 100644
--- a/src/ui/RoomSettings.cpp
+++ b/src/ui/RoomSettings.cpp
@@ -27,6 +27,7 @@ RoomSettings::RoomSettings(QString roomid, QObject *parent)
: QObject(parent)
, roomid_{std::move(roomid)}
{
+ connect(this, &RoomSettings::accessJoinRulesChanged, &RoomSettings::allowedRoomsChanged);
retrieveRoomInfo();
// get room setting notifications
@@ -66,22 +67,15 @@ RoomSettings::RoomSettings(QString roomid, QObject *parent)
});
// access rules
- if (info_.join_rule == state::JoinRule::Public) {
- if (info_.guest_access) {
- accessRules_ = 0;
- } else {
- accessRules_ = 1;
- }
- } else if (info_.join_rule == state::JoinRule::Invite) {
- accessRules_ = 2;
- } else if (info_.join_rule == state::JoinRule::Knock) {
- accessRules_ = 3;
- } else if (info_.join_rule == state::JoinRule::Restricted) {
- accessRules_ = 4;
- } else if (info_.join_rule == state::JoinRule::KnockRestricted) {
- accessRules_ = 5;
- }
+ this->accessRules_ = cache::client()
+ ->getStateEvent(roomid_.toStdString())
+ .value_or(mtx::events::StateEvent{})
+ .content;
+ using mtx::events::state::AccessState;
+ guestRules_ = info_.guest_access ? AccessState::CanJoin : AccessState::Forbidden;
emit accessJoinRulesChanged();
+
+ this->allowedRoomsModel = new RoomSettingsAllowedRoomsModel(this);
}
QString
@@ -158,10 +152,49 @@ RoomSettings::notifications()
return notifications_;
}
-int
-RoomSettings::accessJoinRules()
+bool
+RoomSettings::privateAccess() const
{
- return accessRules_;
+ return accessRules_.join_rule != mtx::events::state::JoinRule::Public;
+}
+
+bool
+RoomSettings::guestAccess() const
+{
+ return guestRules_ == mtx::events::state::AccessState::CanJoin;
+}
+bool
+RoomSettings::knockingEnabled() const
+{
+ return accessRules_.join_rule == mtx::events::state::JoinRule::Knock ||
+ accessRules_.join_rule == mtx::events::state::JoinRule::KnockRestricted;
+}
+bool
+RoomSettings::restrictedEnabled() const
+{
+ return accessRules_.join_rule == mtx::events::state::JoinRule::Restricted ||
+ accessRules_.join_rule == mtx::events::state::JoinRule::KnockRestricted;
+}
+
+QStringList
+RoomSettings::allowedRooms() const
+{
+ QStringList rooms;
+ rooms.reserve(accessRules_.allow.size());
+ for (const auto &e : accessRules_.allow) {
+ if (e.type == mtx::events::state::JoinAllowanceType::RoomMembership)
+ rooms.push_back(QString::fromStdString(e.room_id));
+ }
+ return rooms;
+}
+void
+RoomSettings::setAllowedRooms(QStringList rooms)
+{
+ accessRules_.allow.clear();
+ for (const auto &e : rooms) {
+ accessRules_.allow.push_back(
+ {mtx::events::state::JoinAllowanceType::RoomMembership, e.toStdString()});
+ }
}
void
@@ -254,24 +287,48 @@ RoomSettings::isEncryptionEnabled() const
bool
RoomSettings::supportsKnocking() const
{
- return info_.version != "" && info_.version != "1" && info_.version != "2" &&
- info_.version != "3" && info_.version != "4" && info_.version != "5" &&
- info_.version != "6";
+ const static std::set unsupported{
+ "",
+ "1",
+ "2",
+ "3",
+ "4",
+ "5",
+ "6",
+ };
+ return !unsupported.count(info_.version);
}
bool
RoomSettings::supportsRestricted() const
{
- return info_.version != "" && info_.version != "1" && info_.version != "2" &&
- info_.version != "3" && info_.version != "4" && info_.version != "5" &&
- info_.version != "6" && info_.version != "7";
+ const static std::set unsupported{
+ "",
+ "1",
+ "2",
+ "3",
+ "4",
+ "5",
+ "6",
+ "7",
+ };
+ return !unsupported.count(info_.version);
}
bool
RoomSettings::supportsKnockRestricted() const
{
- return info_.version != "" && info_.version != "1" && info_.version != "2" &&
- info_.version != "3" && info_.version != "4" && info_.version != "5" &&
- info_.version != "6" && info_.version != "7" && info_.version != "8" &&
- info_.version != "9";
+ const static std::set unsupported{
+ "",
+ "1",
+ "2",
+ "3",
+ "4",
+ "5",
+ "6",
+ "7",
+ "8",
+ "9",
+ };
+ return !unsupported.count(info_.version);
}
void
@@ -327,47 +384,41 @@ RoomSettings::changeNotifications(int currentIndex)
}
void
-RoomSettings::changeAccessRules(int index)
+RoomSettings::changeAccessRules(bool private_,
+ bool guestsAllowed,
+ bool knockingAllowed,
+ bool restrictedAllowed)
{
using namespace mtx::events::state;
- auto guest_access = [](int index) -> state::GuestAccess {
+ auto guest_access = [guestsAllowed]() -> state::GuestAccess {
state::GuestAccess event;
- if (index == 0)
+ if (guestsAllowed)
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;
+ auto join_rule = [this, private_, knockingAllowed, restrictedAllowed]() -> state::JoinRules {
+ state::JoinRules event = this->accessRules_;
- switch (index) {
- case 0:
- case 1:
+ if (!private_) {
event.join_rule = state::JoinRule::Public;
- break;
- case 2:
- event.join_rule = state::JoinRule::Invite;
- break;
- case 3:
- event.join_rule = state::JoinRule::Knock;
- break;
- case 4:
- event.join_rule = state::JoinRule::Restricted;
- break;
- case 5:
+ } else if (knockingAllowed && restrictedAllowed && supportsKnockRestricted()) {
event.join_rule = state::JoinRule::KnockRestricted;
- break;
- default:
+ } else if (knockingAllowed && supportsKnocking()) {
+ event.join_rule = state::JoinRule::Knock;
+ } else if (restrictedAllowed && supportsRestricted()) {
+ event.join_rule = state::JoinRule::Restricted;
+ } else {
event.join_rule = state::JoinRule::Invite;
}
return event;
- }(index);
+ }();
updateAccessRules(roomid_.toStdString(), join_rule, guest_access);
}
@@ -445,13 +496,16 @@ RoomSettings::updateAccessRules(const std::string &room_id,
const mtx::events::state::JoinRules &join_rule,
const mtx::events::state::GuestAccess &guest_access)
{
- isLoading_ = true;
+ isLoading_ = true;
+ allowedRoomsModified_ = false;
emit loadingChanged();
+ emit allowedRoomsModifiedChanged();
http::client()->send_state_event(
room_id,
join_rule,
- [this, room_id, guest_access](const mtx::responses::EventId &, mtx::http::RequestErr err) {
+ [this, room_id, guest_access, join_rule](const mtx::responses::EventId &,
+ mtx::http::RequestErr err) {
if (err) {
nhlog::net()->warn("failed to send m.room.join_rule: {} {}",
static_cast(err->status_code),
@@ -465,7 +519,7 @@ RoomSettings::updateAccessRules(const std::string &room_id,
http::client()->send_state_event(
room_id,
guest_access,
- [this](const mtx::responses::EventId &, mtx::http::RequestErr err) {
+ [this, join_rule](const mtx::responses::EventId &, mtx::http::RequestErr err) {
if (err) {
nhlog::net()->warn("failed to send m.room.guest_access: {} {}",
static_cast(err->status_code),
@@ -475,6 +529,9 @@ RoomSettings::updateAccessRules(const std::string &room_id,
isLoading_ = false;
emit loadingChanged();
+
+ this->accessRules_ = join_rule;
+ emit accessJoinRulesChanged();
});
});
}
@@ -576,3 +633,101 @@ RoomSettings::updateAvatar()
});
});
}
+
+RoomSettingsAllowedRoomsModel::RoomSettingsAllowedRoomsModel(RoomSettings *parent)
+ : QAbstractListModel(parent)
+ , settings(parent)
+{
+ this->allowedRoomIds = settings->allowedRooms();
+
+ auto prIds = cache::client()->getParentRoomIds(settings->roomId().toStdString());
+ for (const auto &prId : prIds) {
+ this->parentSpaces.insert(QString::fromStdString(prId));
+ }
+
+ this->listedRoomIds = QStringList(parentSpaces.begin(), parentSpaces.end());
+
+ for (const auto &e : this->allowedRoomIds) {
+ if (!this->parentSpaces.count(e))
+ this->listedRoomIds.push_back(e);
+ }
+}
+
+QHash
+RoomSettingsAllowedRoomsModel::roleNames() const
+{
+ return {
+ {Roles::Name, "name"},
+ {Roles::IsAllowed, "allowed"},
+ {Roles::IsSpaceParent, "isParent"},
+ };
+}
+
+int
+RoomSettingsAllowedRoomsModel::rowCount(const QModelIndex &) const
+{
+ return listedRoomIds.size();
+}
+
+QVariant
+RoomSettingsAllowedRoomsModel::data(const QModelIndex &index, int role) const
+{
+ if (index.row() < 0 || index.row() > listedRoomIds.size())
+ return {};
+
+ if (role == Roles::IsAllowed) {
+ return allowedRoomIds.contains(listedRoomIds.at(index.row()));
+ } else if (role == Roles::IsSpaceParent) {
+ return parentSpaces.find(listedRoomIds.at(index.row())) != parentSpaces.cend();
+ } else if (role == Roles::Name) {
+ auto id = listedRoomIds.at(index.row());
+ auto info = cache::client()->getRoomInfo({
+ id.toStdString(),
+ });
+ if (!info.empty())
+ return QString::fromStdString(info[id].name);
+ else
+ return "";
+ } else {
+ return {};
+ }
+}
+
+bool
+RoomSettingsAllowedRoomsModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ if (index.row() < 0 || index.row() > listedRoomIds.size())
+ return false;
+
+ if (role != Roles::IsAllowed)
+ return false;
+
+ if (value.toBool()) {
+ if (!allowedRoomIds.contains(listedRoomIds.at(index.row())))
+ allowedRoomIds.push_back(listedRoomIds.at(index.row()));
+ } else {
+ allowedRoomIds.removeAll(listedRoomIds.at(index.row()));
+ }
+
+ return true;
+}
+
+void
+RoomSettingsAllowedRoomsModel::addRoom(QString room)
+{
+ if (listedRoomIds.contains(room) || !room.startsWith('!'))
+ return;
+
+ beginInsertRows(QModelIndex(), listedRoomIds.size(), listedRoomIds.size());
+ listedRoomIds.push_back(room);
+ allowedRoomIds.push_back(room);
+ endInsertRows();
+}
+
+void
+RoomSettings::applyAllowedFromModel()
+{
+ this->setAllowedRooms(this->allowedRoomsModel->allowedRoomIds);
+ this->allowedRoomsModified_ = true;
+ emit allowedRoomsModifiedChanged();
+}
diff --git a/src/ui/RoomSettings.h b/src/ui/RoomSettings.h
index 4cb5bcf4..35698310 100644
--- a/src/ui/RoomSettings.h
+++ b/src/ui/RoomSettings.h
@@ -5,10 +5,13 @@
#pragma once
+#include
#include
#include
#include
+#include
+
#include
#include
@@ -27,6 +30,43 @@ signals:
void stopLoading();
};
+class RoomSettings;
+
+class RoomSettingsAllowedRoomsModel : public QAbstractListModel
+{
+ Q_OBJECT
+
+public:
+ enum Roles
+ {
+ Name,
+ IsAllowed,
+ IsSpaceParent,
+ };
+
+ explicit RoomSettingsAllowedRoomsModel(RoomSettings *parent);
+
+ QHash roleNames() const override;
+ int rowCount(const QModelIndex &) const override;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ bool
+ setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole) override;
+ Q_INVOKABLE void addRoom(QString room);
+
+ Qt::ItemFlags flags(const QModelIndex &) const override
+ {
+ return Qt::ItemIsEditable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled |
+ Qt::ItemNeverHasChildren;
+ }
+
+ QStringList allowedRoomIds;
+
+private:
+ QStringList listedRoomIds;
+ std::unordered_set parentSpaces;
+ RoomSettings *settings;
+};
+
class RoomSettings : public QObject
{
Q_OBJECT
@@ -39,7 +79,10 @@ class RoomSettings : public QObject
Q_PROPERTY(QString roomAvatarUrl READ roomAvatarUrl NOTIFY avatarUrlChanged)
Q_PROPERTY(int memberCount READ memberCount CONSTANT)
Q_PROPERTY(int notifications READ notifications NOTIFY notificationsChanged)
- Q_PROPERTY(int accessJoinRules READ accessJoinRules NOTIFY accessJoinRulesChanged)
+ Q_PROPERTY(bool privateAccess READ privateAccess NOTIFY accessJoinRulesChanged)
+ Q_PROPERTY(bool guestAccess READ guestAccess NOTIFY accessJoinRulesChanged)
+ Q_PROPERTY(bool knockingEnabled READ knockingEnabled NOTIFY accessJoinRulesChanged)
+ Q_PROPERTY(bool restrictedEnabled READ restrictedEnabled NOTIFY accessJoinRulesChanged)
Q_PROPERTY(bool isLoading READ isLoading NOTIFY loadingChanged)
Q_PROPERTY(bool canChangeAvatar READ canChangeAvatar CONSTANT)
Q_PROPERTY(bool canChangeJoinRules READ canChangeJoinRules CONSTANT)
@@ -49,6 +92,11 @@ class RoomSettings : public QObject
Q_PROPERTY(bool supportsKnocking READ supportsKnocking CONSTANT)
Q_PROPERTY(bool supportsRestricted READ supportsRestricted CONSTANT)
Q_PROPERTY(bool supportsKnockRestricted READ supportsKnockRestricted CONSTANT)
+ Q_PROPERTY(
+ QStringList allowedRooms READ allowedRooms WRITE setAllowedRooms NOTIFY allowedRoomsChanged)
+ Q_PROPERTY(RoomSettingsAllowedRoomsModel *allowedRoomsModel MEMBER allowedRoomsModel CONSTANT)
+ Q_PROPERTY(
+ bool allowedRoomsModified READ allowedRoomsModified NOTIFY allowedRoomsModifiedChanged)
public:
RoomSettings(QString roomid, QObject *parent = nullptr);
@@ -62,7 +110,10 @@ public:
QString roomAvatarUrl();
int memberCount() const;
int notifications();
- int accessJoinRules();
+ bool privateAccess() const;
+ bool guestAccess() const;
+ bool knockingEnabled() const;
+ bool restrictedEnabled() const;
bool isLoading() const;
//! Whether the user has enough power level to send m.room.join_rules events.
bool canChangeJoinRules() const;
@@ -76,14 +127,22 @@ public:
bool supportsKnocking() const;
bool supportsRestricted() const;
bool supportsKnockRestricted() const;
+ QStringList allowedRooms() const;
+ void setAllowedRooms(QStringList rooms);
+ bool allowedRoomsModified() const { return allowedRoomsModified_; }
Q_INVOKABLE void enableEncryption();
Q_INVOKABLE void updateAvatar();
- Q_INVOKABLE void changeAccessRules(int index);
+ Q_INVOKABLE void changeAccessRules(bool private_,
+ bool guestsAllowed,
+ bool knockingAllowed,
+ bool restrictedAllowed);
Q_INVOKABLE void changeNotifications(int currentIndex);
Q_INVOKABLE void changeTopic(QString topic);
Q_INVOKABLE void changeName(QString name);
+ Q_INVOKABLE void applyAllowedFromModel();
+
signals:
void loadingChanged();
void roomNameChanged();
@@ -92,7 +151,9 @@ signals:
void encryptionChanged();
void notificationsChanged();
void accessJoinRulesChanged();
+ void allowedRoomsChanged();
void displayError(const QString &errorMessage);
+ void allowedRoomsModifiedChanged();
public slots:
void stopLoading();
@@ -106,9 +167,14 @@ private:
private:
QString roomid_;
- bool usesEncryption_ = false;
- bool isLoading_ = false;
+ bool usesEncryption_ = false;
+ bool isLoading_ = false;
+ bool allowedRoomsModified_ = false;
RoomInfo info_;
int notifications_ = 0;
- int accessRules_ = 0;
+
+ mtx::events::state::JoinRules accessRules_;
+ mtx::events::state::AccessState guestRules_ = mtx::events::state::AccessState::Forbidden;
+
+ RoomSettingsAllowedRoomsModel *allowedRoomsModel;
};