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
This commit is contained in:
Luke Barnard 2017-06-15 11:49:16 +01:00
parent a05bafed6a
commit b90ceaa111

View file

@ -179,6 +179,10 @@ module.exports = React.createClass({
'joining?', newState.joining, '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 // NB: This does assume that the roomID will not change for the lifetime of
// the RoomView instance // the RoomView instance
if (initial) { if (initial) {
@ -218,23 +222,18 @@ module.exports = React.createClass({
// which must be by alias or invite wherever possible (peeking currently does // which must be by alias or invite wherever possible (peeking currently does
// not work over federation). // not work over federation).
// NB. We peek if we are not in the room, although if we try to peek into // NB. We peek if we have never seen the room before (i.e. js-sdk does not know
// a room in which we have a member event (ie. we've left) synapse will just // about it). We don't peek in the historical case where we were joined but are
// send us the same data as we get in the sync (ie. the last events we saw). // 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; const room = this.state.room;
let isUserJoined = null;
if (room) { if (room) {
isUserJoined = room.hasMembershipState(
MatrixClientPeg.get().credentials.userId, 'join',
);
this._updateAutoComplete(room); this._updateAutoComplete(room);
this.tabComplete.loadEntries(room); this.tabComplete.loadEntries(room);
} } else if (!this.state.joining && this.state.roomId) {
if (!isUserJoined && !this.state.joining && this.state.roomId) {
if (this.props.autoJoin) { if (this.props.autoJoin) {
this.onJoinButtonClicked(); this.onJoinButtonClicked();
} else if (this.state.roomId) { } else {
console.log("Attempting to peek into room %s", this.state.roomId); console.log("Attempting to peek into room %s", this.state.roomId);
this.setState({ this.setState({
peekLoading: true, peekLoading: true,
@ -622,6 +621,7 @@ module.exports = React.createClass({
} }
this.setState({ this.setState({
room: room, room: room,
waitingForRoom: false,
}, () => { }, () => {
this._onRoomLoaded(room); this._onRoomLoaded(room);
}); });
@ -677,7 +677,12 @@ module.exports = React.createClass({
onRoomMemberMembership: function(ev, member, oldMembership) { onRoomMemberMembership: function(ev, member, oldMembership) {
if (member.userId == MatrixClientPeg.get().credentials.userId) { 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 } onRejectClick={ this.onRejectThreepidInviteButtonClicked }
canPreview={ false } error={ this.state.roomLoadError } canPreview={ false } error={ this.state.roomLoadError }
roomAlias={room_alias} roomAlias={room_alias}
spinner={this.state.joining} spinner={this.state.joining || this.state.waitingForRoom}
inviterName={inviterName} inviterName={inviterName}
invitedEmail={invitedEmail} invitedEmail={invitedEmail}
room={this.state.room} room={this.state.room}
@ -1583,7 +1588,7 @@ module.exports = React.createClass({
<RoomPreviewBar onJoinClick={this.onJoinButtonClicked} <RoomPreviewBar onJoinClick={this.onJoinButtonClicked}
onForgetClick={ this.onForgetClick } onForgetClick={ this.onForgetClick }
onRejectClick={this.onRejectThreepidInviteButtonClicked} onRejectClick={this.onRejectThreepidInviteButtonClicked}
spinner={this.state.joining} spinner={this.state.joining || this.state.waitingForRoom}
inviterName={inviterName} inviterName={inviterName}
invitedEmail={invitedEmail} invitedEmail={invitedEmail}
canPreview={this.state.canPeek} canPreview={this.state.canPeek}