Fix welcome user

https://github.com/matrix-org/matrix-react-sdk/pull/3101 meant we
don't get logged straight in after registering if using an email
address, but this was the point at which we made a chat with the
welcome user. Instead, set a flag in memory that we should try &
make a chat with the welcome user for that user ID if we get a
session for them.

Of course, if the user logs in on both tabs, this would mean each
would make a chat with the welcome user (although actually this
was a problem with the old code too). Check our m.direct to see if
we've started a chat with the welcome user before making one (which
also means we have to make sure the cached sync is up to date...
see comments).
This commit is contained in:
David Baker 2019-06-14 15:31:19 +01:00
parent 2a7301fa8f
commit 8fa50b26a6
3 changed files with 85 additions and 18 deletions

View file

@ -53,6 +53,7 @@ import { messageForSyncError } from '../../utils/ErrorUtils';
import ResizeNotifier from "../../utils/ResizeNotifier";
import { ValidatedServerConfig } from "../../utils/AutoDiscoveryUtils";
import AutoDiscoveryUtils from "../../utils/AutoDiscoveryUtils";
import DMRoomMap from '../../utils/DMRoomMap';
// Disable warnings for now: we use deprecated bluebird functions
// and need to migrate, but they spam the console with warnings.
@ -887,6 +888,7 @@ export default React.createClass({
}
return;
}
MatrixClientPeg.setJustRegisteredUserId(credentials.user_id);
this.onRegistered(credentials);
},
onDifferentServerClicked: (ev) => {
@ -1134,26 +1136,65 @@ export default React.createClass({
/**
* Called when a new logged in session has started
*/
_onLoggedIn: async function() {
_onLoggedIn: function() {
this.setStateForNewView({ view: VIEWS.LOGGED_IN });
if (this._is_registered) {
this._is_registered = false;
if (MatrixClientPeg.currentUserIsJustRegistered()) {
MatrixClientPeg.setJustRegisteredUserId(null);
if (this.props.config.welcomeUserId && getCurrentLanguage().startsWith("en")) {
const roomId = await createRoom({
dmUserId: this.props.config.welcomeUserId,
// Only view the welcome user if we're NOT looking at a room
andView: !this.state.currentRoomId,
});
// if successful, return because we're already
// viewing the welcomeUserId room
// else, if failed, fall through to view_home_page
if (roomId) {
return;
// We can end up with multiple tabs post-registration where the user
// might then end up with a session and we don't want them all making
// a chat with the welcome user: try to de-dupe.
// We need to wait for the first sync to complete for this to
// work though.
let waitFor;
if (!this.firstSyncComplete) {
waitFor = this.firstSyncPromise.promise;
} else {
waitFor = Promise.resolve();
}
waitFor.then(async () => {
const welcomeUserRooms = DMRoomMap.shared().getDMRoomsForUserId(
this.props.config.welcomeUserId,
);
if (welcomeUserRooms.length === 0) {
const roomId = await createRoom({
dmUserId: this.props.config.welcomeUserId,
// Only view the welcome user if we're NOT looking at a room
andView: !this.state.currentRoomId,
});
// This is a bit of a hack, but since the deduplication relies
// on m.direct being up to date, we need to force a sync
// of the database, otherwise if the user goes to the other
// tab before the next save happens (a few minutes), the
// saved sync will be restored from the db and this code will
// run without the update to m.direct, making another welcome
// user room.
const saveWelcomeUser = (ev) => {
if (
ev.getType() == 'm.direct' &&
ev.getContent() &&
ev.getContent()[this.props.config.welcomeUserId]
) {
MatrixClientPeg.get().store.save(true);
MatrixClientPeg.get().removeListener(
"accountData", saveWelcomeUser,
);
}
};
MatrixClientPeg.get().on("accountData", saveWelcomeUser);
// if successful, return because we're already
// viewing the welcomeUserId room
// else, if failed, fall through to view_home_page
if (roomId) {
return;
}
}
// The user has just logged in after registering
dis.dispatch({action: 'view_home_page'});
});
}
// The user has just logged in after registering
dis.dispatch({action: 'view_home_page'});
} else {
this._showScreenAfterLogin();
}
@ -1694,9 +1735,6 @@ export default React.createClass({
return MatrixClientPeg.get();
}
}
// XXX: This should be in state or ideally store(s) because we risk not
// rendering the most up-to-date view of state otherwise.
this._is_registered = true;
return Lifecycle.setLoggedIn(credentials);
},