From fe403ddc709801262d0848b991691ae6c1d7123d Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Mon, 19 Sep 2022 21:39:37 +0200 Subject: [PATCH] Rework how access rules for rooms are modified completely --- resources/qml/Root.qml | 16 ++ .../dialogs/AllowedRoomsSettingsDialog.qml | 178 ++++++++++++ resources/qml/dialogs/RoomSettings.qml | 104 +++++-- resources/res.qrc | 1 + src/MainWindow.cpp | 1 + src/ui/RoomSettings.cpp | 263 ++++++++++++++---- src/ui/RoomSettings.h | 78 +++++- 7 files changed, 562 insertions(+), 79 deletions(-) create mode 100644 resources/qml/dialogs/AllowedRoomsSettingsDialog.qml 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; };