port BrawlViewModel to SessionContainer
This commit is contained in:
parent
f4983b5ba6
commit
b32f5711bf
1 changed files with 33 additions and 66 deletions
|
@ -1,28 +1,24 @@
|
||||||
import {Session} from "../matrix/Session.js";
|
|
||||||
import {Sync} from "../matrix/Sync.js";
|
|
||||||
import {SessionViewModel} from "./session/SessionViewModel.js";
|
import {SessionViewModel} from "./session/SessionViewModel.js";
|
||||||
import {LoginViewModel} from "./LoginViewModel.js";
|
import {LoginViewModel} from "./LoginViewModel.js";
|
||||||
import {SessionPickerViewModel} from "./SessionPickerViewModel.js";
|
import {SessionPickerViewModel} from "./SessionPickerViewModel.js";
|
||||||
import {EventEmitter} from "../utils/EventEmitter.js";
|
import {EventEmitter} from "../utils/EventEmitter.js";
|
||||||
|
|
||||||
export function createNewSessionId() {
|
|
||||||
return (Math.floor(Math.random() * Number.MAX_SAFE_INTEGER)).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
export class BrawlViewModel extends EventEmitter {
|
export class BrawlViewModel extends EventEmitter {
|
||||||
constructor({storageFactory, sessionInfoStorage, createHsApi, clock}) {
|
constructor({createSessionContainer, sessionInfoStorage, storageFactory, clock}) {
|
||||||
super();
|
super();
|
||||||
this._storageFactory = storageFactory;
|
this._createSessionContainer = createSessionContainer;
|
||||||
this._sessionInfoStorage = sessionInfoStorage;
|
this._sessionInfoStorage = sessionInfoStorage;
|
||||||
this._createHsApi = createHsApi;
|
this._storageFactory = storageFactory;
|
||||||
this._clock = clock;
|
this._clock = clock;
|
||||||
|
|
||||||
this._loading = false;
|
this._loading = false;
|
||||||
this._error = null;
|
this._error = null;
|
||||||
this._sessionViewModel = null;
|
this._sessionViewModel = null;
|
||||||
this._sessionSubscription = null;
|
|
||||||
this._loginViewModel = null;
|
this._loginViewModel = null;
|
||||||
this._sessionPickerViewModel = null;
|
this._sessionPickerViewModel = null;
|
||||||
|
|
||||||
|
this._sessionContainer = null;
|
||||||
|
this._sessionCallback = this._sessionCallback.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
async load() {
|
async load() {
|
||||||
|
@ -33,12 +29,29 @@ export class BrawlViewModel extends EventEmitter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_sessionCallback(sessionContainer) {
|
||||||
|
if (sessionContainer) {
|
||||||
|
this._setSection(() => {
|
||||||
|
this._sessionContainer = sessionContainer;
|
||||||
|
this._sessionViewModel = new SessionViewModel(sessionContainer);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// switch between picker and login
|
||||||
|
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({
|
||||||
sessionInfoStorage: this._sessionInfoStorage,
|
sessionInfoStorage: this._sessionInfoStorage,
|
||||||
storageFactory: this._storageFactory,
|
storageFactory: this._storageFactory,
|
||||||
sessionCallback: sessionInfo => this._onSessionPicked(sessionInfo)
|
createSessionContainer: this._createSessionContainer,
|
||||||
|
sessionCallback: this._sessionCallback,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
|
@ -51,20 +64,14 @@ export class BrawlViewModel extends EventEmitter {
|
||||||
_showLogin() {
|
_showLogin() {
|
||||||
this._setSection(() => {
|
this._setSection(() => {
|
||||||
this._loginViewModel = new LoginViewModel({
|
this._loginViewModel = new LoginViewModel({
|
||||||
createHsApi: this._createHsApi,
|
|
||||||
defaultHomeServer: "https://matrix.org",
|
defaultHomeServer: "https://matrix.org",
|
||||||
loginCallback: loginData => this._onLoginFinished(loginData)
|
createSessionContainer: this._createSessionContainer,
|
||||||
|
sessionCallback: this._sessionCallback,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_showSession(session, sync) {
|
|
||||||
this._setSection(() => {
|
|
||||||
this._sessionViewModel = new SessionViewModel({session, sync});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
get activeSection() {
|
get activeSection() {
|
||||||
if (this._error) {
|
if (this._error) {
|
||||||
return "error";
|
return "error";
|
||||||
|
@ -79,66 +86,26 @@ export class BrawlViewModel extends EventEmitter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_setSection(setter) {
|
_setSection(setter) {
|
||||||
const oldSection = this.activeSection;
|
|
||||||
// clear all members the activeSection depends on
|
// clear all members the activeSection depends on
|
||||||
this._error = null;
|
this._error = null;
|
||||||
this._loading = false;
|
this._loading = false;
|
||||||
this._sessionViewModel = null;
|
this._sessionViewModel = null;
|
||||||
this._loginViewModel = null;
|
this._loginViewModel = null;
|
||||||
this._sessionPickerViewModel = null;
|
this._sessionPickerViewModel = null;
|
||||||
|
|
||||||
|
if (this._sessionContainer) {
|
||||||
|
this._sessionContainer.stop();
|
||||||
|
this._sessionContainer = null;
|
||||||
|
}
|
||||||
// now set it again
|
// now set it again
|
||||||
setter();
|
setter();
|
||||||
const newSection = this.activeSection;
|
|
||||||
// remove session subscription when navigating away
|
|
||||||
if (oldSection === "session" && newSection !== oldSection) {
|
|
||||||
this._sessionSubscription();
|
|
||||||
this._sessionSubscription = null;
|
|
||||||
}
|
|
||||||
this.emit("change", "activeSection");
|
this.emit("change", "activeSection");
|
||||||
}
|
}
|
||||||
|
|
||||||
get loadingText() { return this._loadingText; }
|
get error() { return this._error; }
|
||||||
get sessionViewModel() { return this._sessionViewModel; }
|
get sessionViewModel() { return this._sessionViewModel; }
|
||||||
get loginViewModel() { return this._loginViewModel; }
|
get loginViewModel() { return this._loginViewModel; }
|
||||||
get sessionPickerViewModel() { return this._sessionPickerViewModel; }
|
get sessionPickerViewModel() { return this._sessionPickerViewModel; }
|
||||||
get errorText() { return this._error && this._error.message; }
|
|
||||||
|
|
||||||
async _onLoginFinished(loginData) {
|
|
||||||
if (loginData) {
|
|
||||||
// TODO: extract random() as it is a source of non-determinism
|
|
||||||
const sessionId = createNewSessionId();
|
|
||||||
const sessionInfo = {
|
|
||||||
id: sessionId,
|
|
||||||
deviceId: loginData.device_id,
|
|
||||||
userId: loginData.user_id,
|
|
||||||
homeServer: loginData.homeServerUrl,
|
|
||||||
accessToken: loginData.access_token,
|
|
||||||
lastUsed: this._clock.now()
|
|
||||||
};
|
|
||||||
await this._sessionInfoStorage.add(sessionInfo);
|
|
||||||
this._loadSession(sessionInfo);
|
|
||||||
} else {
|
|
||||||
this._showPicker();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_onSessionPicked(sessionInfo) {
|
|
||||||
if (sessionInfo) {
|
|
||||||
this._loadSession(sessionInfo);
|
|
||||||
this._sessionInfoStorage.updateLastUsed(sessionInfo.id, this._clock.now());
|
|
||||||
} else {
|
|
||||||
this._showLogin();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async _loadSession(sessionInfo) {
|
|
||||||
this._setSection(() => {
|
|
||||||
// TODO this is pseudo code-ish
|
|
||||||
const container = this._createSessionContainer();
|
|
||||||
this._sessionViewModel = new SessionViewModel({session, sync});
|
|
||||||
this._sessionSubscription = this._activeSessionContainer.subscribe(this._updateSessionState);
|
|
||||||
this._activeSessionContainer.start(sessionInfo);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue