Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -282,16 +282,11 @@
inline
class="hidden w-full h-full page-content relative z-50"
></flag-input-modal>
<territory-patterns-modal
id="territory-patterns-modal"
<cosmetics-modal
id="cosmetics-modal"
inline
class="hidden w-full h-full page-content relative z-50"
></territory-patterns-modal>
<effects-modal
id="effects-modal"
inline
class="hidden w-full h-full page-content relative z-50"
></effects-modal>
></cosmetics-modal>
<ranked-modal
id="page-ranked"
inline
Expand Down
10 changes: 4 additions & 6 deletions resources/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@
"cosmetics": {
"adfree": "ad-free for life!",
"artist_label": "Artist:",
"button_title": "Pick your cosmetics!",
"color_label": "Color:",
"common": "Common",
"epic": "Epic",
Expand All @@ -397,7 +398,9 @@
"legendary": "Legendary",
"per_day": "/day",
"rare": "Rare",
"search": "Search...",
"soft": "Caps",
"title": "Cosmetics",
"uncommon": "Uncommon",
"unlimited_ranked": "Unlimited ranked",
"usd_value": "Value: {usd}"
Expand Down Expand Up @@ -432,14 +435,11 @@
"veryfast": "Very Fast"
},
"effects": {
"button_title": "Pick an effect!",
"nukeType": {
"atom": "Atom",
"hydro": "Hydrogen",
"mirvWarhead": "MIRV"
},
"search": "Search...",
"title": "Effects",
"type": {
"nukeExplosion": "Nuke Explosion",
"nukeTrail": "Nuke Trail",
Expand Down Expand Up @@ -1399,10 +1399,8 @@
"pattern": {
"default": "Default"
},
"search": "Search...",
"select_skin": "Skin",
"selected": "selected",
"title": "Skins"
"selected": "selected"
},
"token_login_modal": {
"logging_in": "Logging in...",
Expand Down
19 changes: 12 additions & 7 deletions src/client/PatternInput.ts → src/client/CosmeticsInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,13 @@ import { getPlayerCosmetics } from "./Cosmetics";
import { crazyGamesSDK } from "./CrazyGamesSDK";
import { translateText } from "./Utils";

@customElement("pattern-input")
export class PatternInput extends LitElement {
/**
* Lobby button that opens the cosmetics modal (skins, crowns, effects).
* Previews the selected skin/pattern; shows a "Cosmetics" label when the
* player is on defaults.
*/
@customElement("cosmetics-input")
export class CosmeticsInput extends LitElement {
@state() public pattern: PlayerPattern | null = null;
@state() public skin: PlayerSkin | null = null;
@state() public selectedColor: string | null = null;
Expand All @@ -36,7 +41,7 @@ export class PatternInput extends LitElement {
e.preventDefault();
e.stopPropagation();
this.dispatchEvent(
new CustomEvent("pattern-input-click", {
new CustomEvent("cosmetics-input-click", {
bubbles: true,
composed: true,
}),
Expand Down Expand Up @@ -109,13 +114,13 @@ export class PatternInput extends LitElement {
}

const showSelect = this.shouldShowSelectLabel();
const buttonTitle = translateText("territory_patterns.title");
const buttonTitle = translateText("cosmetics.button_title");

// Show loading state
if (this.isLoading) {
return html`
<button
id="pattern-input"
id="cosmetics-input"
class="pattern-btn m-0 p-0 w-full h-full flex cursor-pointer justify-center items-center focus:outline-none focus:ring-0 bg-surface rounded-lg overflow-hidden"
disabled
>
Expand Down Expand Up @@ -144,7 +149,7 @@ export class PatternInput extends LitElement {

return html`
<button
id="pattern-input"
id="cosmetics-input"
class="pattern-btn m-0 p-0 w-full h-full flex cursor-pointer justify-center items-center focus:outline-none focus:ring-0 transition-all duration-200 hover:scale-105 bg-surface hover:brightness-[1.08] active:brightness-[0.95] hover:shadow-[var(--shadow-action-card-hover)] rounded-lg overflow-hidden"
title=${buttonTitle}
@click=${this.onInputClick}
Expand All @@ -162,7 +167,7 @@ export class PatternInput extends LitElement {
? "text-[7px] leading-tight px-0.5"
: "text-[10px] leading-none break-words px-1"} font-black text-white uppercase w-full text-center"
>
${translateText("territory_patterns.select_skin")}
${translateText("cosmetics.title")}
</span>`
: null}
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
import { PlayerPattern } from "../core/Schemas";
import { BaseModal } from "./components/BaseModal";
import "./components/CosmeticButton";
import "./components/EffectsGrid";
import "./components/NotLoggedInWarning";
import { modalHeader } from "./components/ui/ModalHeader";
import {
Expand All @@ -22,12 +23,16 @@ import {
} from "./Cosmetics";
import { translateText } from "./Utils";

@customElement("territory-patterns-modal")
export class TerritoryPatternsModal extends BaseModal {
protected routerName = "territory-patterns";
public previewButton: HTMLElement | null = null;
/**
* One modal for every non-flag cosmetic: a Skins tab (patterns + image skins)
* and an Effects tab (all effect types via the tabbed effects-grid). Opened
* from the lobby's "Cosmetics" button.
*/
@customElement("cosmetics-modal")
export class CosmeticsModal extends BaseModal {
protected routerName = "cosmetics";

@state() private selectedPattern: PlayerPattern | null;
@state() private selectedPattern: PlayerPattern | null = null;
@state() private selectedColor: string | null = null;
@state() private selectedSkinName: string | null = null;
@state() private search = "";
Expand All @@ -36,7 +41,16 @@ export class TerritoryPatternsModal extends BaseModal {
private userSettings: UserSettings = new UserSettings();
private userMeResponse: UserMeResponse | false = false;

private _onPatternSelected = async () => {
protected modalConfig() {
return {
tabs: [
{ key: "skins", label: translateText("store.patterns") },
{ key: "effects", label: translateText("store.effects") },
],
};
}

private _onCosmeticSelected = async () => {
await this.updateFromSettings();
this.refresh();
};
Expand All @@ -51,15 +65,15 @@ export class TerritoryPatternsModal extends BaseModal {
);
window.addEventListener(
`${USER_SETTINGS_CHANGED_EVENT}:${PATTERN_KEY}`,
this._onPatternSelected,
this._onCosmeticSelected,
);
}

disconnectedCallback() {
super.disconnectedCallback();
window.removeEventListener(
`${USER_SETTINGS_CHANGED_EVENT}:${PATTERN_KEY}`,
this._onPatternSelected,
this._onCosmeticSelected,
);
}

Expand Down Expand Up @@ -102,34 +116,32 @@ export class TerritoryPatternsModal extends BaseModal {
);

return html`
<div class="flex flex-col">
<div
class="flex flex-wrap gap-4 p-8 justify-center items-stretch content-start"
>
${items.map((r) => {
const isSelected =
r.type === "pattern"
? (r.cosmetic === null && this.selectedPattern === null) ||
(r.cosmetic !== null &&
this.selectedPattern?.name === r.cosmetic.name &&
(this.selectedPattern?.colorPalette?.name ?? null) ===
(r.colorPalette?.name ?? null))
: (() => {
const skinName = (r.cosmetic as Skin | null)?.name ?? null;
return (
(skinName === null && this.selectedSkinName === null) ||
(skinName !== null && this.selectedSkinName === skinName)
);
})();
return html`
<cosmetic-button
.resolved=${r}
.selected=${isSelected}
.onSelect=${(rc: ResolvedCosmetic) => this.selectCosmetic(rc)}
></cosmetic-button>
`;
})}
</div>
<div
class="flex flex-wrap gap-4 p-8 justify-center items-stretch content-start"
>
${items.map((r) => {
const isSelected =
r.type === "pattern"
? (r.cosmetic === null && this.selectedPattern === null) ||
(r.cosmetic !== null &&
this.selectedPattern?.name === r.cosmetic.name &&
(this.selectedPattern?.colorPalette?.name ?? null) ===
(r.colorPalette?.name ?? null))
: (() => {
const skinName = (r.cosmetic as Skin | null)?.name ?? null;
return (
(skinName === null && this.selectedSkinName === null) ||
(skinName !== null && this.selectedSkinName === skinName)
);
})();
return html`
<cosmetic-button
.resolved=${r}
.selected=${isSelected}
.onSelect=${(rc: ResolvedCosmetic) => this.selectCosmetic(rc)}
></cosmetic-button>
`;
})}
</div>
`;
}
Expand All @@ -140,7 +152,7 @@ export class TerritoryPatternsModal extends BaseModal {
class="relative flex flex-col border-b border-white/10 pb-4 shrink-0"
>
${modalHeader({
title: translateText("territory_patterns.title"),
title: translateText("cosmetics.title"),
onBack: () => this.close(),
ariaLabel: translateText("common.back"),
rightContent: html`<not-logged-in-warning></not-logged-in-warning>`,
Expand All @@ -152,7 +164,7 @@ export class TerritoryPatternsModal extends BaseModal {
rounded-xl shadow-inner text-xl text-center focus:outline-none
focus:ring-2 focus:ring-blue-500/50 focus:border-blue-500 text-white placeholder-white/30 transition-all"
type="text"
placeholder=${translateText("territory_patterns.search")}
placeholder=${translateText("cosmetics.search")}
.value=${this.search}
@change=${this.handleSearch}
@keyup=${this.handleSearch}
Expand All @@ -162,7 +174,19 @@ export class TerritoryPatternsModal extends BaseModal {
`;
}

protected renderBody() {
protected renderBody(tab: string) {
let grid: TemplateResult;
if (tab === "effects") {
grid = html`<effects-grid
mode="select"
tabbed
.cosmetics=${this.cosmetics}
.userMeResponse=${this.userMeResponse}
.search=${this.search}
></effects-grid>`;
} else {
grid = this.renderSkinGrid();
}
return html`
<div class="flex justify-center py-3 shrink-0">
<o-button
Expand All @@ -176,7 +200,7 @@ export class TerritoryPatternsModal extends BaseModal {
}}
></o-button>
</div>
<div class="px-3 pb-3">${this.renderSkinGrid()}</div>
<div class="px-3 pb-3">${grid}</div>
`;
}

Expand All @@ -202,8 +226,8 @@ export class TerritoryPatternsModal extends BaseModal {
);
this.selectedSkinName = skinName;
this.selectedPattern = null;
// Stay open — the tile highlight moves to the new selection.
this.refresh();
this.close();
}

private selectPattern(pattern: PlayerPattern | null) {
Expand All @@ -219,9 +243,9 @@ export class TerritoryPatternsModal extends BaseModal {
}
this.selectedPattern = pattern;
this.selectedSkinName = null;
// Stay open — the tile highlight moves to the new selection.
this.refresh();
this.showSkinSelectedPopup();
this.close();
}

private showSkinSelectedPopup() {
Expand Down
Loading
Loading