Port remaining room settings to FormCard

This commit is contained in:
Tobias Fella
2023-09-02 11:42:38 +00:00
parent 43ecd188f1
commit 48f7e06c01
3 changed files with 746 additions and 818 deletions

View File

@@ -8,358 +8,333 @@ import QtQuick.Layouts 1.15
import QtQuick.Window 2.15
import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
import org.kde.kirigamiaddons.formcard 1.0 as FormCard
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0
Kirigami.ScrollablePage {
FormCard.FormCardPage {
id: root
property NeoChatRoom room
title: i18n("General")
topPadding: 0
leftPadding: 0
rightPadding: 0
ColumnLayout {
spacing: 0
MobileForm.FormHeader {
Layout.fillWidth: true
title: i18n("Room Information")
FormCard.FormHeader {
title: i18n("Room Information")
}
FormCard.FormCard {
FormCard.AbstractFormDelegate {
background: null
contentItem: RowLayout {
Item {
Layout.fillWidth: true
}
KirigamiComponents.Avatar {
id: avatar
Layout.alignment: Qt.AlignRight
name: room.name
source: room.avatarMediaId ? ("image://mxc/" + room.avatarMediaId) : ""
implicitWidth: Kirigami.Units.iconSizes.medium
implicitHeight: Kirigami.Units.iconSizes.medium
}
QQC2.Button {
Layout.alignment: Qt.AlignLeft
enabled: room.canSendState("m.room.avatar")
visible: enabled
icon.name: "cloud-upload"
text: i18n("Update avatar")
display: QQC2.AbstractButton.IconOnly
onClicked: {
const fileDialog = openFileDialog.createObject(QQC2.ApplicationWindow.overlay)
fileDialog.chosen.connect(function(path) {
if (!path) return
room.changeAvatar(path)
})
fileDialog.open()
}
QQC2.ToolTip.text: text
QQC2.ToolTip.visible: hovered
}
Item {
Layout.fillWidth: true
}
}
}
MobileForm.FormCard {
Layout.fillWidth: true
FormCard.FormTextFieldDelegate {
id: roomNameField
label: i18n("Room name:")
text: room.name
enabled: room.canSendState("m.room.name")
}
FormCard.AbstractFormDelegate {
id: roomTopicField
enabled: room.canSendState("m.room.topic")
background: Item {}
contentItem: ColumnLayout {
spacing: 0
MobileForm.AbstractFormDelegate {
QQC2.Label {
id: roomTopicLabel
text: i18n("Room topic:")
Layout.fillWidth: true
background: Item {}
contentItem: RowLayout {
Item {
Layout.fillWidth: true
}
QQC2.TextArea {
Accessible.description: roomTopicLabel.text
Layout.fillWidth: true
text: room.topic
onTextChanged: roomTopicField.text = text
}
}
}
FormCard.AbstractFormDelegate {
background: Item {}
contentItem: RowLayout {
Item {
Layout.fillWidth: true
}
QQC2.Button {
Layout.bottomMargin: Kirigami.Units.smallSpacing
Layout.topMargin: Kirigami.Units.smallSpacing
enabled: room.name !== roomNameField.text || room.topic !== roomTopicField.text
text: i18n("Save")
onClicked: {
if (room.name != roomNameField.text) {
room.setName(roomNameField.text)
}
KirigamiComponents.Avatar {
id: avatar
Layout.alignment: Qt.AlignRight
name: room.name
source: room.avatarMediaId ? ("image://mxc/" + room.avatarMediaId) : ""
implicitWidth: Kirigami.Units.iconSizes.medium
implicitHeight: Kirigami.Units.iconSizes.medium
}
QQC2.Button {
Layout.alignment: Qt.AlignLeft
enabled: room.canSendState("m.room.avatar")
visible: enabled
icon.name: "cloud-upload"
text: i18n("Update avatar")
display: QQC2.AbstractButton.IconOnly
onClicked: {
const fileDialog = openFileDialog.createObject(QQC2.ApplicationWindow.overlay)
fileDialog.chosen.connect(function(path) {
if (!path) return
room.changeAvatar(path)
})
fileDialog.open()
}
QQC2.ToolTip.text: text
QQC2.ToolTip.visible: hovered
}
Item {
Layout.fillWidth: true
if (room.topic != roomTopicField.text) {
room.setTopic(roomTopicField.text)
}
}
}
MobileForm.FormTextFieldDelegate {
id: roomNameField
label: i18n("Room name:")
text: room.name
enabled: room.canSendState("m.room.name")
}
}
FormCard.FormTextDelegate {
id: roomIdDelegate
text: i18n("Room ID")
description: room.id
contentItem.children: QQC2.Button {
visible: roomIdDelegate.hovered
text: i18n("Copy room ID to clipboard")
icon.name: "edit-copy"
display: QQC2.AbstractButton.IconOnly
onClicked: {
Clipboard.saveText(room.id)
}
MobileForm.AbstractFormDelegate {
id: roomTopicField
Layout.fillWidth: true
enabled: room.canSendState("m.room.topic")
background: Item {}
contentItem: ColumnLayout {
QQC2.Label {
id: roomTopicLabel
text: i18n("Room topic:")
Layout.fillWidth: true
}
QQC2.TextArea {
Accessible.description: roomTopicLabel.text
Layout.fillWidth: true
text: room.topic
onTextChanged: roomTopicField.text = text
}
QQC2.ToolTip.text: text
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
QQC2.ToolTip.visible: hovered
}
}
FormCard.FormTextDelegate {
text: i18n("Room version")
description: room.version
contentItem.children: QQC2.Button {
visible: room.canSwitchVersions()
enabled: room.version < room.maxRoomVersion
text: i18n("Upgrade Room")
icon.name: "arrow-up-double"
onClicked: {
if (room.canSwitchVersions()) {
roomUpgradeSheet.currentRoomVersion = room.version
roomUpgradeSheet.open()
}
}
MobileForm.AbstractFormDelegate {
Layout.fillWidth: true
background: Item {}
contentItem: RowLayout {
Item {
Layout.fillWidth: true
}
QQC2.Button {
Layout.bottomMargin: Kirigami.Units.smallSpacing
Layout.topMargin: Kirigami.Units.smallSpacing
enabled: room.name !== roomNameField.text || room.topic !== roomTopicField.text
text: i18n("Save")
onClicked: {
if (room.name != roomNameField.text) {
room.setName(roomNameField.text)
}
if (room.topic != roomTopicField.text) {
room.setTopic(roomTopicField.text)
}
}
}
}
QQC2.ToolTip {
text: text
delay: Kirigami.Units.toolTipDelay
}
MobileForm.FormTextDelegate {
id: roomIdDelegate
text: i18n("Room ID")
description: room.id
}
}
}
contentItem.children: QQC2.Button {
visible: roomIdDelegate.hovered
text: i18n("Copy room ID to clipboard")
icon.name: "edit-copy"
FormCard.FormHeader {
title: i18n("Aliases")
}
FormCard.FormCard {
FormCard.FormTextDelegate {
visible: room.aliases.length <= 0
text: i18n("No canonical alias set")
}
Repeater {
id: altAliasRepeater
model: room.aliases.slice().reverse()
delegate: FormCard.FormTextDelegate {
text: modelData
description: room.canonicalAlias.length > 0 && modelData === room.canonicalAlias ? "Canonical alias" : ""
contentItem.children: [
QQC2.ToolButton {
id: setCanonicalAliasButton
visible: modelData !== room.canonicalAlias && room.canSendState("m.room.canonical_alias")
text: i18n("Make this alias the room's canonical alias")
icon.name: "checkmark"
display: QQC2.AbstractButton.IconOnly
onClicked: {
Clipboard.saveText(room.id)
room.setCanonicalAlias(modelData)
}
QQC2.ToolTip.text: text
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
QQC2.ToolTip.visible: hovered
}
}
MobileForm.FormTextDelegate {
text: i18n("Room version")
description: room.version
contentItem.children: QQC2.Button {
visible: room.canSwitchVersions()
enabled: room.version < room.maxRoomVersion
text: i18n("Upgrade Room")
icon.name: "arrow-up-double"
QQC2.ToolTip {
text: setCanonicalAliasButton.text
delay: Kirigami.Units.toolTipDelay
}
},
QQC2.ToolButton {
id: deleteButton
visible: room.canSendState("m.room.canonical_alias")
text: i18n("Delete alias")
icon.name: "edit-delete-remove"
display: QQC2.AbstractButton.IconOnly
onClicked: {
if (room.canSwitchVersions()) {
roomUpgradeSheet.currentRoomVersion = room.version
roomUpgradeSheet.open()
}
room.unmapAlias(modelData)
}
QQC2.ToolTip {
text: text
text: deleteButton.text
delay: Kirigami.Units.toolTipDelay
}
}
}
]
}
}
FormCard.AbstractFormDelegate {
visible: room.canSendState("m.room.canonical_alias")
MobileForm.FormHeader {
Layout.fillWidth: true
title: i18n("Aliases")
}
MobileForm.FormCard {
Layout.fillWidth: true
contentItem: ColumnLayout {
spacing: 0
MobileForm.FormTextDelegate {
visible: room.aliases.length <= 0
text: i18n("No canonical alias set")
}
Repeater {
id: altAliasRepeater
model: room.aliases.slice().reverse()
contentItem : RowLayout {
Kirigami.ActionTextField {
id: aliasAddField
delegate: MobileForm.FormTextDelegate {
text: modelData
description: room.canonicalAlias.length > 0 && modelData === room.canonicalAlias ? "Canonical alias" : ""
contentItem.children: [
QQC2.ToolButton {
id: setCanonicalAliasButton
visible: modelData !== room.canonicalAlias && room.canSendState("m.room.canonical_alias")
text: i18n("Make this alias the room's canonical alias")
icon.name: "checkmark"
display: QQC2.AbstractButton.IconOnly
onClicked: {
room.setCanonicalAlias(modelData)
}
QQC2.ToolTip {
text: setCanonicalAliasButton.text
delay: Kirigami.Units.toolTipDelay
}
},
QQC2.ToolButton {
id: deleteButton
visible: room.canSendState("m.room.canonical_alias")
text: i18n("Delete alias")
icon.name: "edit-delete-remove"
display: QQC2.AbstractButton.IconOnly
onClicked: {
room.unmapAlias(modelData)
}
QQC2.ToolTip {
text: deleteButton.text
delay: Kirigami.Units.toolTipDelay
}
}
]
}
}
MobileForm.AbstractFormDelegate {
Layout.fillWidth: true
visible: room.canSendState("m.room.canonical_alias")
contentItem : RowLayout {
Kirigami.ActionTextField {
id: aliasAddField
placeholderText: i18n("#new_alias:server.org")
Layout.fillWidth: true
placeholderText: i18n("#new_alias:server.org")
rightActions: Kirigami.Action {
icon.name: "edit-clear"
visible: aliasAddField.text.length > 0
onTriggered: {
aliasAddField.text = ""
}
}
onAccepted: {
room.mapAlias(aliasAddField.text)
}
}
QQC2.Button {
id: addButton
text: i18n("Add new alias")
Accessible.name: text
icon.name: "list-add"
display: QQC2.AbstractButton.IconOnly
onClicked: {
room.mapAlias(aliasAddField.text)
}
QQC2.ToolTip {
text: addButton.text
delay: Kirigami.Units.toolTipDelay
}
rightActions: Kirigami.Action {
icon.name: "edit-clear"
visible: aliasAddField.text.length > 0
onTriggered: {
aliasAddField.text = ""
}
}
}
}
}
MobileForm.FormHeader {
Layout.fillWidth: true
title: i18n("URL Previews")
}
MobileForm.FormCard {
Layout.fillWidth: true
contentItem: ColumnLayout {
spacing: 0
MobileForm.FormCheckDelegate {
text: i18n("Enable URL previews by default for room members")
checked: room.defaultUrlPreviewState
visible: room.canSendState("org.matrix.room.preview_urls")
onToggled: {
room.defaultUrlPreviewState = checked
onAccepted: {
room.mapAlias(aliasAddField.text)
}
}
MobileForm.FormCheckDelegate {
text: i18n("Enable URL previews")
// Most users won't see the above setting so tell them the default.
description: room.defaultUrlPreviewState ? i18n("URL previews are enabled by default in this room") : i18n("URL previews are disabled by default in this room")
checked: room.urlPreviewEnabled
onToggled: {
room.urlPreviewEnabled = checked
}
}
}
}
Kirigami.InlineMessage {
Layout.fillWidth: true
Layout.maximumWidth: Kirigami.Units.gridUnit * 30
Layout.alignment: Qt.AlignHCenter
text: i18n("This room continues another conversation.")
type: Kirigami.MessageType.Information
visible: room.predecessorId && room.connection.room(room.predecessorId)
actions: Kirigami.Action {
text: i18n("See older messages…")
onTriggered: {
RoomManager.enterRoom(Controller.activeConnection.room(room.predecessorId));
root.close();
}
}
}
Kirigami.InlineMessage {
Layout.fillWidth: true
Layout.maximumWidth: Kirigami.Units.gridUnit * 30
Layout.alignment: Qt.AlignHCenter
text: i18n("This room has been replaced.")
type: Kirigami.MessageType.Information
visible: room.successorId && room.connection.room(room.successorId)
actions: Kirigami.Action {
text: i18n("See new room…")
onTriggered: {
RoomManager.enterRoom(Controller.activeConnection.room(room.successorId));
root.close();
}
}
}
Component {
id: openFileDialog
OpenFileDialog {
parentWindow: root.Window.window
}
}
Kirigami.OverlaySheet {
id: roomUpgradeSheet
property var currentRoomVersion
title: i18n("Upgrade the Room")
Kirigami.FormLayout {
QQC2.SpinBox {
id: spinBox
Kirigami.FormData.label: i18n("Select new version")
from: room.version
to: room.maxRoomVersion
value: room.version
}
QQC2.Button {
text: i18n("Confirm")
id: addButton
text: i18n("Add new alias")
Accessible.name: text
icon.name: "list-add"
display: QQC2.AbstractButton.IconOnly
onClicked: {
room.switchVersion(spinBox.value)
roomUpgradeSheet.close()
room.mapAlias(aliasAddField.text)
}
QQC2.ToolTip {
text: addButton.text
delay: Kirigami.Units.toolTipDelay
}
}
}
}
}
FormCard.FormHeader {
title: i18n("URL Previews")
}
FormCard.FormCard {
FormCard.FormCheckDelegate {
text: i18n("Enable URL previews by default for room members")
checked: room.defaultUrlPreviewState
visible: room.canSendState("org.matrix.room.preview_urls")
onToggled: {
room.defaultUrlPreviewState = checked
}
}
FormCard.FormCheckDelegate {
text: i18n("Enable URL previews")
// Most users won't see the above setting so tell them the default.
description: room.defaultUrlPreviewState ? i18n("URL previews are enabled by default in this room") : i18n("URL previews are disabled by default in this room")
checked: room.urlPreviewEnabled
onToggled: {
room.urlPreviewEnabled = checked
}
}
}
Kirigami.InlineMessage {
Layout.maximumWidth: Kirigami.Units.gridUnit * 30
Layout.alignment: Qt.AlignHCenter
text: i18n("This room continues another conversation.")
type: Kirigami.MessageType.Information
visible: room.predecessorId && room.connection.room(room.predecessorId)
actions: Kirigami.Action {
text: i18n("See older messages…")
onTriggered: {
RoomManager.enterRoom(Controller.activeConnection.room(room.predecessorId));
root.close();
}
}
}
Kirigami.InlineMessage {
Layout.maximumWidth: Kirigami.Units.gridUnit * 30
Layout.alignment: Qt.AlignHCenter
text: i18n("This room has been replaced.")
type: Kirigami.MessageType.Information
visible: room.successorId && room.connection.room(room.successorId)
actions: Kirigami.Action {
text: i18n("See new room…")
onTriggered: {
RoomManager.enterRoom(Controller.activeConnection.room(room.successorId));
root.close();
}
}
}
property Component openFileDialog: Component {
id: openFileDialog
OpenFileDialog {
parentWindow: root.Window.window
}
}
property Kirigami.OverlaySheet roomUpgradeSheet: Kirigami.OverlaySheet {
id: roomUpgradeSheet
property var currentRoomVersion
title: i18n("Upgrade the Room")
Kirigami.FormLayout {
QQC2.SpinBox {
id: spinBox
Kirigami.FormData.label: i18n("Select new version")
from: room.version
to: room.maxRoomVersion
value: room.version
}
QQC2.Button {
text: i18n("Confirm")
onClicked: {
room.switchVersion(spinBox.value)
roomUpgradeSheet.close()
}
}
}
}
}

View File

@@ -6,441 +6,414 @@ import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
import org.kde.kirigamiaddons.formcard 1.0 as FormCard
import org.kde.kirigamiaddons.delegates 1.0 as Delegates
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.kitemmodels 1.0
import org.kde.neochat 1.0
Kirigami.ScrollablePage {
FormCard.FormCardPage {
id: root
property NeoChatRoom room
title: i18nc('@title:window', 'Permissions')
topPadding: 0
leftPadding: 0
rightPadding: 0
UserListModel {
property UserListModel userListModel: UserListModel {
id: userListModel
room: root.room
}
ListModel {
property ListModel powerLevelModel: ListModel {
id: powerLevelModel
}
ColumnLayout {
spacing: 0
MobileForm.FormHeader {
Layout.fillWidth: true
title: i18n("Privileged Users")
}
MobileForm.FormCard {
Layout.fillWidth: true
contentItem: ColumnLayout {
spacing: 0
Repeater {
model: KSortFilterProxyModel {
sourceModel: userListModel
sortRole: "powerLevel"
sortOrder: Qt.DescendingOrder
filterRowCallback: function(source_row, source_parent) {
let powerLevelRole = sourceModel.data(sourceModel.index(source_row, 0, source_parent), UserListModel.PowerLevelRole)
return powerLevelRole > 0;
}
}
delegate: MobileForm.FormTextDelegate {
text: name
description: userId
contentItem.children: RowLayout {
spacing: Kirigami.Units.largeSpacing
QQC2.Label {
visible: !room.canSendState("m.room.power_levels")
text: powerLevelString
color: Kirigami.Theme.disabledTextColor
}
QQC2.ComboBox {
focusPolicy: Qt.NoFocus // provided by parent
model: powerLevelModel
textRole: "text"
valueRole: "powerLevel"
visible: room.canSendState("m.room.power_levels")
Component.onCompleted: {
/**
* This is very silly but the only way to populate the model with
* translated strings. Done here because the model needs to be filled
* before the first delegate sets it's current index.
*/
if (powerLevelModel.count == 0) {
powerLevelModel.append({"text": i18n("Member (0)"), "powerLevel": 0});
powerLevelModel.append({"text": i18n("Moderator (50)"), "powerLevel": 50});
powerLevelModel.append({"text": i18n("Admin (100)"), "powerLevel": 100});
}
currentIndex = indexOfValue(powerLevel)
}
onActivated: {
room.setUserPowerLevel(userId, currentValue)
}
}
}
}
FormCard.FormHeader {
title: i18n("Privileged Users")
}
FormCard.FormCard {
Repeater {
model: KSortFilterProxyModel {
sourceModel: userListModel
sortRoleName: "powerLevel"
sortOrder: Qt.DescendingOrder
filterRowCallback: function(source_row, source_parent) {
let powerLevelRole = sourceModel.data(sourceModel.index(source_row, 0, source_parent), UserListModel.PowerLevelRole)
return powerLevelRole > 0;
}
MobileForm.FormDelegateSeparator { below: userListSearchCard }
MobileForm.AbstractFormDelegate {
id: userListSearchCard
Layout.fillWidth: true
visible: room.canSendState("m.room.power_levels")
contentItem: Kirigami.SearchField {
id: userListSearchField
autoAccept: false
Layout.fillWidth: true
Keys.onUpPressed: userListView.decrementCurrentIndex()
Keys.onDownPressed: userListView.incrementCurrentIndex()
onAccepted: {
let currentUser = userListView.itemAtIndex(userListView.currentIndex);
currentUser.action.trigger();
}
}
delegate: FormCard.FormTextDelegate {
text: name
description: userId
contentItem.children: RowLayout {
spacing: Kirigami.Units.largeSpacing
QQC2.Label {
visible: !room.canSendState("m.room.power_levels")
text: powerLevelString
color: Kirigami.Theme.disabledTextColor
}
QQC2.Popup {
id: userListSearchPopup
x: userListSearchField.x
y: userListSearchField.y - height
width: userListSearchField.width
height: {
let maxHeight = userListSearchField.mapToGlobal(userListSearchField.x, userListSearchField.y).y - Kirigami.Units.largeSpacing * 3;
let minHeight = Kirigami.Units.gridUnit * 2 + userListSearchPopup.padding * 2;
let filterContentHeight = userListView.contentHeight + userListSearchPopup.padding * 2;
return Math.max(Math.min(filterContentHeight, maxHeight), minHeight);
QQC2.ComboBox {
focusPolicy: Qt.NoFocus // provided by parent
model: powerLevelModel
textRole: "text"
valueRole: "powerLevel"
visible: room.canSendState("m.room.power_levels")
Component.onCompleted: {
/**
* This is very silly but the only way to populate the model with
* translated strings. Done here because the model needs to be filled
* before the first delegate sets it's current index.
*/
if (powerLevelModel.count == 0) {
powerLevelModel.append({"text": i18n("Member (0)"), "powerLevel": 0});
powerLevelModel.append({"text": i18n("Moderator (50)"), "powerLevel": 50});
powerLevelModel.append({"text": i18n("Admin (100)"), "powerLevel": 100});
}
currentIndex = indexOfValue(powerLevel)
}
padding: Kirigami.Units.smallSpacing
leftPadding: Kirigami.Units.smallSpacing / 2
rightPadding: Kirigami.Units.smallSpacing / 2
modal: false
onClosed: userListSearchField.text = ""
background: Kirigami.ShadowedRectangle {
property color borderColor: Kirigami.Theme.textColor
Kirigami.Theme.colorSet: Kirigami.Theme.View
Kirigami.Theme.inherit: false
radius: 4
color: Kirigami.Theme.backgroundColor
border {
color: Qt.rgba(borderColor.r, borderColor.g, borderColor.b, 0.3)
width: 1
}
shadow {
xOffset: 0
yOffset: 4
color: Qt.rgba(0, 0, 0, 0.3)
size: 8
}
}
contentItem: QQC2.ScrollView {
// HACK: Hide unnecessary horizontal scrollbar (https://bugreports.qt.io/browse/QTBUG-83890)
QQC2.ScrollBar.horizontal.policy: QQC2.ScrollBar.AlwaysOff
ListView {
id: userListView
clip: true
model: UserFilterModel {
id: userListFilterModel
sourceModel: userListModel
filterText: userListSearchField.text
onFilterTextChanged: {
if (filterText.length > 0 && !userListSearchPopup.visible) {
userListSearchPopup.open()
} else if (filterText.length <= 0 && userListSearchPopup.visible) {
userListSearchPopup.close()
}
}
}
delegate: Delegates.RoundedItemDelegate {
id: userListItem
required property string userId
required property string avatar
required property string name
required property int powerLevel
required property string powerLevelString
text: name
contentItem: RowLayout {
KirigamiComponents.Avatar {
Layout.preferredWidth: Kirigami.Units.iconSizes.medium
Layout.preferredHeight: Kirigami.Units.iconSizes.medium
source: userListItem.avatar ? ("image://" + userListItem.avatar) : ""
name: userListItem.name
}
Delegates.SubtitleContentItem {
itemDelegate: userListItem
subtitle: userListItem.userId
labelItem.textFormat: Text.PlainText
subtitleItem.textFormat: Text.PlainText
Layout.fillWidth: true
}
QQC2.Label {
visible: userListItem.powerLevel > 0
text: userListItem.powerLevelString
color: Kirigami.Theme.disabledTextColor
textFormat: Text.PlainText
wrapMode: Text.NoWrap
}
}
action: Kirigami.Action {
id: editPowerLevelAction
onTriggered: {
userListSearchPopup.close()
let dialog = powerLevelDialog.createObject(applicationWindow().overlay, {
room: root.room,
userId: userListItem.userId,
powerLevel: userListItem.powerLevel
});
dialog.open();
}
}
Component {
id: powerLevelDialog
PowerLevelDialog {
id: powerLevelDialog
}
}
}
}
onActivated: {
room.setUserPowerLevel(userId, currentValue)
}
}
}
}
}
FormCard.FormDelegateSeparator { below: userListSearchCard }
FormCard.AbstractFormDelegate {
id: userListSearchCard
visible: room.canSendState("m.room.power_levels")
MobileForm.FormHeader {
Layout.fillWidth: true
visible: room.canSendState("m.room.power_levels")
title: i18n("Default permissions")
}
MobileForm.FormCard {
Layout.fillWidth: true
visible: room.canSendState("m.room.power_levels")
contentItem: ColumnLayout {
spacing: 0
MobileForm.FormComboBoxDelegate {
text: i18n("Default user power level")
description: i18n("This is power level for all new users when joining the room")
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.defaultUserPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.defaultUserPowerLevel = currentValue
}
MobileForm.FormComboBoxDelegate {
text: i18n("Default power level to set the room state")
description: i18n("This is used for all state events that do not have their own entry here")
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.statePowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.statePowerLevel = currentValue
}
MobileForm.FormComboBoxDelegate {
text: i18n("Default power level to send messages")
description: i18n("This is used for all message events that do not have their own entry here")
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.defaultEventPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.defaultEventPowerLevel = currentValue
contentItem: Kirigami.SearchField {
id: userListSearchField
autoAccept: false
Layout.fillWidth: true
Keys.onUpPressed: userListView.decrementCurrentIndex()
Keys.onDownPressed: userListView.incrementCurrentIndex()
onAccepted: {
let currentUser = userListView.itemAtIndex(userListView.currentIndex);
currentUser.action.trigger();
}
}
}
QQC2.Popup {
id: userListSearchPopup
MobileForm.FormHeader {
Layout.fillWidth: true
visible: room.canSendState("m.room.power_levels")
title: i18n("Basic permissions")
}
MobileForm.FormCard {
Layout.fillWidth: true
visible: room.canSendState("m.room.power_levels")
contentItem: ColumnLayout {
spacing: 0
MobileForm.FormComboBoxDelegate {
text: i18n("Invite users")
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.invitePowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.invitePowerLevel = currentValue
}
MobileForm.FormComboBoxDelegate {
text: i18n("Kick users")
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.kickPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.kickPowerLevel = currentValue
}
MobileForm.FormComboBoxDelegate {
text: i18n("Ban users")
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.banPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.banPowerLevel = currentValue
}
MobileForm.FormComboBoxDelegate {
text: i18n("Remove message sent by other users")
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.redactPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.redactPowerLevel = currentValue
}
}
}
x: userListSearchField.x
y: userListSearchField.y - height
width: userListSearchField.width
height: {
let maxHeight = userListSearchField.mapToGlobal(userListSearchField.x, userListSearchField.y).y - Kirigami.Units.largeSpacing * 3;
let minHeight = Kirigami.Units.gridUnit * 2 + userListSearchPopup.padding * 2;
let filterContentHeight = userListView.contentHeight + userListSearchPopup.padding * 2;
MobileForm.FormHeader {
Layout.fillWidth: true
visible: room.canSendState("m.room.power_levels")
title: i18n("Event permissions")
}
MobileForm.FormCard {
Layout.fillWidth: true
visible: room.canSendState("m.room.power_levels")
contentItem: ColumnLayout {
spacing: 0
MobileForm.FormComboBoxDelegate {
text: i18n("Change user permissions")
description: "m.room.power_levels"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.powerLevelPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.powerLevelPowerLevel = currentValue
return Math.max(Math.min(filterContentHeight, maxHeight), minHeight);
}
MobileForm.FormComboBoxDelegate {
text: i18n("Change the room name")
description: "m.room.name"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.namePowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.namePowerLevel = currentValue
padding: Kirigami.Units.smallSpacing
leftPadding: Kirigami.Units.smallSpacing / 2
rightPadding: Kirigami.Units.smallSpacing / 2
modal: false
onClosed: userListSearchField.text = ""
background: Kirigami.ShadowedRectangle {
property color borderColor: Kirigami.Theme.textColor
Kirigami.Theme.colorSet: Kirigami.Theme.View
Kirigami.Theme.inherit: false
radius: 4
color: Kirigami.Theme.backgroundColor
border {
color: Qt.rgba(borderColor.r, borderColor.g, borderColor.b, 0.3)
width: 1
}
shadow {
xOffset: 0
yOffset: 4
color: Qt.rgba(0, 0, 0, 0.3)
size: 8
}
}
MobileForm.FormComboBoxDelegate {
text: i18n("Change the room avatar")
description: "m.room.avatar"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.avatarPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.avatarPowerLevel = currentValue
}
MobileForm.FormComboBoxDelegate {
text: i18n("Change the room canonical alias")
description: "m.room.canonical_alias"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.canonicalAliasPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.canonicalAliasPowerLevel = currentValue
}
MobileForm.FormComboBoxDelegate {
text: i18n("Change the room topic")
description: "m.room.topic"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.topicPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.topicPowerLevel = currentValue
}
MobileForm.FormComboBoxDelegate {
text: i18n("Enable encryption for the room")
description: "m.room.encryption"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.encryptionPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.encryptionPowerLevel = currentValue
}
MobileForm.FormComboBoxDelegate {
text: i18n("Change the room history visibility")
description: "m.room.history_visibility"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.historyVisibilityPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.historyVisibilityPowerLevel = currentValue
}
MobileForm.FormComboBoxDelegate {
text: i18n("Set pinned events")
description: "m.room.pinned_events"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.pinnedEventsPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.pinnedEventsPowerLevel = currentValue
}
MobileForm.FormComboBoxDelegate {
text: i18n("Upgrade the room")
description: "m.room.tombstone"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.tombstonePowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.tombstonePowerLevel = currentValue
}
MobileForm.FormComboBoxDelegate {
text: i18n("Set the room server access control list (ACL)")
description: "m.room.server_acl"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.serverAclPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.serverAclPowerLevel = currentValue
}
MobileForm.FormComboBoxDelegate {
visible: room.isSpace
text: i18n("Set the children of this space")
description: "m.space.child"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.spaceChildPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.spaceChildPowerLevel = currentValue
}
MobileForm.FormComboBoxDelegate {
text: i18n("Set the parent space of this room")
description: "m.space.parent"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.spaceChildPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.spaceParentPowerLevel = currentValue
contentItem: QQC2.ScrollView {
// HACK: Hide unnecessary horizontal scrollbar (https://bugreports.qt.io/browse/QTBUG-83890)
QQC2.ScrollBar.horizontal.policy: QQC2.ScrollBar.AlwaysOff
ListView {
id: userListView
clip: true
model: UserFilterModel {
id: userListFilterModel
sourceModel: userListModel
filterText: userListSearchField.text
onFilterTextChanged: {
if (filterText.length > 0 && !userListSearchPopup.visible) {
userListSearchPopup.open()
} else if (filterText.length <= 0 && userListSearchPopup.visible) {
userListSearchPopup.close()
}
}
}
delegate: Delegates.RoundedItemDelegate {
id: userListItem
required property string userId
required property string avatar
required property string name
required property int powerLevel
required property string powerLevelString
text: name
contentItem: RowLayout {
KirigamiComponents.Avatar {
Layout.preferredWidth: Kirigami.Units.iconSizes.medium
Layout.preferredHeight: Kirigami.Units.iconSizes.medium
source: userListItem.avatar ? ("image://" + userListItem.avatar) : ""
name: userListItem.name
}
Delegates.SubtitleContentItem {
itemDelegate: userListItem
subtitle: userListItem.userId
labelItem.textFormat: Text.PlainText
subtitleItem.textFormat: Text.PlainText
Layout.fillWidth: true
}
QQC2.Label {
visible: userListItem.powerLevel > 0
text: userListItem.powerLevelString
color: Kirigami.Theme.disabledTextColor
textFormat: Text.PlainText
wrapMode: Text.NoWrap
}
}
action: Kirigami.Action {
id: editPowerLevelAction
onTriggered: {
userListSearchPopup.close()
let dialog = powerLevelDialog.createObject(applicationWindow().overlay, {
room: root.room,
userId: userListItem.userId,
powerLevel: userListItem.powerLevel
});
dialog.open();
}
}
Component {
id: powerLevelDialog
PowerLevelDialog {
id: powerLevelDialog
}
}
}
}
}
}
}
}
FormCard.FormHeader {
visible: room.canSendState("m.room.power_levels")
title: i18n("Default permissions")
}
FormCard.FormCard {
visible: room.canSendState("m.room.power_levels")
FormCard.FormComboBoxDelegate {
text: i18n("Default user power level")
description: i18n("This is power level for all new users when joining the room")
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.defaultUserPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.defaultUserPowerLevel = currentValue
}
FormCard.FormComboBoxDelegate {
text: i18n("Default power level to set the room state")
description: i18n("This is used for all state events that do not have their own entry here")
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.statePowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.statePowerLevel = currentValue
}
FormCard.FormComboBoxDelegate {
text: i18n("Default power level to send messages")
description: i18n("This is used for all message events that do not have their own entry here")
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.defaultEventPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.defaultEventPowerLevel = currentValue
}
}
FormCard.FormHeader {
visible: room.canSendState("m.room.power_levels")
title: i18n("Basic permissions")
}
FormCard.FormCard {
visible: room.canSendState("m.room.power_levels")
FormCard.FormComboBoxDelegate {
text: i18n("Invite users")
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.invitePowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.invitePowerLevel = currentValue
}
FormCard.FormComboBoxDelegate {
text: i18n("Kick users")
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.kickPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.kickPowerLevel = currentValue
}
FormCard.FormComboBoxDelegate {
text: i18n("Ban users")
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.banPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.banPowerLevel = currentValue
}
FormCard.FormComboBoxDelegate {
text: i18n("Remove message sent by other users")
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.redactPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.redactPowerLevel = currentValue
}
}
FormCard.FormHeader {
visible: room.canSendState("m.room.power_levels")
title: i18n("Event permissions")
}
FormCard.FormCard {
visible: room.canSendState("m.room.power_levels")
FormCard.FormComboBoxDelegate {
text: i18n("Change user permissions")
description: "m.room.power_levels"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.powerLevelPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.powerLevelPowerLevel = currentValue
}
FormCard.FormComboBoxDelegate {
text: i18n("Change the room name")
description: "m.room.name"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.namePowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.namePowerLevel = currentValue
}
FormCard.FormComboBoxDelegate {
text: i18n("Change the room avatar")
description: "m.room.avatar"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.avatarPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.avatarPowerLevel = currentValue
}
FormCard.FormComboBoxDelegate {
text: i18n("Change the room canonical alias")
description: "m.room.canonical_alias"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.canonicalAliasPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.canonicalAliasPowerLevel = currentValue
}
FormCard.FormComboBoxDelegate {
text: i18n("Change the room topic")
description: "m.room.topic"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.topicPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.topicPowerLevel = currentValue
}
FormCard.FormComboBoxDelegate {
text: i18n("Enable encryption for the room")
description: "m.room.encryption"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.encryptionPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.encryptionPowerLevel = currentValue
}
FormCard.FormComboBoxDelegate {
text: i18n("Change the room history visibility")
description: "m.room.history_visibility"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.historyVisibilityPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.historyVisibilityPowerLevel = currentValue
}
FormCard.FormComboBoxDelegate {
text: i18n("Set pinned events")
description: "m.room.pinned_events"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.pinnedEventsPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.pinnedEventsPowerLevel = currentValue
}
FormCard.FormComboBoxDelegate {
text: i18n("Upgrade the room")
description: "m.room.tombstone"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.tombstonePowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.tombstonePowerLevel = currentValue
}
FormCard.FormComboBoxDelegate {
text: i18n("Set the room server access control list (ACL)")
description: "m.room.server_acl"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.serverAclPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.serverAclPowerLevel = currentValue
}
FormCard.FormComboBoxDelegate {
visible: room.isSpace
text: i18n("Set the children of this space")
description: "m.space.child"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.spaceChildPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.spaceChildPowerLevel = currentValue
}
FormCard.FormComboBoxDelegate {
text: i18n("Set the parent space of this room")
description: "m.space.parent"
textRole: "text"
valueRole: "powerLevel"
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.spaceChildPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.spaceParentPowerLevel = currentValue
}
}
}

View File

@@ -6,138 +6,118 @@ import QtQuick 2.15
import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
import org.kde.kirigamiaddons.formcard 1.0 as FormCard
import org.kde.neochat 1.0
Kirigami.ScrollablePage {
FormCard.FormCardPage {
id: root
property NeoChatRoom room
property string needUpgradeRoom: i18n("You need to upgrade this room to a newer version to enable this setting.")
title: i18n("Security")
topPadding: 0
leftPadding: 0
rightPadding: 0
ColumnLayout {
spacing: 0
MobileForm.FormHeader {
Layout.fillWidth: true
title: i18nc("@option:check", "Encryption")
}
MobileForm.FormCard {
Layout.fillWidth: true
contentItem: ColumnLayout {
spacing: 0
MobileForm.FormSwitchDelegate {
id: enableEncryptionSwitch
text: i18n("Enable encryption")
description: i18nc("option:check", "Once enabled, encryption cannot be disabled.")
enabled: room.canEncryptRoom
checked: room.usesEncryption
onToggled: if (checked) {
let dialog = confirmEncryptionDialog.createObject(applicationWindow(), {room: room});
dialog.open();
}
}
FormCard.FormHeader {
title: i18nc("@option:check", "Encryption")
}
FormCard.FormCard {
FormCard.FormSwitchDelegate {
id: enableEncryptionSwitch
text: i18n("Enable encryption")
description: i18nc("option:check", "Once enabled, encryption cannot be disabled.")
enabled: room.canEncryptRoom
checked: room.usesEncryption
onToggled: if (checked) {
let dialog = confirmEncryptionDialog.createObject(applicationWindow(), {room: room});
dialog.open();
}
}
}
MobileForm.FormHeader {
Layout.fillWidth: true
title: i18nc("@option:check", "Access")
}
MobileForm.FormCard {
Layout.fillWidth: true
contentItem: ColumnLayout {
spacing: 0
MobileForm.FormRadioDelegate {
text: i18nc("@option:check", "Private (invite only)")
description: i18n("Only invited people can join.")
checked: room.joinRule === "invite"
enabled: room.canSendState("m.room.join_rules")
onCheckedChanged: if (checked) {
room.joinRule = "invite";
}
}
MobileForm.FormRadioDelegate {
text: i18nc("@option:check", "Space members")
description: i18n("Anyone in a space can find and join.") +
(!["8", "9", "10"].includes(room.version) ? `\n${needUpgradeRoom}` : "")
checked: room.joinRule === "restricted"
enabled: room.canSendState("m.room.join_rules") && ["8", "9", "10"].includes(room.version) && false
onCheckedChanged: if (checked) {
room.joinRule = "restricted";
}
}
MobileForm.FormRadioDelegate {
text: i18nc("@option:check", "Knock")
description: i18n("People not in the room need to request an invite to join the room.") +
(!["7", "8", "9", "10"].includes(room.version) ? `\n${needUpgradeRoom}` : "")
checked: room.joinRule === "knock"
// https://spec.matrix.org/v1.4/rooms/#feature-matrix
enabled: room.canSendState("m.room.join_rules") && ["7", "8", "9", "10"].includes(room.version)
onCheckedChanged: if (checked) {
room.joinRule = "knock";
}
}
MobileForm.FormRadioDelegate {
text: i18nc("@option:check", "Public")
description: i18nc("@option:check", "Anyone can find and join.")
checked: room.joinRule === "public"
enabled: room.canSendState("m.room.join_rules")
onCheckedChanged: if (checked) {
room.joinRule = "public";
}
}
FormCard.FormHeader {
title: i18nc("@option:check", "Access")
}
FormCard.FormCard {
FormCard.FormRadioDelegate {
text: i18nc("@option:check", "Private (invite only)")
description: i18n("Only invited people can join.")
checked: room.joinRule === "invite"
enabled: room.canSendState("m.room.join_rules")
onCheckedChanged: if (checked) {
room.joinRule = "invite";
}
}
MobileForm.FormHeader {
Layout.fillWidth: true
title: i18nc("@option:check", "Message history visibility")
FormCard.FormRadioDelegate {
text: i18nc("@option:check", "Space members")
description: i18n("Anyone in a space can find and join.") +
(!["8", "9", "10"].includes(room.version) ? `\n${needUpgradeRoom}` : "")
checked: room.joinRule === "restricted"
enabled: room.canSendState("m.room.join_rules") && ["8", "9", "10"].includes(room.version) && false
onCheckedChanged: if (checked) {
room.joinRule = "restricted";
}
}
MobileForm.FormCard {
Layout.fillWidth: true
contentItem: ColumnLayout {
spacing: 0
MobileForm.FormRadioDelegate {
text: i18nc("@option:check", "Anyone")
description: i18nc("@option:check", "Anyone, regardless of whether they have joined, can view history.")
checked: room.historyVisibility === "world_readable"
enabled: room.canSendState("m.room.history_visibility")
onCheckedChanged: if (checked) {
room.historyVisibility = "world_readable"
}
}
MobileForm.FormRadioDelegate {
text: i18nc("@option:check", "Members only")
description: i18nc("@option:check", "All members can view the entire message history, even before they joined.")
checked: room.historyVisibility === "shared"
enabled: room.canSendState("m.room.history_visibility")
onCheckedChanged: if (checked) {
room.historyVisibility = "shared"
}
}
MobileForm.FormRadioDelegate {
text: i18nc("@option:check", "Members only (since invite)")
description: i18nc("@option:check", "New members can view the message history from the point they were invited to the room.")
checked: room.historyVisibility === "invited"
enabled: room.canSendState("m.room.history_visibility")
onCheckedChanged: if (checked) {
room.historyVisibility = "invited"
}
}
MobileForm.FormRadioDelegate {
text: i18nc("@option:check", "Members only (since joining)")
description: i18nc("@option:check", "New members can view the message history from the point they joined the room.")
checked: room.historyVisibility === "joined"
enabled: room.canSendState("m.room.history_visibility")
onCheckedChanged: if (checked) {
room.historyVisibility = "joined"
}
}
FormCard.FormRadioDelegate {
text: i18nc("@option:check", "Knock")
description: i18n("People not in the room need to request an invite to join the room.") +
(!["7", "8", "9", "10"].includes(room.version) ? `\n${needUpgradeRoom}` : "")
checked: room.joinRule === "knock"
// https://spec.matrix.org/v1.4/rooms/#feature-matrix
enabled: room.canSendState("m.room.join_rules") && ["7", "8", "9", "10"].includes(room.version)
onCheckedChanged: if (checked) {
room.joinRule = "knock";
}
}
FormCard.FormRadioDelegate {
text: i18nc("@option:check", "Public")
description: i18nc("@option:check", "Anyone can find and join.")
checked: room.joinRule === "public"
enabled: room.canSendState("m.room.join_rules")
onCheckedChanged: if (checked) {
room.joinRule = "public";
}
}
}
FormCard.FormHeader {
title: i18nc("@option:check", "Message history visibility")
}
FormCard.FormCard {
FormCard.FormRadioDelegate {
text: i18nc("@option:check", "Anyone")
description: i18nc("@option:check", "Anyone, regardless of whether they have joined, can view history.")
checked: room.historyVisibility === "world_readable"
enabled: room.canSendState("m.room.history_visibility")
onCheckedChanged: if (checked) {
room.historyVisibility = "world_readable"
}
}
FormCard.FormRadioDelegate {
text: i18nc("@option:check", "Members only")
description: i18nc("@option:check", "All members can view the entire message history, even before they joined.")
checked: room.historyVisibility === "shared"
enabled: room.canSendState("m.room.history_visibility")
onCheckedChanged: if (checked) {
room.historyVisibility = "shared"
}
}
FormCard.FormRadioDelegate {
text: i18nc("@option:check", "Members only (since invite)")
description: i18nc("@option:check", "New members can view the message history from the point they were invited to the room.")
checked: room.historyVisibility === "invited"
enabled: room.canSendState("m.room.history_visibility")
onCheckedChanged: if (checked) {
room.historyVisibility = "invited"
}
}
FormCard.FormRadioDelegate {
text: i18nc("@option:check", "Members only (since joining)")
description: i18nc("@option:check", "New members can view the message history from the point they joined the room.")
checked: room.historyVisibility === "joined"
enabled: room.canSendState("m.room.history_visibility")
onCheckedChanged: if (checked) {
room.historyVisibility = "joined"
}
}
}
@@ -155,7 +135,7 @@ Kirigami.ScrollablePage {
}
}
Component {
property Component confirmEncryptionDialog: Component {
id: confirmEncryptionDialog
ConfirmEncryptionDialog {
@@ -168,7 +148,7 @@ Kirigami.ScrollablePage {
}
}
Connections {
property Connections connections: Connections {
target: room
onEncryption: {
enableEncryptionSwitch.checked = room.usesEncryption