pull/114/head
maxime 1 year ago
parent 32b79ed5c4
commit 64e8362e53

@ -13,13 +13,18 @@ export interface EditableCourtBallProps extends CourtBallProps {
onRemove: () => void onRemove: () => void
} }
export function CourtBall({
export function CourtBall({ onPosValidated, ball, onRemove }: EditableCourtBallProps) { onPosValidated,
ball,
onRemove,
}: EditableCourtBallProps) {
const pieceRef = useRef<HTMLDivElement>(null) const pieceRef = useRef<HTMLDivElement>(null)
function courtBallPiece({ x, y }: Pos, function courtBallPiece(
{ x, y }: Pos,
pieceRef?: RefObject<HTMLDivElement>, pieceRef?: RefObject<HTMLDivElement>,
onKeyUp?: KeyboardEventHandler) { onKeyUp?: KeyboardEventHandler,
) {
return ( return (
<div <div
className={"ball-div"} className={"ball-div"}
@ -47,16 +52,9 @@ export function CourtBall({ onPosValidated, ball, onRemove }: EditableCourtBallP
} }
position={NULL_POS} position={NULL_POS}
nodeRef={pieceRef}> nodeRef={pieceRef}>
{courtBallPiece( {courtBallPiece(ball.pos, pieceRef, (e) => {
ball.pos,
pieceRef,
(e) => {
if (e.key == "Delete") onRemove() if (e.key == "Delete") onRemove()
}, })}
)}
</Draggable> </Draggable>
) )
} }

@ -77,7 +77,7 @@ export function placeObjectAt(
id: BALL_ID, id: BALL_ID,
pos, pos,
actions: [], actions: [],
frozen: false frozen: false,
} }
break break
} }
@ -403,7 +403,12 @@ export function drainTerminalStateOnChildContent(
//filter out all frozen components that are not present on the parent's terminal state anymore //filter out all frozen components that are not present on the parent's terminal state anymore
childContent = { childContent = {
components: childContent.components.filter(comp => comp.type === "phantom" || (comp.frozen && tryGetComponent(comp.id, parentTerminalState.components))) components: childContent.components.filter(
(comp) =>
comp.type === "phantom" ||
(comp.frozen &&
tryGetComponent(comp.id, parentTerminalState.components)),
),
} }
for (const parentComponent of parentTerminalState.components) { for (const parentComponent of parentTerminalState.components) {

@ -156,7 +156,9 @@ function GuestModeEditor() {
) )
} }
const tacticName = localStorage.getItem(GUEST_MODE_TITLE_STORAGE_KEY) ?? "Nouvelle Tactique" const tacticName =
localStorage.getItem(GUEST_MODE_TITLE_STORAGE_KEY) ??
"Nouvelle Tactique"
const courtRef = useRef<HTMLDivElement>(null) const courtRef = useRef<HTMLDivElement>(null)
const [stepId, setStepId] = useState(ROOT_STEP_ID) const [stepId, setStepId] = useState(ROOT_STEP_ID)
@ -165,8 +167,7 @@ function GuestModeEditor() {
SaveStates.Guest, SaveStates.Guest,
useMemo( useMemo(
() => () =>
debounceAsync( debounceAsync(async (content: StepContent) => {
async (content: StepContent) => {
localStorage.setItem( localStorage.setItem(
GUEST_MODE_STEP_CONTENT_STORAGE_KEY + stepId, GUEST_MODE_STEP_CONTENT_STORAGE_KEY + stepId,
JSON.stringify(content), JSON.stringify(content),
@ -182,23 +183,29 @@ function GuestModeEditor() {
stepId, stepId,
stepsTree, stepsTree,
async (stepId) => { async (stepId) => {
const content = JSON.parse(localStorage.getItem( const content = JSON.parse(
GUEST_MODE_STEP_CONTENT_STORAGE_KEY + stepId, localStorage.getItem(
)!) GUEST_MODE_STEP_CONTENT_STORAGE_KEY +
const courtBounds = courtRef.current!.getBoundingClientRect() stepId,
const relativePositions = computeRelativePositions(courtBounds, content) )!,
)
const courtBounds =
courtRef.current!.getBoundingClientRect()
const relativePositions = computeRelativePositions(
courtBounds,
content,
)
return { content, relativePositions } return { content, relativePositions }
}, },
async (stepId, content) => localStorage.setItem( async (stepId, content) =>
localStorage.setItem(
GUEST_MODE_STEP_CONTENT_STORAGE_KEY + stepId, GUEST_MODE_STEP_CONTENT_STORAGE_KEY + stepId,
JSON.stringify(content), JSON.stringify(content),
), ),
) )
return SaveStates.Guest return SaveStates.Guest
}, }, 250),
250,
),
[stepId], [stepId],
), ),
) )
@ -281,7 +288,6 @@ function UserModeEditor() {
const tacticId = parseInt(idStr!) const tacticId = parseInt(idStr!)
const navigation = useNavigate() const navigation = useNavigate()
const courtRef = useRef<HTMLDivElement>(null) const courtRef = useRef<HTMLDivElement>(null)
const [stepId, setStepId] = useState(1) const [stepId, setStepId] = useState(1)
@ -301,12 +307,17 @@ function UserModeEditor() {
`tactics/${tacticId}/steps/${id}`, `tactics/${tacticId}/steps/${id}`,
) )
if (!response.ok) if (!response.ok)
throw new Error("Error when retrieving children content") throw new Error(
"Error when retrieving children content",
)
const content = await response.json() const content = await response.json()
const courtBounds = courtRef.current!.getBoundingClientRect() const courtBounds =
const relativePositions = computeRelativePositions(courtBounds, content) courtRef.current!.getBoundingClientRect()
const relativePositions = computeRelativePositions(
courtBounds,
content,
)
return { return {
content, content,
relativePositions, relativePositions,
@ -386,10 +397,7 @@ function UserModeEditor() {
) )
if (!response.ok) return if (!response.ok) return
setStepId(step) setStepId(step)
setStepContent( setStepContent(await response.json(), false)
await response.json(),
false,
)
}, },
[tacticId, setStepContent], [tacticId, setStepContent],
) )
@ -479,7 +487,7 @@ function EditorPage({
onAddStep, onAddStep,
courtRef, courtRef,
}: EditorViewProps) { }: EditorViewProps) {
const [titleStyle, setTitleStyle] = useState<CSSProperties>({}) const [titleStyle, setTitleStyle] = useState<CSSProperties>({})
const [rootStepsNode, setRootStepsNode] = useState(initialStepsNode) const [rootStepsNode, setRootStepsNode] = useState(initialStepsNode)
@ -508,7 +516,9 @@ function EditorPage({
const relativePositions = useMemo(() => { const relativePositions = useMemo(() => {
const courtBounds = courtRef.current?.getBoundingClientRect() const courtBounds = courtRef.current?.getBoundingClientRect()
return courtBounds ? computeRelativePositions(courtBounds, content) : new Map() return courtBounds
? computeRelativePositions(courtBounds, content)
: new Map()
}, [content, courtRef]) }, [content, courtRef])
// const setContent = useCallback( // const setContent = useCallback(
@ -952,7 +962,7 @@ function EditorStepsTree({
onAddChildren, onAddChildren,
onRemoveNode, onRemoveNode,
onStepSelected, onStepSelected,
}: EditorStepsTreeProps) { }: EditorStepsTreeProps) {
return ( return (
<div <div
id="steps-div" id="steps-div"
@ -986,7 +996,7 @@ function PlayerRack({
setObjects, setObjects,
courtRef, courtRef,
setComponents, setComponents,
}: PlayerRackProps) { }: PlayerRackProps) {
const courtBounds = useCallback( const courtBounds = useCallback(
() => courtRef.current!.getBoundingClientRect(), () => courtRef.current!.getBoundingClientRect(),
[courtRef], [courtRef],
@ -1048,7 +1058,7 @@ function CourtPlayerArrowAction({
setContent, setContent,
setPreviewAction, setPreviewAction,
courtRef, courtRef,
}: CourtPlayerArrowActionProps) { }: CourtPlayerArrowActionProps) {
const courtBounds = useCallback( const courtBounds = useCallback(
() => courtRef.current!.getBoundingClientRect(), () => courtRef.current!.getBoundingClientRect(),
[courtRef], [courtRef],
@ -1236,29 +1246,38 @@ function computeRelativePositions(courtBounds: DOMRect, content: StepContent) {
return relativePositionsCache return relativePositionsCache
} }
async function updateStepContents(stepId: number, async function updateStepContents(
stepId: number,
stepsTree: StepInfoNode, stepsTree: StepInfoNode,
getStepContent: (stepId: number) => Promise<ComputedStepContent>, getStepContent: (stepId: number) => Promise<ComputedStepContent>,
setStepContent: (stepId: number, content: StepContent) => Promise<void>, setStepContent: (stepId: number, content: StepContent) => Promise<void>,
) { ) {
async function updateSteps(
step: StepInfoNode,
content: StepContent,
async function updateSteps(step: StepInfoNode, content: StepContent, relativePositions: ComputedRelativePositions) { relativePositions: ComputedRelativePositions,
) {
const terminalStateContent = computeTerminalState( const terminalStateContent = computeTerminalState(
content, content,
relativePositions, relativePositions,
) )
const tasks = step.children.map(async (child) => { const tasks = step.children.map(async (child) => {
const { content: childContent, relativePositions: childRelativePositions } = await getStepContent(child.id) const {
content: childContent,
relativePositions: childRelativePositions,
} = await getStepContent(child.id)
const childUpdatedContent = drainTerminalStateOnChildContent( const childUpdatedContent = drainTerminalStateOnChildContent(
terminalStateContent, terminalStateContent,
childContent, childContent,
) )
if (childUpdatedContent) { if (childUpdatedContent) {
await setStepContent(child.id, childUpdatedContent) await setStepContent(child.id, childUpdatedContent)
await updateSteps(child, childUpdatedContent, childRelativePositions) await updateSteps(
child,
childUpdatedContent,
childRelativePositions,
)
} }
}) })

Loading…
Cancel
Save