瀏覽代碼

no message

zhejiushizhuce 2 年之前
父節點
當前提交
a760a2091a

+ 2 - 3
src/App.js

@@ -74,7 +74,6 @@ import LoadingFull from "@components/Loading/LoadingFull";
 import {ClickAwayListener} from "@mui/base/ClickAwayListener";
 import useGlobalClick from "@hooks/useGlobalClick";
 import SoundHelp from "@utils/SoundManger";
-import usePreviousRoute from "@hooks/usePreviousRoute";
 import {ROUTE_PATH} from "@constants/routes";
 import {onChangeUser, onChangeUserID} from "@features/actions/mainAction";
 const App = () => {
@@ -84,7 +83,7 @@ const App = () => {
     const userID=useSelector(getUserID);
     const turnplate=useSelector(getTurnplate);
     const appRef = useRef(null);
-    const {theme, direction,setIsShowWheel} = useThemeProvider();
+    const {theme, direction,setIsShowWheel,preLocation,gameID} = useThemeProvider();
     const {pathname, search, hash} = useLocation();
     const gaKey = process.env.REACT_APP_PUBLIC_GA;
     gaKey && ReactGA.initialize(gaKey);
@@ -94,7 +93,7 @@ const App = () => {
     const plugins = direction === 'rtl' ? [rtlPlugin] : [];
     const hallServerUrl=useSelector(getHallServerUrl);
     useGlobalClick();
-    const {preLocation,gameID}=usePreviousRoute();
+    // const {preLocation,gameID}=usePreviousRoute();
     const serverKick=useSelector(getKickState);
     const promoteInstall=useSelector(getPromoteInstall);
     const muiTheme = createTheme({

二進制
src/assets/share/share_11.png


二進制
src/assets/share/share_12.png


二進制
src/assets/share/share_13.png


二進制
src/assets/share/share_14.png


二進制
src/assets/share/share_16.png


二進制
src/assets/share/share_17.png


二進制
src/assets/share/share_3.png


二進制
src/assets/share/share_7.png


二進制
src/assets/share/share_8.png


+ 8 - 1
src/components/GameItem/index.jsx

@@ -5,7 +5,7 @@ import symbol from "@assets/symbol-defs.svg";
 import React from "react";
 import {ROUTE_PATH} from "@constants/routes";
 import {localStorageSet} from "@utils/helpers";
-import {LOCAL_GAME_URL} from "@constants/localkey";
+import {LOCAL_GAME_INFO, LOCAL_GAME_URL} from "@constants/localkey";
 import Imgix from "@components/Imgix";
 import LazyImgix from "@components/Imgix/LazyImgix";
 import {ReactComponent as UNLikeIcon} from "@assets/singlesvg/xiai_bai.svg";
@@ -44,10 +44,17 @@ const GameItem=({data,handleRoom,...props})=>{
         }
         return room;
     }
+    const saveGameInfo=(item)=>{
+        let info={
+            data:item
+        }
+        localStorageSet(LOCAL_GAME_INFO+item.id,JSON.stringify(info));
+    }
     const onEnterGame=()=>{
         let id=data.id;
         let url=data.link;
         localStorageSet(LOCAL_GAME_URL+id,url);
+        saveGameInfo(data);
         let path=ROUTE_PATH.GAME+"/"+id;
         global.authLockPath=path;
         navigate(path);

+ 8 - 1
src/components/GameRoom/index.jsx

@@ -8,7 +8,7 @@ import React, {cloneElement, useEffect, useRef, useState} from "react";
 import TransitionGroup from "react-transition-group/TransitionGroup";
 import {useNavigate} from "react-router-dom";
 import {formatCash, localStorageSet} from "@utils/helpers";
-import {LOCAL_GAME_URL} from "@constants/localkey";
+import {LOCAL_GAME_INFO, LOCAL_GAME_URL} from "@constants/localkey";
 import {ROUTE_PATH} from "@constants/routes";
 import styled from 'styled-components/macro';
 import Button from "@mui/material/Button";
@@ -59,6 +59,12 @@ const GameRoom = ({open,data,height="5rem",mobile=false,user,onClose,...props})
         }
         global.msgBoxShow(data)
     }
+    const saveGameInfo=(item)=>{
+        let info={
+            data:item
+        }
+        localStorageSet(LOCAL_GAME_INFO+item.id,JSON.stringify(info));
+    }
     const handleGame=(item)=>{
         if (checkLack(item)){
             lackCash();
@@ -69,6 +75,7 @@ const GameRoom = ({open,data,height="5rem",mobile=false,user,onClose,...props})
         if (url.indexOf("?"))url+=("&level="+item.type);
         else url+=("?level="+item.type);
         localStorageSet(LOCAL_GAME_URL+id,url);
+        saveGameInfo(data);
         let path=ROUTE_PATH.GAME+"/"+id;
         global.authLockPath=path;
         navigate(path);

+ 2 - 1
src/constants/localkey.js

@@ -5,6 +5,7 @@ const LOCAL_USER_INFO="USER_INFO";
 const LOCAL_IS_LOGIN="IS_LOGIN";
 const LOCAL_SIGN="G_SIGN";
 const LOCAL_GAME_URL="LOCAL_GAME_URL_";
+const LOCAL_GAME_INFO="LOCAL_GAME_INFO_";
 const LOCAL_CUSTOM_LOCK="LOCAL_CUSTOM_LOCK";
 const LOCAL_WHEEL_RETAIN="LOCAL_WHEEL_RETAIN";
 const LOCAL_WHEEL_INVITE_CODE="LOCAL_WHEEL_INVITE_CODE";
@@ -13,4 +14,4 @@ const LOCAL_WD_PASS="LOCAL_WD_PASS";
 const LOCAL_WD_PASS_SET_TIME="LOCAL_WD_PASS_SET_TIME";
 const LOCAL_FAVO_IDS="LOCAL_FAVO_IDS";
 const LOCAL_FAVO_DATA="LOCAL_FAVO_DATA";
-export {LOCAL_VISTOR_ID,LOCAL_USER_INFO,LOCAL_IS_LOGIN,LOCAL_SIGN,LOCAL_GAME_URL,LOCAL_CUSTOM_LOCK,LOCAL_WHEEL_RETAIN,LOCAL_WHEEL_INVITE_CODE,LOCAL_WD_PASS,LOCAL_WD_PASS_SET_TIME,LOCAL_ACTIVITY_C,LOCAL_FAVO_IDS,LOCAL_FAVO_DATA};
+export {LOCAL_VISTOR_ID,LOCAL_USER_INFO,LOCAL_IS_LOGIN,LOCAL_SIGN,LOCAL_GAME_URL,LOCAL_CUSTOM_LOCK,LOCAL_WHEEL_RETAIN,LOCAL_WHEEL_INVITE_CODE,LOCAL_WD_PASS,LOCAL_WD_PASS_SET_TIME,LOCAL_ACTIVITY_C,LOCAL_FAVO_IDS,LOCAL_FAVO_DATA,LOCAL_GAME_INFO};

+ 5 - 0
src/contexts/themeContext.js

@@ -6,6 +6,7 @@ import {ROUTE_PATH} from "@constants/routes";
 import {useSelector} from "react-redux";
 import {getUserInfo, isLogined} from "@features/mainSlice";
 import SoundHelp from "@utils/SoundManger";
+import usePreviousRoute from "@hooks/usePreviousRoute";
 
 const ThemeContext = createContext(undefined);
 
@@ -65,6 +66,7 @@ export const ThemeProvider = ({children}) => {
     const [isOpenSub, setIsOpenSub]=useState(false);
     const isLogin=useSelector(isLogined);
     const user=useSelector(getUserInfo);
+    const {preLocation,gameID}=usePreviousRoute();
     const initWindowSize=()=>{
         if (isMobile())global.device="m";
         else global.device="d";
@@ -206,6 +208,9 @@ export const ThemeProvider = ({children}) => {
                 //sound
                 soundOpen,
                 toggleSoundOpen,
+                //preroute hook
+                preLocation,
+                gameID
             }}>
             {children}
         </ThemeContext.Provider>

+ 65 - 0
src/hooks/useGameIFrame.js

@@ -0,0 +1,65 @@
+import {useEffect, useRef, useState} from "react";
+import {ROUTE_PATH} from "@constants/routes";
+import {openFullScreen} from "@utils/helpers";
+import {useNavigate} from "react-router-dom";
+
+const useGameIFrame = () => {
+    const iFrameRef = useRef(null);
+    const [isGameLoad,setIsGameLoad]=useState(false);
+    const navigate = useNavigate();
+    const onBack=()=>{
+        // dispatch(reqGameInfo());
+        navigate(ROUTE_PATH.BACK);
+    }
+    const receiveMessage=(event)=>{
+        let data=event.data;
+        // console.log(data);
+        if (data&&data.cmd!=null){
+            // toast.success(JSON.stringify(data))
+            if (data.cmd==="back"){
+                onBack();
+            }
+            else if (data.cmd==="pay"){
+                navigate(ROUTE_PATH.PAY);
+            }
+            else if (data.cmd==="withdraw"){
+                navigate(ROUTE_PATH.SAQUE);
+            }
+            else if (data.cmd==="fullScreen"){
+                openFullScreen();
+            }
+            else if (data.cmd==="closeLoading"){
+                setIsGameLoad(true);
+            }
+        }
+    }
+    const handleLoadGame=()=>{
+        setIsGameLoad(true);
+    }
+    const initGameEvent=()=>{
+        const gameFrame = iFrameRef.current;
+        if(gameFrame!=null){
+            gameFrame.addEventListener('load', handleLoadGame);
+        }
+        window.addEventListener("message", receiveMessage, false);
+    }
+    const removeGameEvent=()=>{
+        const gameFrame = iFrameRef.current;
+        if(gameFrame!=null){
+            gameFrame.removeEventListener('load', handleLoadGame);
+        }
+        window.removeEventListener("message", receiveMessage);
+    }
+    useEffect(() => {
+        initGameEvent();
+        return () => {
+            removeGameEvent();
+        };
+    }, [iFrameRef]);
+    return {
+        iFrameRef,
+        isGameLoad,
+        setIsGameLoad
+    };
+}
+export default useGameIFrame;

+ 1 - 1
src/hooks/usePreviousRoute.js

@@ -26,7 +26,7 @@ const usePreviousRoute = () => {
             setPreLocation({...currentLocation})
             setCurrentLocation({...location});
             parseGameID();
-        }, [location]);
+        }, [location.pathname]);
     return {
         preLocation,
         gameID

+ 3 - 2
src/layout/BreadCrumb/index.jsx

@@ -7,10 +7,11 @@ import symbol from '@assets/symbol-defs.svg';
 import {useThemeProvider} from "@contexts/themeContext";
 import SvgIcon from "@components/SvgIcon";
 const i18n=global.i18n;
-const BreadCrumb=()=>{
+const BreadCrumb=({customChain=null})=>{
     const {isMobile} = useThemeProvider();
     const {pathname} = useLocation();
-    const chain=useSelector(getRouteChain(pathname));
+    const routeChain=useSelector(getRouteChain(pathname));
+    const chain=customChain==null?routeChain:customChain;
     const currRoute=useSelector(getRoute(pathname));
 
     useEffect(() => {

+ 1 - 0
src/layout/BreadCrumb/styles.module.scss

@@ -20,6 +20,7 @@
     & .nav_active{
       color: var(--header);
       cursor: default;
+      pointer-events: none;
     }
     & .icon{
       width: .75rem;

+ 4 - 1
src/layout/Navbar/styles.module.scss

@@ -34,8 +34,10 @@
   padding-left:85px;
   box-shadow:var(--widget-shadow);
   pointer-events: auto;
+  transition: padding .3s ease;
   &.nav_open{
-    padding-left:270px;
+    //padding-left:270px;
+    padding-left:16.9rem;
   }
   &_mobile{
     //position:fixed;
@@ -82,6 +84,7 @@
   &.nav_open{
     padding-left:16.9rem;
   }
+  transition: padding .3s ease;
 }
 .btn_sign_in{
   //padding: 12px 5px !important;

+ 0 - 1
src/layout/Routes/index.jsx

@@ -7,7 +7,6 @@ import CSSTransition from "react-transition-group/CSSTransition";
 import SubScreen from "@components/SubScreen";
 import RouteContainer from "@layout/Routes/RouteContainer";
 import {Navigate} from "react-router";
-import usePreviousRoute from "@hooks/usePreviousRoute";
 import {ROUTE_PATH, ROUTE_TYPE_POP_OR_FULL} from "@constants/routes";
 import {useThemeProvider} from "@contexts/themeContext";
 import useAuthLockRoute from "@hooks/useAuthLockRoute";

+ 7 - 1
src/locales/languages/en_US.json

@@ -228,7 +228,13 @@
     "back": "Back",
     "msg_title": "Leave the game",
     "msg_content": "Are you sure you want to leave?",
-    "cancel": "Cancel"
+    "cancel": "Cancel",
+    "brand_by": "By",
+    "tips": {
+      "movie_mode": "Movie Mode",
+      "full_screen": "Full Screen"
+    },
+    "share_title": "Share This Game"
   },
   "msgbox": {
     "title": "Prompt",

+ 7 - 1
src/locales/languages/es_MX.json

@@ -225,7 +225,13 @@
     "back": "Atrás",
     "msg_title": "Salir del juego",
     "msg_content": "¿Estás seguro de que deseas salir?",
-    "cancel": "Cancelar"
+    "cancel": "Cancelar",
+    "brand_by": "Por",
+    "tips": {
+      "movie_mode": "Modo película",
+      "full_screen": "Pantalla completa"
+    },
+    "share_title": "Comparte este juego"
   },
   "msgbox": {
     "title": "Mensaje",

+ 7 - 1
src/locales/languages/pt_BR.json

@@ -225,7 +225,13 @@
     "back": "Voltar",
     "msg_title": "Sair do jogo",
     "msg_content": "Você tem certeza que deseja sair?",
-    "cancel": "Cancelar"
+    "cancel": "Cancelar",
+    "brand_by": "Por",
+    "tips": {
+      "movie_mode": "Modo Filme",
+      "full_screen": "Tela cheia"
+    },
+    "share_title": "Compartilhe este jogo"
   },
   "msgbox": {
     "title": "Prompt",

+ 7 - 1
src/locales/languages/ru_RU.json

@@ -225,7 +225,13 @@
     "back": "Назад",
     "msg_title": "Покинуть игру",
     "msg_content": "Вы уверены, что хотите выйти?",
-    "cancel": "Отмена"
+    "cancel": "Отмена",
+    "brand_by": "Источник",
+    "tips": {
+      "movie_mode": "Режим фильма",
+      "full_screen": "Полноэкранный"
+    },
+    "share_title": "Поделиться этой игрой"
   },
   "msgbox": {
     "title": "Подсказка",

+ 7 - 1
src/locales/languages/zh_TW.json

@@ -225,7 +225,13 @@
     "back": "返回",
     "msg_title": "退出遊戲",
     "msg_content": "您確定要退出嗎?",
-    "cancel": "取消"
+    "cancel": "取消",
+    "brand_by": "來源",
+    "tips": {
+      "movie_mode": "電影模式",
+      "full_screen": "全螢幕"
+    },
+    "share_title": "分享這個遊戲"
   },
   "msgbox": {
     "title": "提示",

+ 2 - 0
src/styles/_global.scss

@@ -132,10 +132,12 @@ input, input::placeholder {
 .sidebar-open{
     //margin-left: 250px;
     margin-left: var(--side-open);
+    transition: margin .3s ease;
 }
 .sidebar-close{
     //margin-left: 65px;
     margin-left: var(--side-close);
+    transition: margin .3s ease;
 }
 .sidebar-nav{
     //padding: 20px 10px 80px;

+ 255 - 2
src/widgets/WGame/WDGame/WDGame.jsx

@@ -1,15 +1,268 @@
 //桌面游戏容器
 import Spring from "@components/Spring";
 import styles from "./styles.module.scss";
+import {LOCAL_GAME_INFO, LOCAL_GAME_URL, LOCAL_SIGN} from "@constants/localkey";
+import {localStorageGet, openFullScreen} from "@utils/helpers";
+import React, {useEffect, useState} from "react";
+import {useDispatch, useSelector} from "react-redux";
+import {getGameLike, getRoute, isLogined, updateGameLike} from "@features/mainSlice";
+import BreadCrumb from "@layout/BreadCrumb";
+import {useThemeProvider} from "@contexts/themeContext";
+import {getHallConnState} from "@features/socketSlice";
+import Imgix from "@components/Imgix";
+import SmallLoading from "@components/SmallLoading";
+import SvgIcon from "@components/SvgIcon";
+import useGameIFrame from "@hooks/useGameIFrame";
+import MTooltip from "@components/MTooltip";
+import {updatePageGameLike} from "@features/pageSlice";
+import {reqUpdateFavoInfo} from "@features/api";
+import Popup from "@components/Popup";
+const i18n=global.i18n;
 
 const WDGame=()=>{
+    // const {pathname}=useLocation();
+    const {preLocation,gameID} = useThemeProvider();
+    const gameid=gameID;
+    const [gameURL, setGameURL] = useState("");
+    const [gameInfo, setGameInfo] = useState({});
+    const prePathname=preLocation.pathname==null?"/casino":preLocation.pathname;
+    const preRoute=useSelector(getRoute(prePathname));
+    const isConnected=useSelector(getHallConnState);
+    const {isGameLoad,setIsGameLoad,iFrameRef}=useGameIFrame();
+    const [movieMode,setMovieMode]=useState(false);
+    const isLike=useSelector(getGameLike(gameID));
+    const dispatch = useDispatch();
+    const isLogin=useSelector(isLogined);
+    const [openShare,setOpenShare]=useState(false);
+    const shareData=[
+        {type:'fb',icon:'3'},
+        {type:'twitter',icon:'8'},
+        {type:'tg',icon:'7'},
+        {type:'vk',icon:'11'},
+        {type:'line',icon:'12'},
+        {type:'skype',icon:'13'},
+        {type:'ok',icon:'14'},
+        {type:'in',icon:'16'},
+        {type:'ws',icon:'17'},
+    ]
+    const onShare=(item)=>{
+        let type=item.type;
+        let title="";
+        if (gameInfo!=null)title=gameInfo.title;
+        let text="";
+        let link=window.location.href;
+        let url="";
+        switch(type){
+            case 'fb':
+                url=`https://www.facebook.com/sharer.php?title=${title}&text=${text}&u=${link}`;
+                break
+            case 'twitter':
+                url=`https://twitter.com/share?title=${title}&text=${text}&url=${link}`;
+                break
+            case 'tg':
+                url=`https://t.me/share?title=${title}&text=${text}&url=${link}`;
+                break
+            case 'vk':
+                url=`http://vk.com/share.php?url=${link}&title=${title}&text=${text}`;
+                break
+            case 'line':
+                url=`https://lineit.line.me/share/ui?url=${link}&title=${title}&text=${text}`;
+                break
+            case 'skype':
+                url=`https://web.skype.com/share?url=${link}&title=${title}&text=${text}`;
+                break
+            case 'ok':
+                url=`https://connect.ok.ru/offer?url=url=${link}&title=${title}`;
+                break
+            case 'in':
+                url=`https://www.linkedin.com/sharing/share-offsite/?url=${link}`;
+                break
+            case 'ws':
+                url=`https://api.whatsapp.com/send?url=${link}&title=${title}&text=${text}`;
+                break
+        }
+        window.open(url);
+    }
+    const parseURL=()=>{
+        let key=LOCAL_GAME_URL+gameid;
+        let sign=localStorageGet(LOCAL_SIGN);
+        let url=localStorageGet(key);
+        if (url==null)return;
+        if (url.indexOf("?")===-1)url=url+"?sign="+sign;
+        else url=url+"&sign="+sign;
+        setGameURL(url);
+    }
+    const parseInfo=()=>{
+        if (gameid==="")return;
+        let local=localStorageGet(LOCAL_GAME_INFO+gameid);
+        if (local!=null&&local!==""){
+            let info=JSON.parse(local);
+            if (info!=null){
+                setGameInfo(info.data);
+            }
+        }
+    }
+    const getRouteChain=()=>{
+        let chain=[];
+        if (preRoute!=null)chain.push(preRoute);
+        if (gameInfo!=null){
+            chain.push({
+                title:gameInfo.title,
+                path:""
+            })
+        }
+        return chain;
+    }
+    const onGameFullScreen=()=>{
+        const iframe = iFrameRef.current;
+        if (iframe) {
+            if (iframe.requestFullscreen) {
+                iframe.requestFullscreen();
+            } else if (iframe.mozRequestFullScreen) { /* Firefox */
+                iframe.mozRequestFullScreen();
+            } else if (iframe.webkitRequestFullscreen) { /* Chrome, Safari & Opera */
+                iframe.webkitRequestFullscreen();
+            } else if (iframe.msRequestFullscreen) { /* IE/Edge */
+                iframe.msRequestFullscreen();
+            }
+        }
+    }
+    const onChangeMovieMode=()=>{
+        setMovieMode(!movieMode);
+    }
+    const handleLike=()=>{
+        let info={id:gameID,data:gameInfo,like:(1-isLike)}
+        dispatch(updateGameLike(info));
+        dispatch(updatePageGameLike(info));
+        if(isLogin)dispatch(reqUpdateFavoInfo(info));
+    }
+    useEffect(()=>{
+        parseURL();
+        parseInfo();
+        return ()=>{
+        }
+    },[gameid])
+    useEffect(()=>{
+        if (!isConnected){
+            setIsGameLoad(false);
+        }
+    },[isConnected])
+    const renderTopNavBar=()=>{
+        let chain=getRouteChain();
+        let brand=gameInfo.brand?gameInfo.brand:"";
+        return (
+            <div className={styles.game_top_nav_wrap}>
+                <BreadCrumb customChain={chain}></BreadCrumb>
+                <div className={styles.brand_con}>
+                    {i18n.t("game.brand_by")}
+                    <span className={styles.brand}>{brand}</span>
+                </div>
+            </div>
+        )
+    }
     const renderGame=()=>{
-
+        let title="game";
+        if (gameInfo&&gameInfo.title!=null){
+            title=gameInfo.title;
+        }
+        return (
+            <div className={`${styles.game_area} ${movieMode?styles.movie_mode:''}`}>
+                <div className={`${styles.game_action_wrap} ${styles.game_action_wrap_top}`}></div>
+                <div className={styles.game_main}>
+                    <div className={styles.game_iframe_wrap}>
+                        {
+                            isConnected?(
+                                <iframe
+                                    ref={iFrameRef}
+                                    id={"game"}
+                                    title={title}
+                                    src={gameURL}
+                                    allow="fullscreen"
+                                    sandbox='allow-same-origin allow-scripts allow-popups allow-forms'
+                                >
+                                </iframe>
+                            ):(<></>)
+                        }
+                        {renderLoading()}
+                    </div>
+                </div>
+                <div className={`${styles.game_action_wrap} ${styles.game_action_wrap_bottom}`}>
+                    <div className={styles.action_item_con}>
+                        <button className={`${styles.action_item} ${isLike===1?styles.active_star:''}`} onClick={handleLike}>
+                            <SvgIcon className={styles.icon} herf={"icon_Favorites1"}></SvgIcon>
+                            {38}
+                        </button>
+                        <button className={styles.action_item} onClick={()=>{
+                            setOpenShare(true);
+                        }}>
+                            <SvgIcon className={styles.icon} herf={"icon_Send"}></SvgIcon>
+                        </button>
+                    </div>
+                    <div className={styles.action_item_con}>
+                        <MTooltip title={i18n.t('game.tips.movie_mode')} placement="top">
+                            <button className={`${styles.action_item} ${movieMode ? styles.active : ''}`}
+                                    onClick={onChangeMovieMode}>
+                                <SvgIcon className={styles.icon} herf={"icon_Movie"}></SvgIcon>
+                            </button>
+                        </MTooltip>
+                        <MTooltip title={i18n.t('game.tips.full_screen')} placement="top">
+                            <button className={`${styles.action_item}`} onClick={onGameFullScreen}>
+                                <SvgIcon className={styles.icon} herf={"icon_FullScreen"}></SvgIcon>
+                            </button>
+                        </MTooltip>
+                    </div>
+                </div>
+            </div>
+        )
+    }
+    const renderLoading = () => {
+        if (isGameLoad) return (<></>);
+        let imgsrc = gameInfo.img ? gameInfo.img:"";
+        return (
+            <div className={styles.loading_wrap}>
+                {
+                    imgsrc!==""?(
+                        <Imgix className={styles.loading_bg} src={imgsrc} width={1024} imgixParams={{blur:150}} />
+                    ):(<></>)
+                }
+                <div className={styles.loading}>
+                    <SmallLoading />
+                </div>
+            </div>
+        )
+    }
+    const renderShareBox=()=>{
+        return (
+            <Popup onClose={()=>{
+                setOpenShare(false);
+            }} open={openShare}>
+                <div className={styles.share_box}>
+                    <span className={styles.title}>
+                        {i18n.t("game.share_title")}
+                    </span>
+                    <div className={styles.content}>
+                        {
+                            shareData.map((item,index)=>{
+                                return (
+                                    <button key={index} className={styles.share_btn} onClick={()=>{
+                                        onShare(item);
+                                    }}>
+                                        <img src={require("@assets/share/share_"+item.icon+".png")}/>
+                                    </button>
+                                )
+                            })
+                        }
+                    </div>
+                </div>
+            </Popup>
+        )
     }
     return (
         <Spring type={"slideUp"}>
             <div className={`${styles.container} page-max-width-wrap`}>
-
+                {renderTopNavBar()}
+                {renderGame()}
+                {renderShareBox()}
             </div>
         </Spring>
     )

+ 175 - 1
src/widgets/WGame/WDGame/styles.module.scss

@@ -1,10 +1,184 @@
 .container{
   display: flex;
   flex-direction: column;
-  gap: 1rem;
+  gap: 0.75rem;
   margin-top:1.25rem;
   margin-bottom: 2rem;
 }
+.game_top_nav_wrap{
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  width: 100%;
+  & .brand_con{
+    display: flex;
+    //font-size: 1rem;
+    color: var(--text);
+    gap: 0.25rem;
+    & .brand{
+      color: var(--header);
+    }
+  }
+}
 .game_area{
+  display: flex;
+  flex-direction: column;
+  //width: 100%;
+  transition: all .3s;
+  &.movie_mode{
+    margin-left: -1.875rem;
+    margin-right: -1.875rem;
+  }
+}
+.game_action_wrap{
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 0 .625rem;
+  height: 3.375rem;
+  background-color: var(--body);
+  &_top{
+    border-bottom: 1px solid rgba(105,112,122,.5);
+  }
+  &_bottom{
+    border-top: 1px solid rgba(105,112,122,.5);
+  }
+  & .action_item_con{
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    gap: 0.25rem;
+  }
+  & .action_item{
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    gap: 0.25rem;
+    height: 2.75rem;
+    min-width: 2.75rem;
+    color: var(--text);
+    font-weight: 500;
+    border-radius: var(--border-radius);
+    background-color: transparent;
+    padding: 0 .5rem;
+    & .icon{
+      width: 1.4em;
+      height: 1.4em;
+      fill: var(--text);
+      transition: all .3s ease-in-out;
+    }
+    &:hover{
+      background-color: var(--nav-item-hover) !important;
+      color: var(--header);
+      & .icon{
+        transform: scale(1.15);
+        fill: var(--header);
+      }
+    }
+    &.active{
+      & .icon{
+        fill: var(--primary-color);
+      }
+    }
+    &.active_star{
+      & .icon{
+        fill:#ffdf46;
+      }
+    }
+  }
+}
+.game_main{
+  position: relative;
+  width: 100%;
+  aspect-ratio: 1624/750;
+  background-color: var(--body);
+}
+.game_iframe_wrap{
+  position:relative;
+  width: 100%;
+  height: 100%;
+  background-color: #000000;
+  iframe{
+    position: absolute;
+    left: 0;
+    top: 0;
+    width: 100%;
+    height: 100%;
+    border: none;
+    z-index: 1;
+  }
+  & .loading_wrap{
+    position: absolute;
+    height: 100%;
+    width: 100%;
+    left: 0;
+    top: 0;
+    text-align: center;
+    font-size: 0;
+    padding: 0;
+    margin: 0;
+    overflow: hidden;
+    z-index: 2;
+    & .loading_bg{
+      position: absolute;
+      z-index: 1;
+      width: 100%;
+      height: auto;
+      animation: imgscale 5s linear infinite;
+    }
+    & .loading{
+      position: absolute;
+      z-index: 2;
+      inset: 0;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+    }
+  }
+}
+@keyframes imgscale{
+  0% {
+    transform: scale(1);
+    opacity: .75
+  }
 
+  50% {
+    transform: scale(1.05);
+    opacity: 1
+  }
+
+  to {
+    transform: scale(1);
+    opacity: .75
+  }
+}
+.share_box{
+  width: 100%;
+  height: 100%;
+  & .title{
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 1.125rem;
+    color: var(--header);
+    text-align: center;
+    font-weight: 600;
+  }
+  & .content{
+    padding: 2rem 0rem;
+    display: flex;
+    //flex-direction: column;
+    gap: 1rem;
+    flex-wrap: wrap;
+    align-items: center;
+    justify-content: center;
+    & .share_btn{
+      width: 2.5rem;
+      height: 2.5rem;
+      img{
+        width: 100%;
+        height: 100%;
+      }
+    }
+  }
 }

+ 7 - 43
src/widgets/WGame/index.jsx

@@ -14,7 +14,8 @@ import {ROUTE_PATH} from "@constants/routes";
 import {useDispatch, useSelector} from "react-redux";
 import {reqGameInfo} from "@features/api";
 import {getHallConnState} from "@features/socketSlice";
-import Draggable from 'react-draggable'; // The default
+import Draggable from 'react-draggable';
+import useGameIFrame from "@hooks/useGameIFrame"; // The default
 const i18n=global.i18n;
 
 const WGame=()=>{
@@ -23,38 +24,17 @@ const WGame=()=>{
     const gameid=pathname.split("/").pop();
     const [openBox,setOpenBox]=useState(false);
     const [openPrompt,setOpenPrompt]=useState(false);
-    const [isGameLoad,setIsGameLoad]=useState(false);
+    // const [isGameLoad,setIsGameLoad]=useState(false);
     const isConnected=useSelector(getHallConnState);
     var gameURL="";
     const navigate=useNavigate();
     const backBoxRef = useRef(null);
     const [dragDeltaY,setDragDeltaY]=useState(0);
+    const {isGameLoad,setIsGameLoad,iFrameRef}=useGameIFrame();
     const onBack=()=>{
         // dispatch(reqGameInfo());
         navigate(ROUTE_PATH.BACK);
     }
-    const receiveMessage=(event)=>{
-        let data=event.data;
-        // console.log(data);
-        if (data&&data.cmd!=null){
-            // toast.success(JSON.stringify(data))
-            if (data.cmd==="back"){
-                onBack();
-            }
-            else if (data.cmd==="pay"){
-                navigate(ROUTE_PATH.PAY);
-            }
-            else if (data.cmd==="withdraw"){
-                navigate(ROUTE_PATH.SAQUE);
-            }
-            else if (data.cmd==="fullScreen"){
-                openFullScreen();
-            }
-            else if (data.cmd==="closeLoading"){
-                setIsGameLoad(true);
-            }
-        }
-    }
     const parseURL=()=>{
         let key=LOCAL_GAME_URL+gameid;
         let sign=localStorageGet(LOCAL_SIGN);
@@ -66,27 +46,10 @@ const WGame=()=>{
         gameURL=url;
     }
     parseURL();
-    const handleLoadGame=()=>{
-        setIsGameLoad(true);
-    }
-    const initGameEvent=()=>{
-        const gameFrame = document.getElementById('game');
-        if(gameFrame!=null){
-            gameFrame.addEventListener('load', handleLoadGame);
-        }
-        window.addEventListener("message", receiveMessage, false);
-    }
-    const removeGameEvent=()=>{
-        const gameFrame = document.getElementById('game');
-        if(gameFrame!=null){
-            gameFrame.removeEventListener('load', handleLoadGame);
-        }
-        window.removeEventListener("message", receiveMessage);
-    }
+
     useEffect(() => {
-        initGameEvent();
         return () => {
-            removeGameEvent();
+
         };
     }, []);
     useEffect(()=>{
@@ -140,6 +103,7 @@ const WGame=()=>{
     const renderGame = () => {
         return (
             <iframe
+                ref={iFrameRef}
                 id={"game"}
                 title={"game"}
                 src={gameURL}