chg: dev: massive refactor on front-end for unification and readiness #8
This commit is contained in:
@@ -7,22 +7,10 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { BonusBox, BonusStatsDialog, Avatar } from '@mine-components';
|
||||
import { formatTime } from '@global-utils/format';
|
||||
import { useGame } from '@mine-contexts';
|
||||
import BonusBox from './BonusBox';
|
||||
import BonusStatsDialog from './BonusStatsDialog';
|
||||
|
||||
const renderAvatar = player => {
|
||||
if (!player.registered) return null;
|
||||
return (
|
||||
<div className="timer-avatar">
|
||||
{player.avatar
|
||||
? <img src={player.avatar} alt={player.name} className="timer-avatar__img" />
|
||||
: <span className="timer-avatar__initials">{player.name.slice(0, 2).toUpperCase()}</span>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const GameTimer = () => {
|
||||
const { overlay, connectionLost, endRef, activePlayer, red, blue } = useGame();
|
||||
@@ -85,84 +73,61 @@ const GameTimer = () => {
|
||||
}
|
||||
}, [activePlayer, isRunning]);
|
||||
|
||||
const syncTimes = useCallback(() => {
|
||||
let currentRedTime = pausedRedTimeRef.current;
|
||||
let currentBlueTime = pausedBlueTimeRef.current;
|
||||
|
||||
if (!activePlayer && redStartTimeRef.current) {
|
||||
currentRedTime += Math.floor((Date.now() - redStartTimeRef.current) / 1000);
|
||||
} else if (activePlayer && blueStartTimeRef.current) {
|
||||
currentBlueTime += Math.floor((Date.now() - blueStartTimeRef.current) / 1000);
|
||||
}
|
||||
|
||||
setRedTime(currentRedTime);
|
||||
setBlueTime(currentBlueTime);
|
||||
}, [activePlayer]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isRunning) {
|
||||
if (timerIntervalRef.current) {
|
||||
clearInterval(timerIntervalRef.current);
|
||||
}
|
||||
if (timerIntervalRef.current) clearInterval(timerIntervalRef.current);
|
||||
return;
|
||||
}
|
||||
|
||||
timerIntervalRef.current = setInterval(() => {
|
||||
let currentRedTime = pausedRedTimeRef.current;
|
||||
let currentBlueTime = pausedBlueTimeRef.current;
|
||||
|
||||
if (!activePlayer && redStartTimeRef.current) {
|
||||
currentRedTime += Math.floor((Date.now() - redStartTimeRef.current) / 1000);
|
||||
} else if (activePlayer && blueStartTimeRef.current) {
|
||||
currentBlueTime += Math.floor((Date.now() - blueStartTimeRef.current) / 1000);
|
||||
}
|
||||
|
||||
setRedTime(currentRedTime);
|
||||
setBlueTime(currentBlueTime);
|
||||
}, 100);
|
||||
timerIntervalRef.current = setInterval(syncTimes, 100);
|
||||
|
||||
return () => {
|
||||
if (timerIntervalRef.current) {
|
||||
clearInterval(timerIntervalRef.current);
|
||||
}
|
||||
if (timerIntervalRef.current) clearInterval(timerIntervalRef.current);
|
||||
};
|
||||
}, [isRunning, activePlayer]);
|
||||
}, [isRunning, activePlayer, syncTimes]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleFocus = () => {
|
||||
if (isRunning) {
|
||||
let currentRedTime = pausedRedTimeRef.current;
|
||||
let currentBlueTime = pausedBlueTimeRef.current;
|
||||
|
||||
if (!activePlayer && redStartTimeRef.current) {
|
||||
currentRedTime += Math.floor((Date.now() - redStartTimeRef.current) / 1000);
|
||||
} else if (activePlayer && blueStartTimeRef.current) {
|
||||
currentBlueTime += Math.floor((Date.now() - blueStartTimeRef.current) / 1000);
|
||||
}
|
||||
|
||||
setRedTime(currentRedTime);
|
||||
setBlueTime(currentBlueTime);
|
||||
}
|
||||
if (isRunning) syncTimes();
|
||||
};
|
||||
|
||||
window.addEventListener('focus', handleFocus);
|
||||
return () => window.removeEventListener('focus', handleFocus);
|
||||
}, [isRunning, activePlayer]);
|
||||
}, [isRunning, activePlayer, syncTimes]);
|
||||
|
||||
useEffect(() => () => {
|
||||
if (timerIntervalRef.current) clearInterval(timerIntervalRef.current);
|
||||
}, []);
|
||||
|
||||
const formatTime = seconds => {
|
||||
const mins = Math.floor(seconds / 60);
|
||||
const secs = seconds % 60;
|
||||
return `${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;
|
||||
};
|
||||
|
||||
const openBonusDialog = () => setBonusDialogOpen(true);
|
||||
const closeBonusDialog = () => setBonusDialogOpen(false);
|
||||
|
||||
return (
|
||||
<div className="game-timer-container">
|
||||
<BonusBox color="red" points={red.bonusPoints ?? 0} onClick={openBonusDialog} />
|
||||
<BonusBox color="red" points={red.bonusPoints ?? 0} onClick={() => setBonusDialogOpen(true)} />
|
||||
<div className={`game-timer red-timer ${!activePlayer ? 'active' : ''}`}>
|
||||
{renderAvatar(red)}
|
||||
<Avatar player={red} />
|
||||
<i className={`fa ${!activePlayer ? 'fa-hourglass-half' : 'fa-hourglass-start'} timer-icon`} />
|
||||
<span className="timer-display">{formatTime(redTime)}</span>
|
||||
</div>
|
||||
<div className={`game-timer blue-timer ${activePlayer ? 'active' : ''}`}>
|
||||
{renderAvatar(blue)}
|
||||
<Avatar player={blue} />
|
||||
<i className={`fa ${activePlayer ? 'fa-hourglass-half' : 'fa-hourglass-start'} timer-icon`} />
|
||||
<span className="timer-display">{formatTime(blueTime)}</span>
|
||||
</div>
|
||||
<BonusBox color="blue" points={blue.bonusPoints ?? 0} onClick={openBonusDialog} />
|
||||
<BonusStatsDialog open={bonusDialogOpen} onClose={closeBonusDialog} red={red} blue={blue} />
|
||||
<BonusBox color="blue" points={blue.bonusPoints ?? 0} onClick={() => setBonusDialogOpen(true)} />
|
||||
<BonusStatsDialog open={bonusDialogOpen} onClose={() => setBonusDialogOpen(false)} red={red} blue={blue} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user