use url navigation in root view model

also track all view models as it is
important everything is properly disposed now
This commit is contained in:
Bruno Windels 2020-10-09 17:03:38 +02:00
parent 33627edcb3
commit 927e8134d3
2 changed files with 56 additions and 59 deletions

View File

@ -29,77 +29,60 @@ export class RootViewModel extends ViewModel {
this._storageFactory = storageFactory; this._storageFactory = storageFactory;
this._error = null; this._error = null;
this._sessionViewModel = null;
this._loginViewModel = null;
this._sessionPickerViewModel = null; this._sessionPickerViewModel = null;
this._sessionLoadViewModel = null;
this._sessionContainer = null; this._loginViewModel = null;
this._sessionCallback = this._sessionCallback.bind(this); this._sessionViewModel = null;
} }
async load() { async load() {
// TODO: deduplicate code here this.track(this.navigation.observe("login").subscribe(() => this._applyNavigation()));
this.track(this.navigation.observe("login").subscribe(shown => { this.track(this.navigation.observe("session").subscribe(() => this._applyNavigation()));
if (shown) { if (!this._applyNavigation()) {
this._showLogin(); try {
// redirect depending on what sessions are already present
const sessionInfos = await this._sessionInfoStorage.getAll();
const url = this._urlForSessionInfos(sessionInfos);
this.urlRouter.history.replaceUrl(url);
this.urlRouter.applyUrl(url);
} catch (err) {
this._setSection(() => this._error = err);
} }
})); }
this.track(this.navigation.observe("session").subscribe(sessionId => { }
if (sessionId === true) {
this._showPicker();
} else if (sessionId) {
this._showSessionLoader(sessionId);
}
}));
_applyNavigation() {
const isLogin = this.navigation.observe("login").get(); const isLogin = this.navigation.observe("login").get();
const sessionId = this.navigation.observe("session").get(); const sessionId = this.navigation.observe("session").get();
if (isLogin) { if (isLogin) {
this._showLogin(); this._showLogin();
return true;
} else if (sessionId === true) { } else if (sessionId === true) {
this._showPicker(); this._showPicker();
return true;
} else if (sessionId) { } else if (sessionId) {
this._showSessionLoader(sessionId); this._showSessionLoader(sessionId);
} else { return true;
const sessionInfos = await this._sessionInfoStorage.getAll();
let url;
if (sessionInfos.length === 0) {
url = this.urlRouter.urlForSegment("login");
} else if (sessionInfos.length === 1) {
url = this.urlRouter.urlForSegment("session", sessionInfos[0].id);
} else {
url = this.urlRouter.urlForSegment("session");
}
this.urlRouter.replaceUrl(url);
} }
return false;
} }
_sessionCallback(sessionContainer) { _urlForSessionInfos(sessionInfos) {
if (sessionContainer) { if (sessionInfos.length === 0) {
this._setSection(() => { return this.urlRouter.urlForSegment("login");
this._sessionContainer = sessionContainer; } else if (sessionInfos.length === 1) {
this._sessionViewModel = new SessionViewModel(this.childOptions({sessionContainer})); return this.urlRouter.urlForSegment("session", sessionInfos[0].id);
this._sessionViewModel.start();
});
} else { } else {
// switch between picker and login return this.urlRouter.urlForSegment("session");
if (this.activeSection === "login") {
this._showPicker();
} else {
this._showLogin();
}
} }
} }
async _showPicker() { async _showPicker() {
this._setSection(() => { this._setSection(() => {
this._sessionPickerViewModel = new SessionPickerViewModel({ this._sessionPickerViewModel = new SessionPickerViewModel(this.childOptions({
sessionInfoStorage: this._sessionInfoStorage, sessionInfoStorage: this._sessionInfoStorage,
storageFactory: this._storageFactory, storageFactory: this._storageFactory,
createSessionContainer: this._createSessionContainer, }));
sessionCallback: this._sessionCallback,
});
}); });
try { try {
await this._sessionPickerViewModel.load(); await this._sessionPickerViewModel.load();
@ -110,11 +93,22 @@ export class RootViewModel extends ViewModel {
_showLogin() { _showLogin() {
this._setSection(() => { this._setSection(() => {
this._loginViewModel = new LoginViewModel({ this._loginViewModel = new LoginViewModel(this.childOptions({
defaultHomeServer: "https://matrix.org", defaultHomeServer: "https://matrix.org",
createSessionContainer: this._createSessionContainer, createSessionContainer: this._createSessionContainer,
sessionCallback: this._sessionCallback, ready: sessionContainer => {
}); const url = this.urlRouter.urlForSegment("session", sessionContainer.sessionId);
this.urlRouter.replaceUrl(url);
this._showSession(sessionContainer);
},
}));
});
}
_showSession(sessionContainer) {
this._setSection(() => {
this._sessionViewModel = new SessionViewModel(this.childOptions({sessionContainer}));
this._sessionViewModel.start();
}); });
} }
@ -126,7 +120,7 @@ export class RootViewModel extends ViewModel {
sessionContainer.startWithExistingSession(sessionId); sessionContainer.startWithExistingSession(sessionId);
return sessionContainer; return sessionContainer;
}, },
sessionCallback: this._sessionCallback ready: sessionContainer => this._showSession(sessionContainer)
}); });
this._sessionLoadViewModel.start(); this._sessionLoadViewModel.start();
}); });
@ -151,17 +145,16 @@ export class RootViewModel extends ViewModel {
_setSection(setter) { _setSection(setter) {
// clear all members the activeSection depends on // clear all members the activeSection depends on
this._error = null; this._error = null;
this._sessionViewModel = null; this._sessionPickerViewModel = this.disposeTracked(this._sessionPickerViewModel);
this._loginViewModel = null; this._sessionLoadViewModel = this.disposeTracked(this._sessionLoadViewModel);
this._sessionPickerViewModel = null; this._loginViewModel = this.disposeTracked(this._loginViewModel);
this._sessionLoadViewModel = null; this._sessionViewModel = this.disposeTracked(this._sessionViewModel);
if (this._sessionContainer) {
this._sessionContainer.stop();
this._sessionContainer = null;
}
// now set it again // now set it again
setter(); setter();
this._sessionPickerViewModel && this.track(this._sessionPickerViewModel);
this._sessionLoadViewModel && this.track(this._sessionLoadViewModel);
this._loginViewModel && this.track(this._loginViewModel);
this._sessionViewModel && this.track(this._sessionViewModel);
this.emitChange("activeSection"); this.emitChange("activeSection");
} }

View File

@ -70,6 +70,10 @@ export class SessionContainer {
return (Math.floor(this._random() * Number.MAX_SAFE_INTEGER)).toString(); return (Math.floor(this._random() * Number.MAX_SAFE_INTEGER)).toString();
} }
get sessionId() {
return this._sessionId;
}
async startWithExistingSession(sessionId) { async startWithExistingSession(sessionId) {
if (this._status.get() !== LoadStatus.NotLoading) { if (this._status.get() !== LoadStatus.NotLoading) {
return; return;