mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 09:30:45 +00:00
Fixes & cleans up Username input (#2619)
## Description: **Fix:** Error box like "Username must be at least 3 characters long" sometimes still remains after the game starts. See bug report with screenshot: https://discord.com/channels/1284581928254701718/1449169462426079343/1449169462426079343 This is while in main.ts, element username-validation-error is already set to hidden. Most of the time this works but apparently sometimes there's a re-render which removes the 'hidden' tag again. Most probable solution for this edge case: clear validationError first. Then to make sure, still hide element username-validation-error. **Cleanup username.ts:** - Remove cat and clover emojis from validPattern. For single player games, the only other validity checks are done from GameRunner calling sanitize() from Util.ts. And from GameImpl where from addPlayer the PlayerImpl are created, which uses sanitizeUserName also from username.ts, which uses validPattern again. Both GameRunner and PlayerImpl therefor allow emoji. But for muliplayer there's an extra step where ClientJoinMessageSchema enforces UserNameSchema = SafeString. Which does NOT allow cat or clover emoji. So for multiplayer you get an error and can't join a game with cat or clover emoji. To align their behavior more, just disallow the emojis from validPattern from the start. Almost no-one ever used them anyway, they were once put in because a developer liked to use them before the existance of ClientJoinMessageSchema. There's more consolidation/refactoring possible but this is an important first step. - Remove sending arg max: MAX_USERNAME_LENGTH for translation key invalid_chars, since the translation string doesn't contain params **Cleanup UserNameInput.ts:** - Remove userSettings: isn't used anywhere in the code - Remove dispatchUsernameEvent: nowhere in the repo is event 'username-change' listened to. Also, dispatchUsernameEvent is only called from connectedCallBack but not anywhere else. It seems like handleChange was made for this. Also main.ts calls usernameInput.getCurrentUsername() and doesn't listen for the event either. ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced ## Please put your Discord username so you can be contacted if a bug or regression is found: tryout33
This commit is contained in:
@@ -502,6 +502,10 @@ class Client {
|
||||
() => {
|
||||
console.log("Closing modals");
|
||||
document.getElementById("settings-button")?.classList.add("hidden");
|
||||
if (this.usernameInput) {
|
||||
// fix edge case where username-validation-error is re-rendered and hidden tag removed
|
||||
this.usernameInput.validationError = "";
|
||||
}
|
||||
document
|
||||
.getElementById("username-validation-error")
|
||||
?.classList.add("hidden");
|
||||
|
||||
@@ -2,7 +2,6 @@ import { LitElement, html } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators.js";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { translateText } from "../client/Utils";
|
||||
import { UserSettings } from "../core/game/UserSettings";
|
||||
import {
|
||||
MAX_USERNAME_LENGTH,
|
||||
validateUsername,
|
||||
@@ -15,7 +14,6 @@ export class UsernameInput extends LitElement {
|
||||
@state() private username: string = "";
|
||||
@property({ type: String }) validationError: string = "";
|
||||
private _isValid: boolean = true;
|
||||
private userSettings: UserSettings = new UserSettings();
|
||||
|
||||
// Remove static styles since we're using Tailwind
|
||||
|
||||
@@ -31,7 +29,6 @@ export class UsernameInput extends LitElement {
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.username = this.getStoredUsername();
|
||||
this.dispatchUsernameEvent();
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -83,16 +80,6 @@ export class UsernameInput extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
private dispatchUsernameEvent() {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("username-change", {
|
||||
detail: { username: this.username },
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
private generateNewUsername(): string {
|
||||
const newUsername = "Anon" + this.uuidToThreeDigits();
|
||||
this.storeUsername(newUsername);
|
||||
|
||||
@@ -22,7 +22,7 @@ const matcher = new RegExpMatcher({
|
||||
export const MIN_USERNAME_LENGTH = 3;
|
||||
export const MAX_USERNAME_LENGTH = 27;
|
||||
|
||||
const validPattern = /^[a-zA-Z0-9_[\] 🐈🍀üÜ]+$/u;
|
||||
const validPattern = /^[a-zA-Z0-9_[\] üÜ]+$/u; // Don't allow more than in UserNameSchema
|
||||
|
||||
const shadowNames = [
|
||||
"NicePeopleOnly",
|
||||
@@ -123,9 +123,7 @@ export function validateUsername(username: string): {
|
||||
if (!validPattern.test(username)) {
|
||||
return {
|
||||
isValid: false,
|
||||
error: translateText("username.invalid_chars", {
|
||||
max: MAX_USERNAME_LENGTH,
|
||||
}),
|
||||
error: translateText("username.invalid_chars"),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -105,8 +105,8 @@ describe("username.ts functions", () => {
|
||||
const res = validateUsername("Good_Name123");
|
||||
expect(res.isValid).toBe(true);
|
||||
});
|
||||
test("accepts allowed Unicode like 🐈 or ü", () => {
|
||||
const res = validateUsername("Cat🐈Üser");
|
||||
test("accepts allowed Unicode like ü", () => {
|
||||
const res = validateUsername("Üser");
|
||||
expect(res.isValid).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -123,7 +123,7 @@ describe("username.ts functions", () => {
|
||||
.slice(0, MAX_USERNAME_LENGTH),
|
||||
},
|
||||
{ input: "", expected: "xxx" },
|
||||
{ input: "Ünicode🐈Test!", expected: "Ünicode🐈Test" },
|
||||
{ input: "Ünicode Test!", expected: "Ünicode Test" },
|
||||
])('sanitizeUsername("%s") → "%s"', ({ input, expected }) => {
|
||||
const out = sanitizeUsername(input);
|
||||
expect(out).toBe(expected);
|
||||
|
||||
Reference in New Issue
Block a user