mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-23 20:10:43 +00:00
make it a dedicated stats modal, not under account (#4627)
## Description: seperates the stats modal into a dedicated path, with gameID support e.g. : #modal=stats&gameID=VvyXpL9x ## 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 ## Please put your Discord username so you can be contacted if a bug or regression is found: w.o.n
This commit is contained in:
+19
-52
@@ -19,7 +19,6 @@ import {
|
||||
sendMagicLink,
|
||||
} from "./Auth";
|
||||
import "./components/baseComponents/stats/DiscordUserHeader";
|
||||
import "./components/baseComponents/stats/GameInfoView";
|
||||
import "./components/baseComponents/stats/PlayerGameHistoryView";
|
||||
import type { PlayerGameHistoryCache } from "./components/baseComponents/stats/PlayerGameHistoryView";
|
||||
import "./components/baseComponents/stats/PlayerStatsTable";
|
||||
@@ -35,7 +34,6 @@ import "./components/SubscriptionPanel";
|
||||
import { modalHeader } from "./components/ui/ModalHeader";
|
||||
import { fetchCosmetics } from "./Cosmetics";
|
||||
import { crazyGamesSDK, type CrazyGamesUser } from "./CrazyGamesSDK";
|
||||
import { modalRouter } from "./ModalRouter";
|
||||
import { translateText } from "./Utils";
|
||||
|
||||
@customElement("account-modal")
|
||||
@@ -53,8 +51,8 @@ export class AccountModal extends BaseModal {
|
||||
private statsTree: PlayerStatsTree | null = null;
|
||||
// Preserves the Games tab's accumulated list + cursor across tab switches.
|
||||
private gameHistoryCache: PlayerGameHistoryCache | null = null;
|
||||
@state() private selectedGameId: string | null = null;
|
||||
private gamesScrollTop = 0;
|
||||
private restoreGamesScrollAfterOpen = false;
|
||||
private cosmetics: Cosmetics | null = null;
|
||||
|
||||
constructor() {
|
||||
@@ -105,14 +103,6 @@ export class AccountModal extends BaseModal {
|
||||
}
|
||||
|
||||
protected renderHeaderSlot() {
|
||||
if (this.selectedGameId) {
|
||||
return modalHeader({
|
||||
title: translateText("game_list.stats"),
|
||||
onBack: () => this.backToGames(),
|
||||
ariaLabel: translateText("common.back"),
|
||||
});
|
||||
}
|
||||
|
||||
const isLoggedIn = !!this.userMeResponse?.user;
|
||||
const publicId = this.userMeResponse?.player?.publicId ?? "";
|
||||
const displayId = publicId || translateText("account_modal.not_found");
|
||||
@@ -154,9 +144,6 @@ export class AccountModal extends BaseModal {
|
||||
if (this.isLoadingUser || !this.isLinkedAccount()) {
|
||||
return {};
|
||||
}
|
||||
if (this.selectedGameId) {
|
||||
return {};
|
||||
}
|
||||
return {
|
||||
tabs: [
|
||||
{ key: "account", label: translateText("account_modal.tab_account") },
|
||||
@@ -181,15 +168,6 @@ export class AccountModal extends BaseModal {
|
||||
: this.renderLoginOptions()}
|
||||
</div>`;
|
||||
}
|
||||
if (this.selectedGameId) {
|
||||
return html`
|
||||
<div class="custom-scrollbar mr-1">
|
||||
<div class="p-6">
|
||||
<game-info-view .gameId=${this.selectedGameId}></game-info-view>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
return html`
|
||||
<div class="custom-scrollbar mr-1">
|
||||
<div class="p-6">${this.renderTab(tab)}</div>
|
||||
@@ -602,15 +580,15 @@ export class AccountModal extends BaseModal {
|
||||
|
||||
private openGameStats(gameId: string): void {
|
||||
this.gamesScrollTop = this.modalEl?.getScrollTop() ?? 0;
|
||||
this.modalEl?.setScrollTop(0);
|
||||
this.selectedGameId = gameId;
|
||||
modalRouter.syncArgs(this.routerName, { tab: null, gameID: gameId });
|
||||
const statsModal = document.querySelector<
|
||||
HTMLElement & { openFromAccount(gameId: string): void }
|
||||
>("game-stats-modal");
|
||||
statsModal?.openFromAccount(gameId);
|
||||
}
|
||||
|
||||
private backToGames(): void {
|
||||
this.selectedGameId = null;
|
||||
modalRouter.syncArgs(this.routerName, { gameID: null, tab: "games" });
|
||||
void this.restoreGamesScroll();
|
||||
public returnToGames(): void {
|
||||
this.restoreGamesScrollAfterOpen = true;
|
||||
this.open({ tab: "games" });
|
||||
}
|
||||
|
||||
private async restoreGamesScroll(): Promise<void> {
|
||||
@@ -623,15 +601,20 @@ export class AccountModal extends BaseModal {
|
||||
this.modalEl?.setScrollTop(this.gamesScrollTop);
|
||||
}
|
||||
|
||||
private resetGameStatsNavigation(): void {
|
||||
this.selectedGameId = null;
|
||||
this.gamesScrollTop = 0;
|
||||
private finishLoadingUser(): void {
|
||||
this.isLoadingUser = false;
|
||||
this.requestUpdate();
|
||||
if (this.restoreGamesScrollAfterOpen) {
|
||||
this.restoreGamesScrollAfterOpen = false;
|
||||
void this.restoreGamesScroll();
|
||||
}
|
||||
}
|
||||
|
||||
private resetPlayerData(): void {
|
||||
this.statsTree = null;
|
||||
this.gameHistoryCache = null;
|
||||
this.resetGameStatsNavigation();
|
||||
this.gamesScrollTop = 0;
|
||||
this.restoreGamesScrollAfterOpen = false;
|
||||
}
|
||||
|
||||
private renderLogoutButton(): TemplateResult {
|
||||
@@ -830,19 +813,6 @@ export class AccountModal extends BaseModal {
|
||||
}
|
||||
|
||||
protected onOpen(args?: Record<string, unknown>): void {
|
||||
if (args !== undefined) {
|
||||
const gameId =
|
||||
typeof args.gameID === "string" && args.gameID.length > 0
|
||||
? args.gameID
|
||||
: null;
|
||||
this.resetGameStatsNavigation();
|
||||
if (gameId) {
|
||||
this.activeTab = "games";
|
||||
this.selectedGameId = gameId;
|
||||
this.modalEl?.setScrollTop(0);
|
||||
}
|
||||
}
|
||||
|
||||
this.isLoadingUser = true;
|
||||
this.handleLinkResult(args);
|
||||
|
||||
@@ -861,19 +831,16 @@ export class AccountModal extends BaseModal {
|
||||
this.loadPlayerProfile(this.userMeResponse.player.publicId);
|
||||
}
|
||||
}
|
||||
this.isLoadingUser = false;
|
||||
this.requestUpdate();
|
||||
this.finishLoadingUser();
|
||||
})
|
||||
.catch((err) => {
|
||||
console.warn("Failed to fetch user info in AccountModal.open():", err);
|
||||
this.isLoadingUser = false;
|
||||
this.requestUpdate();
|
||||
this.finishLoadingUser();
|
||||
});
|
||||
this.requestUpdate();
|
||||
}
|
||||
|
||||
protected onClose(): void {
|
||||
this.resetGameStatsNavigation();
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("close", { bubbles: true, composed: true }),
|
||||
);
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import { html } from "lit";
|
||||
import { customElement, state } from "lit/decorators.js";
|
||||
import "./components/baseComponents/stats/GameInfoView";
|
||||
import { BaseModal } from "./components/BaseModal";
|
||||
import { modalHeader } from "./components/ui/ModalHeader";
|
||||
import { translateText } from "./Utils";
|
||||
|
||||
@customElement("game-stats-modal")
|
||||
export class GameStatsModal extends BaseModal {
|
||||
protected routerName = "stats";
|
||||
|
||||
@state() private gameId: string | null = null;
|
||||
private openedFromAccount = false;
|
||||
|
||||
protected renderHeaderSlot() {
|
||||
return modalHeader({
|
||||
title: translateText("game_list.stats"),
|
||||
onBack: () => this.back(),
|
||||
ariaLabel: translateText("common.back"),
|
||||
});
|
||||
}
|
||||
|
||||
protected renderBody() {
|
||||
return html`
|
||||
<div class="custom-scrollbar mr-1">
|
||||
<div class="p-6">
|
||||
<game-info-view .gameId=${this.gameId}></game-info-view>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
protected onOpen(args?: Record<string, unknown>): void {
|
||||
this.gameId =
|
||||
typeof args?.gameID === "string" && args.gameID.length > 0
|
||||
? args.gameID
|
||||
: null;
|
||||
}
|
||||
|
||||
protected onClose(): void {
|
||||
this.gameId = null;
|
||||
this.openedFromAccount = false;
|
||||
}
|
||||
|
||||
public openFromAccount(gameId: string): void {
|
||||
this.openedFromAccount = true;
|
||||
this.open({ gameID: gameId });
|
||||
}
|
||||
|
||||
private back(): void {
|
||||
const returnToAccount = this.openedFromAccount;
|
||||
this.close();
|
||||
if (!returnToAccount) return;
|
||||
|
||||
document
|
||||
.querySelector<HTMLElement & { returnToGames(): void }>("account-modal")
|
||||
?.returnToGames();
|
||||
}
|
||||
}
|
||||
@@ -233,6 +233,7 @@ export class LangSelector extends LitElement {
|
||||
"news-modal",
|
||||
"news-button",
|
||||
"account-modal",
|
||||
"game-stats-modal",
|
||||
"game-info-view",
|
||||
"ranking-controls",
|
||||
"ranking-header",
|
||||
|
||||
@@ -33,6 +33,7 @@ import { FlagInputModal } from "./FlagInputModal";
|
||||
import "./GameModeSelector";
|
||||
import { GameModeSelector } from "./GameModeSelector";
|
||||
import { GameStartingModal } from "./GameStartingModal";
|
||||
import "./GameStatsModal";
|
||||
import "./GoogleAdElement";
|
||||
import { HelpModal } from "./HelpModal";
|
||||
import "./HomepagePromos";
|
||||
@@ -301,6 +302,10 @@ class Client {
|
||||
tag: "account-modal",
|
||||
pageId: "page-account",
|
||||
});
|
||||
modalRouter.register("stats", {
|
||||
tag: "game-stats-modal",
|
||||
pageId: "page-stats",
|
||||
});
|
||||
modalRouter.register("help", { tag: "help-modal", pageId: "page-help" });
|
||||
modalRouter.register("news", { tag: "news-modal", pageId: "page-news" });
|
||||
modalRouter.register("language", {
|
||||
|
||||
Reference in New Issue
Block a user