Factor EditableTextContainer out of ChangeDisplayName
Take the non-displayname-specific bits out of ChangeDisplayName into a new EditableTextContainer, so that we can reuse the logic elsewhere.
This commit is contained in:
parent
88be2827fd
commit
3194c5c61d
4 changed files with 169 additions and 80 deletions
|
@ -51,6 +51,7 @@ module.exports.components['views.dialogs.QuestionDialog'] = require('./component
|
||||||
module.exports.components['views.dialogs.SetDisplayNameDialog'] = require('./components/views/dialogs/SetDisplayNameDialog');
|
module.exports.components['views.dialogs.SetDisplayNameDialog'] = require('./components/views/dialogs/SetDisplayNameDialog');
|
||||||
module.exports.components['views.dialogs.TextInputDialog'] = require('./components/views/dialogs/TextInputDialog');
|
module.exports.components['views.dialogs.TextInputDialog'] = require('./components/views/dialogs/TextInputDialog');
|
||||||
module.exports.components['views.elements.EditableText'] = require('./components/views/elements/EditableText');
|
module.exports.components['views.elements.EditableText'] = require('./components/views/elements/EditableText');
|
||||||
|
module.exports.components['views.elements.EditableTextContainer'] = require('./components/views/elements/EditableTextContainer');
|
||||||
module.exports.components['views.elements.PowerSelector'] = require('./components/views/elements/PowerSelector');
|
module.exports.components['views.elements.PowerSelector'] = require('./components/views/elements/PowerSelector');
|
||||||
module.exports.components['views.elements.ProgressBar'] = require('./components/views/elements/ProgressBar');
|
module.exports.components['views.elements.ProgressBar'] = require('./components/views/elements/ProgressBar');
|
||||||
module.exports.components['views.elements.TintableSvg'] = require('./components/views/elements/TintableSvg');
|
module.exports.components['views.elements.TintableSvg'] = require('./components/views/elements/TintableSvg');
|
||||||
|
|
|
@ -49,6 +49,8 @@ module.exports = React.createClass({
|
||||||
label: '',
|
label: '',
|
||||||
placeholder: '',
|
placeholder: '',
|
||||||
editable: true,
|
editable: true,
|
||||||
|
className: "mx_EditableText",
|
||||||
|
placeholderClassName: "mx_EditableText_placeholder",
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
147
src/components/views/elements/EditableTextContainer.js
Normal file
147
src/components/views/elements/EditableTextContainer.js
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import sdk from '../../../index';
|
||||||
|
import q from 'q';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A component which wraps an EditableText, with a spinner while updates take
|
||||||
|
* place.
|
||||||
|
*
|
||||||
|
* Parent components should supply an 'onSubmit' callback which returns a
|
||||||
|
* promise; a spinner is shown until the promise resolves.
|
||||||
|
*
|
||||||
|
* The parent can also supply a 'getIntialValue' callback, which works in a
|
||||||
|
* similarly asynchronous way. If this is not provided, the initial value is
|
||||||
|
* taken from the 'initialValue' property.
|
||||||
|
*/
|
||||||
|
export default class EditableTextContainer extends React.Component {
|
||||||
|
constructor(props, context) {
|
||||||
|
super(props, context);
|
||||||
|
|
||||||
|
this._unmounted = false;
|
||||||
|
this.state = {
|
||||||
|
busy: false,
|
||||||
|
errorString: null,
|
||||||
|
value: props.initialValue,
|
||||||
|
};
|
||||||
|
this._onValueChanged=this._onValueChanged.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
if (this.props.getInitialValue === undefined) {
|
||||||
|
// use whatever was given in the initialValue property.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({busy: true});
|
||||||
|
|
||||||
|
this.props.getInitialValue().done(
|
||||||
|
(result) => {
|
||||||
|
if (this._unmounted) { return; }
|
||||||
|
this.setState({
|
||||||
|
busy: false,
|
||||||
|
value: result,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
if (this._unmounted) { return; }
|
||||||
|
this.setState({
|
||||||
|
errorString: error.toString(),
|
||||||
|
busy: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this._unmounted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_onValueChanged(value, shouldSubmit) {
|
||||||
|
if (!shouldSubmit) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
busy: true,
|
||||||
|
errorString: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.props.onSubmit(value).done(
|
||||||
|
() => {
|
||||||
|
if (this._unmounted) { return; }
|
||||||
|
this.setState({
|
||||||
|
busy: false,
|
||||||
|
value: value,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
if (this._unmounted) { return; }
|
||||||
|
this.setState({
|
||||||
|
errorString: error.toString(),
|
||||||
|
busy: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if (this.state.busy) {
|
||||||
|
var Loader = sdk.getComponent("elements.Spinner");
|
||||||
|
return (
|
||||||
|
<Loader />
|
||||||
|
);
|
||||||
|
} else if (this.state.errorString) {
|
||||||
|
return (
|
||||||
|
<div className="error">{this.state.errorString}</div>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
var EditableText = sdk.getComponent('elements.EditableText');
|
||||||
|
return (
|
||||||
|
<EditableText initialValue={this.state.value}
|
||||||
|
placeholder={this.props.placeholder}
|
||||||
|
onValueChanged={this._onValueChanged}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
EditableTextContainer.propTypes = {
|
||||||
|
/* callback to retrieve the initial value. */
|
||||||
|
getInitialValue: React.PropTypes.func,
|
||||||
|
|
||||||
|
/* initial value; used if getInitialValue is not given */
|
||||||
|
initialValue: React.PropTypes.string,
|
||||||
|
|
||||||
|
/* placeholder text to use when the value is empty (and not being
|
||||||
|
* edited) */
|
||||||
|
placeholder: React.PropTypes.string,
|
||||||
|
|
||||||
|
/* callback to update the value. Called with a single argument: the new
|
||||||
|
* value. */
|
||||||
|
onSubmit: React.PropTypes.func,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
EditableTextContainer.defaultProps = {
|
||||||
|
initialValue: "",
|
||||||
|
placeholder: "",
|
||||||
|
onSubmit: function(v) {return q(); },
|
||||||
|
};
|
|
@ -21,29 +21,10 @@ var MatrixClientPeg = require("../../../MatrixClientPeg");
|
||||||
|
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'ChangeDisplayName',
|
displayName: 'ChangeDisplayName',
|
||||||
propTypes: {
|
|
||||||
onFinished: React.PropTypes.func
|
|
||||||
},
|
|
||||||
|
|
||||||
getDefaultProps: function() {
|
_getDisplayName: function() {
|
||||||
return {
|
|
||||||
onFinished: function() {},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
getInitialState: function() {
|
|
||||||
return {
|
|
||||||
busy: false,
|
|
||||||
errorString: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
componentWillMount: function() {
|
|
||||||
var cli = MatrixClientPeg.get();
|
var cli = MatrixClientPeg.get();
|
||||||
this.setState({busy: true});
|
return cli.getProfileInfo(cli.credentials.userId).then(function(result) {
|
||||||
var self = this;
|
|
||||||
cli.getProfileInfo(cli.credentials.userId).done(function(result) {
|
|
||||||
|
|
||||||
var displayname = result.displayname;
|
var displayname = result.displayname;
|
||||||
if (!displayname) {
|
if (!displayname) {
|
||||||
if (MatrixClientPeg.get().isGuest()) {
|
if (MatrixClientPeg.get().isGuest()) {
|
||||||
|
@ -53,68 +34,26 @@ module.exports = React.createClass({
|
||||||
displayname = MatrixClientPeg.get().getUserIdLocalpart();
|
displayname = MatrixClientPeg.get().getUserIdLocalpart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return displayname;
|
||||||
self.setState({
|
|
||||||
displayName: displayname,
|
|
||||||
busy: false
|
|
||||||
});
|
|
||||||
}, function(error) {
|
}, function(error) {
|
||||||
self.setState({
|
throw new Error("Failed to fetch display name");
|
||||||
errorString: "Failed to fetch display name",
|
|
||||||
busy: false
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
changeDisplayname: function(new_displayname) {
|
_changeDisplayName: function(new_displayname) {
|
||||||
this.setState({
|
var cli = MatrixClientPeg.get();
|
||||||
busy: true,
|
return cli.setDisplayName(new_displayname).catch(function(e) {
|
||||||
errorString: null,
|
throw new Error("Failed to set display name");
|
||||||
})
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
MatrixClientPeg.get().setDisplayName(new_displayname).then(function() {
|
|
||||||
self.setState({
|
|
||||||
busy: false,
|
|
||||||
displayName: new_displayname
|
|
||||||
});
|
|
||||||
}, function(error) {
|
|
||||||
self.setState({
|
|
||||||
busy: false,
|
|
||||||
errorString: "Failed to set display name"
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
edit: function() {
|
|
||||||
this.refs.displayname_edit.edit()
|
|
||||||
},
|
|
||||||
|
|
||||||
onValueChanged: function(new_value, shouldSubmit) {
|
|
||||||
if (shouldSubmit) {
|
|
||||||
this.changeDisplayname(new_value);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
if (this.state.busy) {
|
var EditableTextContainer = sdk.getComponent('elements.EditableTextContainer');
|
||||||
var Loader = sdk.getComponent("elements.Spinner");
|
return (
|
||||||
return (
|
<EditableTextContainer
|
||||||
<Loader />
|
getInitialValue={this._getDisplayName}
|
||||||
);
|
placeholder="No display name"
|
||||||
} else if (this.state.errorString) {
|
onSubmit={this._changeDisplayName} />
|
||||||
return (
|
);
|
||||||
<div className="error">{this.state.errorString}</div>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
var EditableText = sdk.getComponent('elements.EditableText');
|
|
||||||
return (
|
|
||||||
<EditableText ref="displayname_edit" initialValue={this.state.displayName}
|
|
||||||
className="mx_EditableText"
|
|
||||||
placeholderClassName="mx_EditableText_placeholder"
|
|
||||||
placeholder="No display name"
|
|
||||||
onValueChanged={this.onValueChanged} />
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue