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 {
|
Component {
|
||||||
id: roomMembersComponent
|
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 {
|
Label {
|
||||||
text: qsTr("Room access")
|
text: qsTr("Anyone can join")
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
color: Nheko.colors.text
|
color: Nheko.colors.text
|
||||||
}
|
}
|
||||||
|
|
||||||
ComboBox {
|
ToggleButton {
|
||||||
|
id: publicRoomButton
|
||||||
|
|
||||||
enabled: roomSettings.canChangeJoinRules
|
enabled: roomSettings.canChangeJoinRules
|
||||||
model: {
|
checked: !roomSettings.privateAccess
|
||||||
let opts = [qsTr("Anyone and guests"), qsTr("Anyone"), qsTr("Invited users")];
|
Layout.alignment: Qt.AlignRight
|
||||||
if (roomSettings.supportsKnocking)
|
}
|
||||||
opts.push(qsTr("By knocking"));
|
|
||||||
|
|
||||||
if (roomSettings.supportsRestricted)
|
Label {
|
||||||
opts.push(qsTr("Restricted by membership in other rooms"));
|
text: qsTr("Allow knocking")
|
||||||
|
Layout.fillWidth: true
|
||||||
if (roomSettings.supportsKnockRestricted)
|
color: Nheko.colors.text
|
||||||
opts.push(qsTr("Restricted by membership in other rooms or by knocking"));
|
visible: knockingButton.visible
|
||||||
|
}
|
||||||
return opts;
|
|
||||||
}
|
ToggleButton {
|
||||||
currentIndex: roomSettings.accessJoinRules
|
id: knockingButton
|
||||||
onActivated: {
|
|
||||||
roomSettings.changeAccessRules(index);
|
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
|
Layout.fillWidth: true
|
||||||
WheelHandler{} // suppress scrolling changing values
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
|
|
|
@ -166,6 +166,7 @@
|
||||||
<file>qml/dialogs/ReadReceipts.qml</file>
|
<file>qml/dialogs/ReadReceipts.qml</file>
|
||||||
<file>qml/dialogs/RoomDirectory.qml</file>
|
<file>qml/dialogs/RoomDirectory.qml</file>
|
||||||
<file>qml/dialogs/RoomMembers.qml</file>
|
<file>qml/dialogs/RoomMembers.qml</file>
|
||||||
|
<file>qml/dialogs/AllowedRoomsSettingsDialog.qml</file>
|
||||||
<file>qml/dialogs/RoomSettings.qml</file>
|
<file>qml/dialogs/RoomSettings.qml</file>
|
||||||
<file>qml/dialogs/UserProfile.qml</file>
|
<file>qml/dialogs/UserProfile.qml</file>
|
||||||
<file>qml/emoji/EmojiPicker.qml</file>
|
<file>qml/emoji/EmojiPicker.qml</file>
|
||||||
|
|
|
@ -148,6 +148,7 @@ MainWindow::registerQmlTypes()
|
||||||
qRegisterMetaType<mtx::responses::PublicRoom>();
|
qRegisterMetaType<mtx::responses::PublicRoom>();
|
||||||
qRegisterMetaType<mtx::responses::Profile>();
|
qRegisterMetaType<mtx::responses::Profile>();
|
||||||
qRegisterMetaType<CombinedImagePackModel *>();
|
qRegisterMetaType<CombinedImagePackModel *>();
|
||||||
|
qRegisterMetaType<RoomSettingsAllowedRoomsModel *>();
|
||||||
qRegisterMetaType<mtx::events::collections::TimelineEvents>();
|
qRegisterMetaType<mtx::events::collections::TimelineEvents>();
|
||||||
qRegisterMetaType<std::vector<DeviceInfo>>();
|
qRegisterMetaType<std::vector<DeviceInfo>>();
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ RoomSettings::RoomSettings(QString roomid, QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, roomid_{std::move(roomid)}
|
, roomid_{std::move(roomid)}
|
||||||
{
|
{
|
||||||
|
connect(this, &RoomSettings::accessJoinRulesChanged, &RoomSettings::allowedRoomsChanged);
|
||||||
retrieveRoomInfo();
|
retrieveRoomInfo();
|
||||||
|
|
||||||
// get room setting notifications
|
// get room setting notifications
|
||||||
|
@ -66,22 +67,15 @@ RoomSettings::RoomSettings(QString roomid, QObject *parent)
|
||||||
});
|
});
|
||||||
|
|
||||||
// access rules
|
// access rules
|
||||||
if (info_.join_rule == state::JoinRule::Public) {
|
this->accessRules_ = cache::client()
|
||||||
if (info_.guest_access) {
|
->getStateEvent<mtx::events::state::JoinRules>(roomid_.toStdString())
|
||||||
accessRules_ = 0;
|
.value_or(mtx::events::StateEvent<mtx::events::state::JoinRules>{})
|
||||||
} else {
|
.content;
|
||||||
accessRules_ = 1;
|
using mtx::events::state::AccessState;
|
||||||
}
|
guestRules_ = info_.guest_access ? AccessState::CanJoin : AccessState::Forbidden;
|
||||||
} 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;
|
|
||||||
}
|
|
||||||
emit accessJoinRulesChanged();
|
emit accessJoinRulesChanged();
|
||||||
|
|
||||||
|
this->allowedRoomsModel = new RoomSettingsAllowedRoomsModel(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString
|
||||||
|
@ -158,10 +152,49 @@ RoomSettings::notifications()
|
||||||
return notifications_;
|
return notifications_;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
bool
|
||||||
RoomSettings::accessJoinRules()
|
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
|
void
|
||||||
|
@ -254,24 +287,48 @@ RoomSettings::isEncryptionEnabled() const
|
||||||
bool
|
bool
|
||||||
RoomSettings::supportsKnocking() const
|
RoomSettings::supportsKnocking() const
|
||||||
{
|
{
|
||||||
return info_.version != "" && info_.version != "1" && info_.version != "2" &&
|
const static std::set<std::string_view> unsupported{
|
||||||
info_.version != "3" && info_.version != "4" && info_.version != "5" &&
|
"",
|
||||||
info_.version != "6";
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
"4",
|
||||||
|
"5",
|
||||||
|
"6",
|
||||||
|
};
|
||||||
|
return !unsupported.count(info_.version);
|
||||||
}
|
}
|
||||||
bool
|
bool
|
||||||
RoomSettings::supportsRestricted() const
|
RoomSettings::supportsRestricted() const
|
||||||
{
|
{
|
||||||
return info_.version != "" && info_.version != "1" && info_.version != "2" &&
|
const static std::set<std::string_view> unsupported{
|
||||||
info_.version != "3" && info_.version != "4" && info_.version != "5" &&
|
"",
|
||||||
info_.version != "6" && info_.version != "7";
|
"1",
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
"4",
|
||||||
|
"5",
|
||||||
|
"6",
|
||||||
|
"7",
|
||||||
|
};
|
||||||
|
return !unsupported.count(info_.version);
|
||||||
}
|
}
|
||||||
bool
|
bool
|
||||||
RoomSettings::supportsKnockRestricted() const
|
RoomSettings::supportsKnockRestricted() const
|
||||||
{
|
{
|
||||||
return info_.version != "" && info_.version != "1" && info_.version != "2" &&
|
const static std::set<std::string_view> unsupported{
|
||||||
info_.version != "3" && info_.version != "4" && info_.version != "5" &&
|
"",
|
||||||
info_.version != "6" && info_.version != "7" && info_.version != "8" &&
|
"1",
|
||||||
info_.version != "9";
|
"2",
|
||||||
|
"3",
|
||||||
|
"4",
|
||||||
|
"5",
|
||||||
|
"6",
|
||||||
|
"7",
|
||||||
|
"8",
|
||||||
|
"9",
|
||||||
|
};
|
||||||
|
return !unsupported.count(info_.version);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -327,47 +384,41 @@ RoomSettings::changeNotifications(int currentIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
RoomSettings::changeAccessRules(int index)
|
RoomSettings::changeAccessRules(bool private_,
|
||||||
|
bool guestsAllowed,
|
||||||
|
bool knockingAllowed,
|
||||||
|
bool restrictedAllowed)
|
||||||
{
|
{
|
||||||
using namespace mtx::events::state;
|
using namespace mtx::events::state;
|
||||||
|
|
||||||
auto guest_access = [](int index) -> state::GuestAccess {
|
auto guest_access = [guestsAllowed]() -> state::GuestAccess {
|
||||||
state::GuestAccess event;
|
state::GuestAccess event;
|
||||||
|
|
||||||
if (index == 0)
|
if (guestsAllowed)
|
||||||
event.guest_access = state::AccessState::CanJoin;
|
event.guest_access = state::AccessState::CanJoin;
|
||||||
else
|
else
|
||||||
event.guest_access = state::AccessState::Forbidden;
|
event.guest_access = state::AccessState::Forbidden;
|
||||||
|
|
||||||
return event;
|
return event;
|
||||||
}(index);
|
}();
|
||||||
|
|
||||||
auto join_rule = [](int index) -> state::JoinRules {
|
auto join_rule = [this, private_, knockingAllowed, restrictedAllowed]() -> state::JoinRules {
|
||||||
state::JoinRules event;
|
state::JoinRules event = this->accessRules_;
|
||||||
|
|
||||||
switch (index) {
|
if (!private_) {
|
||||||
case 0:
|
|
||||||
case 1:
|
|
||||||
event.join_rule = state::JoinRule::Public;
|
event.join_rule = state::JoinRule::Public;
|
||||||
break;
|
} else if (knockingAllowed && restrictedAllowed && supportsKnockRestricted()) {
|
||||||
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:
|
|
||||||
event.join_rule = state::JoinRule::KnockRestricted;
|
event.join_rule = state::JoinRule::KnockRestricted;
|
||||||
break;
|
} else if (knockingAllowed && supportsKnocking()) {
|
||||||
default:
|
event.join_rule = state::JoinRule::Knock;
|
||||||
|
} else if (restrictedAllowed && supportsRestricted()) {
|
||||||
|
event.join_rule = state::JoinRule::Restricted;
|
||||||
|
} else {
|
||||||
event.join_rule = state::JoinRule::Invite;
|
event.join_rule = state::JoinRule::Invite;
|
||||||
}
|
}
|
||||||
|
|
||||||
return event;
|
return event;
|
||||||
}(index);
|
}();
|
||||||
|
|
||||||
updateAccessRules(roomid_.toStdString(), join_rule, guest_access);
|
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::JoinRules &join_rule,
|
||||||
const mtx::events::state::GuestAccess &guest_access)
|
const mtx::events::state::GuestAccess &guest_access)
|
||||||
{
|
{
|
||||||
isLoading_ = true;
|
isLoading_ = true;
|
||||||
|
allowedRoomsModified_ = false;
|
||||||
emit loadingChanged();
|
emit loadingChanged();
|
||||||
|
emit allowedRoomsModifiedChanged();
|
||||||
|
|
||||||
http::client()->send_state_event(
|
http::client()->send_state_event(
|
||||||
room_id,
|
room_id,
|
||||||
join_rule,
|
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) {
|
if (err) {
|
||||||
nhlog::net()->warn("failed to send m.room.join_rule: {} {}",
|
nhlog::net()->warn("failed to send m.room.join_rule: {} {}",
|
||||||
static_cast<int>(err->status_code),
|
static_cast<int>(err->status_code),
|
||||||
|
@ -465,7 +519,7 @@ RoomSettings::updateAccessRules(const std::string &room_id,
|
||||||
http::client()->send_state_event(
|
http::client()->send_state_event(
|
||||||
room_id,
|
room_id,
|
||||||
guest_access,
|
guest_access,
|
||||||
[this](const mtx::responses::EventId &, mtx::http::RequestErr err) {
|
[this, join_rule](const mtx::responses::EventId &, mtx::http::RequestErr err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
nhlog::net()->warn("failed to send m.room.guest_access: {} {}",
|
nhlog::net()->warn("failed to send m.room.guest_access: {} {}",
|
||||||
static_cast<int>(err->status_code),
|
static_cast<int>(err->status_code),
|
||||||
|
@ -475,6 +529,9 @@ RoomSettings::updateAccessRules(const std::string &room_id,
|
||||||
|
|
||||||
isLoading_ = false;
|
isLoading_ = false;
|
||||||
emit loadingChanged();
|
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
|
#pragma once
|
||||||
|
|
||||||
|
#include <QAbstractListModel>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
#include <mtx/events/event_type.hpp>
|
#include <mtx/events/event_type.hpp>
|
||||||
#include <mtx/events/guest_access.hpp>
|
#include <mtx/events/guest_access.hpp>
|
||||||
|
|
||||||
|
@ -27,6 +30,43 @@ signals:
|
||||||
void stopLoading();
|
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
|
class RoomSettings : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -39,7 +79,10 @@ class RoomSettings : public QObject
|
||||||
Q_PROPERTY(QString roomAvatarUrl READ roomAvatarUrl NOTIFY avatarUrlChanged)
|
Q_PROPERTY(QString roomAvatarUrl READ roomAvatarUrl NOTIFY avatarUrlChanged)
|
||||||
Q_PROPERTY(int memberCount READ memberCount CONSTANT)
|
Q_PROPERTY(int memberCount READ memberCount CONSTANT)
|
||||||
Q_PROPERTY(int notifications READ notifications NOTIFY notificationsChanged)
|
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 isLoading READ isLoading NOTIFY loadingChanged)
|
||||||
Q_PROPERTY(bool canChangeAvatar READ canChangeAvatar CONSTANT)
|
Q_PROPERTY(bool canChangeAvatar READ canChangeAvatar CONSTANT)
|
||||||
Q_PROPERTY(bool canChangeJoinRules READ canChangeJoinRules 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 supportsKnocking READ supportsKnocking CONSTANT)
|
||||||
Q_PROPERTY(bool supportsRestricted READ supportsRestricted CONSTANT)
|
Q_PROPERTY(bool supportsRestricted READ supportsRestricted CONSTANT)
|
||||||
Q_PROPERTY(bool supportsKnockRestricted READ supportsKnockRestricted 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:
|
public:
|
||||||
RoomSettings(QString roomid, QObject *parent = nullptr);
|
RoomSettings(QString roomid, QObject *parent = nullptr);
|
||||||
|
@ -62,7 +110,10 @@ public:
|
||||||
QString roomAvatarUrl();
|
QString roomAvatarUrl();
|
||||||
int memberCount() const;
|
int memberCount() const;
|
||||||
int notifications();
|
int notifications();
|
||||||
int accessJoinRules();
|
bool privateAccess() const;
|
||||||
|
bool guestAccess() const;
|
||||||
|
bool knockingEnabled() const;
|
||||||
|
bool restrictedEnabled() const;
|
||||||
bool isLoading() const;
|
bool isLoading() const;
|
||||||
//! Whether the user has enough power level to send m.room.join_rules events.
|
//! Whether the user has enough power level to send m.room.join_rules events.
|
||||||
bool canChangeJoinRules() const;
|
bool canChangeJoinRules() const;
|
||||||
|
@ -76,14 +127,22 @@ public:
|
||||||
bool supportsKnocking() const;
|
bool supportsKnocking() const;
|
||||||
bool supportsRestricted() const;
|
bool supportsRestricted() const;
|
||||||
bool supportsKnockRestricted() const;
|
bool supportsKnockRestricted() const;
|
||||||
|
QStringList allowedRooms() const;
|
||||||
|
void setAllowedRooms(QStringList rooms);
|
||||||
|
bool allowedRoomsModified() const { return allowedRoomsModified_; }
|
||||||
|
|
||||||
Q_INVOKABLE void enableEncryption();
|
Q_INVOKABLE void enableEncryption();
|
||||||
Q_INVOKABLE void updateAvatar();
|
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 changeNotifications(int currentIndex);
|
||||||
Q_INVOKABLE void changeTopic(QString topic);
|
Q_INVOKABLE void changeTopic(QString topic);
|
||||||
Q_INVOKABLE void changeName(QString name);
|
Q_INVOKABLE void changeName(QString name);
|
||||||
|
|
||||||
|
Q_INVOKABLE void applyAllowedFromModel();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void loadingChanged();
|
void loadingChanged();
|
||||||
void roomNameChanged();
|
void roomNameChanged();
|
||||||
|
@ -92,7 +151,9 @@ signals:
|
||||||
void encryptionChanged();
|
void encryptionChanged();
|
||||||
void notificationsChanged();
|
void notificationsChanged();
|
||||||
void accessJoinRulesChanged();
|
void accessJoinRulesChanged();
|
||||||
|
void allowedRoomsChanged();
|
||||||
void displayError(const QString &errorMessage);
|
void displayError(const QString &errorMessage);
|
||||||
|
void allowedRoomsModifiedChanged();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void stopLoading();
|
void stopLoading();
|
||||||
|
@ -106,9 +167,14 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString roomid_;
|
QString roomid_;
|
||||||
bool usesEncryption_ = false;
|
bool usesEncryption_ = false;
|
||||||
bool isLoading_ = false;
|
bool isLoading_ = false;
|
||||||
|
bool allowedRoomsModified_ = false;
|
||||||
RoomInfo info_;
|
RoomInfo info_;
|
||||||
int notifications_ = 0;
|
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