Private
Public Access
1
0

chg: dev: more, massive refactor for front-end #4

This commit is contained in:
2026-04-10 19:09:05 +02:00
parent b57442bec1
commit d186a96f0d
13 changed files with 402 additions and 296 deletions

View File

@@ -9,12 +9,12 @@
import React from 'react';
import { useGame } from '../contexts/GameContext';
import useServerComm from '../hooks/useServerComm';
import useServerCommunication from '../hooks/useServerCommunication';
import GridControl from './grid/GridControl';
export const GameBoard = ({ gameAssoc, gameInherited, isEnvDev }) => {
const { gridReady } = useGame();
const { onClick, resign } = useServerComm(gameAssoc, gameInherited, isEnvDev);
const { onClick, resign } = useServerCommunication(gameAssoc, gameInherited, isEnvDev);
if (!gridReady) {
return (
@@ -24,5 +24,10 @@ export const GameBoard = ({ gameAssoc, gameInherited, isEnvDev }) => {
);
}
return <GridControl onClick={onClick} resign={resign} />;
return (
<GridControl
onClick={onClick}
resign={resign}
/>
);
};

View File

@@ -2,13 +2,13 @@ import React from 'react';
import { useGame } from '../../contexts/GameContext';
import GridField from './GridField';
import UserControl from '../user/UserControl';
import { BOMB_SYMBOLS, bombRadius } from '../../constants';
import { BOMB_SYMBOLS, bombRadius } from '../../utils/constants';
const GridControl = ({ onClick, resign }) => {
const {
overlay, overlayTitle, overlaySubTitle,
webPlayer, activePlayer, mines, foundMines, bombSelected,
red, blue, cells, setCells, onBombToggle,
webPlayer, activePlayer, bombSelected,
cells, setCells,
} = useGame();
const handleHover = (row, col) => {
@@ -39,13 +39,6 @@ const GridControl = ({ onClick, resign }) => {
</div>
</div>
<UserControl
webPlayer={webPlayer}
activePlayer={activePlayer}
mines={mines}
foundMines={foundMines}
red={red}
blue={blue}
onBombToggle={onBombToggle}
resign={resign}
/>
<div className="grid-container">
@@ -58,7 +51,7 @@ const GridControl = ({ onClick, resign }) => {
onClick={() => onClick([r, c])}
onMouseEnter={() => handleHover(r, c)}
/>
))
)),
)}
</div>
</div>

View File

@@ -1,12 +1,12 @@
import React, { memo } from 'react';
import { IMG } from '../../constants';
import { IMAGES } from '../../utils/constants';
const bombSrc = area => {
if (null === area) return null;
const vert = ['left', 'center', 'right'][area[0]] ?? null;
const hor = ['top', 'middle', 'bottom'][area[1]] ?? null;
if (null === vert || null === hor) return IMG + 'bg-bomb-empty-outbg.png';
return `${IMG}bg-bomb-${hor}-${vert}-outbg.png`;
if (null === vert || null === hor) return IMAGES.bombEmpty;
return IMAGES.bombPos(hor, vert);
};
const GridField = memo(function GridField({ cell, onClick, onMouseEnter }) {
@@ -28,13 +28,12 @@ const GridField = memo(function GridField({ cell, onClick, onMouseEnter }) {
const bSrc = bombSrc(bombTargetArea);
const showLast = lastClickedRed || lastClickedBlue;
const lastClass = 'field-' + (lastClickedRed ? 'red' : 'blue') + '-last last-clicked';
const lastSrc = lastClickedRed ? IMG + 'bg-last-red-outbg.png' : IMG + 'bg-last-blue-outbg.png';
return (
<div className="field-wrapper" onClick={onClick} onMouseEnter={onMouseEnter}>
<img className="field-target" src={IMG + 'bg-target-outbg.png'} alt="" />
<img className="field-target" src={IMAGES.target} alt="" />
{bSrc && <img className="field-bomb-target" src={bSrc} alt="" />}
{showLast && <img className={lastClass} src={lastSrc} alt="" />}
{showLast && <img className={lastClass} src={IMAGES.last(lastClickedRed ? 'red' : 'blue')} alt="" />}
<div className={fieldClass}>
<div className="field-corner">{inner}</div>
</div>

View File

@@ -1,34 +1,38 @@
import React, { memo } from 'react';
const SRC = '/images/';
import { IMAGES } from '../../utils/constants';
const User = memo(function User({
color, webPlayer,
name, desc, active, mines, haveBomb, enabledBomb,
color,
webPlayer,
name,
desc,
active,
mines,
haveBomb,
enabledBomb,
onClickBombSelector,
}) {
const buzzClass = 'bomb-container'
+ (active && color === webPlayer && haveBomb && enabledBomb ? ' buzz' : '');
const bombImg = haveBomb
? SRC + (enabledBomb && active ? 'bg-bomb-outbg.png' : 'bg-bomb-disabled-outbg.png')
: SRC + 'bg-bomb-exploded-outbg.png';
return (
<div className={`user-container user-${color}`}>
<div className="user-header">
<div className="user-color">{color}</div>
{active && <img src={`${SRC}bg-cursor-${color}-outbg.png`} alt="" className="user-cursor" />}
<img src={`${SRC}bg-figure-${color}-outbg.png`} alt="" />
{active && <img src={IMAGES.cursor(color)} alt="" className="user-cursor" />}
<img src={IMAGES.figure(color)} alt="" />
</div>
<div className="user-name"> {name} </div>
<div className="user-caret"><i className="fa fa-caret-down" /></div>
<div className="user-desc"> {desc} </div>
<div className="user-control">
<img src={`${SRC}bg-flag-${color}-outbg.png`} alt="" />
<img src={IMAGES.flag(color)} alt="" />
<div className="user-control-mines">{mines}</div>
<div className={buzzClass} onClick={onClickBombSelector}>
<div className="bomb"><img src={bombImg} alt="" /></div>
<div className="bomb">
{haveBomb && <img src={enabledBomb && active ? IMAGES.bomb : IMAGES.bombDisabled} alt="" />}
{!haveBomb && <img src={IMAGES.bombExploded} alt="" />}
</div>
</div>
<div className="clear" />
</div>

View File

@@ -1,7 +1,9 @@
import React from 'react';
import { useGame } from '../../contexts/GameContext';
import User from './User';
const UserControl = ({ webPlayer, activePlayer, mines, foundMines, red, blue, onBombToggle, resign }) => {
const UserControl = ({ resign }) => {
const { webPlayer, activePlayer, mines, foundMines, red, blue, onBombToggle } = useGame();
const activeColor = activePlayer ? 'blue' : 'red';
const resignClass = 'resign' + (activeColor !== webPlayer ? ' disabled' : '');
const minesClass = 'active-mines' + (foundMines ? ' found-mine' : '');