mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 11:00:48 +03:00
Rework how access rules for rooms are modified completely
This commit is contained in:
parent
603b90a6f5
commit
fe403ddc70
7 changed files with 562 additions and 79 deletions
|
@ -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
|
||||
|
||||
|
|
178
resources/qml/dialogs/AllowedRoomsSettingsDialog.qml
Normal file
178
resources/qml/dialogs/AllowedRoomsSettingsDialog.qml
Normal file
|
@ -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()
|
||||
}
|
||||
|
||||
}
|
|
@ -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"));
|
||||
|
||||
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);
|
||||
checked: !roomSettings.privateAccess
|
||||
Layout.alignment: Qt.AlignRight
|
||||
}
|
||||
|
||||
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 {
|
||||
|
|
|
@ -166,6 +166,7 @@
|
|||
<file>qml/dialogs/ReadReceipts.qml</file>
|
||||
<file>qml/dialogs/RoomDirectory.qml</file>
|
||||
<file>qml/dialogs/RoomMembers.qml</file>
|
||||
<file>qml/dialogs/AllowedRoomsSettingsDialog.qml</file>
|
||||
<file>qml/dialogs/RoomSettings.qml</file>
|
||||
<file>qml/dialogs/UserProfile.qml</file>
|
||||
<file>qml/emoji/EmojiPicker.qml</file>
|
||||
|
|
|
@ -148,6 +148,7 @@ MainWindow::registerQmlTypes()
|
|||
qRegisterMetaType<mtx::responses::PublicRoom>();
|
||||
qRegisterMetaType<mtx::responses::Profile>();
|
||||
qRegisterMetaType<CombinedImagePackModel *>();
|
||||
qRegisterMetaType<RoomSettingsAllowedRoomsModel *>();
|
||||
qRegisterMetaType<mtx::events::collections::TimelineEvents>();
|
||||
qRegisterMetaType<std::vector<DeviceInfo>>();
|
||||
|
||||
|
|
|
@ -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<mtx::events::state::JoinRules>(roomid_.toStdString())
|
||||
.value_or(mtx::events::StateEvent<mtx::events::state::JoinRules>{})
|
||||
.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<std::string_view> 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<std::string_view> 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<std::string_view> 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);
|
||||
}
|
||||
|
@ -446,12 +497,15 @@ RoomSettings::updateAccessRules(const std::string &room_id,
|
|||
const mtx::events::state::GuestAccess &guest_access)
|
||||
{
|
||||
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<int>(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<int>(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<int, QByteArray>
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -5,10 +5,13 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QObject>
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
#include <mtx/events/event_type.hpp>
|
||||
#include <mtx/events/guest_access.hpp>
|
||||
|
||||
|
@ -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<int, QByteArray> 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<QString> 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();
|
||||
|
@ -108,7 +169,12 @@ private:
|
|||
QString roomid_;
|
||||
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;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue