import { LitElement, html } from "lit"; import { customElement, property, state } from "lit/decorators.js"; import { getRuntimeClientServerConfig } from "../../core/configuration/ConfigLoader"; import { UserSettings } from "../../core/game/UserSettings"; import { crazyGamesSDK } from "../CrazyGamesSDK"; import { copyToClipboard, translateText } from "../Utils"; @customElement("copy-button") export class CopyButton extends LitElement { @property({ type: String, attribute: "lobby-id" }) lobbyId = ""; @property({ type: String, attribute: "lobby-suffix" }) lobbySuffix = ""; @property({ type: Boolean, attribute: "include-lobby-query" }) includeLobbyQuery = false; @property({ type: String, attribute: "copy-text" }) copyText = ""; @property({ type: String, attribute: "display-text" }) displayText = ""; @property({ type: Boolean, attribute: "show-visibility-toggle" }) showVisibilityToggle = true; @property({ type: Boolean, attribute: "show-copy-icon" }) showCopyIcon = true; @property({ type: Boolean }) compact = false; @state() private copySuccess = false; @state() private lobbyIdVisible = true; private userSettings: UserSettings = new UserSettings(); private maskLabel = html`••••••••`; createRenderRoot() { return this; } protected willUpdate( changedProperties: Map, ) { if (changedProperties.has("lobbyId")) { this.lobbyIdVisible = this.userSettings.lobbyIdVisibility(); this.copySuccess = false; } if (changedProperties.has("copyText")) { this.copySuccess = false; } if ( changedProperties.has("showVisibilityToggle") || changedProperties.has("compact") ) { if (!this.showVisibilityToggle || this.compact) { this.lobbyIdVisible = true; } } } private toggleVisibility() { if (!this.showVisibilityToggle || this.compact) return; this.lobbyIdVisible = !this.lobbyIdVisible; } private enableSelectAll(e: Event) { (e.currentTarget as HTMLElement).classList.add("select-all"); } private clearSelectAll(e: Event) { (e.currentTarget as HTMLElement).classList.remove("select-all"); } private async buildCopyUrl(): Promise { const config = await getRuntimeClientServerConfig(); let url = `${window.location.origin}/${config.workerPath(this.lobbyId)}/game/${this.lobbyId}`; if (this.includeLobbyQuery) { url += `?lobby&s=${encodeURIComponent(this.lobbySuffix)}`; } return url; } private async resolveCopyText(): Promise { if (this.copyText) return this.copyText; if (crazyGamesSDK.isOnCrazyGames()) { return crazyGamesSDK.createInviteLink(this.lobbyId); } if (!this.lobbyId) return ""; return await this.buildCopyUrl(); } private async handleCopy() { const text = await this.resolveCopyText(); if (!text) { alert("Error copying game id"); return; } await copyToClipboard( text, () => (this.copySuccess = true), () => (this.copySuccess = false), ); } private canCopy() { return Boolean(this.copyText || this.lobbyId); } render() { const canCopy = this.canCopy(); const allowMask = this.showVisibilityToggle && !this.compact; const rawLabel = this.displayText || this.lobbyId || this.copyText; const label = this.copySuccess ? translateText("common.copied") : allowMask && !this.lobbyIdVisible ? this.maskLabel : rawLabel; const disabledClass = canCopy ? "" : "opacity-60 cursor-not-allowed"; const toggleDisabled = !this.lobbyId; const toggleClass = toggleDisabled ? "opacity-60 cursor-not-allowed" : ""; if (this.compact) { return html` ${label} `; } return html` ${this.showVisibilityToggle ? html` ${this.lobbyIdVisible ? html` ` : html` `} ` : ""} ${label} ${this.showCopyIcon ? html` ` : ""} `; } }