Update homepage & in-game promos (#3602)

## Description:

* Replace the static footer ad (HomeFooterAd component) with a Playwire
bottom_rail ad that loads on lobby join and persists into the spawn
phase
* Expand in-game ad slots from 1 to 3 (standard_iab_left1, left3, left4)
with a timer-based visibility check to show a background container when
ads render
* Remove the resize-based footer ad height logic and gutter ad vertical
offset adjustments that depended on it

<img width="1828" height="961" alt="Screenshot 2026-04-16 at 12 14
00 PM"
src="https://github.com/user-attachments/assets/50bfd0de-dd54-4f8b-b75e-04b720a1841b"
/>


<img width="1286" height="939" alt="Screenshot 2026-04-16 at 11 59
18 AM"
src="https://github.com/user-attachments/assets/e0fb0762-82e7-444f-8706-5908aad0f094"
/>
## 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
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Please put your Discord username so you can be contacted if a bug or
regression is found:

evan
This commit is contained in:
Evan
2026-04-16 12:19:12 -07:00
committed by GitHub
parent 57aaf59220
commit adeb6a306a
4 changed files with 128 additions and 165 deletions
+64 -51
View File
@@ -4,29 +4,32 @@ import { GameView } from "../../../core/game/GameView";
import { crazyGamesSDK } from "../../CrazyGamesSDK";
import { Layer } from "./Layer";
const AD_TYPE = "standard_iab_left1";
const AD_CONTAINER_ID = "in-game-bottom-left-ad";
const BOTTOM_RAIL_TYPE = "bottom_rail";
const AD_TYPES = [
{ type: "standard_iab_left1", selectorId: "in-game-bottom-left-ad" },
{ type: "standard_iab_left3", selectorId: "in-game-bottom-left-ad3" },
{ type: "standard_iab_left4", selectorId: "in-game-bottom-left-ad4" },
];
@customElement("in-game-promo")
export class InGamePromo extends LitElement implements Layer {
public game: GameView;
private shouldShow: boolean = false;
private bottomRailActive: boolean = false;
private adsVisible: boolean = false;
private bottomRailDestroyed: boolean = false;
private cornerAdShown: boolean = false;
private adCheckInterval: ReturnType<typeof setTimeout> | null = null;
createRenderRoot() {
return this;
}
init() {
this.showBottomRail();
}
init() {}
tick() {
if (!this.game.inSpawnPhase()) {
if (this.bottomRailActive) {
if (!this.bottomRailDestroyed) {
this.bottomRailDestroyed = true;
this.destroyBottomRail();
}
if (!this.cornerAdShown) {
@@ -37,38 +40,12 @@ export class InGamePromo extends LitElement implements Layer {
}
}
private showBottomRail(): void {
if (!window.adsEnabled) return;
if (!this.game.inSpawnPhase()) return;
if (!window.ramp) {
console.warn("Playwire RAMP not available for bottom_rail ad");
return;
}
this.bottomRailActive = true;
try {
window.ramp.que.push(() => {
try {
window.ramp.spaAddAds([{ type: BOTTOM_RAIL_TYPE }]);
console.log("Bottom rail ad loaded during spawn phase");
} catch (e) {
console.error("Failed to add bottom_rail ad:", e);
}
});
} catch (error) {
console.error("Failed to load bottom_rail ad:", error);
}
}
private destroyBottomRail(): void {
if (!this.bottomRailActive) return;
this.bottomRailActive = false;
if (!window.ramp) return;
try {
window.ramp.spaAds({ ads: [], countPageview: false });
console.log("Bottom rail ad destroyed via spaAds after spawn phase");
window.ramp.destroyUnits("pw-oop-bottom_rail");
console.log("Bottom rail ad destroyed after spawn phase");
} catch (e) {
console.error("Error destroying bottom_rail ad:", e);
}
@@ -93,6 +70,7 @@ export class InGamePromo extends LitElement implements Layer {
this.updateComplete.then(() => {
this.loadAd();
this.checkForAds();
});
}
@@ -115,6 +93,26 @@ export class InGamePromo extends LitElement implements Layer {
});
}
private checkForAds(): void {
if (this.adCheckInterval) {
clearInterval(this.adCheckInterval);
}
this.adCheckInterval = setInterval(() => {
const hasAds = AD_TYPES.some(({ selectorId }) => {
const el = document.getElementById(selectorId);
return el && el.clientHeight > 50;
});
if (hasAds) {
this.adsVisible = true;
this.requestUpdate();
if (this.adCheckInterval) {
clearInterval(this.adCheckInterval);
this.adCheckInterval = null;
}
}
}, 1000);
}
private loadAd(): void {
if (!window.ramp) {
console.warn("Playwire RAMP not available for in-game ad");
@@ -124,23 +122,28 @@ export class InGamePromo extends LitElement implements Layer {
try {
window.ramp.que.push(() => {
try {
window.ramp.spaAddAds([
{
type: AD_TYPE,
selectorId: AD_CONTAINER_ID,
},
]);
console.log("In-game bottom-left ad loaded:", AD_TYPE);
window.ramp.spaAddAds(
AD_TYPES.map(({ type, selectorId }) => ({ type, selectorId })),
);
console.log(
"In-game bottom-left ads loaded:",
AD_TYPES.map((a) => a.type),
);
} catch (e) {
console.error("Failed to add in-game ad:", e);
console.error("Failed to add in-game ads:", e);
}
});
} catch (error) {
console.error("Failed to load in-game ad:", error);
console.error("Failed to load in-game ads:", error);
}
}
public hideAd(): void {
if (this.adCheckInterval) {
clearInterval(this.adCheckInterval);
this.adCheckInterval = null;
}
this.adsVisible = false;
this.destroyBottomRail();
if (crazyGamesSDK.isOnCrazyGames()) {
@@ -156,10 +159,12 @@ export class InGamePromo extends LitElement implements Layer {
}
this.shouldShow = false;
try {
window.ramp.destroyUnits(AD_TYPE);
console.log("successfully destroyed in-game bottom-left ad");
for (const { type } of AD_TYPES) {
window.ramp.destroyUnits(type);
}
console.log("successfully destroyed in-game bottom-left ads");
} catch (e) {
console.error("error destroying in-game ad:", e);
console.error("error destroying in-game ads:", e);
}
this.requestUpdate();
}
@@ -175,10 +180,18 @@ export class InGamePromo extends LitElement implements Layer {
return html`
<div
id="${AD_CONTAINER_ID}"
class="fixed left-0 z-[100] pointer-events-auto"
id="in-game-promo-container"
class="fixed left-0 z-[100] pointer-events-auto flex flex-col-reverse ${this
.adsVisible
? "bg-gray-800 rounded-tr-lg p-1"
: ""}"
style="bottom: -0.7cm"
></div>
>
${AD_TYPES.map(
({ selectorId }) =>
html`<div id="${selectorId}" style="margin:0;padding:0"></div>`,
)}
</div>
`;
}
}