Make power level control permission-aware

This commit is contained in:
miruka 2020-07-13 18:44:20 -04:00
parent f408d511a6
commit 757679a6e0
6 changed files with 43 additions and 12 deletions

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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
} }

View File

@ -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()
} }

View File

@ -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,
}, },