adjust LoginView(Model) further to showing loading status in place
This commit is contained in:
parent
96aa4f83b9
commit
e37101210c
2 changed files with 74 additions and 24 deletions
|
@ -1,5 +1,5 @@
|
||||||
import {EventEmitter} from "../utils/EventEmitter.js";
|
import {EventEmitter} from "../utils/EventEmitter.js";
|
||||||
import {LoadStatus} from "../matrix/SessionContainer.js";
|
import {LoadStatus, LoginFailure} from "../matrix/SessionContainer.js";
|
||||||
import {AbortError} from "../utils/error.js";
|
import {AbortError} from "../utils/error.js";
|
||||||
|
|
||||||
export class LoginViewModel extends EventEmitter {
|
export class LoginViewModel extends EventEmitter {
|
||||||
|
@ -8,6 +8,7 @@ export class LoginViewModel extends EventEmitter {
|
||||||
this._createSessionContainer = createSessionContainer;
|
this._createSessionContainer = createSessionContainer;
|
||||||
this._sessionCallback = sessionCallback;
|
this._sessionCallback = sessionCallback;
|
||||||
this._defaultHomeServer = defaultHomeServer;
|
this._defaultHomeServer = defaultHomeServer;
|
||||||
|
this._homeserver = null;
|
||||||
this._sessionContainer = null;
|
this._sessionContainer = null;
|
||||||
this._loadWaitHandle = null;
|
this._loadWaitHandle = null;
|
||||||
this._loading = false;
|
this._loading = false;
|
||||||
|
@ -18,18 +19,24 @@ export class LoginViewModel extends EventEmitter {
|
||||||
get passwordPlaceholder() { return "Password"; }
|
get passwordPlaceholder() { return "Password"; }
|
||||||
get hsPlaceholder() { return "Your matrix homeserver"; }
|
get hsPlaceholder() { return "Your matrix homeserver"; }
|
||||||
get defaultHomeServer() { return this._defaultHomeServer; }
|
get defaultHomeServer() { return this._defaultHomeServer; }
|
||||||
get error() { return this._error; }
|
get loading() {return this._loading}
|
||||||
get loading() { return this._loading; }
|
|
||||||
|
get showLoadLabel() {
|
||||||
|
return this._loading || this._sessionContainer;
|
||||||
|
}
|
||||||
|
|
||||||
async login(username, password, homeserver) {
|
async login(username, password, homeserver) {
|
||||||
try {
|
try {
|
||||||
this._loading = true;
|
this._loading = true;
|
||||||
this.emit("change", "loading");
|
this.emit("change", "loading");
|
||||||
|
this._homeserver = homeserver;
|
||||||
this._sessionContainer = this._createSessionContainer();
|
this._sessionContainer = this._createSessionContainer();
|
||||||
this._sessionContainer.startWithLogin(homeserver, username, password);
|
this._sessionContainer.startWithLogin(homeserver, username, password);
|
||||||
this._loadWaitHandle = this._sessionContainer.loadStatus.waitFor(s => {
|
this._loadWaitHandle = this._sessionContainer.loadStatus.waitFor(s => {
|
||||||
this.emit("change", "loadStatus");
|
this.emit("change", "loadLabel");
|
||||||
return s === LoadStatus.Ready;
|
return s === LoadStatus.Ready ||
|
||||||
|
s === LoadStatus.LoginFailed ||
|
||||||
|
s === LoadStatus.Error;
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
await this._loadWaitHandle.promise;
|
await this._loadWaitHandle.promise;
|
||||||
|
@ -40,8 +47,17 @@ export class LoginViewModel extends EventEmitter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this._loadWaitHandle = null;
|
this._loadWaitHandle = null;
|
||||||
|
if (this._sessionContainer.loadStatus.get() === LoadStatus.Ready) {
|
||||||
this._sessionCallback(this._sessionContainer);
|
this._sessionCallback(this._sessionContainer);
|
||||||
// wait for parent view model to switch away here
|
// wait for parent view model to switch away here
|
||||||
|
} else {
|
||||||
|
this._loading = false;
|
||||||
|
this.emit("change", "loading");
|
||||||
|
if (this._sessionContainer.loadError) {
|
||||||
|
console.error(this._sessionContainer.loadError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this._error = err;
|
this._error = err;
|
||||||
this._loading = false;
|
this._loading = false;
|
||||||
|
@ -49,21 +65,43 @@ export class LoginViewModel extends EventEmitter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get loadStatus() {
|
get loadLabel() {
|
||||||
return this._sessionContainer && this._sessionContainer.loadStatus;
|
if (this._error) {
|
||||||
|
return `Something went wrong: ${this._error.message}.`;
|
||||||
}
|
}
|
||||||
|
if (this.showLoadLabel) {
|
||||||
get loadError() {
|
|
||||||
if (this._sessionContainer) {
|
if (this._sessionContainer) {
|
||||||
const error = this._sessionContainer.loadError;
|
switch (this._sessionContainer.loadStatus.get()) {
|
||||||
if (error) {
|
case LoadStatus.NotLoading:
|
||||||
return error.message;
|
return `Preparing…`;
|
||||||
|
case LoadStatus.Login:
|
||||||
|
return `Checking your login and password…`;
|
||||||
|
case LoadStatus.LoginFailed:
|
||||||
|
switch (this._sessionContainer.loginFailure) {
|
||||||
|
case LoginFailure.LoginFailure:
|
||||||
|
return `Your username and/or password don't seem to be correct.`;
|
||||||
|
case LoginFailure.Connection:
|
||||||
|
return `Can't connect to ${this._homeserver}.`;
|
||||||
|
case LoginFailure.Unknown:
|
||||||
|
return `Something went wrong while checking your login and password.`;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case LoadStatus.Loading:
|
||||||
|
return `Loading your conversations…`;
|
||||||
|
case LoadStatus.FirstSync:
|
||||||
|
return `Getting your conversations from the server…`;
|
||||||
|
case LoadStatus.Error:
|
||||||
|
return `Something went wrong: ${this._sessionContainer.loadError.message}.`;
|
||||||
|
default:
|
||||||
|
return this._sessionContainer.loadStatus.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return `Preparing…`;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async cancelLogin() {
|
async cancel() {
|
||||||
if (!this._loading) {
|
if (!this._loading) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -81,7 +119,9 @@ export class LoginViewModel extends EventEmitter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cancel() {
|
goBack() {
|
||||||
|
if (!this._loading) {
|
||||||
this._sessionCallback();
|
this._sessionCallback();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,10 @@ export class LoginView extends TemplateView {
|
||||||
}
|
}
|
||||||
|
|
||||||
render(t, vm) {
|
render(t, vm) {
|
||||||
const username = t.input({type: "text", placeholder: vm.usernamePlaceholder});
|
const disabled = vm => vm.loading;
|
||||||
const password = t.input({type: "password", placeholder: vm.passwordPlaceholder});
|
const username = t.input({type: "text", placeholder: vm.usernamePlaceholder, disabled});
|
||||||
const homeserver = t.input({type: "text", placeholder: vm.hsPlaceholder, value: vm.defaultHomeServer});
|
const password = t.input({type: "password", placeholder: vm.passwordPlaceholder, disabled});
|
||||||
|
const homeserver = t.input({type: "text", placeholder: vm.hsPlaceholder, value: vm.defaultHomeServer, disabled});
|
||||||
return t.div({className: "LoginView form"}, [
|
return t.div({className: "LoginView form"}, [
|
||||||
t.h1(["Log in to your homeserver"]),
|
t.h1(["Log in to your homeserver"]),
|
||||||
t.if(vm => vm.error, t => t.div({className: "error"}, vm => vm.error)),
|
t.if(vm => vm.error, t => t.div({className: "error"}, vm => vm.error)),
|
||||||
|
@ -18,10 +19,19 @@ export class LoginView extends TemplateView {
|
||||||
t.div(homeserver),
|
t.div(homeserver),
|
||||||
t.div(t.button({
|
t.div(t.button({
|
||||||
onClick: () => vm.login(username.value, password.value, homeserver.value),
|
onClick: () => vm.login(username.value, password.value, homeserver.value),
|
||||||
disabled: vm => vm.loading
|
disabled
|
||||||
}, "Log In")),
|
}, "Log In")),
|
||||||
t.div(t.button({onClick: () => vm.cancel()}, ["Pick an existing session"])),
|
t.div(t.button({onClick: () => vm.goBack(), disabled}, ["Pick an existing session"])),
|
||||||
|
t.if(vm => vm.showLoadLabel, renderLoadProgress),
|
||||||
t.p(brawlGithubLink(t))
|
t.p(brawlGithubLink(t))
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderLoadProgress(t) {
|
||||||
|
return t.div({className: "loadProgress"}, [
|
||||||
|
t.div({className: "spinner"}),
|
||||||
|
t.p(vm => vm.loadLabel),
|
||||||
|
t.if(vm => vm.loading, t => t.button({onClick: vm => vm.cancel()}, "Cancel login"))
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
Reference in a new issue