Replace sdkReady with firstSyncPromise, add mx_last_room_id
- Create a promise that will serve as a lock to be blocked on by things that need to wait for the first sync before accessing state. - Use this promise to block `view_room` calls until a sync has occured instead of just dropping them silently if the sync hasn't happened yet. - Store the current room ID in a localStorage item `mx_last_room_id` when `view_room` fires. This persists the last viewed room ID so that it can be restored on refresh, browser quit. This replaces the previous logic which set the room following a sync based on the most recent unread room.
This commit is contained in:
parent
4b5b892135
commit
95b40a976c
1 changed files with 41 additions and 39 deletions
|
@ -194,6 +194,10 @@ module.exports = React.createClass({
|
|||
componentWillMount: function() {
|
||||
SdkConfig.put(this.props.config);
|
||||
|
||||
// Used by _viewRoom before getting state from sync
|
||||
this.firstSyncComplete = false;
|
||||
this.firstSyncPromise = q.defer();
|
||||
|
||||
if (this.props.config.sync_timeline_limit) {
|
||||
MatrixClientPeg.opts.initialSyncLimit = this.props.config.sync_timeline_limit;
|
||||
}
|
||||
|
@ -637,26 +641,38 @@ module.exports = React.createClass({
|
|||
}
|
||||
}
|
||||
|
||||
if (this.sdkReady) {
|
||||
// if the SDK is not ready yet, remember what room
|
||||
// we're supposed to be on but don't notify about
|
||||
// the new screen yet (we won't be showing it yet)
|
||||
// The normal case where this happens is navigating
|
||||
// to the room in the URL bar on page load.
|
||||
var presentedId = room_info.room_alias || room_info.room_id;
|
||||
var room = MatrixClientPeg.get().getRoom(room_info.room_id);
|
||||
// Wait for the first sync to complete so that if a room does have an alias,
|
||||
// it would have been retrieved.
|
||||
let waitFor = q(null);
|
||||
if (!firstSyncComplete) {
|
||||
if (!this.firstSyncPromise) {
|
||||
console.warn('Cannot view a room before first sync. room_id:', room_info.room_id);
|
||||
return;
|
||||
}
|
||||
waitFor = this.firstSyncPromise.promise;
|
||||
}
|
||||
|
||||
waitFor.done(() => {
|
||||
let presentedId = room_info.room_alias || room_info.room_id;
|
||||
const room = MatrixClientPeg.get().getRoom(room_info.room_id);
|
||||
if (room) {
|
||||
var theAlias = Rooms.getDisplayAliasForRoom(room);
|
||||
const theAlias = Rooms.getDisplayAliasForRoom(room);
|
||||
if (theAlias) presentedId = theAlias;
|
||||
|
||||
// Store this as the ID of the last room accessed. This is so that we can
|
||||
// persist which room is being stored across refreshes and browser quits.
|
||||
if (localStorage) {
|
||||
localStorage.setItem('mx_last_room_id', room.roomId);
|
||||
}
|
||||
}
|
||||
|
||||
if (room_info.event_id) {
|
||||
presentedId += "/"+room_info.event_id;
|
||||
presentedId += "/" + room_info.event_id;
|
||||
}
|
||||
this.notifyNewScreen('room/'+presentedId);
|
||||
this.notifyNewScreen('room/' + presentedId);
|
||||
newState.ready = true;
|
||||
}
|
||||
this.setState(newState);
|
||||
});
|
||||
},
|
||||
|
||||
_createChat: function() {
|
||||
|
@ -683,7 +699,7 @@ module.exports = React.createClass({
|
|||
this.props.onLoadCompleted();
|
||||
this.setState({loading: false});
|
||||
|
||||
// Show screens (like 'register') that need to be shown without onLoggedIn
|
||||
// Show screens (like 'register') that need to be shown without _onLoggedIn
|
||||
// being called. 'register' needs to be routed here when the email confirmation
|
||||
// link is clicked on.
|
||||
if (this.state.screenAfterLogin &&
|
||||
|
@ -766,6 +782,12 @@ module.exports = React.createClass({
|
|||
);
|
||||
this.notifyNewScreen(this.state.screenAfterLogin.screen);
|
||||
this.setState({screenAfterLogin: null});
|
||||
} else if (localStorage && localStorage.getItem('mx_last_room_id')) {
|
||||
// Before defaulting to directory, show the last viewed room
|
||||
dis.dispatch({
|
||||
action: 'view_room',
|
||||
room_id: localStorage.getItem('mx_last_room_id'),
|
||||
});
|
||||
} else {
|
||||
dis.dispatch({action: 'view_room_directory'});
|
||||
}
|
||||
|
@ -825,33 +847,13 @@ module.exports = React.createClass({
|
|||
}
|
||||
console.log("MatrixClient sync state => %s", state);
|
||||
if (state !== "PREPARED") { return; }
|
||||
self.sdkReady = true;
|
||||
|
||||
self.firstSyncComplete = true;
|
||||
self.firstSyncPromise.resolve();
|
||||
|
||||
if (!self.state.page_type) {
|
||||
if (!self.state.currentRoomId) {
|
||||
var firstRoom = null;
|
||||
if (cli.getRooms() && cli.getRooms().length) {
|
||||
firstRoom = RoomListSorter.mostRecentActivityFirst(
|
||||
cli.getRooms()
|
||||
)[0].roomId;
|
||||
self.setState({ready: true, currentRoomId: firstRoom, page_type: PageTypes.RoomView});
|
||||
}
|
||||
} else {
|
||||
self.setState({ready: true, page_type: PageTypes.RoomView});
|
||||
}
|
||||
|
||||
// we notifyNewScreen now because now the room will actually be displayed,
|
||||
// and (mostly) now we can get the correct alias.
|
||||
var presentedId = self.state.currentRoomId;
|
||||
var room = MatrixClientPeg.get().getRoom(self.state.currentRoomId);
|
||||
if (room) {
|
||||
var theAlias = Rooms.getDisplayAliasForRoom(room);
|
||||
if (theAlias) presentedId = theAlias;
|
||||
}
|
||||
|
||||
if (presentedId != undefined) {
|
||||
self.notifyNewScreen('room/'+presentedId);
|
||||
}
|
||||
// Switch to room view but allow _onLoggedIn to specify a room (if any)
|
||||
self.setState({ready: true});
|
||||
dis.dispatch({action: 'focus_composer'});
|
||||
} else {
|
||||
self.setState({ready: true});
|
||||
|
|
Loading…
Reference in a new issue