This modifies displayed power levels such that:
- If users_default is !== 0:
- the power level 0 is displayed as "Restricted (0)"
- the power level users_default is displayed as "Default ({users_default})"
- Otherwise:
- the power level 0 is displayed as "Default (0)"
When changing users_default, to say, 10, when the textual powers are rendered
again, they will take users_default into account. So those previously at 10
and which would have previously have been rendered "Custom of 10" will now
read "Default (10)". Conversely, those that were "Default (0)" will now read
"Restricted (0)".
180 lines
5.5 KiB
JavaScript
180 lines
5.5 KiB
JavaScript
/*
|
|
Copyright 2015, 2016 OpenMarket 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.
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
import React from 'react';
|
|
import * as Roles from '../../../Roles';
|
|
import { _t } from '../../../languageHandler';
|
|
|
|
module.exports = React.createClass({
|
|
displayName: 'PowerSelector',
|
|
|
|
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.
|
|
// MemberInfo uses controlled; RoomSettings uses non-controlled.
|
|
//
|
|
// ignored if disabled is truthy. false by default.
|
|
controlled: React.PropTypes.bool,
|
|
|
|
// should the user be able to change the value? false by default.
|
|
disabled: React.PropTypes.bool,
|
|
onChange: React.PropTypes.func,
|
|
},
|
|
|
|
getInitialState: function() {
|
|
return {
|
|
levelRoleMap: {},
|
|
reverseRoles: {},
|
|
// List of power levels to show in the drop-down
|
|
options: [],
|
|
};
|
|
},
|
|
|
|
getDefaultProps: function() {
|
|
return {
|
|
maxValue: Infinity,
|
|
usersDefault: 0,
|
|
};
|
|
},
|
|
|
|
componentWillMount: function() {
|
|
this._initStateFromProps(this.props, true);
|
|
},
|
|
|
|
componentWillReceiveProps: function(newProps) {
|
|
this._initStateFromProps(newProps);
|
|
},
|
|
|
|
_initStateFromProps: function(newProps, initial) {
|
|
// This needs to be done now because levelRoleMap has translated strings
|
|
const levelRoleMap = Roles.levelRoleMap(newProps.usersDefault);
|
|
const reverseRoles = {};
|
|
Object.keys(levelRoleMap).forEach(function(key) {
|
|
reverseRoles[levelRoleMap[key]] = key;
|
|
});
|
|
const options = Object.keys(levelRoleMap).filter((l) => {
|
|
return l === undefined || l <= newProps.maxValue;
|
|
});
|
|
|
|
this.setState({
|
|
levelRoleMap,
|
|
reverseRoles,
|
|
options,
|
|
});
|
|
|
|
if (initial) {
|
|
this.setState({
|
|
custom: levelRoleMap[newProps.value] === undefined,
|
|
});
|
|
}
|
|
},
|
|
|
|
onSelectChange: function(event) {
|
|
this.setState({ custom: event.target.value === "Custom" });
|
|
if (event.target.value !== "Custom") {
|
|
this.props.onChange(this.getValue());
|
|
}
|
|
},
|
|
|
|
onCustomBlur: function(event) {
|
|
this.props.onChange(this.getValue());
|
|
},
|
|
|
|
onCustomKeyDown: function(event) {
|
|
if (event.key == "Enter") {
|
|
this.props.onChange(this.getValue());
|
|
}
|
|
},
|
|
|
|
getValue: function() {
|
|
let value;
|
|
if (this.refs.select) {
|
|
value = this.state.reverseRoles[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>;
|
|
} else {
|
|
input = <input
|
|
ref="custom"
|
|
type="text"
|
|
size="3"
|
|
defaultValue={this.props.value}
|
|
onBlur={this.onCustomBlur}
|
|
onKeyDown={this.onCustomKeyDown}
|
|
/>;
|
|
}
|
|
customPicker = <span> of { input }</span>;
|
|
}
|
|
|
|
let selectValue;
|
|
if (this.state.custom) {
|
|
selectValue = "Custom";
|
|
} else {
|
|
selectValue = this.state.levelRoleMap[this.props.value] || "Custom";
|
|
}
|
|
let select;
|
|
if (this.props.disabled) {
|
|
select = <span>{ selectValue }</span>;
|
|
} else {
|
|
// Each level must have a definition in this.state.levelRoleMap
|
|
let options = this.state.options.map((level) => {
|
|
return {
|
|
value: this.state.levelRoleMap[level],
|
|
text: Roles.textualPowerLevel(level, this.props.usersDefault),
|
|
};
|
|
});
|
|
options.push({ value: "Custom", text: _t("Custom level") });
|
|
options = options.map((op) => {
|
|
return <option value={op.value} key={op.value}>{ op.text }</option>;
|
|
});
|
|
|
|
select =
|
|
<select ref="select"
|
|
value={this.props.controlled ? selectValue : undefined}
|
|
defaultValue={!this.props.controlled ? selectValue : undefined}
|
|
onChange={this.onSelectChange}>
|
|
{ options }
|
|
</select>;
|
|
}
|
|
|
|
return (
|
|
<span className="mx_PowerSelector">
|
|
{ select }
|
|
{ customPicker }
|
|
</span>
|
|
);
|
|
},
|
|
});
|