mirror of
https://github.com/element-hq/element-web
synced 2024-11-28 20:38:55 +03:00
Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
commit
c1d70f28d7
5 changed files with 77 additions and 50 deletions
11
src/Roles.js
11
src/Roles.js
|
@ -15,19 +15,20 @@ limitations under the License.
|
|||
*/
|
||||
import { _t } from './languageHandler';
|
||||
|
||||
export function levelRoleMap() {
|
||||
export function levelRoleMap(usersDefault) {
|
||||
return {
|
||||
undefined: _t('Default'),
|
||||
0: _t('User'),
|
||||
0: _t('Restricted'),
|
||||
[usersDefault]: _t('Default'),
|
||||
50: _t('Moderator'),
|
||||
100: _t('Admin'),
|
||||
};
|
||||
}
|
||||
|
||||
export function textualPowerLevel(level, userDefault) {
|
||||
const LEVEL_ROLE_MAP = this.levelRoleMap();
|
||||
export function textualPowerLevel(level, usersDefault) {
|
||||
const LEVEL_ROLE_MAP = this.levelRoleMap(usersDefault);
|
||||
if (LEVEL_ROLE_MAP[level]) {
|
||||
return LEVEL_ROLE_MAP[level] + (level !== undefined ? ` (${level})` : ` (${userDefault})`);
|
||||
return LEVEL_ROLE_MAP[level] + (level !== undefined ? ` (${level})` : ` (${usersDefault})`);
|
||||
} else {
|
||||
return level;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,11 @@ module.exports = React.createClass({
|
|||
|
||||
propTypes: {
|
||||
value: React.PropTypes.number.isRequired,
|
||||
// The maximum value that can be set with the power selector
|
||||
maxValue: React.PropTypes.number.isRequired,
|
||||
|
||||
// Default user power level for the room
|
||||
usersDefault: React.PropTypes.number.isRequired,
|
||||
|
||||
// if true, the <select/> should be a 'controlled' form element and updated by React
|
||||
// to reflect the current value, rather than left freeform.
|
||||
|
@ -41,63 +46,83 @@ module.exports = React.createClass({
|
|||
getInitialState: function() {
|
||||
return {
|
||||
levelRoleMap: {},
|
||||
// List of power levels to show in the drop-down
|
||||
options: [],
|
||||
};
|
||||
},
|
||||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
maxValue: Infinity,
|
||||
usersDefault: 0,
|
||||
};
|
||||
},
|
||||
|
||||
componentWillMount: function() {
|
||||
this._initStateFromProps(this.props);
|
||||
},
|
||||
|
||||
componentWillReceiveProps: function(newProps) {
|
||||
this._initStateFromProps(newProps);
|
||||
},
|
||||
|
||||
_initStateFromProps: function(newProps) {
|
||||
// This needs to be done now because levelRoleMap has translated strings
|
||||
const levelRoleMap = Roles.levelRoleMap();
|
||||
const levelRoleMap = Roles.levelRoleMap(newProps.usersDefault);
|
||||
const options = Object.keys(levelRoleMap).filter((l) => {
|
||||
return l === undefined || l <= newProps.maxValue;
|
||||
});
|
||||
|
||||
this.setState({
|
||||
levelRoleMap,
|
||||
custom: levelRoleMap[this.props.value] === undefined,
|
||||
options,
|
||||
custom: levelRoleMap[newProps.value] === undefined,
|
||||
});
|
||||
},
|
||||
|
||||
onSelectChange: function(event) {
|
||||
this.setState({ custom: event.target.value === "SELECT_VALUE_CUSTOM" });
|
||||
if (event.target.value !== "SELECT_VALUE_CUSTOM") {
|
||||
this.props.onChange(this.getValue());
|
||||
this.props.onChange(event.target.value);
|
||||
}
|
||||
},
|
||||
|
||||
onCustomBlur: function(event) {
|
||||
this.props.onChange(this.getValue());
|
||||
this.props.onChange(parseInt(this.refs.custom.value));
|
||||
},
|
||||
|
||||
onCustomKeyDown: function(event) {
|
||||
if (event.key == "Enter") {
|
||||
this.props.onChange(this.getValue());
|
||||
this.props.onChange(parseInt(this.refs.custom.value));
|
||||
}
|
||||
},
|
||||
|
||||
getValue: function() {
|
||||
let value;
|
||||
if (this.refs.select) {
|
||||
value = this.refs.select.value;
|
||||
if (this.refs.custom) {
|
||||
if (value === undefined) value = parseInt( this.refs.custom.value );
|
||||
}
|
||||
}
|
||||
return value;
|
||||
},
|
||||
|
||||
render: function() {
|
||||
let customPicker;
|
||||
if (this.state.custom) {
|
||||
let input;
|
||||
if (this.props.disabled) {
|
||||
input = <span>{ this.props.value }</span>;
|
||||
customPicker = <span>{ _t(
|
||||
"Custom of %(powerLevel)s",
|
||||
{ powerLevel: this.props.value },
|
||||
) }</span>;
|
||||
} else {
|
||||
input = <input ref="custom" type="text" size="3" defaultValue={this.props.value} onBlur={this.onCustomBlur} onKeyDown={this.onCustomKeyDown} />;
|
||||
customPicker = <span> = <input
|
||||
ref="custom"
|
||||
type="text"
|
||||
size="3"
|
||||
defaultValue={this.props.value}
|
||||
onBlur={this.onCustomBlur}
|
||||
onKeyDown={this.onCustomKeyDown}
|
||||
/>
|
||||
</span>;
|
||||
}
|
||||
customPicker = <span> of { input }</span>;
|
||||
}
|
||||
|
||||
let selectValue;
|
||||
if (this.state.custom) {
|
||||
selectValue = "SELECT_VALUE_CUSTOM";
|
||||
} else {
|
||||
selectValue = this.state.levelRoleMap[selectValue] ?
|
||||
selectValue = this.state.levelRoleMap[this.props.value] ?
|
||||
this.props.value : "SELECT_VALUE_CUSTOM";
|
||||
}
|
||||
let select;
|
||||
|
@ -105,13 +130,10 @@ module.exports = React.createClass({
|
|||
select = <span>{ this.state.levelRoleMap[selectValue] }</span>;
|
||||
} else {
|
||||
// Each level must have a definition in this.state.levelRoleMap
|
||||
const levels = [0, 50, 100];
|
||||
let options = levels.map((level) => {
|
||||
let options = this.state.options.map((level) => {
|
||||
return {
|
||||
value: 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),
|
||||
text: Roles.textualPowerLevel(level, this.props.usersDefault),
|
||||
};
|
||||
});
|
||||
options.push({ value: "SELECT_VALUE_CUSTOM", text: _t("Custom level") });
|
||||
|
|
|
@ -494,7 +494,6 @@ module.exports = withMatrixClient(React.createClass({
|
|||
const defaultPerms = {
|
||||
can: {},
|
||||
muted: false,
|
||||
modifyLevel: false,
|
||||
};
|
||||
const room = this.props.matrixClient.getRoom(member.roomId);
|
||||
if (!room) return defaultPerms;
|
||||
|
@ -516,13 +515,15 @@ module.exports = withMatrixClient(React.createClass({
|
|||
},
|
||||
|
||||
_calculateCanPermissions: function(me, them, powerLevels) {
|
||||
const isMe = me.userId === them.userId;
|
||||
const can = {
|
||||
kick: false,
|
||||
ban: false,
|
||||
mute: false,
|
||||
modifyLevel: false,
|
||||
modifyLevelMax: 0,
|
||||
};
|
||||
const canAffectUser = them.powerLevel < me.powerLevel;
|
||||
const canAffectUser = them.powerLevel < me.powerLevel || isMe;
|
||||
if (!canAffectUser) {
|
||||
//console.log("Cannot affect user: %s >= %s", them.powerLevel, me.powerLevel);
|
||||
return can;
|
||||
|
@ -531,16 +532,13 @@ module.exports = withMatrixClient(React.createClass({
|
|||
(powerLevels.events ? powerLevels.events["m.room.power_levels"] : null) ||
|
||||
powerLevels.state_default
|
||||
);
|
||||
const levelToSend = (
|
||||
(powerLevels.events ? powerLevels.events["m.room.message"] : null) ||
|
||||
powerLevels.events_default
|
||||
);
|
||||
|
||||
can.kick = me.powerLevel >= powerLevels.kick;
|
||||
can.ban = me.powerLevel >= powerLevels.ban;
|
||||
can.mute = me.powerLevel >= editPowerLevel;
|
||||
can.toggleMod = me.powerLevel > them.powerLevel && them.powerLevel >= levelToSend;
|
||||
can.modifyLevel = me.powerLevel > them.powerLevel && me.powerLevel >= editPowerLevel;
|
||||
can.modifyLevel = me.powerLevel >= editPowerLevel && (isMe || me.powerLevel > them.powerLevel);
|
||||
can.modifyLevelMax = me.powerLevel;
|
||||
|
||||
return can;
|
||||
},
|
||||
|
||||
|
@ -832,8 +830,11 @@ module.exports = withMatrixClient(React.createClass({
|
|||
presenceCurrentlyActive = this.props.member.user.currentlyActive;
|
||||
}
|
||||
|
||||
let roomMemberDetails = null;
|
||||
const room = this.props.matrixClient.getRoom(this.props.member.roomId);
|
||||
const poweLevelEvent = room ? room.currentState.getStateEvents("m.room.power_levels", "") : null;
|
||||
const powerLevelUsersDefault = poweLevelEvent.getContent().users_default;
|
||||
|
||||
let roomMemberDetails = null;
|
||||
if (this.props.member.roomId) { // is in room
|
||||
const PowerSelector = sdk.getComponent('elements.PowerSelector');
|
||||
const PresenceLabel = sdk.getComponent('rooms.PresenceLabel');
|
||||
|
@ -842,7 +843,9 @@ module.exports = withMatrixClient(React.createClass({
|
|||
{ _t("Level:") } <b>
|
||||
<PowerSelector controlled={true}
|
||||
value={parseInt(this.props.member.powerLevel)}
|
||||
maxValue={this.state.can.modifyLevelMax}
|
||||
disabled={!this.state.can.modifyLevel}
|
||||
usersDefault={powerLevelUsersDefault}
|
||||
onChange={this.onPowerChange} />
|
||||
</b>
|
||||
</div>
|
||||
|
|
|
@ -910,31 +910,31 @@ module.exports = React.createClass({
|
|||
<div className="mx_RoomSettings_powerLevels mx_RoomSettings_settings">
|
||||
<div className="mx_RoomSettings_powerLevel">
|
||||
<span className="mx_RoomSettings_powerLevelKey">{ _t('The default role for new room members is') } </span>
|
||||
<PowerSelector ref="users_default" value={default_user_level} controlled={false} disabled={!can_change_levels || current_user_level < default_user_level} onChange={this.onPowerLevelsChanged} />
|
||||
<PowerSelector ref="users_default" value={default_user_level} usersDefault={default_user_level} controlled={false} disabled={!can_change_levels || current_user_level < default_user_level} onChange={this.onPowerLevelsChanged} />
|
||||
</div>
|
||||
<div className="mx_RoomSettings_powerLevel">
|
||||
<span className="mx_RoomSettings_powerLevelKey">{ _t('To send messages, you must be a') } </span>
|
||||
<PowerSelector ref="events_default" value={send_level} controlled={false} disabled={!can_change_levels || current_user_level < send_level} onChange={this.onPowerLevelsChanged} />
|
||||
<PowerSelector ref="events_default" value={send_level} usersDefault={default_user_level} controlled={false} disabled={!can_change_levels || current_user_level < send_level} onChange={this.onPowerLevelsChanged} />
|
||||
</div>
|
||||
<div className="mx_RoomSettings_powerLevel">
|
||||
<span className="mx_RoomSettings_powerLevelKey">{ _t('To invite users into the room, you must be a') } </span>
|
||||
<PowerSelector ref="invite" value={invite_level} controlled={false} disabled={!can_change_levels || current_user_level < invite_level} onChange={this.onPowerLevelsChanged} />
|
||||
<PowerSelector ref="invite" value={invite_level} usersDefault={default_user_level} controlled={false} disabled={!can_change_levels || current_user_level < invite_level} onChange={this.onPowerLevelsChanged} />
|
||||
</div>
|
||||
<div className="mx_RoomSettings_powerLevel">
|
||||
<span className="mx_RoomSettings_powerLevelKey">{ _t('To configure the room, you must be a') } </span>
|
||||
<PowerSelector ref="state_default" value={state_level} controlled={false} disabled={!can_change_levels || current_user_level < state_level} onChange={this.onPowerLevelsChanged} />
|
||||
<PowerSelector ref="state_default" value={state_level} usersDefault={default_user_level} controlled={false} disabled={!can_change_levels || current_user_level < state_level} onChange={this.onPowerLevelsChanged} />
|
||||
</div>
|
||||
<div className="mx_RoomSettings_powerLevel">
|
||||
<span className="mx_RoomSettings_powerLevelKey">{ _t('To kick users, you must be a') } </span>
|
||||
<PowerSelector ref="kick" value={kick_level} controlled={false} disabled={!can_change_levels || current_user_level < kick_level} onChange={this.onPowerLevelsChanged} />
|
||||
<PowerSelector ref="kick" value={kick_level} usersDefault={default_user_level} controlled={false} disabled={!can_change_levels || current_user_level < kick_level} onChange={this.onPowerLevelsChanged} />
|
||||
</div>
|
||||
<div className="mx_RoomSettings_powerLevel">
|
||||
<span className="mx_RoomSettings_powerLevelKey">{ _t('To ban users, you must be a') } </span>
|
||||
<PowerSelector ref="ban" value={ban_level} controlled={false} disabled={!can_change_levels || current_user_level < ban_level} onChange={this.onPowerLevelsChanged} />
|
||||
<PowerSelector ref="ban" value={ban_level} usersDefault={default_user_level} controlled={false} disabled={!can_change_levels || current_user_level < ban_level} onChange={this.onPowerLevelsChanged} />
|
||||
</div>
|
||||
<div className="mx_RoomSettings_powerLevel">
|
||||
<span className="mx_RoomSettings_powerLevelKey">{ _t('To remove other users\' messages, you must be a') } </span>
|
||||
<PowerSelector ref="redact" value={redact_level} controlled={false} disabled={!can_change_levels || current_user_level < redact_level} onChange={this.onPowerLevelsChanged} />
|
||||
<PowerSelector ref="redact" value={redact_level} usersDefault={default_user_level} controlled={false} disabled={!can_change_levels || current_user_level < redact_level} onChange={this.onPowerLevelsChanged} />
|
||||
</div>
|
||||
|
||||
{ Object.keys(events_levels).map(function(event_type, i) {
|
||||
|
@ -944,7 +944,7 @@ module.exports = React.createClass({
|
|||
return (
|
||||
<div className="mx_RoomSettings_powerLevel" key={event_type}>
|
||||
<span className="mx_RoomSettings_powerLevelKey">{ label } </span>
|
||||
<PowerSelector ref={"event_levels_"+event_type} value={events_levels[event_type]} onChange={self.onPowerLevelsChanged}
|
||||
<PowerSelector ref={"event_levels_"+event_type} value={events_levels[event_type]} usersDefault={default_user_level} onChange={self.onPowerLevelsChanged}
|
||||
controlled={false} disabled={!can_change_levels || current_user_level < events_levels[event_type]} />
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
"This email address was not found": "This email address was not found",
|
||||
"Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Your email address does not appear to be associated with a Matrix ID on this Homeserver.",
|
||||
"Default": "Default",
|
||||
"User": "User",
|
||||
"Restricted": "Restricted",
|
||||
"Moderator": "Moderator",
|
||||
"Admin": "Admin",
|
||||
"Start a chat": "Start a chat",
|
||||
|
@ -150,7 +150,6 @@
|
|||
"%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s widget modified by %(senderName)s",
|
||||
"%(widgetName)s widget added by %(senderName)s": "%(widgetName)s widget added by %(senderName)s",
|
||||
"%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s widget removed by %(senderName)s",
|
||||
"Communities": "Communities",
|
||||
"Message Pinning": "Message Pinning",
|
||||
"%(displayName)s is typing": "%(displayName)s is typing",
|
||||
"%(names)s and %(count)s others are typing|other": "%(names)s and %(count)s others are typing",
|
||||
|
@ -525,6 +524,7 @@
|
|||
"Unverify": "Unverify",
|
||||
"Verify...": "Verify...",
|
||||
"No results": "No results",
|
||||
"Communities": "Communities",
|
||||
"Home": "Home",
|
||||
"Integrations Error": "Integrations Error",
|
||||
"Could not connect to the integration server": "Could not connect to the integration server",
|
||||
|
@ -581,6 +581,7 @@
|
|||
"%(items)s and %(count)s others|other": "%(items)s and %(count)s others",
|
||||
"%(items)s and %(count)s others|one": "%(items)s and one other",
|
||||
"%(items)s and %(lastItem)s": "%(items)s and %(lastItem)s",
|
||||
"Custom of %(powerLevel)s": "Custom of %(powerLevel)s",
|
||||
"Custom level": "Custom level",
|
||||
"Room directory": "Room directory",
|
||||
"Start chat": "Start chat",
|
||||
|
|
Loading…
Reference in a new issue