General code cleanup / tweaks / fixes
- Swap Phases enum to be using string literals - Swap roomId prop on UserSettings for a more sane onUserSettingsClose and make MatrixChat responsible for swapping the room. - s/then/done/ when terminating Promise chains to avoid subtle errors. - Rejig render() of UserSettings so we don't need to indent quite so much.
This commit is contained in:
parent
b9ba4475b8
commit
1af5018597
3 changed files with 170 additions and 166 deletions
|
@ -17,19 +17,10 @@ limitations under the License.
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var MatrixClientPeg = require("./MatrixClientPeg");
|
var MatrixClientPeg = require("./MatrixClientPeg");
|
||||||
var sdk = require('./index');
|
var Notifier = require("./Notifier");
|
||||||
|
|
||||||
// XXX: should we be doing something here to use this as a singleton rather than
|
|
||||||
// class methods?
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
||||||
// we add these wrappers to the js-sdk here in case we want to do react-specific
|
|
||||||
// dispatches or similar in future, and to give us a place to clearly separate
|
|
||||||
// business logic specific from the 'thin' react component and parent wiring component
|
|
||||||
// which actually handles the UI.
|
|
||||||
// XXX: I'm not convinced this abstraction is worth it though.
|
|
||||||
|
|
||||||
loadProfileInfo: function() {
|
loadProfileInfo: function() {
|
||||||
var cli = MatrixClientPeg.get();
|
var cli = MatrixClientPeg.get();
|
||||||
return cli.getProfileInfo(cli.credentials.userId);
|
return cli.getProfileInfo(cli.credentials.userId);
|
||||||
|
@ -48,13 +39,10 @@ module.exports = {
|
||||||
},
|
},
|
||||||
|
|
||||||
getEnableNotifications: function() {
|
getEnableNotifications: function() {
|
||||||
var Notifier = sdk.getComponent('organisms.Notifier');
|
|
||||||
return Notifier.isEnabled();
|
return Notifier.isEnabled();
|
||||||
},
|
},
|
||||||
|
|
||||||
setEnableNotifications: function(enable) {
|
setEnableNotifications: function(enable) {
|
||||||
var Notifier = sdk.getComponent('organisms.Notifier');
|
|
||||||
var self = this;
|
|
||||||
if (!Notifier.supportsDesktopNotifications()) {
|
if (!Notifier.supportsDesktopNotifications()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -70,11 +58,6 @@ module.exports = {
|
||||||
password: old_password
|
password: old_password
|
||||||
};
|
};
|
||||||
|
|
||||||
this.setState({
|
|
||||||
phase: this.Phases.Uploading,
|
|
||||||
errorString: '',
|
|
||||||
})
|
|
||||||
|
|
||||||
return cli.setPassword(authDict, new_password);
|
return cli.setPassword(authDict, new_password);
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
|
|
|
@ -628,6 +628,22 @@ module.exports = React.createClass({
|
||||||
this.showScreen("settings");
|
this.showScreen("settings");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onUserSettingsClose: function() {
|
||||||
|
// XXX: use browser history instead to find the previous room?
|
||||||
|
if (this.state.currentRoom) {
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'view_room',
|
||||||
|
room_id: this.state.currentRoom,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'view_indexed_room',
|
||||||
|
roomIndex: 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var LeftPanel = sdk.getComponent('structures.LeftPanel');
|
var LeftPanel = sdk.getComponent('structures.LeftPanel');
|
||||||
var RoomView = sdk.getComponent('structures.RoomView');
|
var RoomView = sdk.getComponent('structures.RoomView');
|
||||||
|
@ -660,7 +676,7 @@ module.exports = React.createClass({
|
||||||
right_panel = <RightPanel roomId={this.state.currentRoom} collapsed={this.state.collapse_rhs} />
|
right_panel = <RightPanel roomId={this.state.currentRoom} collapsed={this.state.collapse_rhs} />
|
||||||
break;
|
break;
|
||||||
case this.PageTypes.UserSettings:
|
case this.PageTypes.UserSettings:
|
||||||
page_element = <UserSettings roomId={this.state.currentRoom} />
|
page_element = <UserSettings onClose={this.onUserSettingsClose} />
|
||||||
right_panel = <RightPanel collapsed={this.state.collapse_rhs}/>
|
right_panel = <RightPanel collapsed={this.state.collapse_rhs}/>
|
||||||
break;
|
break;
|
||||||
case this.PageTypes.CreateRoom:
|
case this.PageTypes.CreateRoom:
|
||||||
|
|
|
@ -25,10 +25,14 @@ var UserSettingsStore = require('../../UserSettingsStore');
|
||||||
module.exports = React.createClass({
|
module.exports = React.createClass({
|
||||||
displayName: 'UserSettings',
|
displayName: 'UserSettings',
|
||||||
|
|
||||||
Phases: {
|
propTypes: {
|
||||||
Loading: "loading",
|
onClose: React.PropTypes.func
|
||||||
Saving: "saving",
|
},
|
||||||
Display: "display",
|
|
||||||
|
getDefaultProps: function() {
|
||||||
|
return {
|
||||||
|
onClose: function() {}
|
||||||
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
|
@ -37,38 +41,34 @@ module.exports = React.createClass({
|
||||||
displayName: null,
|
displayName: null,
|
||||||
threePids: [],
|
threePids: [],
|
||||||
clientVersion: version,
|
clientVersion: version,
|
||||||
phase: this.Phases.Loading,
|
phase: "UserSettings.LOADING", // LOADING, DISPLAY, SAVING
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillMount: function() {
|
componentWillMount: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var profilePromise = UserSettingsStore.loadProfileInfo();
|
q.all([
|
||||||
var threepidPromise = UserSettingsStore.loadThreePids();
|
UserSettingsStore.loadProfileInfo(), UserSettingsStore.loadThreePids()
|
||||||
|
]).done(function(resps) {
|
||||||
|
self.setState({
|
||||||
|
avatarUrl: resps[0].avatar_url,
|
||||||
|
displayName: resps[0].displayname,
|
||||||
|
threepids: resps[1].threepids,
|
||||||
|
phase: "UserSettings.DISPLAY",
|
||||||
|
});
|
||||||
|
|
||||||
q.all([profilePromise, threepidPromise]).then(
|
// keep a copy of the original state in order to track changes
|
||||||
function(resps) {
|
self.setState({
|
||||||
self.setState({
|
originalState: self.state
|
||||||
avatarUrl: resps[0].avatar_url,
|
});
|
||||||
displayName: resps[0].displayname,
|
}, function(error) {
|
||||||
threepids: resps[1].threepids,
|
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
phase: self.Phases.Display,
|
Modal.createDialog(ErrorDialog, {
|
||||||
});
|
title: "Can't load user settings",
|
||||||
|
description: error.toString()
|
||||||
// keep a copy of the original state in order to track changes
|
});
|
||||||
self.setState({
|
});
|
||||||
originalState: self.state
|
|
||||||
});
|
|
||||||
},
|
|
||||||
function(error) {
|
|
||||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
|
||||||
Modal.createDialog(ErrorDialog, {
|
|
||||||
title: "Can't load user settings",
|
|
||||||
description: error.toString()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
|
@ -95,51 +95,33 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.state.originalState.threepids.length !== this.state.threepids.length ||
|
if (this.state.originalState.threepids.length !== this.state.threepids.length ||
|
||||||
this.state.originalState.threepids.every(function(element, index) {
|
this.state.originalState.threepids.every((element, index) => {
|
||||||
return element === this.state.threepids[index];
|
return element === this.state.threepids[index];
|
||||||
}))
|
})) {
|
||||||
{
|
savePromises.push(
|
||||||
savePromises.push( UserSettingsStore.saveThreePids(this.state.threepids) );
|
UserSettingsStore.saveThreePids(this.state.threepids)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.setState({
|
self.setState({
|
||||||
phase: self.Phases.Saving,
|
phase: "UserSettings.SAVING",
|
||||||
});
|
});
|
||||||
|
|
||||||
q.all(savePromises).then(
|
q.all(savePromises).done(function(resps) {
|
||||||
function(resps) {
|
self.setState({
|
||||||
self.setState({
|
phase: "UserSettings.DISPLAY",
|
||||||
phase: self.Phases.Display,
|
|
||||||
});
|
|
||||||
self.onClose();
|
|
||||||
},
|
|
||||||
function(error) {
|
|
||||||
self.setState({
|
|
||||||
phase: self.Phases.Display,
|
|
||||||
});
|
|
||||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
|
||||||
Modal.createDialog(ErrorDialog, {
|
|
||||||
title: "Can't save user settings",
|
|
||||||
description: error.toString()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
onClose: function(ev) {
|
|
||||||
// XXX: use browser history instead to find the previous room?
|
|
||||||
if (this.props.roomId) {
|
|
||||||
dis.dispatch({
|
|
||||||
action: 'view_room',
|
|
||||||
room_id: this.props.roomId,
|
|
||||||
});
|
});
|
||||||
}
|
self.props.onClose();
|
||||||
else {
|
}, function(error) {
|
||||||
dis.dispatch({
|
self.setState({
|
||||||
action: 'view_indexed_room',
|
phase: "UserSettings.DISPLAY",
|
||||||
roomIndex: 0,
|
|
||||||
});
|
});
|
||||||
}
|
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
|
Modal.createDialog(ErrorDialog, {
|
||||||
|
title: "Can't save user settings",
|
||||||
|
description: error.toString()
|
||||||
|
});
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onAction: function(payload) {
|
onAction: function(payload) {
|
||||||
|
@ -170,7 +152,9 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
onLogoutClicked: function(ev) {
|
onLogoutClicked: function(ev) {
|
||||||
var LogoutPrompt = sdk.getComponent('dialogs.LogoutPrompt');
|
var LogoutPrompt = sdk.getComponent('dialogs.LogoutPrompt');
|
||||||
this.logoutModal = Modal.createDialog(LogoutPrompt, {onCancel: this.onLogoutPromptCancel});
|
this.logoutModal = Modal.createDialog(
|
||||||
|
LogoutPrompt, {onCancel: this.onLogoutPromptCancel}
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
onLogoutPromptCancel: function() {
|
onLogoutPromptCancel: function() {
|
||||||
|
@ -193,100 +177,121 @@ module.exports = React.createClass({
|
||||||
var Loader = sdk.getComponent("elements.Spinner");
|
var Loader = sdk.getComponent("elements.Spinner");
|
||||||
var saving;
|
var saving;
|
||||||
switch (this.state.phase) {
|
switch (this.state.phase) {
|
||||||
case this.Phases.Loading:
|
case "UserSettings.LOADING":
|
||||||
return <Loader />
|
return <Loader />
|
||||||
case this.Phases.Saving:
|
case "UserSettings.SAVING":
|
||||||
saving = <Loader />
|
saving = <Loader />
|
||||||
case this.Phases.Display:
|
// intentional fall through
|
||||||
var RoomHeader = sdk.getComponent('rooms.RoomHeader');
|
case "UserSettings.DISPLAY":
|
||||||
return (
|
break; // quit the switch to return the common state
|
||||||
<div className="mx_UserSettings">
|
default:
|
||||||
<RoomHeader simpleHeader="Settings" onCancelClick={ this.onClose } />
|
throw new Error("Unknown state.phase => " + this.state.phase);
|
||||||
|
}
|
||||||
|
// can only get here if phase is UserSettings.DISPLAY
|
||||||
|
var RoomHeader = sdk.getComponent('rooms.RoomHeader');
|
||||||
|
return (
|
||||||
|
<div className="mx_UserSettings">
|
||||||
|
<RoomHeader simpleHeader="Settings" onCancelClick={ this.props.onClose } />
|
||||||
|
|
||||||
<h2>Profile</h2>
|
<h2>Profile</h2>
|
||||||
|
|
||||||
<div className="mx_UserSettings_section">
|
<div className="mx_UserSettings_section">
|
||||||
<div className="mx_UserSettings_profileTable">
|
<div className="mx_UserSettings_profileTable">
|
||||||
<div className="mx_UserSettings_profileTableRow">
|
<div className="mx_UserSettings_profileTableRow">
|
||||||
|
<div className="mx_UserSettings_profileLabelCell">
|
||||||
|
<label htmlFor="displayName">Display name</label>
|
||||||
|
</div>
|
||||||
|
<div className="mx_UserSettings_profileInputCell">
|
||||||
|
<input id="displayName" ref="displayName"
|
||||||
|
value={ this.state.displayName }
|
||||||
|
onChange={ this.onDisplayNameChange } />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{this.state.threepids.map(function(val, pidIndex) {
|
||||||
|
var id = "email-" + val.address;
|
||||||
|
return (
|
||||||
|
<div className="mx_UserSettings_profileTableRow" key={pidIndex}>
|
||||||
<div className="mx_UserSettings_profileLabelCell">
|
<div className="mx_UserSettings_profileLabelCell">
|
||||||
<label htmlFor="displayName">Display name</label>
|
<label htmlFor={id}>Email</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_UserSettings_profileInputCell">
|
<div className="mx_UserSettings_profileInputCell">
|
||||||
<input id="displayName" ref="displayName" value={ this.state.displayName } onChange={ this.onDisplayNameChange } />
|
<input key={val.address} id={id} value={val.address} disabled />
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{this.state.threepids.map(function(val) {
|
|
||||||
var id = "email-" + val.address;
|
|
||||||
return (
|
|
||||||
<div className="mx_UserSettings_profileTableRow">
|
|
||||||
<div className="mx_UserSettings_profileLabelCell">
|
|
||||||
<label htmlFor={ id }>Email</label>
|
|
||||||
</div>
|
|
||||||
<div className="mx_UserSettings_profileInputCell">
|
|
||||||
<input key={val.address} id={ id } value={ val.address } disabled />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
|
|
||||||
<div className="mx_UserSettings_profileTableRow">
|
|
||||||
<div className="mx_UserSettings_profileLabelCell">
|
|
||||||
<label htmlFor="password1">New password</label>
|
|
||||||
</div>
|
|
||||||
<div className="mx_UserSettings_profileInputCell">
|
|
||||||
<input id="password1" ref="password1" value={ this.state.password1 } />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="mx_UserSettings_profileTableRow">
|
|
||||||
<div className="mx_UserSettings_profileLabelCell">
|
|
||||||
<label htmlFor="password2">Confirm new password</label>
|
|
||||||
</div>
|
|
||||||
<div className="mx_UserSettings_profileInputCell">
|
|
||||||
<input id="password2" ref="password2" value={ this.state.password2 } />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
|
||||||
|
<div className="mx_UserSettings_profileTableRow">
|
||||||
|
<div className="mx_UserSettings_profileLabelCell">
|
||||||
|
<label htmlFor="password1">New password</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="mx_UserSettings_profileInputCell">
|
||||||
<div className="mx_UserSettings_avatarPicker">
|
<input id="password1" ref="password1"
|
||||||
<div className="mx_UserSettings_avatarPicker_edit" onClick={this.editAvatar}></div>
|
value={ this.state.password1 } />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mx_UserSettings_profileTableRow">
|
||||||
|
<div className="mx_UserSettings_profileLabelCell">
|
||||||
|
<label htmlFor="password2">Confirm new password</label>
|
||||||
|
</div>
|
||||||
|
<div className="mx_UserSettings_profileInputCell">
|
||||||
|
<input id="password2" ref="password2"
|
||||||
|
value={ this.state.password2 } />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mx_UserSettings_logout">
|
</div>
|
||||||
<div className="mx_UserSettings_button" onClick={this.onLogoutClicked}>Log out</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2>Notifications</h2>
|
<div className="mx_UserSettings_avatarPicker">
|
||||||
|
<div className="mx_UserSettings_avatarPicker_edit"
|
||||||
<div className="mx_UserSettings_section">
|
onClick={this.editAvatar}>
|
||||||
<div className="mx_UserSettings_notifTable">
|
|
||||||
<div className="mx_UserSettings_notifTableRow">
|
|
||||||
<div className="mx_UserSettings_notifInputCell">
|
|
||||||
<input id="enableNotifications" ref="enableNotifications" type="checkbox" checked={ this.state.enableNotifications } onChange={ this.onEnableNotificationsChange } />
|
|
||||||
</div>
|
|
||||||
<div className="mx_UserSettings_notifLabelCell">
|
|
||||||
<label htmlFor="enableNotifications">Enable desktop notifications</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2>Advanced</h2>
|
|
||||||
|
|
||||||
<div className="mx_UserSettings_section">
|
|
||||||
<div className="mx_UserSettings_advanced">
|
|
||||||
Version {this.state.clientVersion}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mx_UserSettings_save">
|
|
||||||
<div className="mx_UserSettings_spinner">{ saving }</div>
|
|
||||||
<div className="mx_UserSettings_button" onClick={this.onSaveClicked}>Save and close</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
</div>
|
||||||
}
|
|
||||||
|
<div className="mx_UserSettings_logout">
|
||||||
|
<div className="mx_UserSettings_button" onClick={this.onLogoutClicked}>
|
||||||
|
Log out
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Notifications</h2>
|
||||||
|
|
||||||
|
<div className="mx_UserSettings_section">
|
||||||
|
<div className="mx_UserSettings_notifTable">
|
||||||
|
<div className="mx_UserSettings_notifTableRow">
|
||||||
|
<div className="mx_UserSettings_notifInputCell">
|
||||||
|
<input id="enableNotifications"
|
||||||
|
ref="enableNotifications"
|
||||||
|
type="checkbox"
|
||||||
|
checked={ this.state.enableNotifications }
|
||||||
|
onChange={ this.onEnableNotificationsChange } />
|
||||||
|
</div>
|
||||||
|
<div className="mx_UserSettings_notifLabelCell">
|
||||||
|
<label htmlFor="enableNotifications">
|
||||||
|
Enable desktop notifications
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Advanced</h2>
|
||||||
|
|
||||||
|
<div className="mx_UserSettings_section">
|
||||||
|
<div className="mx_UserSettings_advanced">
|
||||||
|
Version {this.state.clientVersion}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mx_UserSettings_save">
|
||||||
|
<div className="mx_UserSettings_spinner">{ saving }</div>
|
||||||
|
<div className="mx_UserSettings_button" onClick={this.onSaveClicked}>
|
||||||
|
Save and close
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue