import { faCrosshairs } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { CSSProperties, useEffect, useReducer, useState } from 'react'; import BorderTiles from './components/BorderTiles'; import FogImages from './components/FogImages'; import HitElems from './components/HitElems'; import Labeling from './components/Labeling'; import Ships from './components/Ships'; import { hitReducer, initlialTarget, initlialTargetPreview, isHit } from './helpers'; import { HitType, TargetPreviewType, TargetType } from './interfaces'; import './styles/App.scss'; function App() { const count = 12; const [target, setTarget] = useState(initlialTarget); const [targetPreview, setTargetPreview] = useState(initlialTargetPreview); const [hits, DispatchHits] = useReducer(hitReducer, [] as HitType[]); // handle visibility and position change of targetPreview useEffect(() => { const {newX, newY, shouldShow, appearOK, eventReady, show, x, y} = targetPreview; const positionChange = !(x === newX && y === newY); // if not ready or no new position if (!eventReady || !positionChange) return; if (show) { // hide preview to change position when hidden setTargetPreview(e => ({...e, appearOK: false, eventReady: false, show: false})); } else if (shouldShow && appearOK && !isHit(hits, newX, newY).length) { // BUT only appear again if it's supposed to (in case the mouse left over the edge) and () setTargetPreview(e => ({...e, appearOK: false, eventReady: false, show: true, x: newX, y: newY})); } }, [targetPreview, hits]) // enable targetPreview event again after 200 mil. sec. useEffect(() => { if (targetPreview.eventReady) return; const autoTimeout = setTimeout(() => { setTargetPreview(e => ({...e, eventReady: true})); }, 200); // or abort if state has changed early return () => { clearTimeout(autoTimeout); } }, [targetPreview.eventReady]); // approve targetPreview new position after 200 mil. sec. useEffect(() => { // early return to start cooldown only when about to show up if (!targetPreview.shouldShow) return; const autoTimeout = setTimeout(() => { setTargetPreview(e => ({...e, appearOK: true})); }, 350); // or abort if movement is repeated early return () => { clearTimeout(autoTimeout); } }, [targetPreview.shouldShow, targetPreview.newX, targetPreview.newY]); return (
{/* Bordes */} {/* Collumn lettes and row numbers */} {/* Ships */} {/* */} {/* Fog images */} {/* */}
{/*

Edit src/App.tsx and save to reload.

*/} Battleships designed by macrovector
); } export default App;