import React, { KeyboardEventHandler, ReactNode, RefObject, useCallback, useRef } from "react" import "../../style/player.css" import Draggable from "react-draggable" import { PlayerPiece } from "./PlayerPiece" import { BallState, PlayerInfo } from "../../model/tactic/Player" import { NULL_POS, Pos, ratioWithinBase } from "../../geo/Pos" export interface CourtPlayerProps { playerInfo: PlayerInfo className?: string availableActions: (ro: HTMLElement) => ReactNode[] } export interface EditableCourtPlayerProps extends CourtPlayerProps { courtRef: RefObject onPositionValidated: (newPos: Pos) => void onRemove: () => void } const MOVE_AREA_SENSIBILITY = 0.001 export const PLAYER_RADIUS_PIXELS = 20 export function CourtPlayer({ playerInfo, className, availableActions, }: CourtPlayerProps) { const pieceRef = useRef(null) return courtPlayerPiece({ playerInfo, pieceRef, className, availableActions: () => availableActions(pieceRef.current!), }) } /** * A player that is placed on the court, which can be selected, and moved in the associated bounds * */ export function EditableCourtPlayer({ playerInfo, className, courtRef, onPositionValidated, onRemove, availableActions, }: EditableCourtPlayerProps) { const pieceRef = useRef(null) const { x, y } = playerInfo.pos return ( { const pieceBounds = pieceRef.current!.getBoundingClientRect() const parentBounds = courtRef.current!.getBoundingClientRect() const pos = ratioWithinBase(pieceBounds, parentBounds) if ( Math.abs(pos.x - x) >= MOVE_AREA_SENSIBILITY || Math.abs(pos.y - y) >= MOVE_AREA_SENSIBILITY ) onPositionValidated(pos) }, [courtRef, onPositionValidated, x, y])}> {courtPlayerPiece({ playerInfo, className, pieceRef, availableActions: () => availableActions(pieceRef.current!), onKeyUp: useCallback( (e: React.KeyboardEvent) => { if (e.key == "Delete") onRemove() }, [onRemove], ), })} ) } interface CourtPlayerPieceProps extends CourtPlayerProps { pieceRef?: RefObject availableActions?: () => ReactNode[] onKeyUp?: KeyboardEventHandler } function courtPlayerPiece({ playerInfo, className, pieceRef, onKeyUp, availableActions, }: CourtPlayerPieceProps) { const usesBall = playerInfo.ballState != BallState.NONE const { x, y } = playerInfo.pos return (
{ availableActions && (
{availableActions()}
) }
) }