From b90ceaa1111451e6184d1b7c350f7c1485fb9140 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Thu, 15 Jun 2017 11:49:16 +0100 Subject: [PATCH] Display a spinner until new room object after join success If we successfully join, display a spinner until the js-sdk indicates (via room membership event or room event) that we can start using the room normally. A room event indicates we have never seen that room which means we need to use the new room object to clobber state.room. This is to make sure we replace the room that is set up for peeking with the room that can be used normally. For historical rooms, this isn't a problem. This is a workaround for the fact that when peeking, the js-sdk calls onRoom, which is difficult to handle from the clients perspective because onRoom should only be called for rooms that you've never seen before. But if you peek a room that you've joined and left and get an onRoom, you run into trouble. You also can't just always use onRoomMembership because this won't be triggered for the first time you see the room. So we end up using a combination of both. See https://github.com/matrix-org/matrix-js-sdk/issues/464 for discussion on improving this --- src/components/structures/RoomView.js | 33 +++++++++++++++------------ 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 0cd8a95938..aa02491f49 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -179,6 +179,10 @@ module.exports = React.createClass({ 'joining?', newState.joining, ); + // finished joining, start waiting for a room and show a spinner. See onRoom. + newState.waitingForRoom = this.state.joining && !newState.joining && + !RoomViewStore.getJoinError(); + // NB: This does assume that the roomID will not change for the lifetime of // the RoomView instance if (initial) { @@ -218,23 +222,18 @@ module.exports = React.createClass({ // which must be by alias or invite wherever possible (peeking currently does // not work over federation). - // NB. We peek if we are not in the room, although if we try to peek into - // a room in which we have a member event (ie. we've left) synapse will just - // send us the same data as we get in the sync (ie. the last events we saw). + // NB. We peek if we have never seen the room before (i.e. js-sdk does not know + // about it). We don't peek in the historical case where we were joined but are + // now not joined because the js-sdk peeking API will clobber our historical room, + // making it impossible to indicate a newly joined room. const room = this.state.room; - let isUserJoined = null; if (room) { - isUserJoined = room.hasMembershipState( - MatrixClientPeg.get().credentials.userId, 'join', - ); - this._updateAutoComplete(room); this.tabComplete.loadEntries(room); - } - if (!isUserJoined && !this.state.joining && this.state.roomId) { + } else if (!this.state.joining && this.state.roomId) { if (this.props.autoJoin) { this.onJoinButtonClicked(); - } else if (this.state.roomId) { + } else { console.log("Attempting to peek into room %s", this.state.roomId); this.setState({ peekLoading: true, @@ -622,6 +621,7 @@ module.exports = React.createClass({ } this.setState({ room: room, + waitingForRoom: false, }, () => { this._onRoomLoaded(room); }); @@ -677,7 +677,12 @@ module.exports = React.createClass({ onRoomMemberMembership: function(ev, member, oldMembership) { if (member.userId == MatrixClientPeg.get().credentials.userId) { - this.forceUpdate(); + + if (member.membership === 'join') { + this.setState({ + waitingForRoom: false, + }); + } } }, @@ -1464,7 +1469,7 @@ module.exports = React.createClass({ onRejectClick={ this.onRejectThreepidInviteButtonClicked } canPreview={ false } error={ this.state.roomLoadError } roomAlias={room_alias} - spinner={this.state.joining} + spinner={this.state.joining || this.state.waitingForRoom} inviterName={inviterName} invitedEmail={invitedEmail} room={this.state.room} @@ -1583,7 +1588,7 @@ module.exports = React.createClass({