import { html } from "lit"; import { customElement, state } from "lit/decorators.js"; import { UserMeResponse } from "../../core/ApiSchemas"; import { getUserMe, hasLinkedAccount } from "../Api"; import { userAuth } from "../Auth"; import { translateText } from "../Utils"; import { BaseModal } from "./BaseModal"; import { modalHeader } from "./ui/ModalHeader"; @customElement("ranked-modal") export class RankedModal extends BaseModal { @state() private elo: number | string = "..."; @state() private userMeResponse: UserMeResponse | false = false; @state() private errorMessage: string | null = null; constructor() { super(); this.id = "page-ranked"; } connectedCallback() { super.connectedCallback(); document.addEventListener( "userMeResponse", this.handleUserMeResponse as EventListener, ); } disconnectedCallback() { document.removeEventListener( "userMeResponse", this.handleUserMeResponse as EventListener, ); super.disconnectedCallback(); } private handleUserMeResponse = ( event: CustomEvent, ) => { this.errorMessage = null; this.userMeResponse = event.detail; this.updateElo(); }; private updateElo() { if (this.errorMessage) { this.elo = translateText("map_component.error"); return; } if (hasLinkedAccount(this.userMeResponse)) { this.elo = this.userMeResponse && this.userMeResponse.player.leaderboard?.oneVone?.elo ? this.userMeResponse.player.leaderboard.oneVone.elo : translateText("matchmaking_modal.no_elo"); } } protected override async onOpen(): Promise { this.elo = "..."; this.errorMessage = null; try { const userMe = await getUserMe(); this.userMeResponse = userMe; } catch (error) { console.error("Failed to fetch user profile for ranked modal", error); this.userMeResponse = false; this.errorMessage = translateText("map_component.error"); this.elo = translateText("map_component.error"); } finally { this.updateElo(); } } createRenderRoot() { return this; } render() { const content = html` ${modalHeader({ title: translateText("mode_selector.ranked_title"), onBack: () => this.close(), ariaLabel: translateText("common.back"), })} ${this.renderCard( translateText("mode_selector.ranked_1v1_title"), this.errorMessage ?? (hasLinkedAccount(this.userMeResponse) ? translateText("matchmaking_modal.elo", { elo: this.elo }) : translateText("mode_selector.ranked_title")), () => this.handleRanked(), )} ${this.renderDisabledCard( translateText("mode_selector.ranked_2v2_title"), translateText("mode_selector.coming_soon"), )} ${this.renderDisabledCard( translateText("mode_selector.coming_soon"), "", )} ${this.renderDisabledCard( translateText("mode_selector.coming_soon"), "", )} `; if (this.inline) { return content; } return html` ${content} `; } private renderCard(title: string, subtitle: string, onClick: () => void) { return html` ${title} ${subtitle} `; } private renderDisabledCard(title: string, subtitle: string) { return html` ${title} ${subtitle} `; } private async handleRanked() { if ((await userAuth()) === false) { this.close(); window.showPage?.("page-account"); return; } document.dispatchEvent(new CustomEvent("open-matchmaking")); } }
${subtitle}