1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- import { Data } from 'types'
- import tld from 'utils/tld'
-
- /* ------------------ Command Class ----------------- */
-
- export type CommandFn<T> = (data: T, initial?: boolean) => void
-
- /**
- * A command makes changes to some applicate state. Every command has an "undo"
- * method to reverse its changes. The apps history is a series of commands.
- */
- export class BaseCommand<T extends any> {
- timestamp = Date.now()
- name: string
- category: string
- private undoFn: CommandFn<T>
- private doFn: CommandFn<T>
- protected restoreBeforeSelectionState: (data: T) => void
- protected restoreAfterSelectionState: (data: T) => void
- protected saveSelectionState: (data: T) => (data: T) => void
- protected manualSelection: boolean
-
- constructor(options: {
- do: CommandFn<T>
- undo: CommandFn<T>
- name: string
- category: string
- manualSelection?: boolean
- }) {
- this.name = options.name
- this.category = options.category
- this.doFn = options.do
- this.undoFn = options.undo
- this.manualSelection = options.manualSelection || false
- this.restoreBeforeSelectionState = () => () => {
- null
- }
- this.restoreAfterSelectionState = () => () => {
- null
- }
- }
-
- undo = (data: T): void => {
- if (this.manualSelection) {
- this.undoFn(data)
- return
- }
-
- // We need to set the selection state to what it was before we after we did the command
- this.restoreAfterSelectionState(data)
- this.undoFn(data)
- this.restoreBeforeSelectionState(data)
- }
-
- redo = (data: T, initial = false): void => {
- if (this.manualSelection) {
- this.doFn(data, initial)
- return
- }
-
- if (!initial) {
- this.restoreBeforeSelectionState(data)
- }
-
- // We need to set the selection state to what it was before we did the command
- this.doFn(data, initial)
-
- if (initial) {
- this.restoreAfterSelectionState = this.saveSelectionState(data)
- }
- }
- }
-
- /* ---------------- Project Specific ---------------- */
-
- /**
- * A subclass of BaseCommand that sends events to our state. In our case, we want our actions
- * to mutate the state's data. Actions do not effect the "active states" in
- * the app.
- */
- export default class Command extends BaseCommand<Data> {
- saveSelectionState = (data: Data): ((next: Data) => void) => {
- const { currentPageId } = data
- const selectedIds = [...tld.getSelectedIds(data)]
- return (next: Data) => {
- next.currentPageId = currentPageId
- next.hoveredId = undefined
- next.pointedId = undefined
- tld.setSelectedIds(next, selectedIds)
- }
- }
- }
|