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() {
|
componentWillMount: function() {
|
||||||
SdkConfig.put(this.props.config);
|
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) {
|
if (this.props.config.sync_timeline_limit) {
|
||||||
MatrixClientPeg.opts.initialSyncLimit = 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) {
|
// Wait for the first sync to complete so that if a room does have an alias,
|
||||||
// if the SDK is not ready yet, remember what room
|
// it would have been retrieved.
|
||||||
// we're supposed to be on but don't notify about
|
let waitFor = q(null);
|
||||||
// the new screen yet (we won't be showing it yet)
|
if (!firstSyncComplete) {
|
||||||
// The normal case where this happens is navigating
|
if (!this.firstSyncPromise) {
|
||||||
// to the room in the URL bar on page load.
|
console.warn('Cannot view a room before first sync. room_id:', room_info.room_id);
|
||||||
var presentedId = room_info.room_alias || room_info.room_id;
|
return;
|
||||||
var room = MatrixClientPeg.get().getRoom(room_info.room_id);
|
}
|
||||||
|
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) {
|
if (room) {
|
||||||
var theAlias = Rooms.getDisplayAliasForRoom(room);
|
const theAlias = Rooms.getDisplayAliasForRoom(room);
|
||||||
if (theAlias) presentedId = theAlias;
|
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) {
|
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;
|
newState.ready = true;
|
||||||
}
|
this.setState(newState);
|
||||||
this.setState(newState);
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_createChat: function() {
|
_createChat: function() {
|
||||||
|
@ -683,7 +699,7 @@ module.exports = React.createClass({
|
||||||
this.props.onLoadCompleted();
|
this.props.onLoadCompleted();
|
||||||
this.setState({loading: false});
|
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
|
// being called. 'register' needs to be routed here when the email confirmation
|
||||||
// link is clicked on.
|
// link is clicked on.
|
||||||
if (this.state.screenAfterLogin &&
|
if (this.state.screenAfterLogin &&
|
||||||
|
@ -766,6 +782,12 @@ module.exports = React.createClass({
|
||||||
);
|
);
|
||||||
this.notifyNewScreen(this.state.screenAfterLogin.screen);
|
this.notifyNewScreen(this.state.screenAfterLogin.screen);
|
||||||
this.setState({screenAfterLogin: null});
|
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 {
|
} else {
|
||||||
dis.dispatch({action: 'view_room_directory'});
|
dis.dispatch({action: 'view_room_directory'});
|
||||||
}
|
}
|
||||||
|
@ -825,33 +847,13 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
console.log("MatrixClient sync state => %s", state);
|
console.log("MatrixClient sync state => %s", state);
|
||||||
if (state !== "PREPARED") { return; }
|
if (state !== "PREPARED") { return; }
|
||||||
self.sdkReady = true;
|
|
||||||
|
self.firstSyncComplete = true;
|
||||||
|
self.firstSyncPromise.resolve();
|
||||||
|
|
||||||
if (!self.state.page_type) {
|
if (!self.state.page_type) {
|
||||||
if (!self.state.currentRoomId) {
|
// Switch to room view but allow _onLoggedIn to specify a room (if any)
|
||||||
var firstRoom = null;
|
self.setState({ready: true});
|
||||||
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);
|
|
||||||
}
|
|
||||||
dis.dispatch({action: 'focus_composer'});
|
dis.dispatch({action: 'focus_composer'});
|
||||||
} else {
|
} else {
|
||||||
self.setState({ready: true});
|
self.setState({ready: true});
|
||||||
|
|
Loading…
Reference in a new issue