[UI/UX] Retry login after registration once, improve error messages (#6887)

* [UI/UX] Retry login after registration once, improve error messages

* Fix tests

* Clarify error that registration was successful but login failed

* Add typing to `onFail()` param

* Send to login form if login fails after successful registration

* Add missing `fixedInt()` to make delay ignore game speed

---------

Co-authored-by: Fabi <192151969+fabske0@users.noreply.github.com>
This commit is contained in:
NightKev 2025-12-23 15:53:44 -06:00 committed by GitHub
parent 5c59d33a81
commit 7941144aff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 84 additions and 59 deletions

View File

@ -79,51 +79,14 @@ export class LoginPhase extends Phase {
}
private showLoginRegister(): void {
const { gameData, phaseManager, ui } = globalScene;
const backButton = () => {
phaseManager.unshiftNew("LoginPhase", false);
this.end();
};
const checkUserInfo = async (): Promise<boolean> => {
ui.playSelect();
const success = await updateUserInfo();
if (!success[0]) {
removeCookie(sessionIdKey);
globalScene.reset(true, true);
return false;
}
return true;
};
const loginButton = async () => {
const success = await checkUserInfo();
if (!success) {
return;
}
await gameData.loadSystem();
this.end();
};
const registerButton = async () => {
const success = await checkUserInfo();
if (!success) {
return;
}
this.end();
};
const { ui } = globalScene;
const goToLoginButton = () => {
globalScene.playSound("ui/menu_open");
ui.setMode(UiMode.LOGIN_FORM, { buttonActions: [loginButton, backButton] });
this.goToLogin();
};
const goToRegistrationButton = () => {
globalScene.playSound("ui/menu_open");
ui.setMode(UiMode.REGISTRATION_FORM, { buttonActions: [registerButton, backButton] });
this.goToRegister();
};
if (this.showText) {
@ -134,4 +97,56 @@ export class LoginPhase extends Phase {
ui.setMode(UiMode.LOGIN_OR_REGISTER, { buttonActions: [goToLoginButton, goToRegistrationButton] });
}
private async checkUserInfo(): Promise<boolean> {
globalScene.ui.playSelect();
const success = await updateUserInfo();
if (!success[0]) {
removeCookie(sessionIdKey);
globalScene.reset(true, true);
return false;
}
return true;
}
public goToLogin(): void {
const { gameData, ui, phaseManager } = globalScene;
const backButton = () => {
phaseManager.unshiftNew("LoginPhase", false);
this.end();
};
const loginButton = async () => {
const success = await this.checkUserInfo();
if (!success) {
return;
}
await gameData.loadSystem();
this.end();
};
globalScene.playSound("ui/menu_open");
ui.setMode(UiMode.LOGIN_FORM, { buttonActions: [loginButton, backButton] });
}
public goToRegister(): void {
const { phaseManager, ui } = globalScene;
const backButton = () => {
phaseManager.unshiftNew("LoginPhase", false);
this.end();
};
const registerButton = async () => {
const success = await this.checkUserInfo();
if (!success) {
return;
}
this.end();
};
globalScene.playSound("ui/menu_open");
ui.setMode(UiMode.REGISTRATION_FORM, { buttonActions: [registerButton, backButton] });
}
}

View File

@ -74,6 +74,7 @@ export abstract class ApiBase {
console.log(`Sending ${config.method ?? "GET"} request to: `, this.base + path, config);
}
// TODO: need some sort of error handling here?
return await fetch(this.base + path, config);
}

View File

@ -52,7 +52,7 @@ export class PokerogueAccountApi extends ApiBase {
console.warn("Register failed!", err);
}
return "Unknown error!";
return "Unknown registration error!";
}
/**
@ -76,7 +76,7 @@ export class PokerogueAccountApi extends ApiBase {
console.warn("Login failed!", err);
}
return "Unknown error!";
return "Unknown login error!";
}
/**

View File

@ -2,9 +2,11 @@ import { pokerogueApi } from "#api/pokerogue-api";
import { globalScene } from "#app/global-scene";
import { TextStyle } from "#enums/text-style";
import { UiMode } from "#enums/ui-mode";
import type { LoginPhase } from "#phases/login-phase";
import type { InputFieldConfig } from "#ui/form-modal-ui-handler";
import type { ModalConfig } from "#ui/modal-ui-handler";
import { addTextObject } from "#ui/text";
import { fixedInt } from "#utils/common";
import i18next from "i18next";
import { LoginRegisterInfoContainerUiHandler } from "./login-register-info-container-ui-handler";
@ -86,7 +88,7 @@ export class RegistrationFormUiHandler extends LoginRegisterInfoContainerUiHandl
this.submitAction = originalRegistrationAction;
this.sanitizeInputs();
globalScene.ui.setMode(UiMode.LOADING, { buttonActions: [] });
const onFail = error => {
const onFail = (error: string) => {
globalScene.ui.setMode(UiMode.REGISTRATION_FORM, Object.assign(config, { errorMessage: error?.trim() }));
globalScene.ui.playError();
};
@ -109,18 +111,25 @@ export class RegistrationFormUiHandler extends LoginRegisterInfoContainerUiHandl
if (registerError) {
onFail(registerError);
} else {
pokerogueApi.account
.login({
username: usernameInput.text,
password: passwordInput.text,
})
.then(loginError => {
if (loginError) {
onFail(loginError);
} else {
originalRegistrationAction?.();
}
});
const username = usernameInput.text;
const password = passwordInput.text;
pokerogueApi.account.login({ username, password }).then(loginError => {
if (loginError) {
// retry once if the first attempt fails
const retryLogin = () => {
pokerogueApi.account.login({ username, password }).then(error => {
if (error) {
(globalScene.phaseManager.getCurrentPhase() as LoginPhase).goToLogin();
} else {
originalRegistrationAction?.();
}
});
};
globalScene.time.delayedCall(fixedInt(2000), retryLogin);
} else {
originalRegistrationAction?.();
}
});
}
});
}

View File

@ -85,12 +85,12 @@ describe("Pokerogue Account API", () => {
expect(error).toBe("Username is already taken");
});
it('should return "Unknown error" and report a warning on ERROR', async () => {
it('should return "Unknown registration error!" and report a warning on ERROR', async () => {
server.use(http.post(`${apiBase}/account/register`, () => HttpResponse.error()));
const error = await accountApi.register(registerParams);
expect(error).toBe("Unknown error!");
expect(error).toBe("Unknown registration error!");
expect(console.warn).toHaveBeenCalledWith("Register failed!", expect.any(Error));
});
});
@ -119,12 +119,12 @@ describe("Pokerogue Account API", () => {
expect(console.warn).toHaveBeenCalledWith("Login failed!", 401, "Unauthorized");
});
it('should return "Unknown error" and report a warning on ERROR', async () => {
it('should return "Unknown login error!" and report a warning on ERROR', async () => {
server.use(http.post(`${apiBase}/account/login`, () => HttpResponse.error()));
const error = await accountApi.login(loginParams);
expect(error).toBe("Unknown error!");
expect(error).toBe("Unknown login error!");
expect(console.warn).toHaveBeenCalledWith("Login failed!", expect.any(Error));
});
});