index.jsx 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. import styles from "@components/GameList/styles.module.scss";
  2. import React, {useEffect, useState} from "react";
  3. import GameItem from "@components/GameItem";
  4. import {REQ_STATUS} from "@api/config";
  5. import SmallLoading from "@components/SmallLoading";
  6. import {useThemeProvider} from "@contexts/themeContext";
  7. import GameRoom from "@components/GameRoom";
  8. import {total} from "react-big-calendar/lib/utils/dates";
  9. const i18n =global.i18n;
  10. const objInfo={
  11. timer:null
  12. }
  13. const GameList=({data,status,reqMore,user})=>{
  14. // data={
  15. // type:0,//游戏分类
  16. // page:1,
  17. // pageSize:40,
  18. // total:42,
  19. // totalPage:1,
  20. // data:[
  21. // {
  22. // gid:0,//gameid
  23. // img:"https://bc.imgix.net/game/image/f76d3f4a-9712-4bd1-9426-f3ab7069b6a2.png?auto=format&dpr=3&w=200",//图片
  24. // link:"",//跳转的链接
  25. // online:1006,//游戏人数
  26. // desc:"BC Originals",//描述
  27. // },
  28. // {
  29. // gid:0,//gameid
  30. // img:"https://bc.imgix.net/game/image/ff0b0511-1f48-43d1-8dd3-294bb6437b4b.png?auto=format&dpr=3&w=200",//图片
  31. // link:"",//跳转的链接
  32. // online:100,//游戏人数
  33. // desc:"BC Originals",//描述
  34. // },
  35. // {
  36. // gid:0,//gameid
  37. // img:"https://bc.imgix.net/game/image/d33b3fad-b6df-450b-bd85-528a17383043.png?auto=format&dpr=3&w=200",//图片
  38. // link:"",//跳转的链接
  39. // online:100,//游戏人数
  40. // desc:"BC Originals",//描述
  41. // },
  42. // {
  43. // gid:0,//gameid
  44. // img:"https://bc.imgix.net/game/image/5b3a4099-9462-4d3c-a854-ade78aad0d60.png?auto=format&dpr=3&w=200",//图片
  45. // link:"",//跳转的链接
  46. // online:100,//游戏人数
  47. // desc:"BC Originals",//描述
  48. // },
  49. // {
  50. // gid:0,//gameid
  51. // img:"https://bc.imgix.net/game/image/f76d3f4a-9712-4bd1-9426-f3ab7069b6a2.png?auto=format&dpr=3&w=200",//图片
  52. // link:"",//跳转的链接
  53. // online:100,//游戏人数
  54. // desc:"BC Originals",//描述
  55. // },
  56. // {
  57. // gid:0,//gameid
  58. // img:"https://bc.imgix.net/game/image/ff0b0511-1f48-43d1-8dd3-294bb6437b4b.png?auto=format&dpr=3&w=200",//图片
  59. // link:"",//跳转的链接
  60. // online:100,//游戏人数
  61. // desc:"BC Originals",//描述
  62. // },
  63. // {
  64. // gid:0,//gameid
  65. // img:"https://bc.imgix.net/game/image/d33b3fad-b6df-450b-bd85-528a17383043.png?auto=format&dpr=3&w=200",//图片
  66. // link:"",//跳转的链接
  67. // online:100,//游戏人数
  68. // desc:"BC Originals",//描述
  69. // },
  70. // {
  71. // gid:0,//gameid
  72. // img:"https://bc.imgix.net/game/image/5b3a4099-9462-4d3c-a854-ade78aad0d60.png?auto=format&dpr=3&w=200",//图片
  73. // link:"",//跳转的链接
  74. // online:100,//游戏人数
  75. // desc:"BC Originals",//描述
  76. // },
  77. // ]
  78. // }
  79. const {isMobile} = useThemeProvider();
  80. const M_LIST_COL=3;
  81. const M_LIST_ROW=1;
  82. const [selected,setSelected]=useState(-1);
  83. const [roomRow,setRoomRow]=useState({});
  84. const [showPopRoom,setShowPopRoom]=useState(false);
  85. const roomHeight=5.2;
  86. const rowTop=roomHeight+0.75;
  87. const handleReset=(e)=>{
  88. setSelected(-1);
  89. setRoomRow({});
  90. }
  91. useEffect(()=>{
  92. document.addEventListener("click",handleReset);
  93. return ()=>{
  94. document.removeEventListener("click",handleReset);
  95. resetTimer();
  96. }
  97. },[])
  98. const resetTimer=()=>{
  99. if (objInfo.timer!=null){
  100. clearTimeout(objInfo.timer);
  101. objInfo.timer=null;
  102. }
  103. }
  104. const checkSetRoom=(e,item,row,total)=>{
  105. let target=e.target;
  106. if (target){
  107. let rect=target.getBoundingClientRect();
  108. let cH = document.documentElement.clientHeight;
  109. let cB=rect.bottom;
  110. if (cH-cB>80)row=row+1;
  111. }else row=row+1;
  112. if (row>=total)row=total-1;
  113. let roomRowItem={
  114. row:row,
  115. data:item
  116. }
  117. if (roomRow.row===row){
  118. setRoomRow({
  119. hide:true,
  120. ...roomRowItem
  121. });
  122. resetTimer();
  123. objInfo.timer=setTimeout(()=>{
  124. setRoomRow(roomRowItem);
  125. },10)
  126. }
  127. else setRoomRow(roomRowItem);
  128. }
  129. const handleSelect=(e,data,row,total)=>{
  130. e.stopPropagation();
  131. if (data.id===selected){
  132. handleReset();
  133. }
  134. else
  135. {
  136. setSelected(data.id);
  137. checkSetRoom(e,data,row,total);
  138. }
  139. }
  140. const handlePopSelected=(e,data,row,totall)=>{
  141. e.stopPropagation();
  142. setRoomRow({
  143. row:-1,
  144. data:data
  145. });
  146. setShowPopRoom(true);
  147. }
  148. const handlePopClose=()=>{
  149. setRoomRow({});
  150. setShowPopRoom(false);
  151. }
  152. const renderGameListDesktop=()=>{
  153. let list=data.data;
  154. if (list==null)list=[];
  155. return (
  156. <>
  157. <div id={"gameList"} className={styles.game_list}>
  158. {
  159. list.map((item, index) => {
  160. return (
  161. <GameItem key={index} data={item} handleRoom={handlePopSelected}></GameItem>
  162. )
  163. })
  164. }
  165. </div>
  166. <GameRoom open={showPopRoom} data={roomRow.data} user={user} onClose={handlePopClose}></GameRoom>
  167. </>
  168. )
  169. }
  170. const formatMList = (list) => {
  171. let mList = [];
  172. if (list) {
  173. for (let i = 0; i < list.length; i += M_LIST_COL) {
  174. let rowArr = list.slice(i, i + M_LIST_COL);
  175. mList.push(rowArr);
  176. }
  177. }
  178. return mList;
  179. }
  180. const renderRoom=(row,len)=>{
  181. if (roomRow==null)return (<></>);
  182. if (roomRow.hide)return (<></>);
  183. let rrow=roomRow.row;
  184. let data=roomRow.data;
  185. if (rrow===row){
  186. return (
  187. <GameRoom open={true} data={data} height={roomHeight+"rem"} mobile={true} user={user}></GameRoom>
  188. )
  189. }
  190. else return (<></>);
  191. }
  192. const renderGameListMobile=()=>{
  193. let list=data.data;
  194. if (list==null)list=[];
  195. list=formatMList(list);
  196. let len=list.length;
  197. return (
  198. <div id={"gameList"} className={styles.game_list_mobile}>
  199. {
  200. list.map((rowArr,row)=>{
  201. let rowStyle={};
  202. if (roomRow!=null){
  203. // if (roomRow.row===row){
  204. if (row>=roomRow.row){
  205. // rowStyle.marginTop=roomHeight;
  206. rowStyle.transform=`translateY(${rowTop+"rem"})`;
  207. }
  208. // if (roomRow.row===row){
  209. // rowStyle.marginTop=roomHeight;
  210. // }
  211. }
  212. return (
  213. <>
  214. {renderRoom(row,len)}
  215. <div key={row} className={styles.list_row} style={rowStyle}>
  216. {
  217. rowArr.map((item, col) => {
  218. let itemStyle={}
  219. if (selected!==-1){
  220. if (item.id!==selected){
  221. itemStyle.filter="brightness(60%)"
  222. }
  223. else
  224. {
  225. itemStyle.transform="scale(1.05)";
  226. }
  227. }
  228. return (
  229. <GameItem key={col} data={item} handleRoom={(e,data)=>{
  230. handleSelect(e,data,row,len)
  231. }} row={row} style={itemStyle}></GameItem>
  232. )
  233. })
  234. }
  235. </div>
  236. </>
  237. )
  238. })
  239. }
  240. </div>
  241. )
  242. }
  243. const renderGameList = () => {
  244. if (isMobile()) return renderGameListMobile();
  245. else return renderGameListDesktop();
  246. }
  247. const renderProgress = () => {
  248. let list = data.data;
  249. if (list == null) list = [];
  250. let current = list.length;
  251. let total = data.total;
  252. let progress = Math.ceil((current / total) * 100);
  253. let spro =progress+"%";
  254. return (
  255. <div className={styles.page_progress}>
  256. <span>{current} / {total}</span>
  257. <div className={styles.progress}>
  258. <div className={styles.green} style={{width:spro}}></div>
  259. </div>
  260. <span>{spro}</span>
  261. </div>
  262. )
  263. }
  264. const renderLoading=()=>{
  265. return (<SmallLoading fill={"#fff"}/>)
  266. }
  267. const onClickMore=()=>{
  268. if (reqMore){
  269. let page=Number(data.page)+1;
  270. let tabtype=data.tabtype;
  271. let id=data.id;
  272. reqMore(id,tabtype,page);
  273. }
  274. }
  275. const renderShowMoreBtn=()=>{
  276. let isNomore=Number(data.page)===Number(data.totalPage);
  277. let label=isNomore?i18n.t("game_list.no_more"):i18n.t("game_list.show_more");
  278. return (
  279. <div className={styles.show_more}>
  280. <button className={styles.more_btn} disabled={isNomore} onClick={()=>{
  281. if (status!=REQ_STATUS.LOADING){
  282. onClickMore();
  283. }
  284. }}>
  285. {
  286. status===REQ_STATUS.LOADING?renderLoading():(<div>{label}</div>)
  287. }
  288. </button>
  289. </div>
  290. )
  291. }
  292. const renderShowMore=()=>{
  293. let isNomore=Number(data.page)===Number(data.totalPage);
  294. let moreStyle={};
  295. if (roomRow&&roomRow.row!=null){
  296. let row=roomRow.row;
  297. if (row>=0){
  298. moreStyle.transform=`translateY(${rowTop+"rem"})`;
  299. moreStyle.marginBottom=rowTop+"rem";
  300. }
  301. }
  302. if (isNomore){
  303. if (isMobile()) return (<div className={`${styles.page_con} ${styles.page_nomore}`} style={moreStyle}></div>)
  304. else return (<></>);
  305. }
  306. return (
  307. <div className={styles.page_con} style={moreStyle}>
  308. {renderProgress()}
  309. {renderShowMoreBtn()}
  310. </div>
  311. )
  312. }
  313. return (
  314. <div className={`w-100 ${styles.list_container}`}>
  315. {renderGameList()}
  316. {renderShowMore()}
  317. </div>
  318. )
  319. }
  320. export default GameList;