add simple undo/redo
continuous-integration/drone/push Build is passing Details

pull/116/head
maxime 1 year ago committed by maxime.batista
parent cca7ee1b1b
commit 102bc774af

@ -0,0 +1,22 @@
import { StepContent } from "../model/tactic/Tactic.ts"
export class ContentVersions {
private index = 0
private contents: StepContent[] = []
public insertAndCut(content: StepContent) {
this.contents.splice(this.index + 1)
this.contents.push(content)
this.index = this.contents.length - 1
}
public previous(): StepContent | null {
if (this.index == 0) return null
return this.contents[--this.index]
}
public next(): StepContent | null {
if (this.index == this.contents.length - 1) return null
return this.contents[++this.index]
}
}

@ -92,6 +92,7 @@ import { ServiceError, TacticService } from "../service/TacticService.ts"
import { LocalStorageTacticService } from "../service/LocalStorageTacticService.ts" import { LocalStorageTacticService } from "../service/LocalStorageTacticService.ts"
import { APITacticService } from "../service/APITacticService.ts" import { APITacticService } from "../service/APITacticService.ts"
import { useParams } from "react-router-dom" import { useParams } from "react-router-dom"
import { ContentVersions } from "../editor/ContentVersions.ts"
const ERROR_STYLE: CSSProperties = { const ERROR_STYLE: CSSProperties = {
borderColor: "red", borderColor: "red",
@ -146,6 +147,11 @@ function EditorPageWrapper({ service }: { service: TacticService }) {
const courtRef = useRef<HTMLDivElement>(null) const courtRef = useRef<HTMLDivElement>(null)
const stepsVersions = useMemo<Map<number, ContentVersions>>(
() => new Map(),
[],
)
const saveContent = useCallback( const saveContent = useCallback(
async (content: StepContent) => { async (content: StepContent) => {
const result = await service.saveContent(stepId!, content) const result = await service.saveContent(stepId!, content)
@ -168,6 +174,17 @@ function EditorPageWrapper({ service }: { service: TacticService }) {
courtBounds, courtBounds,
content, content,
) )
if (id === stepId) {
let versions = stepsVersions.get(stepId!)
if (versions == undefined) {
versions = new ContentVersions()
stepsVersions.set(stepId!, versions)
}
} else {
stepsVersions.delete(id)
}
return { return {
content, content,
relativePositions, relativePositions,
@ -181,7 +198,7 @@ function EditorPageWrapper({ service }: { service: TacticService }) {
) )
return SaveStates.Ok return SaveStates.Ok
}, },
[service, stepId, stepsTree], [stepsVersions, service, stepId, stepsTree],
) )
const [stepContent, setStepContent, saveState] = const [stepContent, setStepContent, saveState] =
@ -193,6 +210,30 @@ function EditorPageWrapper({ service }: { service: TacticService }) {
const isNotInit = !tacticName || !stepId || !stepsTree || !courtType const isNotInit = !tacticName || !stepId || !stepsTree || !courtType
useEffect(() => {
const handleGlobalControls = (e: KeyboardEvent) => {
if (!e.ctrlKey) return
if (e.key == "z" || e.key == "y") {
let versions = stepsVersions.get(stepId!)
if (versions == undefined) {
versions = new ContentVersions()
stepsVersions.set(stepId!, versions)
}
const previous =
e.key == "z" ? versions.previous() : versions.next()
if (previous) {
setStepContent(previous, false)
}
}
}
document.addEventListener("keydown", handleGlobalControls)
return () =>
document.removeEventListener("keydown", handleGlobalControls)
}, [stepsVersions, setStepContent, stepId])
useEffect(() => { useEffect(() => {
async function init() { async function init() {
const contextResult = await service.getContext() const contextResult = await service.getContext()
@ -218,11 +259,16 @@ function EditorPageWrapper({ service }: { service: TacticService }) {
) )
return return
} }
const versions = new ContentVersions()
stepsVersions.set(stepId, versions)
versions.insertAndCut(contentResult)
setStepContent(contentResult, false) setStepContent(contentResult, false)
} }
if (isNotInit) init() if (isNotInit) init()
}, [isNotInit, service, setStepContent]) }, [isNotInit, service, setStepContent, stepsVersions])
const editorService: EditorService = useMemo( const editorService: EditorService = useMemo(
() => ({ () => ({
@ -239,6 +285,7 @@ function EditorPageWrapper({ service }: { service: TacticService }) {
const result = await service.removeStep(step) const result = await service.removeStep(step)
if (typeof result !== "string") if (typeof result !== "string")
setStepsTree(removeStepNode(stepsTree!, step)) setStepsTree(removeStepNode(stepsTree!, step))
stepsVersions.delete(step)
return result return result
}, },
@ -260,7 +307,7 @@ function EditorPageWrapper({ service }: { service: TacticService }) {
setStepContent(result, false) setStepContent(result, false)
}, },
}), }),
[service, setStepContent, stepsTree], [stepsVersions, service, setStepContent, stepsTree],
) )
if (panicMessage) { if (panicMessage) {

Loading…
Cancel
Save