Private
Public Access
1
0

chg: dev: use namespaces for front-end #4

This commit is contained in:
2026-04-10 21:53:50 +02:00
parent c660c13ea2
commit 5b55a6ce73
18 changed files with 208 additions and 34 deletions

View File

@@ -1,6 +1,14 @@
/**
* This file is part of the SplendidBear Websites' projects.
*
* Copyright (c) 2026 @ www.splendidbear.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import React from 'react';
import { createRoot } from 'react-dom/client';
import MineSeeker from './mine-seeker/MineSeeker';
const wrapper = document.getElementById('mine-wrapper');

View File

@@ -1,7 +1,16 @@
/**
* This file is part of the SplendidBear Websites' projects.
*
* Copyright (c) 2026 @ www.splendidbear.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import React, { useRef } from 'react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { GameProvider } from './contexts/GameProvider';
import { GameBoard } from './components/GameBoard';
import { GameProvider } from '@mine-contexts';
import { GameBoard } from '@mine-components';
const queryClient = new QueryClient();

View File

@@ -1,4 +1,4 @@
/*
/**
* This file is part of the SplendidBear Websites' projects.
*
* Copyright (c) 2026 @ www.splendidbear.org
@@ -8,8 +8,8 @@
*/
import React from 'react';
import { useGame } from '../contexts/GameContext';
import useServerCommunication from '../hooks/useServerCommunication';
import { useGame } from '@mine-contexts';
import { useServerCommunication } from '@mine-hooks';
import GridControl from './grid/GridControl';
export const GameBoard = ({ gameAssoc, gameInherited, isEnvDev }) => {

View File

@@ -1,8 +1,17 @@
/**
* This file is part of the SplendidBear Websites' projects.
*
* Copyright (c) 2026 @ www.splendidbear.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import React from 'react';
import { useGame } from '../../contexts/GameContext';
import { useGame } from '@mine-contexts';
import GridField from './GridField';
import UserControl from '../user/UserControl';
import { BOMB_SYMBOLS, bombRadius } from '../../utils/constants';
import { BOMB_SYMBOLS, bombRadius } from '@mine-utils';
const GridControl = ({ onClick, resign }) => {
const {

View File

@@ -1,5 +1,14 @@
/**
* This file is part of the SplendidBear Websites' projects.
*
* Copyright (c) 2026 @ www.splendidbear.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import React, { memo } from 'react';
import { IMAGES } from '../../utils/constants';
import { IMAGES } from '@mine-utils';
const bombSrc = area => {
if (null === area) return null;

View File

@@ -0,0 +1,14 @@
/**
* This file is part of the SplendidBear Websites' projects.
*
* Copyright (c) 2026 @ www.splendidbear.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
export { GameBoard } from './GameBoard';
export { default as GridControl } from './grid/GridControl';
export { default as GridField } from './grid/GridField';
export { default as User } from './user/User';
export { default as UserControl } from './user/UserControl';

View File

@@ -1,17 +1,28 @@
import React, { memo } from 'react';
import { IMAGES } from '../../utils/constants';
/**
* This file is part of the SplendidBear Websites' projects.
*
* Copyright (c) 2026 @ www.splendidbear.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
const User = memo(function User({
color,
webPlayer,
name,
desc,
active,
mines,
haveBomb,
enabledBomb,
onClickBombSelector,
}) {
import React, { memo } from 'react';
import { IMAGES } from '@mine-utils';
const User = memo(function User(
{
color,
webPlayer,
name,
desc,
active,
mines,
haveBomb,
enabledBomb,
onClickBombSelector,
},
) {
const buzzClass = 'bomb-container'
+ (active && color === webPlayer && haveBomb && enabledBomb ? ' buzz' : '');

View File

@@ -1,5 +1,14 @@
/**
* This file is part of the SplendidBear Websites' projects.
*
* Copyright (c) 2026 @ www.splendidbear.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import React from 'react';
import { useGame } from '../../contexts/GameContext';
import { useGame } from '@mine-contexts';
import User from './User';
const UserControl = ({ resign }) => {

View File

@@ -1,3 +1,12 @@
/**
* This file is part of the SplendidBear Websites' projects.
*
* Copyright (c) 2026 @ www.splendidbear.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { createContext, useContext } from 'react';
const GameContext = createContext(null);

View File

@@ -1,9 +1,17 @@
/**
* This file is part of the SplendidBear Websites' projects.
*
* Copyright (c) 2026 @ www.splendidbear.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import React, { useRef } from 'react';
import { Howl } from 'howler';
import GameContext from './GameContext';
import useGameRefs from '../hooks/useGameRefs';
import useGameState from '../hooks/useGameState';
import { DESC, IMAGES, patchCells } from '../utils/constants';
import { useGameRefs, useGameState } from '@mine-hooks';
import { DESC, IMAGES, patchCells } from '@mine-utils';
export const GameProvider = ({ children }) => {
const {
@@ -41,7 +49,8 @@ export const GameProvider = ({ children }) => {
won: new Howl({ src: ['/sound/won.mp3'] }),
});
// ── Sync helpers (keep ref + state in lockstep) ──────────────────────────
/** Sync helpers (keep ref + state in lockstep) */
const syncWebPlayer = v => {
webPlayerRef.current = v;
setWebPlayer(v);
@@ -69,7 +78,8 @@ export const GameProvider = ({ children }) => {
setBlue(n);
};
// ── Overlay ───────────────────────────────────────────────────────────────
/** Overlay */
const showOverlay = (title, sub) => {
setOverlay(true);
setOverlayTitle(title);
@@ -78,7 +88,8 @@ export const GameProvider = ({ children }) => {
const hideOverlay = () => setOverlay(false);
// ── Cell helpers ──────────────────────────────────────────────────────────
/** Cell helpers */
const applyRevealedCell = (cell, player, isMainCell = false) => {
const { row, col, value } = cell;
setCells(prev => {
@@ -105,7 +116,8 @@ export const GameProvider = ({ children }) => {
});
};
// ── Game logic ────────────────────────────────────────────────────────────
/** Game logic */
const changePlayer = () => {
const wasColor = activePlayerRef.current ? 'blue' : 'red';
const nextColor = activePlayerRef.current ? 'red' : 'blue';

View File

@@ -0,0 +1,13 @@
/**
* This file is part of the SplendidBear Websites' projects.
*
* Copyright (c) 2026 @ www.splendidbear.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
export { useGame } from './GameContext';
export { GameProvider } from './GameProvider';
export { default as GameContext } from './GameContext';

View File

@@ -0,0 +1,13 @@
/**
* This file is part of the SplendidBear Websites' projects.
*
* Copyright (c) 2026 @ www.splendidbear.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
export { default as useGameRefs } from './useGameRefs';
export { default as useGameState } from './useGameState';
export { default as useServerCommunication } from './useServerCommunication';

View File

@@ -1,5 +1,14 @@
/**
* This file is part of the SplendidBear Websites' projects.
*
* Copyright (c) 2026 @ www.splendidbear.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { useRef } from 'react';
import { PLAYER_DEF } from '../utils/constants';
import { PLAYER_DEF } from '@mine-utils';
const useGameRefs = () => {
const webPlayerRef = useRef(null);

View File

@@ -1,5 +1,14 @@
/**
* This file is part of the SplendidBear Websites' projects.
*
* Copyright (c) 2026 @ www.splendidbear.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import { useState } from 'react';
import { initCells, PLAYER_DEF } from '../utils/constants';
import { initCells, PLAYER_DEF } from '@mine-utils';
const useGameState = () => {
const [webPlayer, setWebPlayer] = useState(null);

View File

@@ -1,7 +1,16 @@
/**
* This file is part of the SplendidBear Websites' projects.
*
* Copyright (c) 2026 @ www.splendidbear.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import React, { useEffect, useRef } from 'react';
import { useMutation, useQuery } from '@tanstack/react-query';
import { useGame } from '../contexts/GameContext';
import { DESC } from '../utils/constants';
import { useGame } from '@mine-contexts';
import { DESC } from '@mine-utils';
/** Handles all server communication: SSE (Mercure), REST calls, and the initialization lifecycle. */
const useServerCommunication = (gameAssoc, gameInherited, isEnvDev) => {

View File

@@ -1,3 +1,12 @@
/**
* This file is part of the SplendidBear Websites' projects.
*
* Copyright (c) 2026 @ www.splendidbear.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
import React from 'react';
export const ROWS = 16;

View File

@@ -0,0 +1,10 @@
/**
* This file is part of the SplendidBear Websites' projects.
*
* Copyright (c) 2026 @ www.splendidbear.org
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
export { DESC, IMAGES, BOMB_SYMBOLS, PLAYER_DEF, bombRadius, initCells, patchCells } from './constants';

View File

@@ -1,12 +1,24 @@
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import symfonyPlugin from 'vite-plugin-symfony';
import { fileURLToPath } from 'url';
import { dirname, resolve } from 'path';
const __dirname = dirname(fileURLToPath(import.meta.url));
export default defineConfig({
plugins: [
react(),
symfonyPlugin({ refresh: true }),
],
resolve: {
alias: {
'@mine-components': resolve(__dirname, './assets/js/mine-seeker/components'),
'@mine-contexts': resolve(__dirname, './assets/js/mine-seeker/contexts'),
'@mine-hooks': resolve(__dirname, './assets/js/mine-seeker/hooks'),
'@mine-utils': resolve(__dirname, './assets/js/mine-seeker/utils'),
},
},
build: {
rollupOptions: {
input: {