120 lines
4.1 KiB
JavaScript
120 lines
4.1 KiB
JavaScript
"use strict";
|
|
/**
|
|
* Game Iframe SDK - React Hook
|
|
* Custom hook để sử dụng SDK trong React components
|
|
*
|
|
* @example
|
|
* ```tsx
|
|
* import { useGameIframeSDK } from 'game-iframe-sdk/react';
|
|
*
|
|
* function GamePlayer() {
|
|
* const iframeRef = useRef<HTMLIFrameElement>(null);
|
|
*
|
|
* const {
|
|
* isReady,
|
|
* sendGameData,
|
|
* sendLeaderboard
|
|
* } = useGameIframeSDK({
|
|
* iframeRef,
|
|
* iframeOrigin: 'http://senaai.vn:1357',
|
|
* onGameReady: () => console.log('Game ready!'),
|
|
* onAnswerReport: (data) => submitToServer(data),
|
|
* onFinalResult: (data) => showResults(data),
|
|
* });
|
|
*
|
|
* return <iframe ref={iframeRef} src={gameUrl} />;
|
|
* }
|
|
* ```
|
|
*/
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.useGameIframeSDK = useGameIframeSDK;
|
|
const react_1 = require("react");
|
|
const GameIframeSDK_1 = require("./GameIframeSDK");
|
|
function useGameIframeSDK(options) {
|
|
const { iframeRef, iframeOrigin, readyDelay, autoSendOnReady, debug, onGameReady, onAnswerReport, onFinalResult, onLeaderboardRequest, onError, } = options;
|
|
const [isReady, setIsReady] = (0, react_1.useState)(false);
|
|
const sdkRef = (0, react_1.useRef)(null);
|
|
// Use refs for callbacks to avoid re-creating SDK when callbacks change
|
|
const callbacksRef = (0, react_1.useRef)({
|
|
onGameReady,
|
|
onAnswerReport,
|
|
onFinalResult,
|
|
onLeaderboardRequest,
|
|
onError,
|
|
});
|
|
// Update callback refs on each render (no effect re-run)
|
|
callbacksRef.current = {
|
|
onGameReady,
|
|
onAnswerReport,
|
|
onFinalResult,
|
|
onLeaderboardRequest,
|
|
onError,
|
|
};
|
|
// Initialize SDK - only depends on config, NOT callbacks
|
|
(0, react_1.useEffect)(() => {
|
|
const sdk = new GameIframeSDK_1.GameIframeSDK({
|
|
iframeOrigin,
|
|
readyDelay,
|
|
autoSendOnReady,
|
|
debug,
|
|
});
|
|
sdkRef.current = sdk;
|
|
// Subscribe to events using refs (stable references)
|
|
const unsubscribers = [];
|
|
unsubscribers.push(sdk.on('gameReady', () => {
|
|
setIsReady(true);
|
|
callbacksRef.current.onGameReady?.();
|
|
}));
|
|
unsubscribers.push(sdk.on('answerReport', (data) => {
|
|
callbacksRef.current.onAnswerReport?.(data);
|
|
}));
|
|
unsubscribers.push(sdk.on('finalResult', (data) => {
|
|
callbacksRef.current.onFinalResult?.(data);
|
|
}));
|
|
unsubscribers.push(sdk.on('leaderboardRequest', (data) => {
|
|
callbacksRef.current.onLeaderboardRequest?.(data.top || 10);
|
|
}));
|
|
unsubscribers.push(sdk.on('error', (err) => {
|
|
callbacksRef.current.onError?.(err);
|
|
}));
|
|
return () => {
|
|
unsubscribers.forEach((unsub) => unsub());
|
|
sdk.destroy();
|
|
sdkRef.current = null;
|
|
};
|
|
}, [iframeOrigin, readyDelay, autoSendOnReady, debug]); // ✅ No callback deps
|
|
// Sync iframe ref with SDK
|
|
(0, react_1.useEffect)(() => {
|
|
if (sdkRef.current && iframeRef.current) {
|
|
sdkRef.current.setIframe(iframeRef.current);
|
|
}
|
|
}, [iframeRef.current]);
|
|
// Reset ready state when iframe src changes
|
|
(0, react_1.useEffect)(() => {
|
|
setIsReady(false);
|
|
}, [iframeRef.current?.src]);
|
|
// Memoized methods
|
|
const sendGameData = (0, react_1.useCallback)((data) => {
|
|
return sdkRef.current?.sendGameData(data) ?? false;
|
|
}, []);
|
|
const sendLeaderboard = (0, react_1.useCallback)((data) => {
|
|
return sdkRef.current?.sendLeaderboard(data) ?? false;
|
|
}, []);
|
|
const queueGameData = (0, react_1.useCallback)((data) => {
|
|
sdkRef.current?.queueGameData(data);
|
|
}, []);
|
|
const reloadIframe = (0, react_1.useCallback)(() => {
|
|
setIsReady(false);
|
|
return sdkRef.current?.reloadIframe() ?? false;
|
|
}, []);
|
|
return {
|
|
sdk: sdkRef.current,
|
|
isReady,
|
|
sendGameData,
|
|
sendLeaderboard,
|
|
queueGameData,
|
|
reloadIframe,
|
|
};
|
|
}
|
|
exports.default = useGameIframeSDK;
|
|
//# sourceMappingURL=useGameIframeSDK.js.map
|