useGameIFrame.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import { useCallback, useEffect, useRef, useState } from "react";
  2. import { ROUTE_PATH } from "@constants/routes";
  3. import { exitFullScreen, isAndroid, isIOS, isLandscape, isPortrait } from "@utils/helpers";
  4. import { useNavigate } from "react-router-dom";
  5. import { useDispatch, useSelector } from "react-redux";
  6. import { getBankRuptcyGift } from "@features/paySlice";
  7. import { getLandscapeGames, updateGameCardInfo } from "@features/mainSlice";
  8. import { useOrientation } from "react-use";
  9. import { useThemeProvider } from "@contexts/themeContext";
  10. const objInfo = {
  11. closeCount: 0
  12. }
  13. const useGameIFrame = () => {
  14. const iFrameRef = useRef(null);
  15. const [forceLandscape, setForceLandscape] = useState(false);
  16. const [isGameLoad, setIsGameLoad] = useState(false);
  17. const ruptcyGift = useSelector(getBankRuptcyGift);
  18. const LandscapeGames = useSelector(getLandscapeGames);
  19. const { gameID, isMobile } = useThemeProvider();
  20. const navigate = useNavigate();
  21. const dispatch = useDispatch();
  22. const orientation = useOrientation();
  23. const onBack = useCallback(() => {
  24. if (iFrameRef.extBackFunc != null) {
  25. iFrameRef.extBackFunc();
  26. return;
  27. }
  28. navigate(ROUTE_PATH.BACK);
  29. }, [navigate]);
  30. const checkCloseCount = useCallback(() => {
  31. if (objInfo.closeCount >= 2) {
  32. onBack();
  33. }
  34. }, [onBack]);
  35. const safeNavigate = useCallback((route, options) => {
  36. if (isIOS()) {
  37. window.location.href = route;
  38. } else {
  39. navigate(route, options)
  40. }
  41. }, [navigate]);
  42. const receiveMessage = useCallback((event) => {
  43. const gameWindow = iFrameRef.current?.contentWindow;
  44. if (!gameWindow || event.source !== gameWindow) return;
  45. let data = event.data;
  46. if (data && data.cmd != null) {
  47. if (data.cmd === "back") {
  48. onBack();
  49. }
  50. else if (data.cmd === "pay") {
  51. if (!!ruptcyGift && ruptcyGift.length > 0) {
  52. global.showExclusiveGift();
  53. } else {
  54. safeNavigate(isMobile() ? ROUTE_PATH.DEPOSIT : ROUTE_PATH.DEPOSIT_POP, { replace: true })
  55. }
  56. }
  57. else if (data.cmd === "withdraw") {
  58. safeNavigate(isMobile() ? ROUTE_PATH.WITHDRAW : ROUTE_PATH.WITHDRAW_POP, { replace: true });
  59. }
  60. else if (data.cmd === "fullScreen") {
  61. return;
  62. }
  63. else if (data.cmd === "closeLoading") {
  64. setIsGameLoad(true);
  65. objInfo.closeCount++;
  66. checkCloseCount();
  67. }
  68. }
  69. }, [checkCloseCount, isMobile, onBack, ruptcyGift, safeNavigate]);
  70. const clearGameTimeout = useCallback(() => {
  71. const gameFrame = iFrameRef.current;
  72. if (gameFrame != null) {
  73. if (gameFrame.loadtimeout != null) {
  74. clearTimeout(gameFrame.loadtimeout);
  75. gameFrame.loadtimeout = null;
  76. }
  77. }
  78. }, []);
  79. const handleLoadGame = useCallback(() => {
  80. setIsGameLoad(true);
  81. clearGameTimeout();
  82. }, [clearGameTimeout]);
  83. const initGameEvent = useCallback(() => {
  84. const gameFrame = iFrameRef.current;
  85. if (gameFrame != null) {
  86. gameFrame.addEventListener('load', handleLoadGame);
  87. gameFrame.loadtimeout = setTimeout(() => {
  88. handleLoadGame();
  89. }, 5000);
  90. }
  91. window.addEventListener("message", receiveMessage, false);
  92. objInfo.closeCount = 0;
  93. }, [handleLoadGame, receiveMessage]);
  94. const removeGameEvent = useCallback(() => {
  95. const gameFrame = iFrameRef.current;
  96. if (gameFrame != null) {
  97. gameFrame.removeEventListener('load', handleLoadGame);
  98. clearGameTimeout();
  99. }
  100. window.removeEventListener("message", receiveMessage);
  101. objInfo.closeCount = 0;
  102. }, [clearGameTimeout, handleLoadGame, receiveMessage]);
  103. const handleEnterGame = useCallback((data) => {
  104. objInfo.closeCount = 0;
  105. setIsGameLoad(false);
  106. let id = data.id;
  107. dispatch(updateGameCardInfo({
  108. data: data,
  109. level: 0
  110. }))
  111. let path = ROUTE_PATH.GAME + "/" + id;
  112. global.authLockPath = path;
  113. navigate(path);
  114. }, [dispatch, navigate]);
  115. useEffect(() => {
  116. initGameEvent();
  117. return () => {
  118. removeGameEvent();
  119. exitFullScreen();
  120. };
  121. }, [initGameEvent, removeGameEvent]);
  122. useEffect(() => {
  123. const landscape = isLandscape(orientation);
  124. document.documentElement.style.setProperty('--view-size', landscape ? 0.5 : 1);
  125. if (landscape) setForceLandscape(false);
  126. if (landscape || window.innerWidth >= window.innerHeight) {
  127. document.documentElement.classList.add("landscape-page");
  128. } else {
  129. document.documentElement.classList.remove("landscape-page");
  130. }
  131. return () => {
  132. document.documentElement.style.setProperty('--view-size', 1);
  133. document.documentElement.classList.remove("landscape-page");
  134. }
  135. }, [orientation]);
  136. useEffect(() => {
  137. if (Number(gameID) === 0) return;
  138. const ios = isIOS();
  139. const mobileDevice = isAndroid() || ios;
  140. const portrait = isPortrait();
  141. const supportsLandscape = (LandscapeGames || []).some(id => Number(id) === Number(gameID));
  142. if (!supportsLandscape || !mobileDevice || !portrait) {
  143. return;
  144. }
  145. setForceLandscape(true);
  146. document.documentElement.style.setProperty('--view-size', 0.9);
  147. if (isIOS()) {
  148. document.documentElement.style.setProperty('--landscape-ios', "10vh");
  149. }
  150. return () => {
  151. const landscapeScale = isLandscape(orientation) ? 0.5 : 1;
  152. document.documentElement.style.setProperty('--view-size', landscapeScale);
  153. document.documentElement.style.setProperty('--landscape-ios', "0vh");
  154. }
  155. }, [LandscapeGames, gameID, orientation])
  156. return {
  157. iFrameRef,
  158. isGameLoad,
  159. forceLandscape,
  160. safeNavigate,
  161. setIsGameLoad,
  162. handleEnterGame,
  163. };
  164. }
  165. export default useGameIFrame;