App.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. // GA
  2. import ReactGA from 'react-ga4';
  3. // utils
  4. import {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. const objInfo={
  75. gameID:0
  76. }
  77. const App = () => {
  78. const dispatch = useDispatch();
  79. const fetchStatus=useSelector(getFetchStatus);
  80. const userInfo=useSelector(getUserInfo);
  81. const userID=useSelector(getUserID);
  82. const turnplate=useSelector(getTurnplate);
  83. const appRef = useRef(null);
  84. const {theme, direction,setIsShowWheel,preLocation,gameID} = useThemeProvider();
  85. const {pathname, search, hash} = useLocation();
  86. const gaKey = process.env.REACT_APP_PUBLIC_GA;
  87. gaKey && ReactGA.initialize(gaKey);
  88. const navigate = useNavigate();
  89. // auto RTL support for Material-UI components and styled-components
  90. const plugins = direction === 'rtl' ? [rtlPlugin] : [];
  91. const hallServerUrl=useSelector(getHallServerUrl);
  92. useGlobalClick();
  93. // const {preLocation,gameID}=usePreviousRoute();
  94. const serverKick=useSelector(getKickState);
  95. const promoteInstall=useSelector(getPromoteInstall);
  96. const popWheel=useSelector(getPopWheel);
  97. const openPay=useSelector(getOpenPay);
  98. const guest=useSelector(getIsGuest);
  99. const popBindPhone=useSelector(getPopBindPhone);
  100. const [isMaintain, setIsMaintain] = useState(false);
  101. const muiTheme = createTheme({
  102. direction: direction,
  103. });
  104. const cacheRtl = createCache({
  105. key: 'css-rtl',
  106. stylisPlugins: plugins,
  107. });
  108. const startReqRoutes=()=>{
  109. //先请求指纹id
  110. dispatch(getBFP()).then((result)=>{
  111. dispatch(reqGetRoutes());
  112. });
  113. }
  114. const loadFont=()=>{
  115. // let swisscbt=new FontFaceObserver("SWISSC-BT");
  116. // swisscbt.load().then(() => {
  117. //
  118. // })
  119. new FontFaceObserver("SWISSC-BT").load();
  120. new FontFaceObserver("Roboto").load();
  121. new FontFaceObserver("Roboto-1").load();
  122. }
  123. //检查邀请码
  124. const checkInviteCode=()=>{
  125. let name="act";
  126. let code=getUrlParam(name);
  127. if (code!=null){
  128. localStorageSet(LOCAL_WHEEL_INVITE_CODE,code)
  129. }
  130. else {
  131. localStorageSet(LOCAL_WHEEL_INVITE_CODE,"")
  132. }
  133. let cname="c";
  134. let ccode=getUrlParam(cname);
  135. if (ccode!=null){
  136. localStorageSet(LOCAL_ACTIVITY_C,ccode);
  137. }
  138. // else{
  139. // localStorageSet(LOCAL_ACTIVITY_C,"");
  140. // }
  141. let bfp=getUrlParam("bfp");
  142. if (bfp!=null&&bfp!==""){
  143. localStorageSet(LOCAL_VISTOR_ID,bfp);
  144. global.BFP=bfp;
  145. }
  146. }
  147. const reProgressierInstallBanner=()=>{
  148. if (window.NewProgressierInstallBanner!=null)return;
  149. let ProgressierInstallBanner=window.ProgressierInstallBanner;
  150. window.NewProgressierInstallBanner=ProgressierInstallBanner;
  151. window.ProgressierInstallBanner=function (e, t) {
  152. this.remove = async function() {
  153. };
  154. this.render = async function() {
  155. };
  156. this.make = function() {
  157. };
  158. this.init = async function() {
  159. }
  160. }
  161. }
  162. const reqInitData=()=>{
  163. //未初始化
  164. if (userID===-1)return;
  165. //onChangeUser
  166. dispatch(onChangeUser(userInfo));
  167. if (userID>0){
  168. dispatch(connectHall(hallServerUrl));
  169. localStorageSet(LOCAL_WHEEL_INVITE_CODE,"");
  170. // localStorageSet(LOCAL_ACTIVITY_C,"");
  171. //Mail红点屏蔽
  172. dispatch(reqMailCheck());
  173. dispatch(reqFavoGet());
  174. checkOpenBindPrompt();
  175. }
  176. else
  177. {
  178. dispatch(disconnectHall());
  179. }
  180. //pay
  181. // reqPayConfig(dispatch,userInfo);
  182. // dispatch(reqFirstPayConfig(userID))
  183. //customer
  184. // dispatch(reqCustomService());
  185. //turnplate
  186. dispatch(reqTurnplateIndex());
  187. //redpack
  188. // dispatch(reqRedpackCheck());
  189. // dispatch(reqRedpackConfig());
  190. //agent
  191. // dispatch(reqAgentCheck());
  192. //activity
  193. // dispatch(reqGameActivity());
  194. }
  195. const appInitData=()=>{
  196. // scroll to top on route change
  197. //检查是否维护
  198. if (checkMaintain())return;
  199. checkInviteCode();
  200. checkOpenInChrome();
  201. loadFont();
  202. //请求routes
  203. startReqRoutes();
  204. appRef.current && appRef.current.scrollTo(0, 0);
  205. preventDefault();
  206. reProgressierInstallBanner();
  207. SoundHelp.loadAllAudioFile();
  208. // preventTouchMove();
  209. }
  210. const checkOpenCheckin=()=>{
  211. if (userID>0){
  212. if (pathname==="/"){
  213. if(hash==null||hash===""){
  214. let key="checkin_open_time";
  215. let now=Date.now();
  216. let lst=Number(localStorageGet(key,0));
  217. let delta=now-lst;
  218. if (delta<86400000){
  219. return false;
  220. }
  221. dispatch(reqCheckinCheck((isCanCheckIn)=>{
  222. if(hash==null||hash===""){
  223. if(isCanCheckIn===1){
  224. navigate(ROUTE_PATH.CHECK_IN,{replace:true});
  225. localStorageSet(key,Date.now());
  226. }
  227. }
  228. }));
  229. return true;
  230. }
  231. }
  232. }
  233. return false;
  234. }
  235. const onCloseHallWheel=()=>{
  236. checkOpenCheckin();
  237. }
  238. const checkOpenInstallBox=()=>{
  239. if (promoteInstall>0){
  240. if (global.installed===1)return;
  241. global.installed=1;
  242. let time=promoteInstall*1000;
  243. // time=1000;
  244. setTimeout(async ()=>{
  245. if (!isShowInstallBox())return;
  246. let gameID=Number(objInfo.gameID);
  247. if (gameID>0)return;
  248. global.showInstallBox();
  249. },time);
  250. }
  251. }
  252. const checkOpenInChrome=()=>{
  253. let time=200;
  254. setTimeout(async ()=>{
  255. if (!isShowInstallBox())return;
  256. if (isInAppBrowser()){
  257. openUrlUseChrome();
  258. }
  259. },time);
  260. }
  261. //检查打开绑定提示
  262. const checkOpenBindPrompt=()=>{
  263. if (guest!==1)return;
  264. if (popBindPhone!==1)return;
  265. if (global.ispopBindPhone===1)return;
  266. global.showBindPrompt();
  267. global.ispopBindPhone=1;
  268. }
  269. //检查维护
  270. const checkMaintain=()=>{
  271. // let sdate=new Date(2024, 7, 27, 3, 0, 0);
  272. // let edate=new Date(2024, 7, 27, 7, 0, 0);
  273. // let stime=sdate.getTime();
  274. // let etime=edate.getTime();
  275. //巴西时间
  276. let stime=getBrazilTimeStamp("2024-08-27 03:00:00");
  277. // let stime=getBrazilTimeStamp("2024-08-26 16:34:00");
  278. let etime=getBrazilTimeStamp("2024-08-27 07:00:00");
  279. let now=Date.now();
  280. let isopen=false;
  281. if (now>=stime&&now<=etime){
  282. isopen=true;
  283. setIsMaintain(isopen);
  284. }
  285. return isopen;
  286. }
  287. //app Effect
  288. //初始化
  289. useEffect(() => {
  290. appInitData();
  291. return ()=>{
  292. }
  293. }, []);
  294. //用户信息改变
  295. useEffect(()=>{
  296. reqInitData();
  297. },[userID])
  298. //转盘
  299. useEffect(()=>{
  300. if(turnplate){
  301. let times=turnplate.times;
  302. if (times>0){
  303. if (pathname==="/"){
  304. if(hash==null||hash===""){
  305. if(popWheel)setIsShowWheel(true);
  306. return;
  307. }
  308. }
  309. }
  310. }
  311. checkOpenCheckin();
  312. },[turnplate]);
  313. //监听上一次的路由
  314. useEffect(()=>{
  315. if (preLocation){
  316. let pathname=preLocation.pathname;
  317. if (pathname){
  318. if (pathname.startsWith(ROUTE_PATH.GAME)){
  319. //更新金币
  320. if (userID>0){
  321. dispatch(reqGameInfo());
  322. }
  323. }
  324. }
  325. }
  326. //检查是否维护
  327. checkMaintain();
  328. },[preLocation])
  329. //监听gameID
  330. useEffect(()=>{
  331. dispatch(updateCurrGame(gameID))
  332. dispatch(hallSendState());
  333. objInfo.gameID=gameID;
  334. },[gameID])
  335. //监听被服务器踢掉
  336. useEffect(()=>{
  337. if (serverKick===1){
  338. if (pathname.startsWith(ROUTE_PATH.GAME)){
  339. navigate(ROUTE_PATH.HOME,{replace:true});
  340. }
  341. }
  342. },[serverKick])
  343. //监听安装提示
  344. useEffect(()=>{
  345. checkOpenInstallBox();
  346. },[promoteInstall])
  347. //监听打开pay
  348. useEffect(()=>{
  349. if (openPay===1){
  350. navigate(ROUTE_PATH.PAY,{replace:true});
  351. dispatch(updateOpenPay(0));
  352. }
  353. },[openPay])
  354. //app Effect
  355. const renderLayout=()=>{
  356. if (isMaintain)return (
  357. <WMaintainBox open={true}></WMaintainBox>
  358. );
  359. return (
  360. <>
  361. {
  362. fetchStatus===REQ_STATUS.IDLE?<Layout onCloseHallWheel={onCloseHallWheel} />:(<LoadingFull />)
  363. }
  364. </>
  365. )
  366. }
  367. const renderPreload=()=>{
  368. //维护
  369. if (isMaintain)return (<></>);
  370. return (
  371. <>
  372. {
  373. <WInstallBox/>
  374. }
  375. </>
  376. )
  377. }
  378. return (
  379. <CacheProvider value={cacheRtl}>
  380. <MuiThemeProvider theme={muiTheme}>
  381. <ThemeProvider theme={{theme: theme}}>
  382. <SidebarProvider>
  383. <ThemeStyles/>
  384. <ToastContainer theme={theme} autoClose={2500}
  385. position={direction === 'ltr' ? 'top-right' : 'top-left'}/>
  386. <StyleSheetManager stylisPlugins={plugins}>
  387. {
  388. renderLayout()
  389. }
  390. </StyleSheetManager>
  391. {
  392. renderPreload()
  393. }
  394. </SidebarProvider>
  395. </ThemeProvider>
  396. </MuiThemeProvider>
  397. </CacheProvider>
  398. );
  399. }
  400. export default App