Merge remote-tracking branch 'origin/experimental' into dbkr/sas

This commit is contained in:
David Baker 2019-01-28 09:36:39 +00:00
commit b4f02844a8
90 changed files with 3135 additions and 1228 deletions

View file

@ -42,7 +42,9 @@ export default React.createClass({
componentWillUnmount: function() {
const cli = MatrixClientPeg.get();
cli.removeListener("deviceVerificationChanged", this.onDeviceVerificationChanged);
if (cli) {
cli.removeListener("deviceVerificationChanged", this.onDeviceVerificationChanged);
}
},
onDeviceVerificationChanged: function(userId, deviceId, deviceInfo) {

View file

@ -25,12 +25,24 @@ export default class Field extends React.PureComponent {
type: PropTypes.string,
// The field's label string.
label: PropTypes.string,
// The field's placeholder string.
// The field's placeholder string. Defaults to the label.
placeholder: PropTypes.string,
// The type of field to create. Defaults to "input". Should be "input" or "select".
// To define options for a select, use <Field><option ... /></Field>
element: PropTypes.string,
// All other props pass through to the <input>.
};
get value() {
if (!this.refs.fieldInput) return null;
return this.refs.fieldInput.value;
}
set value(newValue) {
if (!this.refs.fieldInput) {
throw new Error("No field input reference");
}
this.refs.fieldInput.value = newValue;
}
render() {
@ -42,6 +54,8 @@ export default class Field extends React.PureComponent {
// Set some defaults for the element
extraProps.type = extraProps.type || "text";
extraProps.ref = "fieldInput";
extraProps.placeholder = extraProps.placeholder || extraProps.label;
const element = this.props.element || "input";
const fieldInput = React.createElement(element, extraProps, this.props.children);

View file

@ -0,0 +1,42 @@
/*
Copyright 2019 New Vector 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.
*/
import React from 'react';
import PropTypes from "prop-types";
import ToggleSwitch from "./ToggleSwitch";
export default class LabelledToggleSwitch extends React.Component {
static propTypes = {
// The value for the toggle switch
value: PropTypes.bool.isRequired,
// The function to call when the value changes
onChange: PropTypes.func.isRequired,
// The translated label for the switch
label: PropTypes.string.isRequired,
};
render() {
// This is a minimal version of a SettingsFlag
return (
<div className="mx_SettingsFlag">
<span className="mx_SettingsFlag_label">{this.props.label}</span>
<ToggleSwitch checked={this.props.value} onChange={this.props.onChange} />
</div>
);
}
}

View file

@ -18,6 +18,7 @@ import React from "react";
import PropTypes from 'prop-types';
import SettingsStore from "../../../settings/SettingsStore";
import { _t } from '../../../languageHandler';
import ToggleSwitch from "./ToggleSwitch";
module.exports = React.createClass({
displayName: 'SettingsFlag',
@ -29,10 +30,6 @@ module.exports = React.createClass({
onChange: PropTypes.func,
isExplicit: PropTypes.bool,
manualSave: PropTypes.bool,
// If group is supplied, then this will create a radio button instead.
group: PropTypes.string,
value: PropTypes.any, // the value for the radio button
},
getInitialState: function() {
@ -46,13 +43,12 @@ module.exports = React.createClass({
};
},
onChange: function(e) {
if (this.props.group && !e.target.checked) return;
onChange: function(checked) {
if (this.props.group && !checked) return;
const newState = this.props.group ? this.props.value : e.target.checked;
if (!this.props.manualSave) this.save(newState);
else this.setState({ value: newState });
if (this.props.onChange) this.props.onChange(newState);
if (!this.props.manualSave) this.save(checked);
else this.setState({ value: checked });
if (this.props.onChange) this.props.onChange(checked);
},
save: function(val = undefined) {
@ -78,34 +74,11 @@ module.exports = React.createClass({
if (!label) label = SettingsStore.getDisplayName(this.props.name, this.props.level);
else label = _t(label);
// We generate a relatively complex ID to avoid conflicts
const id = this.props.name + "_" + this.props.group + "_" + this.props.value + "_" + this.props.level;
let checkbox = (
<input id={id}
type="checkbox"
defaultChecked={value}
onChange={this.onChange}
disabled={!canChange}
/>
);
if (this.props.group) {
checkbox = (
<input id={id}
type="radio"
name={this.props.group}
value={this.props.value}
checked={value === this.props.value}
onChange={this.onChange}
disabled={!canChange}
/>
);
}
return (
<label>
{ checkbox }
{ label }
</label>
<div className="mx_SettingsFlag">
<span className="mx_SettingsFlag_label">{label}</span>
<ToggleSwitch checked={value} onChange={this.onChange} disabled={!canChange} />
</div>
);
},
});

View file

@ -0,0 +1,66 @@
/*
Copyright 2019 New Vector 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.
*/
import React from 'react';
import PropTypes from 'prop-types';
import classNames from "classnames";
export default class ToggleSwitch extends React.Component {
static propTypes = {
// Whether or not this toggle is in the 'on' position. Default false (off).
checked: PropTypes.bool,
// Whether or not the user can interact with the switch
disabled: PropTypes.bool,
// Called when the checked state changes. First argument will be the new state.
onChange: PropTypes.func,
};
constructor(props) {
super(props);
this.state = {
checked: props.checked || false, // default false
};
}
_onClick = (e) => {
e.stopPropagation();
e.preventDefault();
if (this.props.disabled) return;
const newState = !this.state.checked;
this.setState({checked: newState});
if (this.props.onChange) {
this.props.onChange(newState);
}
};
render() {
const classes = classNames({
"mx_ToggleSwitch": true,
"mx_ToggleSwitch_on": this.state.checked,
"mx_ToggleSwitch_enabled": !this.props.disabled,
});
return (
<div className={classes} onClick={this._onClick}>
<div className="mx_ToggleSwitch_ball" />
</div>
);
}
}