|
|
@ -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,
|
|
|
|
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|