import React, { createContext, useContext, useMemo } from 'react'; import { Chess } from 'chess.js'; import type { BoardState, BoardConfig } from './types'; import { useBoardState } from './use-board-state'; import { Dimensions } from 'react-native'; import type { ImageSourcePropType } from 'react-native'; import { MOVE_SPRING, SCALE_SPRING, SNAP_BACK_SPRING, } from '../config/animations'; const { width: SCREEN_WIDTH } = Dimensions.get('window'); const DEFAULT_BOARD_SIZE = Math.floor(SCREEN_WIDTH / 8) * 8; type BoardContextValue = { boardState: BoardState; chess: Chess; config: BoardConfig; }; const BoardStateContext = createContext(null); export type BoardStateProviderProps = { children: React.ReactNode; fen?: string; boardSize?: number; gestureEnabled?: boolean; flipped?: boolean; withLetters?: boolean; withNumbers?: boolean; colors?: Partial; durations?: Partial; fontSource?: ImageSourcePropType; }; const defaultColors: BoardConfig['colors'] = { white: '#D9FDF8', black: '#62B1A8', lastMoveHighlight: 'rgba(255,255,0, 0.5)', checkmateHighlight: '#E84855', promotionPieceButton: '#FF9B71', }; const defaultDurations: BoardConfig['durations'] = { move: 150, }; const defaultAnimations: BoardConfig['animations'] = { move: MOVE_SPRING, scale: SCALE_SPRING, snapBack: SNAP_BACK_SPRING, }; export const BoardStateProvider: React.FC = ({ children, fen, boardSize = DEFAULT_BOARD_SIZE, gestureEnabled = true, flipped = false, withLetters = true, withNumbers = true, colors, durations, fontSource, }) => { const pieceSize = boardSize / 8; const config = useMemo( (): BoardConfig => ({ boardSize, pieceSize, gestureEnabled, flipped, withLetters, withNumbers, colors: { ...defaultColors, ...colors }, durations: { ...defaultDurations, ...durations }, animations: defaultAnimations, fontSource: fontSource ?? null, }), [ boardSize, pieceSize, gestureEnabled, flipped, withLetters, withNumbers, colors, durations, fontSource, ] ); const { boardState, chess } = useBoardState(fen, pieceSize, flipped); const value = useMemo( () => ({ boardState, chess, config, }), [boardState, chess, config] ); return ( {children} ); }; export const useBoardContext = (): BoardContextValue => { const context = useContext(BoardStateContext); if (!context) { throw new Error('useBoardContext must be used within a BoardStateProvider'); } return context; }; export const useBoardConfig = (): BoardConfig => { return useBoardContext().config; }; export const useChess = (): Chess => { return useBoardContext().chess; }; export const useBoardStateValues = (): BoardState => { return useBoardContext().boardState; };