Private
Public Access
1
0

chg: usr: add timers to each player - renew the whole migration #4

This commit is contained in:
2026-04-11 15:19:59 +02:00
parent 5b55a6ce73
commit d388e25192
10 changed files with 391 additions and 107 deletions

View File

@@ -7,10 +7,11 @@
* file that was distributed with this source code.
*/
import React from 'react';
import React, { Fragment } from 'react';
import { useGame } from '@mine-contexts';
import GridField from './GridField';
import UserControl from '../user/UserControl';
import GameTimer from '../GameTimer';
import { BOMB_SYMBOLS, bombRadius } from '@mine-utils';
const GridControl = ({ onClick, resign }) => {
@@ -40,31 +41,34 @@ const GridControl = ({ onClick, resign }) => {
};
return (
<div className="game-wrapper">
<div className={`game-overlay${overlay ? '' : ' hide'}`}>
<div className="game-overlay-window">
<h1>{overlayTitle}</h1>
<h2>{overlaySubTitle}</h2>
<Fragment>
<GameTimer />
<div className="game-wrapper">
<div className={`game-overlay${overlay ? '' : ' hide'}`}>
<div className="game-overlay-window">
<h1>{overlayTitle}</h1>
<h2>{overlaySubTitle}</h2>
</div>
</div>
<UserControl
resign={resign}
/>
<div className="grid-container">
<div className="grid">
{cells.flatMap((row, r) =>
row.map((cell, c) => (
<GridField
key={`${r}_${c}`}
cell={cell}
onClick={() => onClick([r, c])}
onMouseEnter={() => handleHover(r, c)}
/>
)),
)}
</div>
</div>
</div>
<UserControl
resign={resign}
/>
<div className="grid-container">
<div className="grid">
{cells.flatMap((row, r) =>
row.map((cell, c) => (
<GridField
key={`${r}_${c}`}
cell={cell}
onClick={() => onClick([r, c])}
onMouseEnter={() => handleHover(r, c)}
/>
)),
)}
</div>
</div>
</div>
</Fragment>
);
};

View File

@@ -7,7 +7,7 @@
* file that was distributed with this source code.
*/
import React, { memo } from 'react';
import React, { memo, useMemo } from 'react';
import { IMAGES } from '@mine-utils';
const bombSrc = area => {
@@ -25,26 +25,47 @@ const GridField = memo(function GridField({ cell, onClick, onMouseEnter }) {
+ (active ? ' active' : '')
+ (active && 'm' === currentObj ? ' mine' : '')
+ ' color-' + currentObj;
const inner = isNaN(currentImage)
? (
<div className="flag-mine"><img src={currentImage} alt="" />
<div className="flag-mine-base" />
</div>
)
: currentImage ? <div className="flag-number">{currentImage}</div> : null;
const bSrc = bombSrc(bombTargetArea);
const showLast = lastClickedRed || lastClickedBlue;
const lastClass = 'field-' + (lastClickedRed ? 'red' : 'blue') + '-last last-clicked';
const bombSourceString = useMemo(() => bombSrc(bombTargetArea), [bombTargetArea]);
return (
<div className="field-wrapper" onClick={onClick} onMouseEnter={onMouseEnter}>
<img className="field-target" src={IMAGES.target} alt="" />
{bSrc && <img className="field-bomb-target" src={bSrc} alt="" />}
{showLast && <img className={lastClass} src={IMAGES.last(lastClickedRed ? 'red' : 'blue')} alt="" />}
<div
className="field-wrapper"
onClick={onClick}
onMouseEnter={onMouseEnter}
>
<img
className="field-target"
src={IMAGES.target}
alt="Field of target"
/>
{bombSourceString && (
<img
className="field-bomb-target"
src={bombSourceString}
alt="Field of bomb target"
/>
)}
{(lastClickedRed || lastClickedBlue) && (
<img
className={`field-${lastClickedRed ? 'red' : 'blue'}-last last-clicked`}
src={IMAGES.last(lastClickedRed ? 'red' : 'blue')}
alt="Last clicked area"
/>
)}
<div className={fieldClass}>
<div className="field-corner">{inner}</div>
<div className="field-corner">
{isNaN(currentImage) && (
<div className="flag-mine">
<img src={currentImage} alt="" />
<div className="flag-mine-base" />
</div>
)}
{!isNaN(currentImage) && 0 !== currentImage && (
<div className="flag-number">
{currentImage}
</div>
)}
</div>
</div>
</div>
);