// GA import ReactGA from 'react-ga4'; // utils import React, {lazy, Suspense, useState} from 'react'; // styles import ThemeStyles from '@styles/theme'; import './style.scss'; // libs styles import 'react-toastify/dist/ReactToastify.min.css'; import 'react-grid-layout/css/styles.css'; import 'swiper/css'; import 'swiper/css/effect-fade'; import 'swiper/css/pagination'; // fonts import '@fonts/icomoon/icomoon.woff'; // import '@fonts/swisscbt/SWISSC-BT.ttf' // contexts import {SidebarProvider, useSidebar} from '@contexts/sidebarContext'; import {ThemeProvider} from 'styled-components'; // hooks import {useThemeProvider} from '@contexts/themeContext'; import {useEffect, useRef} from 'react'; import {useWindowSize} from 'react-use'; import useAuthRoute from '@hooks/useAuthRoute'; // utils import {StyleSheetManager} from 'styled-components'; import {ThemeProvider as MuiThemeProvider, createTheme} from '@mui/material/styles'; import {getBrazilTimeStamp, getUrlParam, localStorageGet, localStorageSet, preventDefault} from '@utils/helpers'; import rtlPlugin from 'stylis-plugin-rtl'; import {CacheProvider} from '@emotion/react'; import createCache from '@emotion/cache'; // components import {BrowserRouter, HashRouter, Route, Routes, useLocation, useNavigate} from 'react-router-dom'; import {ToastContainer} from 'react-toastify'; import Layout from "@layout/Layout"; import { getBFP, getFetchStatus, getHallServerUrl, getKickState, getOpenPay, getPromoteInstall, getPopWheel, getUserID, getUserInfo, isLogined, updateCurrGame, updateOpenPay, getIsGuest, getPopBindPhone } from '@features/mainSlice'; import {useDispatch, useSelector} from "react-redux"; import {REQ_STATUS} from "@api/config"; import { reqAgentCheck, reqCheckinCheck, reqCustomService, reqFavoGet, reqFirstPayConfig, reqGameActivity, reqGameInfo, reqGetRoutes, reqMailCheck, reqProtectCheck, reqRedpackCheck, reqRedpackConfig, reqTurnplateIndex, reqWithdrawBaseInfo } from "@features/api"; import LoadingScreen from "@components/LoadingScreen"; import DropCoins from "@components/DropCoins"; import {reqPayConfig} from "@features/paySlice"; import {connectHall, disconnectHall, hallSendState} from "@features/actions/hallClient"; import {toast} from "react-toastify"; import {useBlocker} from "react-router"; import FontFaceObserver from 'fontfaceobserver'; import {getTurnplate} from "@features/turnplateSlice"; import {LOCAL_ACTIVITY_C, LOCAL_VISTOR_ID, LOCAL_WHEEL_INVITE_CODE} from "@constants/localkey"; import LoadingFull from "@components/Loading/LoadingFull"; import {ClickAwayListener} from "@mui/base/ClickAwayListener"; import useGlobalClick from "@hooks/useGlobalClick"; import SoundHelp from "@utils/SoundManger"; import {ROUTE_PATH} from "@constants/routes"; import {onChangeUser, onChangeUserID} from "@features/actions/mainAction"; import {isInAppBrowser, isShowInstallBox, openUrlUseChrome} from "@utils/UAUtils"; import WInstallBox from "@widgets/WInstallBox"; import WMaintainBox from "@widgets/WMaintainBox"; import WAreaSelect from "@widgets/WAreaSelect"; const objInfo={ gameID:0 } const App = () => { const dispatch = useDispatch(); const fetchStatus=useSelector(getFetchStatus); const userInfo=useSelector(getUserInfo); const userID=useSelector(getUserID); const turnplate=useSelector(getTurnplate); const appRef = useRef(null); const {theme, direction,setIsShowWheel,preLocation,gameID} = useThemeProvider(); const {pathname, search, hash} = useLocation(); const gaKey = process.env.REACT_APP_PUBLIC_GA; gaKey && ReactGA.initialize(gaKey); const navigate = useNavigate(); // auto RTL support for Material-UI components and styled-components const plugins = direction === 'rtl' ? [rtlPlugin] : []; const hallServerUrl=useSelector(getHallServerUrl); useGlobalClick(); // const {preLocation,gameID}=usePreviousRoute(); const serverKick=useSelector(getKickState); const promoteInstall=useSelector(getPromoteInstall); const popWheel=useSelector(getPopWheel); const openPay=useSelector(getOpenPay); const guest=useSelector(getIsGuest); const popBindPhone=useSelector(getPopBindPhone); const [isMaintain, setIsMaintain] = useState(false); //是否唤起选择area const [isSelectArea, setIsSelectArea] = useState(false); const muiTheme = createTheme({ direction: direction, }); const cacheRtl = createCache({ key: 'css-rtl', stylisPlugins: plugins, }); const startReqRoutes=()=>{ //先请求指纹id dispatch(getBFP()).then((result)=>{ dispatch(reqGetRoutes()); }); } const loadFont=()=>{ // let swisscbt=new FontFaceObserver("SWISSC-BT"); // swisscbt.load().then(() => { // // }) new FontFaceObserver("SWISSC-BT").load(); new FontFaceObserver("Roboto").load(); new FontFaceObserver("Roboto-1").load(); } //检查邀请码 const checkInviteCode=()=>{ let name="act"; let code=getUrlParam(name); if (code!=null){ localStorageSet(LOCAL_WHEEL_INVITE_CODE,code) } else { localStorageSet(LOCAL_WHEEL_INVITE_CODE,"") } let cname="c"; let ccode=getUrlParam(cname); if (ccode!=null){ localStorageSet(LOCAL_ACTIVITY_C,ccode); } // else{ // localStorageSet(LOCAL_ACTIVITY_C,""); // } let bfp=getUrlParam("bfp"); if (bfp!=null&&bfp!==""){ localStorageSet(LOCAL_VISTOR_ID,bfp); global.BFP=bfp; } } const reProgressierInstallBanner=()=>{ if (window.NewProgressierInstallBanner!=null)return; let ProgressierInstallBanner=window.ProgressierInstallBanner; window.NewProgressierInstallBanner=ProgressierInstallBanner; window.ProgressierInstallBanner=function (e, t) { this.remove = async function() { }; this.render = async function() { }; this.make = function() { }; this.init = async function() { } } } const reqInitData=()=>{ //未初始化 if (userID===-1)return; //onChangeUser dispatch(onChangeUser(userInfo)); if (userID>0){ dispatch(connectHall(hallServerUrl)); localStorageSet(LOCAL_WHEEL_INVITE_CODE,""); // localStorageSet(LOCAL_ACTIVITY_C,""); //Mail红点屏蔽 dispatch(reqMailCheck()); dispatch(reqFavoGet()); checkOpenBindPrompt(); } else { dispatch(disconnectHall()); } //pay // reqPayConfig(dispatch,userInfo); // dispatch(reqFirstPayConfig(userID)) //customer // dispatch(reqCustomService()); //turnplate dispatch(reqTurnplateIndex()); //redpack // dispatch(reqRedpackCheck()); // dispatch(reqRedpackConfig()); //agent // dispatch(reqAgentCheck()); //activity // dispatch(reqGameActivity()); } const appInitData=()=>{ // scroll to top on route change //检查是否维护 if (checkMaintain())return; if (checkAreaSelect())return; checkInviteCode(); checkOpenInChrome(); loadFont(); //请求routes startReqRoutes(); appRef.current && appRef.current.scrollTo(0, 0); preventDefault(); reProgressierInstallBanner(); SoundHelp.loadAllAudioFile(); // preventTouchMove(); } const checkOpenCheckin=()=>{ if (userID>0){ if (pathname==="/"){ if(hash==null||hash===""){ let key="checkin_open_time"; let now=Date.now(); let lst=Number(localStorageGet(key,0)); let delta=now-lst; if (delta<86400000){ return false; } dispatch(reqCheckinCheck((isCanCheckIn)=>{ if(hash==null||hash===""){ if(isCanCheckIn===1){ navigate(ROUTE_PATH.CHECK_IN,{replace:true}); localStorageSet(key,Date.now()); } } })); return true; } } } return false; } const onCloseHallWheel=()=>{ checkOpenCheckin(); } const checkOpenInstallBox=()=>{ if (promoteInstall>0){ if (global.installed===1)return; global.installed=1; let time=promoteInstall*1000; // time=1000; setTimeout(async ()=>{ if (!isShowInstallBox())return; let gameID=Number(objInfo.gameID); if (gameID>0)return; global.showInstallBox(); },time); } } const checkOpenInChrome=()=>{ let time=200; setTimeout(async ()=>{ if (!isShowInstallBox())return; if (isInAppBrowser()){ openUrlUseChrome(); } },time); } //检查打开绑定提示 const checkOpenBindPrompt=()=>{ if (guest!==1)return; if (popBindPhone!==1)return; if (global.ispopBindPhone===1)return; if (pathname.startsWith(ROUTE_PATH.GAME))return; global.showBindPrompt(); global.ispopBindPhone=1; } //检查维护 const checkMaintain=()=>{ // let sdate=new Date(2024, 7, 27, 3, 0, 0); // let edate=new Date(2024, 7, 27, 7, 0, 0); // let stime=sdate.getTime(); // let etime=edate.getTime(); //巴西时间 let stime=getBrazilTimeStamp("2024-08-29 01:00:00"); // let stime=getBrazilTimeStamp("2024-08-26 16:34:00"); let etime=getBrazilTimeStamp("2024-08-29 01:10:00"); let now=Date.now(); let isopen=false; if (now>=stime&&now<=etime){ isopen=true; setIsMaintain(isopen); } return isopen; } //检查选择地区 const checkAreaSelect=()=>{ let isopen=false; let areaID=global.getLocalAreaID(); if (areaID<=0){ isopen=true; setIsSelectArea(isopen); global.showAreaSelect(false); } return isopen; } //app Effect //初始化 useEffect(() => { appInitData(); return ()=>{ } }, []); //用户信息改变 useEffect(()=>{ reqInitData(); },[userID]) //转盘 useEffect(()=>{ if(turnplate){ let times=turnplate.times; if (times>0){ if (pathname==="/"){ if(hash==null||hash===""){ if(popWheel){ setIsShowWheel(true); return; } } } } } checkOpenCheckin(); },[turnplate]); //监听上一次的路由 useEffect(()=>{ if (preLocation){ let pathname=preLocation.pathname; if (pathname){ if (pathname.startsWith(ROUTE_PATH.GAME)){ //更新金币 if (userID>0){ dispatch(reqGameInfo()); } } } } //检查是否维护 checkMaintain(); },[preLocation]) //监听gameID useEffect(()=>{ dispatch(updateCurrGame(gameID)) dispatch(hallSendState()); objInfo.gameID=gameID; },[gameID]) //监听被服务器踢掉 useEffect(()=>{ if (serverKick===1){ if (pathname.startsWith(ROUTE_PATH.GAME)){ navigate(ROUTE_PATH.HOME,{replace:true}); } } },[serverKick]) //监听安装提示 useEffect(()=>{ checkOpenInstallBox(); },[promoteInstall]) //监听打开pay useEffect(()=>{ if (openPay===1){ navigate(ROUTE_PATH.PAY,{replace:true}); dispatch(updateOpenPay(0)); } },[openPay]) //app Effect const renderLayout=()=>{ if (isMaintain)return ( ); if (isSelectArea)return (<>); return ( <> { fetchStatus===REQ_STATUS.IDLE?:() } ) } const renderPreload=()=>{ //维护 if (isMaintain)return (<>); if (isSelectArea)return (<>); return ( <> { } ) } const renderAreaSelect=()=>{ return ( ) } return ( { renderLayout() } { renderPreload() } {renderAreaSelect()} ); } export default App