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 QtQuick.Window 2.15
import org.kde.kirigami 2.15 as Kirigami 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.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0 import org.kde.neochat 1.0
Kirigami.ScrollablePage { FormCard.FormCardPage {
id: root id: root
property NeoChatRoom room property NeoChatRoom room
title: i18n("General") title: i18n("General")
topPadding: 0
leftPadding: 0 FormCard.FormHeader {
rightPadding: 0 title: i18n("Room Information")
ColumnLayout { }
spacing: 0 FormCard.FormCard {
MobileForm.FormHeader { FormCard.AbstractFormDelegate {
Layout.fillWidth: true background: null
title: i18n("Room Information") 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 { FormCard.FormTextFieldDelegate {
Layout.fillWidth: true 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 { contentItem: ColumnLayout {
spacing: 0 QQC2.Label {
MobileForm.AbstractFormDelegate { id: roomTopicLabel
text: i18n("Room topic:")
Layout.fillWidth: true Layout.fillWidth: true
background: Item {} }
contentItem: RowLayout { QQC2.TextArea {
Item { Accessible.description: roomTopicLabel.text
Layout.fillWidth: true 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: { if (room.topic != roomTopicField.text) {
const fileDialog = openFileDialog.createObject(QQC2.ApplicationWindow.overlay) room.setTopic(roomTopicField.text)
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.FormTextFieldDelegate { }
id: roomNameField }
label: i18n("Room name:") FormCard.FormTextDelegate {
text: room.name id: roomIdDelegate
enabled: room.canSendState("m.room.name") 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 QQC2.ToolTip.text: text
Layout.fillWidth: true QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
enabled: room.canSendState("m.room.topic") QQC2.ToolTip.visible: hovered
background: Item {} }
contentItem: ColumnLayout { }
QQC2.Label { FormCard.FormTextDelegate {
id: roomTopicLabel text: i18n("Room version")
text: i18n("Room topic:") description: room.version
Layout.fillWidth: true
} contentItem.children: QQC2.Button {
QQC2.TextArea { visible: room.canSwitchVersions()
Accessible.description: roomTopicLabel.text enabled: room.version < room.maxRoomVersion
Layout.fillWidth: true text: i18n("Upgrade Room")
text: room.topic icon.name: "arrow-up-double"
onTextChanged: roomTopicField.text = text
} 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) { QQC2.ToolTip {
room.setTopic(roomTopicField.text) text: text
} delay: Kirigami.Units.toolTipDelay
}
}
}
} }
MobileForm.FormTextDelegate { }
id: roomIdDelegate }
text: i18n("Room ID") }
description: room.id
contentItem.children: QQC2.Button { FormCard.FormHeader {
visible: roomIdDelegate.hovered title: i18n("Aliases")
text: i18n("Copy room ID to clipboard") }
icon.name: "edit-copy" 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 display: QQC2.AbstractButton.IconOnly
onClicked: { onClicked: {
Clipboard.saveText(room.id) room.setCanonicalAlias(modelData)
} }
QQC2.ToolTip {
QQC2.ToolTip.text: text text: setCanonicalAliasButton.text
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay delay: Kirigami.Units.toolTipDelay
QQC2.ToolTip.visible: hovered }
} },
} QQC2.ToolButton {
MobileForm.FormTextDelegate { id: deleteButton
text: i18n("Room version") visible: room.canSendState("m.room.canonical_alias")
description: room.version text: i18n("Delete alias")
icon.name: "edit-delete-remove"
contentItem.children: QQC2.Button { display: QQC2.AbstractButton.IconOnly
visible: room.canSwitchVersions()
enabled: room.version < room.maxRoomVersion
text: i18n("Upgrade Room")
icon.name: "arrow-up-double"
onClicked: { onClicked: {
if (room.canSwitchVersions()) { room.unmapAlias(modelData)
roomUpgradeSheet.currentRoomVersion = room.version
roomUpgradeSheet.open()
}
} }
QQC2.ToolTip { QQC2.ToolTip {
text: text text: deleteButton.text
delay: Kirigami.Units.toolTipDelay delay: Kirigami.Units.toolTipDelay
} }
} }
} ]
} }
} }
FormCard.AbstractFormDelegate {
visible: room.canSendState("m.room.canonical_alias")
MobileForm.FormHeader { contentItem : RowLayout {
Layout.fillWidth: true Kirigami.ActionTextField {
title: i18n("Aliases") id: aliasAddField
}
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()
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 Layout.fillWidth: true
visible: room.canSendState("m.room.canonical_alias")
contentItem : RowLayout { placeholderText: i18n("#new_alias:server.org")
Kirigami.ActionTextField {
id: aliasAddField
Layout.fillWidth: true rightActions: Kirigami.Action {
icon.name: "edit-clear"
placeholderText: i18n("#new_alias:server.org") visible: aliasAddField.text.length > 0
onTriggered: {
rightActions: Kirigami.Action { aliasAddField.text = ""
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
}
} }
} }
}
}
}
MobileForm.FormHeader { onAccepted: {
Layout.fillWidth: true room.mapAlias(aliasAddField.text)
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
} }
} }
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 { QQC2.Button {
text: i18n("Confirm") id: addButton
text: i18n("Add new alias")
Accessible.name: text
icon.name: "list-add"
display: QQC2.AbstractButton.IconOnly
onClicked: { onClicked: {
room.switchVersion(spinBox.value) room.mapAlias(aliasAddField.text)
roomUpgradeSheet.close() }
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 QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami 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.delegates 1.0 as Delegates
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.kitemmodels 1.0 import org.kde.kitemmodels 1.0
import org.kde.neochat 1.0 import org.kde.neochat 1.0
Kirigami.ScrollablePage { FormCard.FormCardPage {
id: root id: root
property NeoChatRoom room property NeoChatRoom room
title: i18nc('@title:window', 'Permissions') title: i18nc('@title:window', 'Permissions')
topPadding: 0
leftPadding: 0
rightPadding: 0
UserListModel { property UserListModel userListModel: UserListModel {
id: userListModel id: userListModel
room: root.room room: root.room
} }
ListModel { property ListModel powerLevelModel: ListModel {
id: powerLevelModel id: powerLevelModel
} }
ColumnLayout { FormCard.FormHeader {
spacing: 0 title: i18n("Privileged Users")
MobileForm.FormHeader { }
Layout.fillWidth: true FormCard.FormCard {
title: i18n("Privileged Users") Repeater {
} model: KSortFilterProxyModel {
MobileForm.FormCard { sourceModel: userListModel
Layout.fillWidth: true sortRoleName: "powerLevel"
contentItem: ColumnLayout { sortOrder: Qt.DescendingOrder
spacing: 0 filterRowCallback: function(source_row, source_parent) {
Repeater { let powerLevelRole = sourceModel.data(sourceModel.index(source_row, 0, source_parent), UserListModel.PowerLevelRole)
model: KSortFilterProxyModel { return powerLevelRole > 0;
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)
}
}
}
}
} }
MobileForm.FormDelegateSeparator { below: userListSearchCard } }
MobileForm.AbstractFormDelegate { delegate: FormCard.FormTextDelegate {
id: userListSearchCard text: name
Layout.fillWidth: true description: userId
visible: room.canSendState("m.room.power_levels") contentItem.children: RowLayout {
spacing: Kirigami.Units.largeSpacing
contentItem: Kirigami.SearchField { QQC2.Label {
id: userListSearchField visible: !room.canSendState("m.room.power_levels")
text: powerLevelString
autoAccept: false color: Kirigami.Theme.disabledTextColor
Layout.fillWidth: true
Keys.onUpPressed: userListView.decrementCurrentIndex()
Keys.onDownPressed: userListView.incrementCurrentIndex()
onAccepted: {
let currentUser = userListView.itemAtIndex(userListView.currentIndex);
currentUser.action.trigger();
}
} }
QQC2.Popup { QQC2.ComboBox {
id: userListSearchPopup focusPolicy: Qt.NoFocus // provided by parent
model: powerLevelModel
x: userListSearchField.x textRole: "text"
y: userListSearchField.y - height valueRole: "powerLevel"
width: userListSearchField.width visible: room.canSendState("m.room.power_levels")
height: { Component.onCompleted: {
let maxHeight = userListSearchField.mapToGlobal(userListSearchField.x, userListSearchField.y).y - Kirigami.Units.largeSpacing * 3; /**
let minHeight = Kirigami.Units.gridUnit * 2 + userListSearchPopup.padding * 2; * This is very silly but the only way to populate the model with
let filterContentHeight = userListView.contentHeight + userListSearchPopup.padding * 2; * translated strings. Done here because the model needs to be filled
* before the first delegate sets it's current index.
return Math.max(Math.min(filterContentHeight, maxHeight), minHeight); */
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 onActivated: {
leftPadding: Kirigami.Units.smallSpacing / 2 room.setUserPowerLevel(userId, currentValue)
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
}
}
}
}
} }
} }
} }
} }
} }
FormCard.FormDelegateSeparator { below: userListSearchCard }
FormCard.AbstractFormDelegate {
id: userListSearchCard
visible: room.canSendState("m.room.power_levels")
MobileForm.FormHeader { contentItem: Kirigami.SearchField {
Layout.fillWidth: true id: userListSearchField
visible: room.canSendState("m.room.power_levels")
title: i18n("Default permissions") autoAccept: false
}
MobileForm.FormCard { Layout.fillWidth: true
Layout.fillWidth: true
visible: room.canSendState("m.room.power_levels") Keys.onUpPressed: userListView.decrementCurrentIndex()
contentItem: ColumnLayout { Keys.onDownPressed: userListView.incrementCurrentIndex()
spacing: 0
MobileForm.FormComboBoxDelegate { onAccepted: {
text: i18n("Default user power level") let currentUser = userListView.itemAtIndex(userListView.currentIndex);
description: i18n("This is power level for all new users when joining the room") currentUser.action.trigger();
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
} }
} }
} QQC2.Popup {
id: userListSearchPopup
MobileForm.FormHeader { x: userListSearchField.x
Layout.fillWidth: true y: userListSearchField.y - height
visible: room.canSendState("m.room.power_levels") width: userListSearchField.width
title: i18n("Basic permissions") height: {
} let maxHeight = userListSearchField.mapToGlobal(userListSearchField.x, userListSearchField.y).y - Kirigami.Units.largeSpacing * 3;
MobileForm.FormCard { let minHeight = Kirigami.Units.gridUnit * 2 + userListSearchPopup.padding * 2;
Layout.fillWidth: true let filterContentHeight = userListView.contentHeight + userListSearchPopup.padding * 2;
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
}
}
}
MobileForm.FormHeader { return Math.max(Math.min(filterContentHeight, maxHeight), minHeight);
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
} }
MobileForm.FormComboBoxDelegate { padding: Kirigami.Units.smallSpacing
text: i18n("Change the room name") leftPadding: Kirigami.Units.smallSpacing / 2
description: "m.room.name" rightPadding: Kirigami.Units.smallSpacing / 2
textRole: "text" modal: false
valueRole: "powerLevel" onClosed: userListSearchField.text = ""
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.namePowerLevel) background: Kirigami.ShadowedRectangle {
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.namePowerLevel = currentValue 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") contentItem: QQC2.ScrollView {
description: "m.room.avatar" // HACK: Hide unnecessary horizontal scrollbar (https://bugreports.qt.io/browse/QTBUG-83890)
textRole: "text" QQC2.ScrollBar.horizontal.policy: QQC2.ScrollBar.AlwaysOff
valueRole: "powerLevel"
model: powerLevelModel ListView {
Component.onCompleted: currentIndex = indexOfValue(room.avatarPowerLevel) id: userListView
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.avatarPowerLevel = currentValue clip: true
}
MobileForm.FormComboBoxDelegate { model: UserFilterModel {
text: i18n("Change the room canonical alias") id: userListFilterModel
description: "m.room.canonical_alias" sourceModel: userListModel
textRole: "text" filterText: userListSearchField.text
valueRole: "powerLevel"
model: powerLevelModel onFilterTextChanged: {
Component.onCompleted: currentIndex = indexOfValue(room.canonicalAliasPowerLevel) if (filterText.length > 0 && !userListSearchPopup.visible) {
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.canonicalAliasPowerLevel = currentValue userListSearchPopup.open()
} } else if (filterText.length <= 0 && userListSearchPopup.visible) {
MobileForm.FormComboBoxDelegate { userListSearchPopup.close()
text: i18n("Change the room topic") }
description: "m.room.topic" }
textRole: "text" }
valueRole: "powerLevel"
model: powerLevelModel delegate: Delegates.RoundedItemDelegate {
Component.onCompleted: currentIndex = indexOfValue(room.topicPowerLevel) id: userListItem
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.topicPowerLevel = currentValue
} required property string userId
MobileForm.FormComboBoxDelegate { required property string avatar
text: i18n("Enable encryption for the room") required property string name
description: "m.room.encryption" required property int powerLevel
textRole: "text" required property string powerLevelString
valueRole: "powerLevel"
model: powerLevelModel text: name
Component.onCompleted: currentIndex = indexOfValue(room.encryptionPowerLevel)
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.encryptionPowerLevel = currentValue contentItem: RowLayout {
} KirigamiComponents.Avatar {
MobileForm.FormComboBoxDelegate { Layout.preferredWidth: Kirigami.Units.iconSizes.medium
text: i18n("Change the room history visibility") Layout.preferredHeight: Kirigami.Units.iconSizes.medium
description: "m.room.history_visibility" source: userListItem.avatar ? ("image://" + userListItem.avatar) : ""
textRole: "text" name: userListItem.name
valueRole: "powerLevel" }
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.historyVisibilityPowerLevel) Delegates.SubtitleContentItem {
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.historyVisibilityPowerLevel = currentValue itemDelegate: userListItem
} subtitle: userListItem.userId
MobileForm.FormComboBoxDelegate { labelItem.textFormat: Text.PlainText
text: i18n("Set pinned events") subtitleItem.textFormat: Text.PlainText
description: "m.room.pinned_events" Layout.fillWidth: true
textRole: "text" }
valueRole: "powerLevel"
model: powerLevelModel QQC2.Label {
Component.onCompleted: currentIndex = indexOfValue(room.pinnedEventsPowerLevel) visible: userListItem.powerLevel > 0
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.pinnedEventsPowerLevel = currentValue
} text: userListItem.powerLevelString
MobileForm.FormComboBoxDelegate { color: Kirigami.Theme.disabledTextColor
text: i18n("Upgrade the room") textFormat: Text.PlainText
description: "m.room.tombstone" wrapMode: Text.NoWrap
textRole: "text" }
valueRole: "powerLevel" }
model: powerLevelModel
Component.onCompleted: currentIndex = indexOfValue(room.tombstonePowerLevel) action: Kirigami.Action {
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.tombstonePowerLevel = currentValue id: editPowerLevelAction
} onTriggered: {
MobileForm.FormComboBoxDelegate { userListSearchPopup.close()
text: i18n("Set the room server access control list (ACL)") let dialog = powerLevelDialog.createObject(applicationWindow().overlay, {
description: "m.room.server_acl" room: root.room,
textRole: "text" userId: userListItem.userId,
valueRole: "powerLevel" powerLevel: userListItem.powerLevel
model: powerLevelModel });
Component.onCompleted: currentIndex = indexOfValue(room.serverAclPowerLevel) dialog.open();
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.serverAclPowerLevel = currentValue }
} }
MobileForm.FormComboBoxDelegate {
visible: room.isSpace Component {
text: i18n("Set the children of this space") id: powerLevelDialog
description: "m.space.child" PowerLevelDialog {
textRole: "text" id: powerLevelDialog
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
} }
} }
} }
} }
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.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami 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 import org.kde.neochat 1.0
Kirigami.ScrollablePage { FormCard.FormCardPage {
id: root id: root
property NeoChatRoom room property NeoChatRoom room
property string needUpgradeRoom: i18n("You need to upgrade this room to a newer version to enable this setting.") property string needUpgradeRoom: i18n("You need to upgrade this room to a newer version to enable this setting.")
title: i18n("Security") title: i18n("Security")
topPadding: 0
leftPadding: 0 FormCard.FormHeader {
rightPadding: 0 title: i18nc("@option:check", "Encryption")
ColumnLayout { }
spacing: 0 FormCard.FormCard {
MobileForm.FormHeader { FormCard.FormSwitchDelegate {
Layout.fillWidth: true id: enableEncryptionSwitch
title: i18nc("@option:check", "Encryption") text: i18n("Enable encryption")
} description: i18nc("option:check", "Once enabled, encryption cannot be disabled.")
MobileForm.FormCard { enabled: room.canEncryptRoom
Layout.fillWidth: true checked: room.usesEncryption
contentItem: ColumnLayout { onToggled: if (checked) {
spacing: 0 let dialog = confirmEncryptionDialog.createObject(applicationWindow(), {room: room});
MobileForm.FormSwitchDelegate { dialog.open();
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 { FormCard.FormHeader {
Layout.fillWidth: true title: i18nc("@option:check", "Access")
title: i18nc("@option:check", "Access") }
} FormCard.FormCard {
MobileForm.FormCard { FormCard.FormRadioDelegate {
Layout.fillWidth: true text: i18nc("@option:check", "Private (invite only)")
contentItem: ColumnLayout { description: i18n("Only invited people can join.")
spacing: 0 checked: room.joinRule === "invite"
MobileForm.FormRadioDelegate { enabled: room.canSendState("m.room.join_rules")
text: i18nc("@option:check", "Private (invite only)") onCheckedChanged: if (checked) {
description: i18n("Only invited people can join.") room.joinRule = "invite";
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.FormRadioDelegate {
MobileForm.FormHeader { text: i18nc("@option:check", "Space members")
Layout.fillWidth: true description: i18n("Anyone in a space can find and join.") +
title: i18nc("@option:check", "Message history visibility") (!["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 { FormCard.FormRadioDelegate {
Layout.fillWidth: true text: i18nc("@option:check", "Knock")
contentItem: ColumnLayout { description: i18n("People not in the room need to request an invite to join the room.") +
spacing: 0 (!["7", "8", "9", "10"].includes(room.version) ? `\n${needUpgradeRoom}` : "")
MobileForm.FormRadioDelegate { checked: room.joinRule === "knock"
text: i18nc("@option:check", "Anyone") // https://spec.matrix.org/v1.4/rooms/#feature-matrix
description: i18nc("@option:check", "Anyone, regardless of whether they have joined, can view history.") enabled: room.canSendState("m.room.join_rules") && ["7", "8", "9", "10"].includes(room.version)
checked: room.historyVisibility === "world_readable" onCheckedChanged: if (checked) {
enabled: room.canSendState("m.room.history_visibility") room.joinRule = "knock";
onCheckedChanged: if (checked) { }
room.historyVisibility = "world_readable" }
} FormCard.FormRadioDelegate {
} text: i18nc("@option:check", "Public")
MobileForm.FormRadioDelegate { description: i18nc("@option:check", "Anyone can find and join.")
text: i18nc("@option:check", "Members only") checked: room.joinRule === "public"
description: i18nc("@option:check", "All members can view the entire message history, even before they joined.") enabled: room.canSendState("m.room.join_rules")
checked: room.historyVisibility === "shared" onCheckedChanged: if (checked) {
enabled: room.canSendState("m.room.history_visibility") room.joinRule = "public";
onCheckedChanged: if (checked) { }
room.historyVisibility = "shared" }
} }
}
MobileForm.FormRadioDelegate { FormCard.FormHeader {
text: i18nc("@option:check", "Members only (since invite)") title: i18nc("@option:check", "Message history visibility")
description: i18nc("@option:check", "New members can view the message history from the point they were invited to the room.") }
checked: room.historyVisibility === "invited" FormCard.FormCard {
enabled: room.canSendState("m.room.history_visibility") FormCard.FormRadioDelegate {
onCheckedChanged: if (checked) { text: i18nc("@option:check", "Anyone")
room.historyVisibility = "invited" 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")
MobileForm.FormRadioDelegate { onCheckedChanged: if (checked) {
text: i18nc("@option:check", "Members only (since joining)") room.historyVisibility = "world_readable"
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") FormCard.FormRadioDelegate {
onCheckedChanged: if (checked) { text: i18nc("@option:check", "Members only")
room.historyVisibility = "joined" 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 id: confirmEncryptionDialog
ConfirmEncryptionDialog { ConfirmEncryptionDialog {
@@ -168,7 +148,7 @@ Kirigami.ScrollablePage {
} }
} }
Connections { property Connections connections: Connections {
target: room target: room
onEncryption: { onEncryption: {
enableEncryptionSwitch.checked = room.usesEncryption enableEncryptionSwitch.checked = room.usesEncryption