import styles from "@components/GameList/styles.module.scss"; import React, { useCallback, useEffect, useRef, useState } from "react"; import GameItem, { GameImgAspectRatio } 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 { useWindowSize } from "react-use"; const i18n = global.i18n; const objInfo = { timer: null } const GameList = ({ data, status, reqMore, user }) => { // data={ // type:0,//游戏分类 // page:1, // pageSize:40, // total:42, // totalPage:1, // data:[ // { // gid:0,//gameid // img:"https://bc.imgix.net/game/image/f76d3f4a-9712-4bd1-9426-f3ab7069b6a2.png?auto=format&dpr=3&w=200",//图片 // link:"",//跳转的链接 // online:1006,//游戏人数 // desc:"BC Originals",//描述 // }, // { // gid:0,//gameid // img:"https://bc.imgix.net/game/image/ff0b0511-1f48-43d1-8dd3-294bb6437b4b.png?auto=format&dpr=3&w=200",//图片 // link:"",//跳转的链接 // online:100,//游戏人数 // desc:"BC Originals",//描述 // }, // { // gid:0,//gameid // img:"https://bc.imgix.net/game/image/d33b3fad-b6df-450b-bd85-528a17383043.png?auto=format&dpr=3&w=200",//图片 // link:"",//跳转的链接 // online:100,//游戏人数 // desc:"BC Originals",//描述 // }, // { // gid:0,//gameid // img:"https://bc.imgix.net/game/image/5b3a4099-9462-4d3c-a854-ade78aad0d60.png?auto=format&dpr=3&w=200",//图片 // link:"",//跳转的链接 // online:100,//游戏人数 // desc:"BC Originals",//描述 // }, // { // gid:0,//gameid // img:"https://bc.imgix.net/game/image/f76d3f4a-9712-4bd1-9426-f3ab7069b6a2.png?auto=format&dpr=3&w=200",//图片 // link:"",//跳转的链接 // online:100,//游戏人数 // desc:"BC Originals",//描述 // }, // { // gid:0,//gameid // img:"https://bc.imgix.net/game/image/ff0b0511-1f48-43d1-8dd3-294bb6437b4b.png?auto=format&dpr=3&w=200",//图片 // link:"",//跳转的链接 // online:100,//游戏人数 // desc:"BC Originals",//描述 // }, // { // gid:0,//gameid // img:"https://bc.imgix.net/game/image/d33b3fad-b6df-450b-bd85-528a17383043.png?auto=format&dpr=3&w=200",//图片 // link:"",//跳转的链接 // online:100,//游戏人数 // desc:"BC Originals",//描述 // }, // { // gid:0,//gameid // img:"https://bc.imgix.net/game/image/5b3a4099-9462-4d3c-a854-ade78aad0d60.png?auto=format&dpr=3&w=200",//图片 // link:"",//跳转的链接 // online:100,//游戏人数 // desc:"BC Originals",//描述 // }, // ] // } const { isMobile, fontScale } = useThemeProvider(); const M_LIST_COL = 3; const [selected, setSelected] = useState(-1); const [roomRow, setRoomRow] = useState({}); const [showPopRoom, setShowPopRoom] = useState(false); const roomHeight = 5.2; const rowTop = roomHeight + 0.75; const gameListRef = useRef(null); const [gridInfo, setGridInfo] = useState({}); const { width } = useWindowSize(); const mobile = isMobile(); const handleReset = (e) => { setSelected(-1); setRoomRow({}); } useEffect(() => { document.addEventListener("click", handleReset); return () => { document.removeEventListener("click", handleReset); resetTimer(); } }, []) const getDesktopCol = useCallback(() => { if (width >= 1264 && width <= 1564) return 6; else if (width >= 963 && width <= 1263) return 5; else if (width >= 622 && width <= 962) return 4; else if (width <= 621) return 3; return 7; }, [width]); const initGridsInfo = useCallback(() => { let parent = gameListRef.current; let totalCol = 3; if (!mobile) totalCol = getDesktopCol(); let gridBaseRatio = GameImgAspectRatio; let totalWidth = mobile ? 100 * totalCol : 160 * totalCol; if (parent != null) totalWidth = parent.clientWidth; let rowGap = parent != null ? window.getComputedStyle(parent).getPropertyValue('grid-row-gap') : "0px"; let gap = Number(rowGap.replace("px", "")); if (gap === 0 || isNaN(gap)) gap = 0.75 * 16 * fontScale; let gridsData = {}; for (let i = 1; i <= 6; i++) { let gridNum = i; let gridWidth = (totalWidth - (totalCol - 1) * gap) / totalCol; let itemWidth = gridWidth * gridNum + (gridNum - 1) * gap; let width = itemWidth + "px"; let aspectRatio = gridBaseRatio * (itemWidth / gridWidth); gridsData[i] = { width, aspectRatio }; } setGridInfo(gridsData); }, [fontScale, getDesktopCol, mobile]); useEffect(() => { initGridsInfo(); }, [initGridsInfo]); const resetTimer = () => { if (objInfo.timer != null) { clearTimeout(objInfo.timer); objInfo.timer = null; } } 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 > 90) row = row + 1; } else row = row + 1; if (row >= total) row = total - 1; let roomRowItem = { row: row, data: item } if (roomRow.row === row) { setRoomRow({ hide: true, ...roomRowItem }); resetTimer(); objInfo.timer = setTimeout(() => { setRoomRow(roomRowItem); }, 10) } else setRoomRow(roomRowItem); } 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: -1, data: data }); setShowPopRoom(true); } const handlePopClose = () => { setRoomRow({}); setShowPopRoom(false); } const renderGameListDesktop = () => { let list = data.data; if (list == null) list = []; return ( <>
{ list.map((item, index) => { let gridNum = item.gridNum != null ? item.gridNum : 1; // gridNum=Math.floor(Math.random()*3)+1; let whStyle = gridInfo[gridNum]; if (whStyle == null) return null; return ( ) }) }
) } const formatMList = (list) => { let mList = []; if (list) { let count = 0; for (let i = 0; i < list.length; i++) { let item = list[i]; let gridNum = item.gridNum != null ? item.gridNum : 1; let row = Math.floor(count / M_LIST_COL); let rowData = mList[row]; if (rowData == null) rowData = []; let nitem = { ...item, gridNum: gridNum } rowData.push(nitem); mList[row] = rowData; count += gridNum; } } return mList; } const renderRoom = (row, len) => { if (roomRow == null) return (<>); if (roomRow.hide) return (<>); let rrow = roomRow.row; let data = roomRow.data; if (rrow === row) { return ( ) } else return (<>); } const renderGameListMobile = () => { let list = data.data; if (list == null) list = []; list = formatMList(list); let len = list.length; return (
{ list.map((rowArr, row) => { let rowStyle = {}; if (roomRow != null) { if (row >= roomRow.row) { rowStyle.transform = `translateY(${rowTop + "rem"})`; } } return ( {renderRoom(row, len)}
{ rowArr.map((item, col) => { let itemStyle = {} if (selected !== -1) { if (item.id !== selected) { itemStyle.filter = "brightness(60%)" } else { itemStyle.transform = "scale(1.05)"; } } let gridNum = item.gridNum != null ? item.gridNum : 1; let whStyle = gridInfo[gridNum]; return ( { handleSelect(e, data, row, len) }} row={row} whStyle={whStyle} style={itemStyle}> ) }) }
) }) }
) } 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 (
{current} / {total}
{spro}
) } const renderLoading = () => { return () } const onClickMore = () => { if (reqMore) { let page = Number(data.page) + 1; let tabtype = data.tabtype; let id = data.id; reqMore(id, tabtype, page); } } const renderShowMoreBtn = () => { let isNomore = Number(data.page) === Number(data.totalPage); let label = isNomore ? i18n.t("game_list.no_more") : i18n.t("game_list.show_more"); return (
) } const renderShowMore = () => { let isNomore = Number(data.page) === Number(data.totalPage); let moreStyle = {}; if (roomRow && roomRow.row != null) { let row = roomRow.row; if (row >= 0) { moreStyle.transform = `translateY(${rowTop + "rem"})`; moreStyle.marginBottom = rowTop + "rem"; } } if (isNomore) { if (isMobile()) return (
) else return (<>); } return (
{renderProgress()} {renderShowMoreBtn()}
) } return (
{renderGameList()} {renderShowMore()}
) } export default GameList;