App.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. // GA
  2. import ReactGA from 'react-ga4';
  3. // utils
  4. import React, {lazy, Suspense, useState} from 'react';
  5. // styles
  6. import ThemeStyles from '@styles/theme';
  7. import './style.scss';
  8. // libs styles
  9. import 'react-toastify/dist/ReactToastify.min.css';
  10. import 'react-grid-layout/css/styles.css';
  11. import 'swiper/css';
  12. import 'swiper/css/effect-fade';
  13. import 'swiper/css/pagination';
  14. // fonts
  15. import '@fonts/icomoon/icomoon.woff';
  16. // import '@fonts/swisscbt/SWISSC-BT.ttf'
  17. // contexts
  18. import {SidebarProvider, useSidebar} from '@contexts/sidebarContext';
  19. import {ThemeProvider} from 'styled-components';
  20. // hooks
  21. import {useThemeProvider} from '@contexts/themeContext';
  22. import {useEffect, useRef} from 'react';
  23. import {useWindowSize} from 'react-use';
  24. import useAuthRoute from '@hooks/useAuthRoute';
  25. // utils
  26. import {StyleSheetManager} from 'styled-components';
  27. import {ThemeProvider as MuiThemeProvider, createTheme} from '@mui/material/styles';
  28. import {getBrazilTimeStamp, getUrlParam, localStorageGet, localStorageSet, preventDefault} from '@utils/helpers';
  29. import rtlPlugin from 'stylis-plugin-rtl';
  30. import {CacheProvider} from '@emotion/react';
  31. import createCache from '@emotion/cache';
  32. // components
  33. import {BrowserRouter, HashRouter, Route, Routes, useLocation, useNavigate} from 'react-router-dom';
  34. import {ToastContainer} from 'react-toastify';
  35. import Layout from "@layout/Layout";
  36. import {
  37. getBFP,
  38. getFetchStatus,
  39. getHallServerUrl, getKickState, getOpenPay, getPromoteInstall, getPopWheel,
  40. getUserID,
  41. getUserInfo,
  42. isLogined,
  43. updateCurrGame, updateOpenPay, getIsGuest, getPopBindPhone
  44. } from '@features/mainSlice';
  45. import {useDispatch, useSelector} from "react-redux";
  46. import {REQ_STATUS} from "@api/config";
  47. import {
  48. reqAgentCheck, reqCheckinCheck,
  49. reqCustomService, reqFavoGet, reqFirstPayConfig, reqGameActivity, reqGameInfo,
  50. reqGetRoutes,
  51. reqMailCheck, reqProtectCheck,
  52. reqRedpackCheck, reqRedpackConfig,
  53. reqTurnplateIndex,
  54. reqWithdrawBaseInfo
  55. } from "@features/api";
  56. import LoadingScreen from "@components/LoadingScreen";
  57. import DropCoins from "@components/DropCoins";
  58. import {reqPayConfig} from "@features/paySlice";
  59. import {connectHall, disconnectHall, hallSendState} from "@features/actions/hallClient";
  60. import {toast} from "react-toastify";
  61. import {useBlocker} from "react-router";
  62. import FontFaceObserver from 'fontfaceobserver';
  63. import {getTurnplate} from "@features/turnplateSlice";
  64. import {LOCAL_ACTIVITY_C, LOCAL_VISTOR_ID, LOCAL_WHEEL_INVITE_CODE} from "@constants/localkey";
  65. import LoadingFull from "@components/Loading/LoadingFull";
  66. import {ClickAwayListener} from "@mui/base/ClickAwayListener";
  67. import useGlobalClick from "@hooks/useGlobalClick";
  68. import SoundHelp from "@utils/SoundManger";
  69. import {ROUTE_PATH} from "@constants/routes";
  70. import {onChangeUser, onChangeUserID} from "@features/actions/mainAction";
  71. import {isInAppBrowser, isShowInstallBox, openUrlUseChrome} from "@utils/UAUtils";
  72. import WInstallBox from "@widgets/WInstallBox";
  73. import WMaintainBox from "@widgets/WMaintainBox";
  74. import WAreaSelect from "@widgets/WAreaSelect";
  75. const objInfo={
  76. gameID:0
  77. }
  78. const App = () => {
  79. const dispatch = useDispatch();
  80. const fetchStatus=useSelector(getFetchStatus);
  81. const userInfo=useSelector(getUserInfo);
  82. const userID=useSelector(getUserID);
  83. const turnplate=useSelector(getTurnplate);
  84. const appRef = useRef(null);
  85. const {theme, direction,setIsShowWheel,preLocation,gameID} = useThemeProvider();
  86. const {pathname, search, hash} = useLocation();
  87. const gaKey = process.env.REACT_APP_PUBLIC_GA;
  88. gaKey && ReactGA.initialize(gaKey);
  89. const navigate = useNavigate();
  90. // auto RTL support for Material-UI components and styled-components
  91. const plugins = direction === 'rtl' ? [rtlPlugin] : [];
  92. const hallServerUrl=useSelector(getHallServerUrl);
  93. useGlobalClick();
  94. // const {preLocation,gameID}=usePreviousRoute();
  95. const serverKick=useSelector(getKickState);
  96. const promoteInstall=useSelector(getPromoteInstall);
  97. const popWheel=useSelector(getPopWheel);
  98. const openPay=useSelector(getOpenPay);
  99. const guest=useSelector(getIsGuest);
  100. const popBindPhone=useSelector(getPopBindPhone);
  101. const [isMaintain, setIsMaintain] = useState(false);
  102. //是否唤起选择area
  103. const [isSelectArea, setIsSelectArea] = useState(false);
  104. const muiTheme = createTheme({
  105. direction: direction,
  106. });
  107. const cacheRtl = createCache({
  108. key: 'css-rtl',
  109. stylisPlugins: plugins,
  110. });
  111. const startReqRoutes=()=>{
  112. //先请求指纹id
  113. dispatch(getBFP()).then((result)=>{
  114. dispatch(reqGetRoutes());
  115. });
  116. }
  117. const loadFont=()=>{
  118. // let swisscbt=new FontFaceObserver("SWISSC-BT");
  119. // swisscbt.load().then(() => {
  120. //
  121. // })
  122. new FontFaceObserver("SWISSC-BT").load();
  123. new FontFaceObserver("Roboto").load();
  124. new FontFaceObserver("Roboto-1").load();
  125. }
  126. //检查邀请码
  127. const checkInviteCode=()=>{
  128. let name="act";
  129. let code=getUrlParam(name);
  130. if (code!=null){
  131. localStorageSet(LOCAL_WHEEL_INVITE_CODE,code)
  132. }
  133. else {
  134. localStorageSet(LOCAL_WHEEL_INVITE_CODE,"")
  135. }
  136. let cname="c";
  137. let ccode=getUrlParam(cname);
  138. if (ccode!=null){
  139. localStorageSet(LOCAL_ACTIVITY_C,ccode);
  140. }
  141. // else{
  142. // localStorageSet(LOCAL_ACTIVITY_C,"");
  143. // }
  144. let bfp=getUrlParam("bfp");
  145. if (bfp!=null&&bfp!==""){
  146. localStorageSet(LOCAL_VISTOR_ID,bfp);
  147. global.BFP=bfp;
  148. }
  149. }
  150. const reProgressierInstallBanner=()=>{
  151. if (window.NewProgressierInstallBanner!=null)return;
  152. let ProgressierInstallBanner=window.ProgressierInstallBanner;
  153. window.NewProgressierInstallBanner=ProgressierInstallBanner;
  154. window.ProgressierInstallBanner=function (e, t) {
  155. this.remove = async function() {
  156. };
  157. this.render = async function() {
  158. };
  159. this.make = function() {
  160. };
  161. this.init = async function() {
  162. }
  163. }
  164. }
  165. const reqInitData=()=>{
  166. //未初始化
  167. if (userID===-1)return;
  168. //onChangeUser
  169. dispatch(onChangeUser(userInfo));
  170. if (userID>0){
  171. dispatch(connectHall(hallServerUrl));
  172. localStorageSet(LOCAL_WHEEL_INVITE_CODE,"");
  173. // localStorageSet(LOCAL_ACTIVITY_C,"");
  174. //Mail红点屏蔽
  175. dispatch(reqMailCheck());
  176. dispatch(reqFavoGet());
  177. checkOpenBindPrompt();
  178. }
  179. else
  180. {
  181. dispatch(disconnectHall());
  182. }
  183. //pay
  184. // reqPayConfig(dispatch,userInfo);
  185. // dispatch(reqFirstPayConfig(userID))
  186. //customer
  187. // dispatch(reqCustomService());
  188. //turnplate
  189. dispatch(reqTurnplateIndex());
  190. //redpack
  191. // dispatch(reqRedpackCheck());
  192. // dispatch(reqRedpackConfig());
  193. //agent
  194. // dispatch(reqAgentCheck());
  195. //activity
  196. // dispatch(reqGameActivity());
  197. }
  198. const appInitData=()=>{
  199. // scroll to top on route change
  200. //检查是否维护
  201. if (checkMaintain())return;
  202. if (checkAreaSelect())return;
  203. checkInviteCode();
  204. checkOpenInChrome();
  205. loadFont();
  206. //请求routes
  207. startReqRoutes();
  208. appRef.current && appRef.current.scrollTo(0, 0);
  209. preventDefault();
  210. reProgressierInstallBanner();
  211. SoundHelp.loadAllAudioFile();
  212. // preventTouchMove();
  213. }
  214. const checkOpenCheckin=()=>{
  215. if (userID>0){
  216. if (pathname==="/"){
  217. if(hash==null||hash===""){
  218. let key="checkin_open_time";
  219. let now=Date.now();
  220. let lst=Number(localStorageGet(key,0));
  221. let delta=now-lst;
  222. if (delta<86400000){
  223. return false;
  224. }
  225. dispatch(reqCheckinCheck((isCanCheckIn)=>{
  226. if(hash==null||hash===""){
  227. if(isCanCheckIn===1){
  228. navigate(ROUTE_PATH.CHECK_IN,{replace:true});
  229. localStorageSet(key,Date.now());
  230. }
  231. }
  232. }));
  233. return true;
  234. }
  235. }
  236. }
  237. return false;
  238. }
  239. const onCloseHallWheel=()=>{
  240. checkOpenCheckin();
  241. }
  242. const checkOpenInstallBox=()=>{
  243. if (promoteInstall>0){
  244. if (global.installed===1)return;
  245. global.installed=1;
  246. let time=promoteInstall*1000;
  247. // time=1000;
  248. setTimeout(async ()=>{
  249. if (!isShowInstallBox())return;
  250. let gameID=Number(objInfo.gameID);
  251. if (gameID>0)return;
  252. global.showInstallBox();
  253. },time);
  254. }
  255. }
  256. const checkOpenInChrome=()=>{
  257. let time=200;
  258. setTimeout(async ()=>{
  259. if (!isShowInstallBox())return;
  260. if (isInAppBrowser()){
  261. openUrlUseChrome();
  262. }
  263. },time);
  264. }
  265. //检查打开绑定提示
  266. const checkOpenBindPrompt=()=>{
  267. if (guest!==1)return;
  268. if (popBindPhone!==1)return;
  269. if (global.ispopBindPhone===1)return;
  270. if (pathname.startsWith(ROUTE_PATH.GAME))return;
  271. global.showBindPrompt();
  272. global.ispopBindPhone=1;
  273. }
  274. //检查维护
  275. const checkMaintain=()=>{
  276. // let sdate=new Date(2024, 7, 27, 3, 0, 0);
  277. // let edate=new Date(2024, 7, 27, 7, 0, 0);
  278. // let stime=sdate.getTime();
  279. // let etime=edate.getTime();
  280. //巴西时间
  281. let stime=getBrazilTimeStamp("2024-08-29 01:00:00");
  282. // let stime=getBrazilTimeStamp("2024-08-26 16:34:00");
  283. let etime=getBrazilTimeStamp("2024-08-29 01:10:00");
  284. let now=Date.now();
  285. let isopen=false;
  286. if (now>=stime&&now<=etime){
  287. isopen=true;
  288. setIsMaintain(isopen);
  289. }
  290. return isopen;
  291. }
  292. //检查选择地区
  293. const checkAreaSelect=()=>{
  294. let isopen=false;
  295. let areaID=global.getLocalAreaID();
  296. if (areaID<=0){
  297. isopen=true;
  298. setIsSelectArea(isopen);
  299. global.showAreaSelect(false);
  300. }
  301. return isopen;
  302. }
  303. //app Effect
  304. //初始化
  305. useEffect(() => {
  306. appInitData();
  307. return ()=>{
  308. }
  309. }, []);
  310. //用户信息改变
  311. useEffect(()=>{
  312. reqInitData();
  313. },[userID])
  314. //转盘
  315. useEffect(()=>{
  316. if(turnplate){
  317. let times=turnplate.times;
  318. if (times>0){
  319. if (pathname==="/"){
  320. if(hash==null||hash===""){
  321. if(popWheel){
  322. setIsShowWheel(true);
  323. return;
  324. }
  325. }
  326. }
  327. }
  328. }
  329. checkOpenCheckin();
  330. },[turnplate]);
  331. //监听上一次的路由
  332. useEffect(()=>{
  333. if (preLocation){
  334. let pathname=preLocation.pathname;
  335. if (pathname){
  336. if (pathname.startsWith(ROUTE_PATH.GAME)){
  337. //更新金币
  338. if (userID>0){
  339. dispatch(reqGameInfo());
  340. }
  341. }
  342. }
  343. }
  344. //检查是否维护
  345. checkMaintain();
  346. },[preLocation])
  347. //监听gameID
  348. useEffect(()=>{
  349. dispatch(updateCurrGame(gameID))
  350. dispatch(hallSendState());
  351. objInfo.gameID=gameID;
  352. },[gameID])
  353. //监听被服务器踢掉
  354. useEffect(()=>{
  355. if (serverKick===1){
  356. if (pathname.startsWith(ROUTE_PATH.GAME)){
  357. navigate(ROUTE_PATH.HOME,{replace:true});
  358. }
  359. }
  360. },[serverKick])
  361. //监听安装提示
  362. useEffect(()=>{
  363. checkOpenInstallBox();
  364. },[promoteInstall])
  365. //监听打开pay
  366. useEffect(()=>{
  367. if (openPay===1){
  368. navigate(ROUTE_PATH.PAY,{replace:true});
  369. dispatch(updateOpenPay(0));
  370. }
  371. },[openPay])
  372. //app Effect
  373. const renderLayout=()=>{
  374. if (isMaintain)return (
  375. <WMaintainBox open={true}></WMaintainBox>
  376. );
  377. if (isSelectArea)return (<></>);
  378. return (
  379. <>
  380. {
  381. fetchStatus===REQ_STATUS.IDLE?<Layout onCloseHallWheel={onCloseHallWheel} />:(<LoadingFull />)
  382. }
  383. </>
  384. )
  385. }
  386. const renderPreload=()=>{
  387. //维护
  388. if (isMaintain)return (<></>);
  389. if (isSelectArea)return (<></>);
  390. return (
  391. <>
  392. {
  393. <WInstallBox/>
  394. }
  395. </>
  396. )
  397. }
  398. const renderAreaSelect=()=>{
  399. return (
  400. <WAreaSelect/>
  401. )
  402. }
  403. return (
  404. <CacheProvider value={cacheRtl}>
  405. <MuiThemeProvider theme={muiTheme}>
  406. <ThemeProvider theme={{theme: theme}}>
  407. <SidebarProvider>
  408. <ThemeStyles/>
  409. <ToastContainer theme={theme} autoClose={2500}
  410. position={direction === 'ltr' ? 'top-right' : 'top-left'}/>
  411. <StyleSheetManager stylisPlugins={plugins}>
  412. {
  413. renderLayout()
  414. }
  415. </StyleSheetManager>
  416. {
  417. renderPreload()
  418. }
  419. {renderAreaSelect()}
  420. </SidebarProvider>
  421. </ThemeProvider>
  422. </MuiThemeProvider>
  423. </CacheProvider>
  424. );
  425. }
  426. export default App