zhejiushizhuce 2 жил өмнө
parent
commit
fe4fd2aea0

BIN
src/assets/gameroom/room_1.png


BIN
src/assets/gameroom/room_2.png


BIN
src/assets/gameroom/room_3.png


BIN
src/assets/gameroom/room_act.png


BIN
src/assets/gameroom/room_deact.png


+ 22 - 2
src/components/GameItem/index.jsx

@@ -7,7 +7,7 @@ import {ROUTE_PATH} from "@constants/routes";
 import {localStorageSet} from "@utils/helpers";
 import {LOCAL_GAME_URL} from "@constants/localkey";
 
-const GameItem=({data,index,onClickItem,...props})=>{
+const GameItem=({data,handleRoom,...props})=>{
     const navigate=useNavigate();
     const renderOlicon=()=>{
         return (
@@ -22,6 +22,16 @@ const GameItem=({data,index,onClickItem,...props})=>{
         }
         return snum;
     }
+    const getRoom=()=>{
+        let room=[];
+        let level_info=data.level_info;
+        if (level_info){
+            for (const key in level_info) {
+                room.push({key:key,value:level_info[key]});
+            }
+        }
+        return room;
+    }
     const onEnterGame=()=>{
         let id=data.id;
         let url=data.link;
@@ -30,6 +40,15 @@ const GameItem=({data,index,onClickItem,...props})=>{
         global.authLockPath=path;
         navigate(path);
     }
+    const handleEnterRoom=(e)=>{
+        if (handleRoom==null)onEnterGame();
+        else
+        {
+            let room=getRoom();
+            if (room.length>1)handleRoom(e,data);
+            else onEnterGame();
+        }
+    }
     // return (
     //     <div className={styles.grid_item}>
     //         <button onClick={()=>{
@@ -66,7 +85,8 @@ const GameItem=({data,index,onClickItem,...props})=>{
         <div className={`${styles.grid_item}`} {...props}>
             <button className={styles.game_img_wrap} onClick={(e)=>{
                 // onEnterGame();
-                if (onClickItem)onClickItem(e,index);
+                // if (handleRoom)handleRoom(e,data);
+                handleEnterRoom(e)
             }}>
                 <LazyLoadImage
                     src={data.img}

+ 3 - 1
src/components/GameItem/styles.module.scss

@@ -6,6 +6,7 @@
   width: 100%;
   //border-radius: var(--border-radius);
   transition: all var(--transition);
+  will-change: transform;
   & .game_img_wrap{
     display: flex;
     flex-direction: column;
@@ -14,10 +15,11 @@
     position: relative;
     background-color: var(--widget-grid-bg);
     border-radius: 0.8rem;
+    aspect-ratio:384/516;
     & .game_img{
       position: relative;
       width: 100%;
-      aspect-ratio:384/516;
+      //aspect-ratio:384/516;
       img{
         width: 100%;
         height: 100%;

+ 188 - 40
src/components/GameList/index.jsx

@@ -3,8 +3,11 @@ import React, {useEffect, useState} from "react";
 import GameItem from "@components/GameItem";
 import {REQ_STATUS} from "@api/config";
 import SmallLoading from "@components/SmallLoading";
+import {useThemeProvider} from "@contexts/themeContext";
+import GameRoom from "@components/GameRoom";
+import {total} from "react-big-calendar/lib/utils/dates";
 const i18n =global.i18n;
-const GameList=({data,status,reqMore})=>{
+const GameList=({data,status,reqMore,user})=>{
     // data={
     //     type:0,//游戏分类
     //     page:1,
@@ -70,61 +73,191 @@ const GameList=({data,status,reqMore})=>{
     //         },
     //     ]
     // }
+    const {isMobile} = useThemeProvider();
+    const M_LIST_COL=3;
+    const M_LIST_ROW=1;
     const [selected,setSelected]=useState(-1);
-    const getColNum=()=>{
-        let num=3;
-        let gamelist=document.querySelector('#gameList');
-        if(gamelist){
-            let style=window.getComputedStyle(gamelist);
-            if (style!=null){
-                let columns=style["grid-template-columns"];
-                let arr=columns.split(" ");
-                num=arr.length;
+    const [roomRow,setRoomRow]=useState({});
+    const [showPopRoom,setShowPopRoom]=useState(false);
+    const roomHeight="5.2rem"
+    const handleReset=(e)=>{
+        setSelected(-1);
+        setRoomRow({});
+    }
+    useEffect(()=>{
+        document.addEventListener("click",handleReset);
+        return ()=>{
+            document.removeEventListener("click",handleReset);
+        }
+    },[])
+    const checkSetRoom=(e,item,row,total)=>{
+        let target=e.target;
+        if (target){
+            let rect=target.getBoundingClientRect();
+            let cH = document.documentElement.clientHeight;
+            let cB=rect.bottom;
+            if (cH-cB>80)row=row+1;
+        }else row=row+1;
+        if (row>=total)row=total-1;
+        setRoomRow({
+            row:row,
+            data:item
+        });
+    }
+    const handleSelect=(e,data,row,total)=>{
+        e.stopPropagation();
+        if (data.id===selected){
+            handleReset();
+        }
+        else
+        {
+            setSelected(data.id);
+            checkSetRoom(e,data,row,total);
+        }
+    }
+    const handlePopSelected=(e,data,row,totall)=>{
+        e.stopPropagation();
+        setRoomRow({
+            row:0,
+            data:data
+        });
+        setShowPopRoom(true);
+    }
+    const handlePopClose=()=>{
+        setRoomRow({});
+        setShowPopRoom(false);
+    }
+    const renderGameListDesktop=()=>{
+        let list=data.data;
+        if (list==null)list=[];
+        return (
+            <>
+                <div id={"gameList"} className={styles.game_list}>
+                    {
+                        list.map((item, index) => {
+                            return (
+                                <GameItem key={index} data={item} handleRoom={handlePopSelected}></GameItem>
+                            )
+                        })
+                    }
+                </div>
+                <GameRoom open={showPopRoom} data={roomRow.data} user={user} onClose={handlePopClose}></GameRoom>
+            </>
+        )
+    }
+    const formatMList = (list) => {
+        let mList = [];
+        if (list) {
+            for (let i = 0; i < list.length; i += M_LIST_COL) {
+                let rowArr = list.slice(i, i + M_LIST_COL);
+                mList.push(rowArr);
             }
         }
-        return num;
+        return mList;
     }
-    const handleSelect=(e,i)=>{
-        setSelected(i);
+    const renderRoom=(row,len)=>{
+        if (roomRow==null)return (<></>);
+        let rrow=roomRow.row;
+        let data=roomRow.data;
+        if (rrow===row){
+            // let level_info=data.level_info;
+            let open=true;
+            return (
+                <GameRoom open={open} data={data} height={roomHeight} mobile={true} user={user}></GameRoom>
+            )
+        }
+        else return (<></>);
     }
-    const renderGameList=()=>{
+    const renderGameListMobile=()=>{
         let list=data.data;
         if (list==null)list=[];
+        list=formatMList(list);
+        let len=list.length;
+        // return (
+        //     <div id={"gameList"} className={styles.game_list}>
+        //         {
+        //             list.map((item,index)=>{
+        //                 let itemStyle={}
+        //                 if (selected!==-1){
+        //                     if (index!==selected){
+        //                         itemStyle.filter="brightness(60%)"
+        //                     }
+        //                     else
+        //                     {
+        //                         itemStyle.transform="scale(1.05)";
+        //                     }
+        //                     let col=getColNum();
+        //                     let s_row=Math.floor(selected/col);
+        //                     let row=Math.floor(index/col);
+        //                     if (s_row===row){
+        //                         itemStyle.marginBottom="100px";
+        //                     }
+        //                 }
+        //                 return (
+        //                     <GameItem style={itemStyle} key={index} data={item} index={index} onClickItem={handleSelect}></GameItem>
+        //                 )
+        //             })
+        //         }
+        //     </div>
+        // )
+
         return (
-            <div id={"gameList"} className={styles.game_list}>
+            <div id={"gameList"} className={styles.game_list_mobile}>
                 {
-                    list.map((item,index)=>{
-                        let itemStyle={}
-                        if (selected!==-1){
-                            if (index!==selected){
-                                itemStyle.filter="brightness(60%)"
-                            }
-                            else
-                            {
-                                itemStyle.transform="scale(1.05)";
-                            }
-                            let col=getColNum();
-                            let s_row=Math.floor(selected/col);
-                            let row=Math.floor(index/col);
-                            if (s_row===row){
-                                itemStyle.marginBottom="100px";
+                    list.map((rowArr,row)=>{
+                        let rowStyle={};
+                        if (roomRow!=null){
+                            // if (roomRow.row===row){
+                            if (row>=roomRow.row){
+                                // rowStyle.marginTop=roomHeight;
+                                rowStyle.transform=`translateY(${roomHeight})`;
                             }
+                            // if (roomRow.row===row){
+                            //     rowStyle.marginTop=roomHeight;
+                            // }
                         }
                         return (
-                            <GameItem style={itemStyle} key={index} data={item} index={index} onClickItem={handleSelect}></GameItem>
+                            <>
+                                {renderRoom(row,len)}
+                                <div key={row} className={styles.list_row} style={rowStyle}>
+                                    {
+                                        rowArr.map((item, col) => {
+                                            let itemStyle={}
+                                            if (selected!==-1){
+                                                if (item.id!==selected){
+                                                    itemStyle.filter="brightness(60%)"
+                                                }
+                                                else
+                                                {
+                                                    itemStyle.transform="scale(1.05)";
+                                                }
+                                            }
+                                            return (
+                                                <GameItem key={col} data={item} handleRoom={(e,data)=>{
+                                                    handleSelect(e,data,row,len)
+                                                }} row={row}  style={itemStyle}></GameItem>
+                                            )
+                                        })
+                                    }
+                                </div>
+                            </>
                         )
                     })
                 }
             </div>
         )
     }
-    const renderProgress=()=>{
-        let list=data.data;
-        if (list==null)list=[];
-        let current=list.length;
-        let total=data.total;
-        let progress=Math.ceil((current/total)*100);
-        let spro=progress+"%";
+    const renderGameList = () => {
+        if (isMobile()) return renderGameListMobile();
+        else return renderGameListDesktop();
+    }
+    const renderProgress = () => {
+        let list = data.data;
+        if (list == null) list = [];
+        let current = list.length;
+        let total = data.total;
+        let progress = Math.ceil((current / total) * 100);
+        let spro =progress+"%";
         return (
             <div className={styles.page_progress}>
                 <span>{current} / {total}</span>
@@ -162,11 +295,26 @@ const GameList=({data,status,reqMore})=>{
             </div>
         )
     }
+    const renderShowMore=()=>{
+        let moreStyle={};
+        if (roomRow&&roomRow.row!=null){
+            let row=roomRow.row;
+            if (row>=0){
+                moreStyle.transform=`translateY(${roomHeight})`;
+                moreStyle.marginBottom=roomHeight;
+            }
+        }
+        return (
+            <div className={styles.page_con} style={moreStyle}>
+                {renderProgress()}
+                {renderShowMoreBtn()}
+            </div>
+        )
+    }
     return (
         <div className={`w-100 ${styles.list_container}`}>
             {renderGameList()}
-            {renderProgress()}
-            {renderShowMoreBtn()}
+            {renderShowMore()}
         </div>
     )
 }

+ 20 - 0
src/components/GameList/styles.module.scss

@@ -9,6 +9,26 @@
       grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
     }
   }
+  & .game_list_mobile{
+    display: flex;
+    flex-direction: column;
+    gap: .75rem;
+    transition: all var(--transition);
+    //will-change: transform;
+    & .list_row{
+      display: grid;
+      gap: .75rem;
+      grid-template-columns: repeat(3,1fr);
+      transition: all var(--transition);
+      //will-change: transform;
+    }
+  }
+  & .page_con{
+    display: flex;
+    flex-direction: column;
+    width: 100%;
+    transition: all var(--transition);
+  }
   & .page_progress {
     display: flex;
     align-items: center;

+ 159 - 0
src/components/GameRoom/index.jsx

@@ -0,0 +1,159 @@
+import styles from './styles.module.scss';
+import bg_1 from "@assets/gameroom/room_deact.png";
+import bg_2 from "@assets/gameroom/room_act.png";
+import bg_3 from "@assets/gameroom/room_deact.png";
+import {animated, useSpring} from '@react-spring/web';
+import CSSTransition from "react-transition-group/CSSTransition";
+import React, {cloneElement, useEffect, 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 {ROUTE_PATH} from "@constants/routes";
+import styled from 'styled-components/macro';
+import Button from "@mui/material/Button";
+import Popup from "@components/Popup";
+const gameBgs=[null,bg_1,bg_2,bg_3,bg_2];
+const fontColors=["","#bc9350","#208e3c","#bc9350","#208e3c"];
+const i18n=global.i18n;
+const StyledRoomButton = styled.button`
+    ${(props) => {
+        return `
+           background:url(${props.background});
+           color:${props.color};
+        `
+    }}
+`
+const GameRoom = ({open,data,height="5rem",mobile=false,user,onClose,...props}) => {
+    const timeout=200;
+    const [show,setShow]=useState(open);
+    const navigate=useNavigate();
+    let openAni=useSpring({
+        from: {opacity: 0, transform: 'scaleY(0.5)'},
+        to: {opacity: 1, transform: 'scaleY(1)'},
+        config: {duration: timeout},
+    })
+    let closeAni=useSpring({
+        from: {opacity: 1, transform: 'scaleY(1)'},
+        to: {opacity: 0, transform: 'scaleY(0.5)'},
+        config: {duration: timeout},
+    })
+    useEffect(()=>{
+        return ()=>{
+
+        }
+    },[])
+    const lackCash=()=>{
+        let onSure=()=>{
+            navigate(ROUTE_PATH.PAY);
+        }
+        let data={
+            content:i18n.t("lackMoney.lackMoney_Label"),
+            sureLabel:i18n.t("lackMoney.sure_label"),
+            sureCB:onSure,
+        }
+        global.msgBoxShow(data)
+    }
+    const handleGame=(item)=>{
+        let limit=item.value;
+        let golds=0;
+        if (user){
+            golds=Number(user.Score)*global.CASH_BASE;
+            limit=Number(limit);
+            if (golds<limit){
+                lackCash();
+                return;
+            }
+        }
+        let id=data.id;
+        let url=data.link;
+        if (url.indexOf("?"))url+=("&level="+item.type);
+        else url+=("?level="+item.type);
+        localStorageSet(LOCAL_GAME_URL+id,url);
+        let path=ROUTE_PATH.GAME+"/"+id;
+        global.authLockPath=path;
+        navigate(path);
+    }
+    const renderMobile=()=>{
+        if (data==null)return (<></>);
+        let level_info=data.level_info;
+        if (level_info==null)return (<></>);
+        let list=[];
+        for (const key in level_info) {
+            list.push({type:key,value:level_info[key]});
+        }
+        let cstyle={}
+        if (show)cstyle=openAni;
+        else cstyle=closeAni;
+        return (
+            <animated.div className={styles.cotiner_m} style={cstyle}>
+                <div className={styles.room_con}>
+                    {
+                        list.map((item, index) => {
+                            return (
+                                <StyledRoomButton color={fontColors[item.type]} background={gameBgs[item.type]} key={index} className={styles.room_item} style={{height: height}} onClick={(e)=>{
+                                    e.stopPropagation();
+                                    handleGame(item);
+                                }}>
+                                    <div className={styles.title_con}>
+                                        {i18n.t("gameRoom.title_"+item.type)}
+                                    </div>
+                                    <div className={styles.limit_con}>
+                                        {global.DOLLAR+" "+formatCash(item.value,0)}
+                                    </div>
+                                </StyledRoomButton>
+                            )
+                        })
+                    }
+                </div>
+            </animated.div>
+        )
+    }
+    const renderDesktop = () => {
+        if (data==null)return (<></>);
+        let level_info=data.level_info;
+        if (level_info==null)return (<></>);
+        let list=[];
+        for (const key in level_info) {
+            list.push({type:key,value:level_info[key]});
+        }
+        return (
+            <Popup onClose={() => {
+                if (onClose) onClose();
+            }} open={open} popupClass={"popup-big"}>
+                <div className={styles.cotiner}>
+                    <div className={styles.title}>{i18n.t("gameRoom.slect_title")}</div>
+                    <div className={styles.room_con}>
+                        {
+                            list.map((item, index) => {
+                                return (
+                                    <StyledRoomButton color={fontColors[item.type]} background={gameBgs[item.type]} key={index} className={`${styles.room_item} ${styles.room_item_desk}`} onClick={(e)=>{
+                                        e.stopPropagation();
+                                        handleGame(item);
+                                    }}>
+                                        <div className={styles.title_con}>
+                                            {i18n.t("gameRoom.title_"+item.type)}
+                                        </div>
+                                        <div className={`${styles.limit_con} ${styles.limit_con_desk}`}>
+                                            {global.DOLLAR+" "+formatCash(item.value,0)}
+                                        </div>
+                                    </StyledRoomButton>
+                                )
+                            })
+                        }
+                    </div>
+                </div>
+            </Popup>
+        )
+    }
+    const renderContainer = () => {
+        if (mobile) return renderMobile();
+        else return renderDesktop();
+    }
+    return (
+        <>
+            {renderContainer()}
+        </>
+    )
+}
+export default GameRoom;

+ 71 - 0
src/components/GameRoom/styles.module.scss

@@ -0,0 +1,71 @@
+@import "../../styles/vars";
+.cotiner{
+  display: flex;
+  flex-direction: column;
+  width: 100%;
+  gap: 1rem;
+  padding: 1rem;
+  & .title{
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 1rem;
+    color: var(--header);
+    margin-top: -2rem;
+  }
+  & .room_con{
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    justify-content: center;
+    gap: 0.5rem;
+  }
+}
+.cotiner_m{
+  //position: absolute;
+  transform-origin: top;
+  transition: all var(--transition);
+  width: 100%;
+  height: 0;
+  & .room_con{
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    justify-content: center;
+    gap: 0.5rem;
+    width: 100%;
+  }
+}
+.room_item{
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: space-between;
+  width: 33%;
+  background-size: 100% 100%;
+  font-family: "MyriadPro-Bold";
+  &_desk{
+    aspect-ratio: 244/157;
+    @media screen and (min-width: $width-desktop-midd-max){
+      font-size: 1.4rem;
+    }
+  }
+  & .title_con{
+    margin-top: 0.75rem;
+  }
+  & .limit_con{
+    color: #fff;
+    font-size: 1rem;
+    margin-bottom: 1rem;
+    &_desk{
+      @media screen and (min-width: $width-desktop-midd-max){
+        font-size: 1.5rem;
+        margin-bottom: 1.7rem;
+      }
+    }
+  }
+  img{
+    width: 100%;
+    height: 100%;
+  }
+}

BIN
src/fonts/myriadpro/MYRIADPRO-BOLD.OTF


BIN
src/fonts/myriadpro/MYRIADPRO-REGULAR.OTF


+ 8 - 0
src/fonts/myriadpro/style.css

@@ -0,0 +1,8 @@
+@font-face {
+    font-family: "MyriadPro-Regular";
+    src: url('../../fonts/myriadpro/MYRIADPRO-REGULAR.OTF') format('opentype');
+}
+@font-face {
+    font-family: "MyriadPro-Bold";
+    src: url('../../fonts/myriadpro/MYRIADPRO-BOLD.OTF') format('opentype');
+}

+ 10 - 0
src/locales/languages/en_US.json

@@ -422,5 +422,15 @@
     "login_pass_des": "Change your login password regularly to keep it unique and secure.",
     "withdraw_pass_title": "Change Withdraw Password",
     "withdraw_pass_des": "Change your withdraw password regularly to keep it unique and secure."
+  },
+  "gameRoom": {
+    "slect_title": "Room Selection",
+    "title_1": "JUNIOR",
+    "title_2": "SENIOR",
+    "title_3": "SUPERIOR"
+  },
+  "lackMoney": {
+    "lackMoney_Label": "I'm sorry! Your balance is insufficient, please top up.",
+    "sure_label": "Deposit Now"
   }
 }

+ 1 - 0
src/style.scss

@@ -9,4 +9,5 @@
 @import "fonts/icomoon/style.css";
 @import "fonts/swisscbt/style.css";
 @import "fonts/roboto/style.css";
+@import "fonts/myriadpro/style.css";
 @import "styles/swipeable";

+ 3 - 1
src/widgets/ModuleGameList/index.jsx

@@ -4,17 +4,19 @@ import {useThemeProvider} from "@contexts/themeContext";
 import {useDispatch, useSelector} from "react-redux";
 import {getGameListStatus} from "@features/gameListSlice";
 import {reqGameList} from "@features/api";
+import {getUserInfo} from "@features/mainSlice";
 
 const ModuleGameList=({data})=>{
     const {isMobile} = useThemeProvider();
     const dispatch = useDispatch();
     const status=useSelector(getGameListStatus(data._mkey));
+    const user=useSelector(getUserInfo);
     const reqMore=(tabtype,page)=>{
         dispatch(reqGameList({mkey:data._mkey,tabtype,page}));
     }
     return (
         <div className={``}>
-            <GameList data={data} status={status} reqMore={reqMore}>
+            <GameList data={data} status={status} reqMore={reqMore} user={user}>
 
             </GameList>
         </div>