Merge remote-tracking branch 'origin/develop' into dbkr/email_notifs

This commit is contained in:
David Baker 2016-04-29 11:09:02 +01:00
commit fab7111fd7
7 changed files with 45 additions and 10 deletions

View file

@ -25,9 +25,14 @@ You can use matrix-react-sdk directly, but to do this you would have to provide
How to customise the SDK How to customise the SDK
======================== ========================
The SDK uses the 'atomic' design pattern as seen at http://patternlab.io to The SDK formerly used the 'atomic' design pattern as seen at http://patternlab.io to
encourage a very modular and reusable architecture, making it easy to encourage a very modular and reusable architecture, making it easy to
customise and use UI widgets independently of the rest of the SDK and your app. customise and use UI widgets independently of the rest of the SDK and your app.
So unfortunately at the moment this document does not describe how to customize your UI!
###This is the old description for the atomic design pattern:
In practice this means: In practice this means:
* The UI of the app is strictly split up into a hierarchy of components. * The UI of the app is strictly split up into a hierarchy of components.

View file

@ -1181,7 +1181,7 @@ module.exports = React.createClass({
defaultIsUrl={this.props.config.default_is_url} defaultIsUrl={this.props.config.default_is_url}
customHsUrl={this.getCurrentHsUrl()} customHsUrl={this.getCurrentHsUrl()}
customIsUrl={this.getCurrentIsUrl()} customIsUrl={this.getCurrentIsUrl()}
onForgotPasswordClick={this.onForgotPasswordClick} onForgotPasswordClick={this.onForgotPasswordClick}
onLoginAsGuestClick={this.props.enableGuest && this.props.config && this.props.config.default_hs_url ? this._registerAsGuest.bind(this, true) : undefined} onLoginAsGuestClick={this.props.enableGuest && this.props.config && this.props.config.default_hs_url ? this._registerAsGuest.bind(this, true) : undefined}
onCancelClick={ this.state.guestCreds ? this.onReturnToGuestClick : null } onCancelClick={ this.state.guestCreds ? this.onReturnToGuestClick : null }
/> />

View file

@ -85,6 +85,12 @@ module.exports = React.createClass({
// opaque readreceipt info for each userId; used by ReadReceiptMarker // opaque readreceipt info for each userId; used by ReadReceiptMarker
// to manage its animations // to manage its animations
this._readReceiptMap = {}; this._readReceiptMap = {};
this._isMounted = true;
},
componentWillUnmount: function() {
this._isMounted = false;
}, },
/* get the DOM node representing the given event */ /* get the DOM node representing the given event */
@ -201,6 +207,10 @@ module.exports = React.createClass({
} }
}, },
_isUnmounting: function() {
return !this._isMounted;
},
_getEventTiles: function() { _getEventTiles: function() {
var EventTile = sdk.getComponent('rooms.EventTile'); var EventTile = sdk.getComponent('rooms.EventTile');
@ -351,6 +361,7 @@ module.exports = React.createClass({
onWidgetLoad={this._onWidgetLoad} onWidgetLoad={this._onWidgetLoad}
readReceipts={readReceipts} readReceipts={readReceipts}
readReceiptMap={this._readReceiptMap} readReceiptMap={this._readReceiptMap}
checkUnmounting={this._isUnmounting}
eventSendStatus={mxEv.status} eventSendStatus={mxEv.status}
last={last} isSelectedEvent={highlight}/> last={last} isSelectedEvent={highlight}/>
</li> </li>

View file

@ -210,7 +210,7 @@ module.exports = React.createClass({
MatrixClientPeg.get().removeListener("RoomState.members", this.onRoomStateMember); MatrixClientPeg.get().removeListener("RoomState.members", this.onRoomStateMember);
} }
window.removeEventListener('resize', this.onResize); window.removeEventListener('resize', this.onResize);
// no need to do this as Dir & Settings are now overlays. It just burnt CPU. // no need to do this as Dir & Settings are now overlays. It just burnt CPU.
// console.log("Tinter.tint from RoomView.unmount"); // console.log("Tinter.tint from RoomView.unmount");
@ -878,7 +878,7 @@ module.exports = React.createClass({
this.setState({ this.setState({
uploadingRoomSettings: true, uploadingRoomSettings: true,
}); });
var newName = this.refs.header.getEditedName(); var newName = this.refs.header.getEditedName();
if (newName !== undefined) { if (newName !== undefined) {
this.refs.room_settings.setName(newName); this.refs.room_settings.setName(newName);
@ -887,7 +887,7 @@ module.exports = React.createClass({
if (newTopic !== undefined) { if (newTopic !== undefined) {
this.refs.room_settings.setTopic(newTopic); this.refs.room_settings.setTopic(newTopic);
} }
this.refs.room_settings.save().then((results) => { this.refs.room_settings.save().then((results) => {
var fails = results.filter(function(result) { return result.state !== "fulfilled" }); var fails = results.filter(function(result) { return result.state !== "fulfilled" });
console.log("Settings saved with %s errors", fails.length); console.log("Settings saved with %s errors", fails.length);
@ -1229,7 +1229,7 @@ module.exports = React.createClass({
rightPanelCollapsed={ this.props.rightPanelCollapsed } rightPanelCollapsed={ this.props.rightPanelCollapsed }
/> />
<div className="mx_RoomView_auxPanel"> <div className="mx_RoomView_auxPanel">
<RoomPreviewBar onJoinClick={ this.onJoinButtonClicked } <RoomPreviewBar onJoinClick={ this.onJoinButtonClicked }
onRejectClick={ this.onRejectThreepidInviteButtonClicked } onRejectClick={ this.onRejectThreepidInviteButtonClicked }
canJoin={ true } canPreview={ false } canJoin={ true } canPreview={ false }
spinner={this.state.joining} spinner={this.state.joining}
@ -1266,7 +1266,7 @@ module.exports = React.createClass({
<div className="mx_RoomView"> <div className="mx_RoomView">
<RoomHeader ref="header" room={this.state.room}/> <RoomHeader ref="header" room={this.state.room}/>
<div className="mx_RoomView_auxPanel"> <div className="mx_RoomView_auxPanel">
<RoomPreviewBar onJoinClick={ this.onJoinButtonClicked } <RoomPreviewBar onJoinClick={ this.onJoinButtonClicked }
onRejectClick={ this.onRejectButtonClicked } onRejectClick={ this.onRejectButtonClicked }
inviterName={ inviterName } inviterName={ inviterName }
canJoin={ true } canPreview={ false } canJoin={ true } canPreview={ false }
@ -1402,8 +1402,8 @@ module.exports = React.createClass({
} }
voiceMuteButton = voiceMuteButton =
<div className="mx_RoomView_voipButton" onClick={this.onMuteAudioClick}> <div className="mx_RoomView_voipButton" onClick={this.onMuteAudioClick}>
<img src={call.isMicrophoneMuted() ? "img/voice-unmute.svg" : "img/voice-mute.svg"} <img src={call.isMicrophoneMuted() ? "img/voice-unmute.svg" : "img/voice-mute.svg"}
alt={call.isMicrophoneMuted() ? "Click to unmute audio" : "Click to mute audio"} alt={call.isMicrophoneMuted() ? "Click to unmute audio" : "Click to mute audio"}
width="21" height="26"/> width="21" height="26"/>
</div> </div>

View file

@ -116,6 +116,12 @@ module.exports = React.createClass({
*/ */
readReceiptMap: React.PropTypes.object, readReceiptMap: React.PropTypes.object,
/* A function which is used to check if the parent panel is being
* unmounted, to avoid unnecessary work. Should return true if we
* are being unmounted.
*/
checkUnmounting: React.PropTypes.func,
/* the status of this event - ie, mxEvent.status. Denormalised to here so /* the status of this event - ie, mxEvent.status. Denormalised to here so
* that we can tell when it changes. */ * that we can tell when it changes. */
eventSendStatus: React.PropTypes.string, eventSendStatus: React.PropTypes.string,
@ -261,6 +267,7 @@ module.exports = React.createClass({
<ReadReceiptMarker key={userId} member={member} <ReadReceiptMarker key={userId} member={member}
leftOffset={left} hidden={hidden} leftOffset={left} hidden={hidden}
readReceiptInfo={readReceiptInfo} readReceiptInfo={readReceiptInfo}
checkUnmounting={this.props.checkUnmounting}
suppressAnimation={this._suppressReadReceiptAnimation} suppressAnimation={this._suppressReadReceiptAnimation}
onClick={this.toggleAllReadAvatars} onClick={this.toggleAllReadAvatars}
/> />

View file

@ -53,6 +53,11 @@ module.exports = React.createClass({
// this room // this room
readReceiptInfo: React.PropTypes.object, readReceiptInfo: React.PropTypes.object,
// A function which is used to check if the parent panel is being
// unmounted, to avoid unnecessary work. Should return true if we
// are being unmounted.
checkUnmounting: React.PropTypes.func,
// callback for clicks on this RR // callback for clicks on this RR
onClick: React.PropTypes.func, onClick: React.PropTypes.func,
}, },
@ -81,6 +86,13 @@ module.exports = React.createClass({
return; return;
} }
// checking the DOM properties can force a re-layout, which can be
// quite expensive; so if the parent messagepanel is being unmounted,
// then don't bother with this.
if (this.props.checkUnmounting && this.props.checkUnmounting()) {
return;
}
var avatarNode = ReactDOM.findDOMNode(this); var avatarNode = ReactDOM.findDOMNode(this);
rrInfo.top = avatarNode.offsetTop; rrInfo.top = avatarNode.offsetTop;
rrInfo.left = avatarNode.offsetLeft; rrInfo.left = avatarNode.offsetLeft;

View file

@ -97,7 +97,7 @@ module.exports = React.createClass({
</div> </div>
<div className="mx_RoomPreviewBar_warningText"> <div className="mx_RoomPreviewBar_warningText">
This invitation was sent to <b><span className="email">{this.props.invitedEmail}</span></b>, which is not associated with this account.<br/> This invitation was sent to <b><span className="email">{this.props.invitedEmail}</span></b>, which is not associated with this account.<br/>
You may wish to login with a different account, or add this email to your this account. You may wish to login with a different account, or add this email to this account.
</div> </div>
</div> </div>
} }