Merge pull request #794 from matrix-org/luke/feature-textual-pls
Implement user power-level changes in timeline
This commit is contained in:
commit
726cb43fee
4 changed files with 94 additions and 15 deletions
29
src/Roles.js
Normal file
29
src/Roles.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
Copyright 2017 Vector Creations Ltd
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
export const LEVEL_ROLE_MAP = {
|
||||||
|
undefined: 'Default',
|
||||||
|
0: 'User',
|
||||||
|
50: 'Moderator',
|
||||||
|
100: 'Admin',
|
||||||
|
};
|
||||||
|
|
||||||
|
export function textualPowerLevel(level, userDefault) {
|
||||||
|
if (LEVEL_ROLE_MAP[level]) {
|
||||||
|
return LEVEL_ROLE_MAP[level] + (level !== undefined ? ` (${level})` : ` (${userDefault})`);
|
||||||
|
} else {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,8 @@ limitations under the License.
|
||||||
var MatrixClientPeg = require("./MatrixClientPeg");
|
var MatrixClientPeg = require("./MatrixClientPeg");
|
||||||
var CallHandler = require("./CallHandler");
|
var CallHandler = require("./CallHandler");
|
||||||
|
|
||||||
|
import * as Roles from './Roles';
|
||||||
|
|
||||||
function textForMemberEvent(ev) {
|
function textForMemberEvent(ev) {
|
||||||
// XXX: SYJS-16 "sender is sometimes null for join messages"
|
// XXX: SYJS-16 "sender is sometimes null for join messages"
|
||||||
var senderName = ev.sender ? ev.sender.name : ev.getSender();
|
var senderName = ev.sender ? ev.sender.name : ev.getSender();
|
||||||
|
@ -182,6 +184,45 @@ function textForEncryptionEvent(event) {
|
||||||
return senderName + " turned on end-to-end encryption (algorithm " + event.getContent().algorithm + ")";
|
return senderName + " turned on end-to-end encryption (algorithm " + event.getContent().algorithm + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Currently will only display a change if a user's power level is changed
|
||||||
|
function textForPowerEvent(event) {
|
||||||
|
const senderName = event.sender ? event.sender.name : event.getSender();
|
||||||
|
if (!event.getPrevContent() || !event.getPrevContent().users) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const userDefault = event.getContent().users_default || 0;
|
||||||
|
// Construct set of userIds
|
||||||
|
let users = [];
|
||||||
|
Object.keys(event.getContent().users).forEach(
|
||||||
|
(userId) => {
|
||||||
|
if (users.indexOf(userId) === -1) users.push(userId);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
Object.keys(event.getPrevContent().users).forEach(
|
||||||
|
(userId) => {
|
||||||
|
if (users.indexOf(userId) === -1) users.push(userId);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
let diff = [];
|
||||||
|
users.forEach((userId) => {
|
||||||
|
// Previous power level
|
||||||
|
const from = event.getPrevContent().users[userId];
|
||||||
|
// Current power level
|
||||||
|
const to = event.getContent().users[userId];
|
||||||
|
if (to !== from) {
|
||||||
|
diff.push(
|
||||||
|
userId +
|
||||||
|
' from ' + Roles.textualPowerLevel(from, userDefault) +
|
||||||
|
' to ' + Roles.textualPowerLevel(to, userDefault)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!diff.length) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return senderName + ' changed the power level of ' + diff.join(', ');
|
||||||
|
}
|
||||||
|
|
||||||
var handlers = {
|
var handlers = {
|
||||||
'm.room.message': textForMessageEvent,
|
'm.room.message': textForMessageEvent,
|
||||||
'm.room.name': textForRoomNameEvent,
|
'm.room.name': textForRoomNameEvent,
|
||||||
|
@ -193,6 +234,7 @@ var handlers = {
|
||||||
'm.room.third_party_invite': textForThreePidInviteEvent,
|
'm.room.third_party_invite': textForThreePidInviteEvent,
|
||||||
'm.room.history_visibility': textForHistoryVisibilityEvent,
|
'm.room.history_visibility': textForHistoryVisibilityEvent,
|
||||||
'm.room.encryption': textForEncryptionEvent,
|
'm.room.encryption': textForEncryptionEvent,
|
||||||
|
'm.room.power_levels': textForPowerEvent,
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
@ -16,17 +16,12 @@ limitations under the License.
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var React = require('react');
|
import React from 'react';
|
||||||
|
import * as Roles from '../../../Roles';
|
||||||
var roles = {
|
|
||||||
0: 'User',
|
|
||||||
50: 'Moderator',
|
|
||||||
100: 'Admin',
|
|
||||||
};
|
|
||||||
|
|
||||||
var reverseRoles = {};
|
var reverseRoles = {};
|
||||||
Object.keys(roles).forEach(function(key) {
|
Object.keys(Roles.LEVEL_ROLE_MAP).forEach(function(key) {
|
||||||
reverseRoles[roles[key]] = key;
|
reverseRoles[Roles.LEVEL_ROLE_MAP[key]] = key;
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
|
@ -49,7 +44,7 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
custom: (roles[this.props.value] === undefined),
|
custom: (Roles.LEVEL_ROLE_MAP[this.props.value] === undefined),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -99,22 +94,34 @@ module.exports = React.createClass({
|
||||||
selectValue = "Custom";
|
selectValue = "Custom";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
selectValue = roles[this.props.value] || "Custom";
|
selectValue = Roles.LEVEL_ROLE_MAP[this.props.value] || "Custom";
|
||||||
}
|
}
|
||||||
var select;
|
var select;
|
||||||
if (this.props.disabled) {
|
if (this.props.disabled) {
|
||||||
select = <span>{ selectValue }</span>;
|
select = <span>{ selectValue }</span>;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// Each level must have a definition in LEVEL_ROLE_MAP
|
||||||
|
const levels = [0, 50, 100];
|
||||||
|
let options = levels.map((level) => {
|
||||||
|
return {
|
||||||
|
value: Roles.LEVEL_ROLE_MAP[level],
|
||||||
|
// Give a userDefault (users_default in the power event) of 0 but
|
||||||
|
// because level !== undefined, this should never be used.
|
||||||
|
text: Roles.textualPowerLevel(level, 0),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
options.push({ value: "Custom", text: "Custom level" });
|
||||||
|
options = options.map((op) => {
|
||||||
|
return <option value={op.value}>{op.text}</option>;
|
||||||
|
});
|
||||||
|
|
||||||
select =
|
select =
|
||||||
<select ref="select"
|
<select ref="select"
|
||||||
value={ this.props.controlled ? selectValue : undefined }
|
value={ this.props.controlled ? selectValue : undefined }
|
||||||
defaultValue={ !this.props.controlled ? selectValue : undefined }
|
defaultValue={ !this.props.controlled ? selectValue : undefined }
|
||||||
onChange={ this.onSelectChange }>
|
onChange={ this.onSelectChange }>
|
||||||
<option value="User">User (0)</option>
|
{ options }
|
||||||
<option value="Moderator">Moderator (50)</option>
|
|
||||||
<option value="Admin">Admin (100)</option>
|
|
||||||
<option value="Custom">Custom level</option>
|
|
||||||
</select>;
|
</select>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ var eventTileTypes = {
|
||||||
'm.room.third_party_invite' : 'messages.TextualEvent',
|
'm.room.third_party_invite' : 'messages.TextualEvent',
|
||||||
'm.room.history_visibility' : 'messages.TextualEvent',
|
'm.room.history_visibility' : 'messages.TextualEvent',
|
||||||
'm.room.encryption' : 'messages.TextualEvent',
|
'm.room.encryption' : 'messages.TextualEvent',
|
||||||
|
'm.room.power_levels' : 'messages.TextualEvent',
|
||||||
};
|
};
|
||||||
|
|
||||||
var MAX_READ_AVATARS = 5;
|
var MAX_READ_AVATARS = 5;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue