Add GameDistributionBanner component and integrate into game UI and home screens

This commit is contained in:
Gautam Anand 2026-03-22 18:16:24 +05:30
parent a59ed84386
commit 4b0097a963
5 changed files with 118 additions and 3 deletions

View file

@ -18,7 +18,8 @@
"mcp__ide__getDiagnostics",
"Bash(npx next build:*)",
"Bash(npx acorn:*)",
"WebSearch"
"WebSearch",
"Bash(npx next:*)"
],
"deny": [
"Bash(git push:*)"

View file

@ -0,0 +1,90 @@
import { useEffect, useState, useRef } from "react";
import sendEvent from "./utils/sendEvent";
function findAdType(screenW, screenH, types, vertThresh) {
let type = 0;
for (let i = 0; i < types.length; i++) {
if (types[i][0] <= screenW * 0.9 && types[i][1] <= screenH * vertThresh) {
type = i;
}
}
if (types[type][0] > screenW || types[type][1] > screenH * vertThresh)
return -1;
return type;
}
export default function GameDistributionBanner({
types,
id,
vertThresh = 0.3,
screenW,
screenH,
}) {
const [type, setType] = useState(
findAdType(screenW, screenH, types, vertThresh)
);
const [isClient, setIsClient] = useState(false);
const containerRef = useRef(null);
useEffect(() => {
if (window.location.hostname === "localhost") setIsClient("debug");
else setIsClient(true);
}, []);
useEffect(() => {
setType(findAdType(screenW, screenH, types, vertThresh));
}, [screenW, screenH, JSON.stringify(types), vertThresh]);
useEffect(() => {
if (type === -1 || !isClient || isClient === "debug") return;
if (typeof gdsdk === "undefined" || typeof gdsdk.showAd === "undefined") return;
function requestBanner() {
try {
gdsdk
.showAd(gdsdk.AdType.Display, { containerId: id })
.then(() => {
sendEvent(`gd_banner_${types[type][0]}x${types[type][1]}`);
})
.catch((e) => console.log("[GD Banner] Request error:", e));
} catch (e) {
console.log("[GD Banner] Request error:", e);
}
}
const initTimer = setTimeout(requestBanner, 200);
const refreshInterval = setInterval(requestBanner, 30000);
return () => {
clearTimeout(initTimer);
clearInterval(refreshInterval);
};
}, [type, isClient, id]);
if (type === -1) return null;
if (!isClient) return null;
return (
<div
ref={containerRef}
id={id}
style={{
width: types[type][0],
height: types[type][1],
backgroundColor: isClient === "debug" ? "rgba(0,0,0,0.5)" : "transparent",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
{isClient === "debug" && (
<div style={{ color: "white", textAlign: "center" }}>
<h3>GD Banner</h3>
<p style={{ fontSize: "0.8em" }}>
{types[type][0]}x{types[type][1]}
</p>
</div>
)}
</div>
);
}

View file

@ -18,6 +18,7 @@ import sendEvent from "./utils/sendEvent";
import Ad from "./bannerAdNitro";
// import Ad from "./bannerAdAdinplay";
import CrazyGamesBanner from "./bannerAdCrazyGames";
import GameDistributionBanner from "./bannerAdGameDistribution";
import AnimatedCounter from "./AnimatedCounter";
import gameStorage from "./utils/localStorage";
import HealthBar from "./duelHealthbar";
@ -542,6 +543,14 @@ export default function GameUI({ inCoolMathGames, inGameDistribution, miniMapSho
</div>
)}
{ inGameDistribution && !onboarding && !singlePlayerRound?.done && !onboarding?.completed && !(width < 700 && height < 350) && (
<div className={`topAdFixed ${(multiplayerTimerShown || onboardingTimerShown || singlePlayerRound)?'moreDown':''}`}>
<GameDistributionBanner
id="gd-banner-gameui"
screenH={height} types={[[728,90]]} screenW={Math.max(400, width-350)} vertThresh={0.3} />
</div>
)}
{ multiplayerState?.gameData?.duel && multiplayerState?.gameData?.state !== 'end' && (
<div className={`hbparent ${isStartingDuel ? 'hb-parent' : ''}`}>

View file

@ -102,9 +102,12 @@ ads.js"></script>*/
} else if(process.env.NEXT_PUBLIC_GAMEDISTRIBUTION === "true") {
window["GD_OPTIONS"] = {
"gameId": "327b25f595b6478789b18768fd909055",
"gameId": "fef00656129743768437b7589b7c48b1",
"onEvent": function(event) {
switch (event.name) {
case "SDK_READY":
console.log("[GD] SDK Ready");
break;
case "SDK_GAME_START":
case "SDK_ERROR":
case "AD_ERROR":
@ -119,6 +122,10 @@ ads.js"></script>*/
case "SDK_REWARDED_WATCH_COMPLETE":
if(window.onGDRewardedComplete) window.onGDRewardedComplete();
break;
case "SDK_REWARDED_WATCH_SKIPPED":
console.log("[GD] Rewarded ad skipped");
if(window.onGDRewardedSkipped) window.onGDRewardedSkipped();
break;
}
},
};

View file

@ -54,6 +54,7 @@ import Stats from "stats.js";
// import getTimeString, { getMaintenanceDate } from "./maintenanceTime";
// import MaintenanceBanner from "./MaintenanceBanner";
import Ad from "./bannerAdNitro";
import GameDistributionBanner from "./bannerAdGameDistribution";
import PendingNameChangeModal from "./pendingNameChangeModal";
@ -2110,7 +2111,7 @@ export default function Home({ }) {
window._gdAdFinished = null;
}
}, 15000);
gdsdk.showAd();
gdsdk.showAd('interstitial');
} else {
adFinished();
}
@ -2741,6 +2742,13 @@ export default function Home({ }) {
inCrazyGames={inCrazyGames} showAdvertisementText={false} screenH={height} types={height < 510 ? [[300, 250]] : [[320, 50], [300, 250]]} screenW={width} vertThresh={width < 600 ? 0.28 : 0.5} />
</div>
}
{inGameDistribution && screen === 'home' && (
<div className="home_ad">
<GameDistributionBanner
id="gd-banner-home"
screenH={height} types={[[300, 250]]} screenW={width} vertThresh={width < 600 ? 0.28 : 0.5} />
</div>
)}
<span id="g2_playerCount" className={`bigSpan onlineText desktop ${screen !== 'home' ? 'notHome' : ''} ${(screen === 'singleplayer' || screen === 'onboarding' || (multiplayerState?.inGame && !['waitingForPlayers', 'findingGame', 'findingOpponent'].includes(multiplayerState?.gameData?.state)) || !multiplayerState?.connected || !multiplayerState?.playerCount) ? 'hide' : ''}`}>
{maintenance ? text("maintenanceMode") : text("onlineCnt", { cnt: multiplayerState?.playerCount || 0 })}
</span>