Make power level control permission-aware
This commit is contained in:
parent
f408d511a6
commit
757679a6e0
7
TODO.md
7
TODO.md
|
@ -1,5 +1,12 @@
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
|
- fix reply bar height
|
||||||
|
- don't trust PowerLevelsEvent, may be old
|
||||||
|
- joining new DM, not loading past events?
|
||||||
|
- HLabeledItem disabled opacity
|
||||||
|
- cancel setPowerLevel future on Cancel button click
|
||||||
|
- enter to trigger apply button
|
||||||
|
- destroy setPowerLevel future on Component.onDestruction
|
||||||
- warn about setting level of someone to 100
|
- warn about setting level of someone to 100
|
||||||
- gray out if no permission to change
|
- gray out if no permission to change
|
||||||
- improve event text
|
- improve event text
|
||||||
|
|
|
@ -1684,6 +1684,7 @@ class MatrixClient(nio.AsyncClient):
|
||||||
guests_allowed = room.guest_access == "can_join",
|
guests_allowed = room.guest_access == "can_join",
|
||||||
|
|
||||||
default_power_level = levels.defaults.users_default,
|
default_power_level = levels.defaults.users_default,
|
||||||
|
own_power_level = levels.get_user_level(self.user_id),
|
||||||
can_invite = levels.can_user_invite(self.user_id),
|
can_invite = levels.can_user_invite(self.user_id),
|
||||||
can_kick = levels.can_user_kick(self.user_id),
|
can_kick = levels.can_user_kick(self.user_id),
|
||||||
can_redact_all = levels.can_user_redact(self.user_id),
|
can_redact_all = levels.can_user_redact(self.user_id),
|
||||||
|
@ -1694,6 +1695,7 @@ class MatrixClient(nio.AsyncClient):
|
||||||
can_set_encryption = can_send_state("m.room.encryption"),
|
can_set_encryption = can_send_state("m.room.encryption"),
|
||||||
can_set_join_rules = can_send_state("m.room.join_rules"),
|
can_set_join_rules = can_send_state("m.room.join_rules"),
|
||||||
can_set_guest_access = can_send_state("m.room.guest_access"),
|
can_set_guest_access = can_send_state("m.room.guest_access"),
|
||||||
|
can_set_power_levels = can_send_state("m.room.power_levels"),
|
||||||
|
|
||||||
last_event_date = last_event_date,
|
last_event_date = last_event_date,
|
||||||
|
|
||||||
|
|
|
@ -180,6 +180,7 @@ class Room(ModelItem):
|
||||||
guests_allowed: bool = True
|
guests_allowed: bool = True
|
||||||
|
|
||||||
default_power_level: int = 0
|
default_power_level: int = 0
|
||||||
|
own_power_level: int = 0
|
||||||
can_invite: bool = False
|
can_invite: bool = False
|
||||||
can_kick: bool = False
|
can_kick: bool = False
|
||||||
can_redact_all: bool = False
|
can_redact_all: bool = False
|
||||||
|
@ -190,6 +191,7 @@ class Room(ModelItem):
|
||||||
can_set_encryption: bool = False
|
can_set_encryption: bool = False
|
||||||
can_set_join_rules: bool = False
|
can_set_join_rules: bool = False
|
||||||
can_set_guest_access: bool = False
|
can_set_guest_access: bool = False
|
||||||
|
can_set_power_levels: bool = False
|
||||||
|
|
||||||
last_event_date: datetime = ZERO_DATE
|
last_event_date: datetime = ZERO_DATE
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,21 @@ import QtQuick 2.12
|
||||||
import QtQuick.Layouts 1.12
|
import QtQuick.Layouts 1.12
|
||||||
|
|
||||||
AutoDirectionLayout {
|
AutoDirectionLayout {
|
||||||
id: control
|
id: root
|
||||||
|
|
||||||
property int defaultLevel: 0
|
property int defaultLevel: 0
|
||||||
|
property int maximumLevel: 100
|
||||||
|
|
||||||
readonly property alias changed: field.changed
|
readonly property alias changed: field.changed
|
||||||
readonly property int level: Math.min(100, parseInt(field.text || "0", 10))
|
|
||||||
|
readonly property int level:
|
||||||
|
Math.min(maximumLevel, parseInt(field.text || "0", 10))
|
||||||
|
|
||||||
readonly property alias fieldFocused: field.activeFocus
|
readonly property alias fieldFocused: field.activeFocus
|
||||||
|
|
||||||
|
readonly property bool fieldOverMaximum:
|
||||||
|
parseInt(field.text || "0", 10) > maximumLevel
|
||||||
|
|
||||||
signal accepted()
|
signal accepted()
|
||||||
|
|
||||||
function reset() { field.reset() }
|
function reset() { field.reset() }
|
||||||
|
@ -26,15 +33,15 @@ AutoDirectionLayout {
|
||||||
|
|
||||||
radius: 0
|
radius: 0
|
||||||
horizontalAlignment: Qt.AlignHCenter
|
horizontalAlignment: Qt.AlignHCenter
|
||||||
validator: IntValidator { top: 100 }
|
validator: IntValidator { top: root.maximumLevel }
|
||||||
inputMethodHints: Qt.ImhFormattedNumbersOnly
|
inputMethodHints: Qt.ImhFormattedNumbersOnly
|
||||||
maximumLength: control.level < 0 ? 16 : 3
|
maximumLength: root.level < 0 ? 16 : String(root.maximumLevel).length
|
||||||
defaultText: String(control.defaultLevel)
|
defaultText: String(root.defaultLevel)
|
||||||
|
error: root.fieldOverMaximum
|
||||||
|
|
||||||
onAccepted: control.accepted()
|
onAccepted: root.accepted()
|
||||||
onActiveFocusChanged:
|
onActiveFocusChanged:
|
||||||
if (! activeFocus && parseInt(text || "0", 10) > 100)
|
if (! activeFocus && fieldOverMaximum) text = root.maximumLevel
|
||||||
text = 100
|
|
||||||
|
|
||||||
Layout.minimumWidth:
|
Layout.minimumWidth:
|
||||||
mainUI.fontMetrics.boundingRect("-999").width +
|
mainUI.fontMetrics.boundingRect("-999").width +
|
||||||
|
@ -52,7 +59,7 @@ AutoDirectionLayout {
|
||||||
height: parent.height
|
height: parent.height
|
||||||
icon.name: "user-power-default"
|
icon.name: "user-power-default"
|
||||||
toolTip.text: qsTr("Limited")
|
toolTip.text: qsTr("Limited")
|
||||||
checked: control.level < 50
|
checked: root.level < 50
|
||||||
uncheckable: false
|
uncheckable: false
|
||||||
onClicked: field.text = 0
|
onClicked: field.text = 0
|
||||||
}
|
}
|
||||||
|
@ -61,7 +68,7 @@ AutoDirectionLayout {
|
||||||
height: parent.height
|
height: parent.height
|
||||||
icon.name: "user-power-50"
|
icon.name: "user-power-50"
|
||||||
toolTip.text: qsTr("Moderator")
|
toolTip.text: qsTr("Moderator")
|
||||||
checked: control.level >= 50 && control.level < 100
|
checked: root.level >= 50 && root.level < 100
|
||||||
uncheckable: false
|
uncheckable: false
|
||||||
onClicked: field.text = 50
|
onClicked: field.text = 50
|
||||||
}
|
}
|
||||||
|
@ -70,7 +77,7 @@ AutoDirectionLayout {
|
||||||
height: parent.height
|
height: parent.height
|
||||||
icon.name: "user-power-100"
|
icon.name: "user-power-100"
|
||||||
toolTip.text: qsTr("Admin")
|
toolTip.text: qsTr("Admin")
|
||||||
checked: control.level >= 100
|
checked: root.level >= 100
|
||||||
uncheckable: false
|
uncheckable: false
|
||||||
onClicked: field.text = 100
|
onClicked: field.text = 100
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@ HListView {
|
||||||
|
|
||||||
property string userId
|
property string userId
|
||||||
property string roomId
|
property string roomId
|
||||||
|
property int ownPowerLevel
|
||||||
|
property int canSetPowerLevels
|
||||||
property QtObject member // RoomMember model item
|
property QtObject member // RoomMember model item
|
||||||
property HStackView stackView
|
property HStackView stackView
|
||||||
|
|
||||||
|
@ -160,6 +162,10 @@ HListView {
|
||||||
|
|
||||||
HLabeledItem {
|
HLabeledItem {
|
||||||
id: powerLevel
|
id: powerLevel
|
||||||
|
enabled:
|
||||||
|
root.canSetPowerLevels &&
|
||||||
|
root.ownPowerLevel > member.power_level
|
||||||
|
|
||||||
label.text: qsTr("Power level:")
|
label.text: qsTr("Power level:")
|
||||||
label.horizontalAlignment: Qt.AlignHCenter
|
label.horizontalAlignment: Qt.AlignHCenter
|
||||||
|
|
||||||
|
@ -168,6 +174,7 @@ HListView {
|
||||||
PowerLevelControl {
|
PowerLevelControl {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
defaultLevel: member.power_level
|
defaultLevel: member.power_level
|
||||||
|
maximumLevel: root.ownPowerLevel
|
||||||
rowSpacing: powerLevel.spacing
|
rowSpacing: powerLevel.spacing
|
||||||
onAccepted: applyButton.clicked()
|
onAccepted: applyButton.clicked()
|
||||||
onFieldFocusedChanged:
|
onFieldFocusedChanged:
|
||||||
|
@ -191,6 +198,7 @@ HListView {
|
||||||
|
|
||||||
ApplyButton {
|
ApplyButton {
|
||||||
id: applyButton
|
id: applyButton
|
||||||
|
enabled: ! powerLevel.item.fieldOverMaximum
|
||||||
loading: setPowerFuture !== null
|
loading: setPowerFuture !== null
|
||||||
onClicked: {
|
onClicked: {
|
||||||
setPowerFuture = py.callClientCoro(
|
setPowerFuture = py.callClientCoro(
|
||||||
|
@ -230,7 +238,7 @@ HListView {
|
||||||
Component.onDestruction: if (setPowerFuture) setPowerFuture.cancel()
|
Component.onDestruction: if (setPowerFuture) setPowerFuture.cancel()
|
||||||
|
|
||||||
Keys.onEnterPressed: Keys.onReturnPressed(event)
|
Keys.onEnterPressed: Keys.onReturnPressed(event)
|
||||||
Keys.onReturnPressed: if (! powerLevelFieldFocused && currentItem) {
|
Keys.onReturnPressed: if (! root.powerLevelFieldFocused && currentItem) {
|
||||||
currentItem.leftClicked()
|
currentItem.leftClicked()
|
||||||
currentItem.clicked()
|
currentItem.clicked()
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,11 @@ HColumnLayout {
|
||||||
{
|
{
|
||||||
userId: chat.userId,
|
userId: chat.userId,
|
||||||
roomId: chat.roomId,
|
roomId: chat.roomId,
|
||||||
|
ownPowerLevel:
|
||||||
|
Qt.binding(() => chat.roomInfo.own_power_level),
|
||||||
|
canSetPowerLevels: Qt.binding(() =>
|
||||||
|
chat.roomInfo.can_set_power_levels
|
||||||
|
),
|
||||||
member: model,
|
member: model,
|
||||||
stackView: stackView,
|
stackView: stackView,
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue
Block a user