import { html } from "lit"; import { customElement, state } from "lit/decorators.js"; import { translateText } from "../client/Utils"; import { UserSettings } from "../core/game/UserSettings"; import "./components/baseComponents/setting/SettingNumber"; import "./components/baseComponents/setting/SettingSlider"; import "./components/baseComponents/setting/SettingToggle"; import { BaseModal } from "./components/BaseModal"; import "./FlagInputModal"; interface FlagInputModalElement extends HTMLElement { open(): void; returnTo?: string; } @customElement("user-setting") export class UserSettingModal extends BaseModal { private userSettings: UserSettings = new UserSettings(); @state() private keySequence: string[] = []; @state() private showEasterEggSettings = false; disconnectedCallback() { window.removeEventListener("keydown", this.handleEasterEggKey); super.disconnectedCallback(); } private handleEasterEggKey = (e: KeyboardEvent) => { if (!this.isModalOpen || this.showEasterEggSettings) return; // Validate that the event target is inside this component const target = e.target as Node; if (!this.contains(target)) { return; } const key = e.key.toLowerCase(); const nextSequence = [...this.keySequence, key].slice(-4); this.keySequence = nextSequence; if (nextSequence.join("") === "evan") { this.triggerEasterEgg(); this.keySequence = []; } }; private triggerEasterEgg() { console.log("🪺 Setting~ unlocked by EVAN combo!"); this.showEasterEggSettings = true; const popup = document.createElement("div"); popup.className = "fixed top-10 left-1/2 p-4 px-6 bg-black/80 text-white text-xl rounded-xl animate-fadePop z-[9999]"; popup.textContent = "🎉 You found a secret setting!"; document.body.appendChild(popup); setTimeout(() => { popup.remove(); }, 5000); } toggleDarkMode(e: CustomEvent<{ checked: boolean }>) { const enabled = e.detail?.checked; if (typeof enabled !== "boolean") { console.warn("Unexpected toggle event payload", e); return; } this.userSettings.set("settings.darkMode", enabled); if (enabled) { document.documentElement.classList.add("dark"); } else { document.documentElement.classList.remove("dark"); } this.dispatchEvent( new CustomEvent("dark-mode-changed", { detail: { darkMode: enabled }, bubbles: true, composed: true, }), ); console.log("🌙 Dark Mode:", enabled ? "ON" : "OFF"); } private toggleEmojis(e: CustomEvent<{ checked: boolean }>) { const enabled = e.detail?.checked; if (typeof enabled !== "boolean") return; this.userSettings.set("settings.emojis", enabled); console.log("🤡 Emojis:", enabled ? "ON" : "OFF"); } private toggleAlertFrame(e: CustomEvent<{ checked: boolean }>) { const enabled = e.detail?.checked; if (typeof enabled !== "boolean") return; this.userSettings.set("settings.alertFrame", enabled); console.log("🚨 Alert frame:", enabled ? "ON" : "OFF"); } private toggleFxLayer(e: CustomEvent<{ checked: boolean }>) { const enabled = e.detail?.checked; if (typeof enabled !== "boolean") return; this.userSettings.set("settings.specialEffects", enabled); console.log("💥 Special effects:", enabled ? "ON" : "OFF"); } private toggleStructureSprites(e: CustomEvent<{ checked: boolean }>) { const enabled = e.detail?.checked; if (typeof enabled !== "boolean") return; this.userSettings.set("settings.structureSprites", enabled); console.log("🏠 Structure sprites:", enabled ? "ON" : "OFF"); } private toggleCursorCostLabel(e: CustomEvent<{ checked: boolean }>) { const enabled = e.detail?.checked; if (typeof enabled !== "boolean") return; this.userSettings.set("settings.cursorCostLabel", enabled); console.log("💰 Cursor build cost:", enabled ? "ON" : "OFF"); } private toggleAnonymousNames(e: CustomEvent<{ checked: boolean }>) { const enabled = e.detail?.checked; if (typeof enabled !== "boolean") return; this.userSettings.set("settings.anonymousNames", enabled); console.log("🙈 Anonymous Names:", enabled ? "ON" : "OFF"); } private toggleLobbyIdVisibility(e: CustomEvent<{ checked: boolean }>) { const hideIds = e.detail?.checked; if (typeof hideIds !== "boolean") return; this.userSettings.set("settings.lobbyIdVisibility", !hideIds); // Invert because checked=hide console.log("👁️ Hidden Lobby IDs:", hideIds ? "ON" : "OFF"); } private toggleLeftClickOpensMenu(e: CustomEvent<{ checked: boolean }>) { const enabled = e.detail?.checked; if (typeof enabled !== "boolean") return; this.userSettings.set("settings.leftClickOpensMenu", enabled); console.log("🖱️ Left Click Opens Menu:", enabled ? "ON" : "OFF"); this.requestUpdate(); } private sliderAttackRatio(e: CustomEvent<{ value: number }>) { const value = e.detail?.value; if (typeof value === "number") { const ratio = value / 100; localStorage.setItem("settings.attackRatio", ratio.toString()); } else { console.warn("Slider event missing detail.value", e); } } private toggleTerritoryPatterns(e: CustomEvent<{ checked: boolean }>) { const enabled = e.detail?.checked; if (typeof enabled !== "boolean") return; this.userSettings.set("settings.territoryPatterns", enabled); console.log("🏳️ Territory Patterns:", enabled ? "ON" : "OFF"); } private togglePerformanceOverlay(e: CustomEvent<{ checked: boolean }>) { const enabled = e.detail?.checked; if (typeof enabled !== "boolean") return; this.userSettings.set("settings.performanceOverlay", enabled); } private openFlagSelector = () => { const flagInputModal = document.querySelector("#flag-input-modal"); if (flagInputModal?.open) { this.close(); flagInputModal.returnTo = "#" + (this.id || "page-options"); flagInputModal.open(); } }; render() { const content = html` ${translateText("user_setting.title")} ${this.renderBasicSettings()} `; if (this.inline) { return content; } return html` ${content} `; } protected onClose(): void { window.removeEventListener("keydown", this.handleEasterEggKey); } private renderBasicSettings() { return html` { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); this.openFlagSelector(); } }} > ${translateText("flag_input.title")} ${translateText("flag_input.button_title")} ) => this.toggleDarkMode(e)} > ${this.showEasterEggSettings ? html` { const value = e.detail?.value; if (value !== undefined) { console.log("Changed:", value); } else { console.warn("Slider event missing detail.value", e); } }} > { const value = e.detail?.value; if (value !== undefined) { console.log("Changed:", value); } else { console.warn("Slider event missing detail.value", e); } }} > ` : null} `; } protected onOpen(): void { window.addEventListener("keydown", this.handleEasterEggKey); } public open() { super.open(); } }