diff --git a/.env.example b/.env.example index ba57a07..82e2164 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,3 @@ APP_ID=2984220425889259895 ZMP_TOKEN= -VITE_GAME_LINK= +VITE_API_URL=https://api.play4promo.online/graphql \ No newline at end of file diff --git a/README.md b/README.md index 7097ba6..4a9dde9 100644 --- a/README.md +++ b/README.md @@ -53,74 +53,34 @@ 1. **Install dependencies**: ```bash - npm install react-unity-webgl + npm install promogame-game-component ``` or ```bash - pnpm install react-unity-webgl + pnpm install promogame-game-component ``` or ```bash - yarn install react-unity-webgl - ``` - -1. **Create** the game component: - ```tsx - import clsx from 'clsx'; - import { useEffect } from 'react'; - import { Unity, useUnityContext } from 'react-unity-webgl'; - import zmpSdk from 'zmp-sdk'; - - export const UnityGame = () => { - const gameLink = import.meta.env.VITE_GAME_LINK; - const { unityProvider, isLoaded, loadingProgression, UNSAFE__unityInstance } = useUnityContext({ - loaderUrl: `${gameLink}/Build/Build.loader.js`, - dataUrl: `${gameLink}/Build/Build.data.unityweb`, - frameworkUrl: `${gameLink}/Build/Build.framework.js.unityweb`, - codeUrl: `${gameLink}/Build/Build.wasm.unityweb`, - }); - - useEffect(() => { - window.ZaloMiniAppSDK = zmpSdk; - window.unityInstance = UNSAFE__unityInstance; - }, [UNSAFE__unityInstance]); - - return ( - <> - {!isLoaded && ( -
- Loading {loadingProgression * 100 + 10}% -
- )} - - - ); - }; - ``` - -1. **Add** game link to env: - - - ``` - APP_ID= - ZMP_TOKEN= - VITE_GAME_LINK=[your game link] + yarn install promogame-game-component ``` 1. **Import** and use it anywhere: ```tsx - export default function MainApp() { - return ( -
- -
- ); - } + export default function MainApp() { + const Loading = ({ progress }: { progress: number }) => { + return ( +
+ Loading {progress * 100}% +
+ ); + }; + + return ( +
+ +
+ ); + } ``` \ No newline at end of file diff --git a/package.json b/package.json index 7b7c033..67ea1dd 100644 --- a/package.json +++ b/package.json @@ -23,10 +23,10 @@ "dependencies": { "clsx": "^2.1.1", "parse-path": "^7.0.0", + "promogame-game-component": "^0.0.12", "prop-types": "^15.8.1", "react": "^18.3.1", "react-dom": "^18.3.1", - "react-unity-webgl": "^9.6.0", "usehooks-ts": "^3.1.0", "zmp-sdk": "latest", "zmp-ui": "latest", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cd052b3..61fb14d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,9 @@ importers: parse-path: specifier: ^7.0.0 version: 7.1.0 + promogame-game-component: + specifier: ^0.0.12 + version: 0.0.12(@babel/core@7.27.1)(@types/react@18.3.21)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) prop-types: specifier: ^15.8.1 version: 15.8.1 @@ -23,9 +26,6 @@ importers: react-dom: specifier: ^18.3.1 version: 18.3.1(react@18.3.1) - react-unity-webgl: - specifier: ^9.6.0 - version: 9.8.0(react@18.3.1) usehooks-ts: specifier: ^3.1.0 version: 3.1.1(react@18.3.1) @@ -92,6 +92,24 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} + '@apollo/client@3.13.8': + resolution: {integrity: sha512-YM9lQpm0VfVco4DSyKooHS/fDTiKQcCHfxr7i3iL6a0kP/jNO5+4NFK6vtRDxaYisd5BrwOZHLJpPBnvRVpKPg==} + peerDependencies: + graphql: ^15.0.0 || ^16.0.0 + graphql-ws: ^5.5.5 || ^6.0.3 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc + subscriptions-transport-ws: ^0.9.0 || ^0.11.0 + peerDependenciesMeta: + graphql-ws: + optional: true + react: + optional: true + react-dom: + optional: true + subscriptions-transport-ws: + optional: true + '@babel/cli@7.27.2': resolution: {integrity: sha512-cfd7DnGlhH6OIyuPSSj3vcfIdnbXukhAyKY8NaZrFadC7pXyL9mOL5WgjcptiEJLi5k3j8aYvLIVCzezrWTaiA==} engines: {node: '>=6.9.0'} @@ -377,6 +395,11 @@ packages: cpu: [x64] os: [win32] + '@graphql-typed-document-node/core@3.2.0': + resolution: {integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==} + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -705,6 +728,22 @@ packages: peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 + '@wry/caches@1.0.1': + resolution: {integrity: sha512-bXuaUNLVVkD20wcGBWRyo7j9N3TxePEWFZj2Y+r9OoUzfqmavM84+mFykRicNsBqatba5JLay1t48wxaXaWnlA==} + engines: {node: '>=8'} + + '@wry/context@0.7.4': + resolution: {integrity: sha512-jmT7Sb4ZQWI5iyu3lobQxICu2nC/vbUhP0vIdd6tHC9PTfenmRmuIFqktc6GH9cgi+ZHnsLWPvfSvc4DrYmKiQ==} + engines: {node: '>=8'} + + '@wry/equality@0.5.7': + resolution: {integrity: sha512-BRFORjsTuQv5gxcXsuDXx6oGRhuVsEGwZy6LOzRRfgu+eSfxbhUQ9L9YtSEIuIjY/o7g3iWFjrc5eSY1GXP2Dw==} + engines: {node: '>=8'} + + '@wry/trie@0.5.0': + resolution: {integrity: sha512-FNoYzHawTMk/6KMQoEG5O4PuioX19UbwdQKF44yw0nLfOypfQdjtfZzo/UIJWAJ23sNIFbD1Ug9lbaDGMwbqQA==} + engines: {node: '>=8'} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -1018,6 +1057,16 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + graphql-tag@2.12.6: + resolution: {integrity: sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==} + engines: {node: '>=10'} + peerDependencies: + graphql: ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + + graphql@16.11.0: + resolution: {integrity: sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==} + engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -1026,6 +1075,9 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -1183,6 +1235,9 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + optimism@0.18.1: + resolution: {integrity: sha512-mLXNwWPa9dgFyDqkNi54sjDyNJ9/fTI6WGBLgnXku1vdKY/jovHfZT5r+aiVeFFLOz+foPNOm5YJ4mqgld2GBQ==} + p-limit@2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} @@ -1445,6 +1500,12 @@ packages: resolution: {integrity: sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==} engines: {node: '>= 0.8'} + promogame-game-component@0.0.12: + resolution: {integrity: sha512-LNELuHnll0M/pQmyZbh82MjTo5/BdiYN9yl/72iOaUIYKjq9KOhLhgfPQfsY7vmh3ipjyrqJpec3hXDtTrohLQ==} + peerDependencies: + react: '*' + react-dom: '*' + prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -1517,6 +1578,17 @@ packages: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + rehackt@0.1.0: + resolution: {integrity: sha512-7kRDOuLHB87D/JESKxQoRwv4DzbIdwkAGQ7p6QKGdVlY1IZheUnVhlk/4UZlNUVxdAXpyxikE3URsG067ybVzw==} + peerDependencies: + '@types/react': '*' + react: '*' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -1620,6 +1692,13 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} + symbol-observable@4.0.0: + resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==} + engines: {node: '>=0.10'} + + tailwind-merge@3.3.0: + resolution: {integrity: sha512-fyW/pEfcQSiigd5SNn0nApUOxx0zB/dm6UDU/rEwc2c3sX2smWUNbapHv+QRqLGVp9GWX3THIa7MUGPo+YkDzQ==} + tailwindcss@3.4.17: resolution: {integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==} engines: {node: '>=14.0.0'} @@ -1642,6 +1721,10 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + ts-invariant@0.10.3: + resolution: {integrity: sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==} + engines: {node: '>=8'} + tsconfck@3.1.5: resolution: {integrity: sha512-CLDfGgUp7XPswWnezWwsCRxNmgQjhYq3VXHM0/XIRxhVrKw0M1if9agzryh1QS3nxjCROvV+xWxoJO1YctzzWg==} engines: {node: ^18 || >=20} @@ -1777,9 +1860,18 @@ packages: resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} engines: {node: '>=10'} + zen-observable-ts@1.2.5: + resolution: {integrity: sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==} + + zen-observable@0.8.15: + resolution: {integrity: sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==} + zmp-sdk@2.45.1: resolution: {integrity: sha512-yN/rSzSIm/KVi02Syz3JTPA9I1w3GdAbI4lbhzlYvIkg0dH70vcmzcDlP+8ldLihhz+t968C8DqMjqsunJ/IWw==} + zmp-sdk@2.46.2: + resolution: {integrity: sha512-abmtpuM0z5j0g+2RkHdvKOljI3zEb857G5S85kyGYm3ThBSfeH4LIWF1XVrIER6MrYA5JGTMMxryY70tmLGw7g==} + zmp-ui@1.11.7: resolution: {integrity: sha512-/EWmrcTuhjiMRdqUqUgaC7ZSsD1ZttQSBIYAERKgfX7lYtpEORO8y9o+ByU7OlJUZ2cKj+/nvWiV7DA3yA5fXg==} @@ -1815,6 +1907,28 @@ snapshots: '@jridgewell/gen-mapping': 0.3.8 '@jridgewell/trace-mapping': 0.3.25 + '@apollo/client@3.13.8(@types/react@18.3.21)(graphql@16.11.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@graphql-typed-document-node/core': 3.2.0(graphql@16.11.0) + '@wry/caches': 1.0.1 + '@wry/equality': 0.5.7 + '@wry/trie': 0.5.0 + graphql: 16.11.0 + graphql-tag: 2.12.6(graphql@16.11.0) + hoist-non-react-statics: 3.3.2 + optimism: 0.18.1 + prop-types: 15.8.1 + rehackt: 0.1.0(@types/react@18.3.21)(react@18.3.1) + symbol-observable: 4.0.0 + ts-invariant: 0.10.3 + tslib: 2.8.1 + zen-observable-ts: 1.2.5 + optionalDependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + transitivePeerDependencies: + - '@types/react' + '@babel/cli@7.27.2(@babel/core@7.27.1)': dependencies: '@babel/core': 7.27.1 @@ -2047,6 +2161,10 @@ snapshots: '@esbuild/win32-x64@0.21.5': optional: true + '@graphql-typed-document-node/core@3.2.0(graphql@16.11.0)': + dependencies: + graphql: 16.11.0 + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -2350,6 +2468,22 @@ snapshots: transitivePeerDependencies: - supports-color + '@wry/caches@1.0.1': + dependencies: + tslib: 2.8.1 + + '@wry/context@0.7.4': + dependencies: + tslib: 2.8.1 + + '@wry/equality@0.5.7': + dependencies: + tslib: 2.8.1 + + '@wry/trie@0.5.0': + dependencies: + tslib: 2.8.1 + ansi-regex@5.0.1: {} ansi-regex@6.1.0: {} @@ -2662,12 +2796,23 @@ snapshots: graceful-fs@4.2.11: {} + graphql-tag@2.12.6(graphql@16.11.0): + dependencies: + graphql: 16.11.0 + tslib: 2.8.1 + + graphql@16.11.0: {} + has-flag@4.0.0: {} hasown@2.0.2: dependencies: function-bind: 1.1.2 + hoist-non-react-statics@3.3.2: + dependencies: + react-is: 16.13.1 + ignore@5.3.2: {} immutable@5.1.2: {} @@ -2794,6 +2939,13 @@ snapshots: dependencies: wrappy: 1.0.2 + optimism@0.18.1: + dependencies: + '@wry/caches': 1.0.1 + '@wry/context': 0.7.4 + '@wry/trie': 0.5.0 + tslib: 2.8.1 + p-limit@2.3.0: dependencies: p-try: 2.2.0 @@ -3102,6 +3254,23 @@ snapshots: pretty-hrtime@1.0.3: {} + promogame-game-component@0.0.12(@babel/core@7.27.1)(@types/react@18.3.21)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@apollo/client': 3.13.8(@types/react@18.3.21)(graphql@16.11.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@graphql-typed-document-node/core': 3.2.0(graphql@16.11.0) + clsx: 2.1.1 + graphql: 16.11.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-unity-webgl: 9.8.0(react@18.3.1) + tailwind-merge: 3.3.0 + zmp-sdk: 2.46.2(@babel/core@7.27.1) + transitivePeerDependencies: + - '@babel/core' + - '@types/react' + - graphql-ws + - subscriptions-transport-ws + prop-types@15.8.1: dependencies: loose-envify: 1.4.0 @@ -3171,6 +3340,11 @@ snapshots: readdirp@4.1.2: {} + rehackt@0.1.0(@types/react@18.3.21)(react@18.3.1): + optionalDependencies: + '@types/react': 18.3.21 + react: 18.3.1 + require-directory@2.1.1: {} require-main-filename@2.0.0: {} @@ -3285,6 +3459,10 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} + symbol-observable@4.0.0: {} + + tailwind-merge@3.3.0: {} + tailwindcss@3.4.17: dependencies: '@alloc/quick-lru': 5.2.0 @@ -3328,6 +3506,10 @@ snapshots: ts-interface-checker@0.1.13: {} + ts-invariant@0.10.3: + dependencies: + tslib: 2.8.1 + tsconfck@3.1.5: {} tslib@1.14.1: {} @@ -3438,6 +3620,12 @@ snapshots: y18n: 5.0.8 yargs-parser: 20.2.9 + zen-observable-ts@1.2.5: + dependencies: + zen-observable: 0.8.15 + + zen-observable@0.8.15: {} + zmp-sdk@2.45.1(@babel/core@7.27.1): dependencies: '@babel/cli': 7.27.2(@babel/core@7.27.1) @@ -3450,6 +3638,18 @@ snapshots: transitivePeerDependencies: - '@babel/core' + zmp-sdk@2.46.2(@babel/core@7.27.1): + dependencies: + '@babel/cli': 7.27.2(@babel/core@7.27.1) + '@sentry/browser': 6.19.7 + '@sentry/tracing': 6.19.7 + '@swc/helpers': 0.4.37 + eventemitter3: 4.0.7 + qrcode: 1.5.4 + raven-js: 3.27.2 + transitivePeerDependencies: + - '@babel/core' + zmp-ui@1.11.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@babel/runtime': 7.27.1 diff --git a/src/MainApp.tsx b/src/MainApp.tsx index ea5aa2d..b3d5d0e 100644 --- a/src/MainApp.tsx +++ b/src/MainApp.tsx @@ -1,9 +1,17 @@ -import { UnityGame } from './components/unity-game'; +import {PromogameGame} from "promogame-game-component"; export default function MainApp() { + const Loading = ({ progress }: { progress: number }) => { + return ( +
+ Loading {progress * 100}% +
+ ); + }; + return (
- +
); } diff --git a/src/components/unity-game.tsx b/src/components/unity-game.tsx deleted file mode 100644 index 4d60149..0000000 --- a/src/components/unity-game.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import clsx from 'clsx'; -import { useEffect } from 'react'; -import { Unity, useUnityContext } from 'react-unity-webgl'; -import zmpSdk from 'zmp-sdk'; - -export const UnityGame = () => { - const gameLink = import.meta.env.VITE_GAME_LINK; - const { unityProvider, isLoaded, loadingProgression, UNSAFE__unityInstance } = useUnityContext({ - loaderUrl: `${gameLink}/Build/Build.loader.js`, - dataUrl: `${gameLink}/Build/Build.data.unityweb`, - frameworkUrl: `${gameLink}/Build/Build.framework.js.unityweb`, - codeUrl: `${gameLink}/Build/Build.wasm.unityweb`, - }); - - useEffect(() => { - window.ZaloMiniAppSDK = zmpSdk; - window.unityInstance = UNSAFE__unityInstance; - }, [UNSAFE__unityInstance]); - - return ( - <> - {!isLoaded && ( -
- Loading {loadingProgression * 100 + 10}% -
- )} - - - ); -};