Removes expensive immer current calls
This commit is contained in:
parent
e4b154950f
commit
364dbe0fd9
16 changed files with 118 additions and 85 deletions
|
@ -6,6 +6,7 @@ import tld from 'utils/tld'
|
||||||
import { DotCircle, Handle } from './misc'
|
import { DotCircle, Handle } from './misc'
|
||||||
import useShapeDef from 'hooks/useShape'
|
import useShapeDef from 'hooks/useShape'
|
||||||
import useShapesToRender from 'hooks/useShapesToRender'
|
import useShapesToRender from 'hooks/useShapesToRender'
|
||||||
|
import styled from 'styles'
|
||||||
|
|
||||||
export default function Defs(): JSX.Element {
|
export default function Defs(): JSX.Element {
|
||||||
const shapeIdsToRender = useShapesToRender()
|
const shapeIdsToRender = useShapesToRender()
|
||||||
|
@ -15,6 +16,7 @@ export default function Defs(): JSX.Element {
|
||||||
<DotCircle id="dot" r={4} />
|
<DotCircle id="dot" r={4} />
|
||||||
<Handle id="handle" r={4} />
|
<Handle id="handle" r={4} />
|
||||||
<ExpandDef />
|
<ExpandDef />
|
||||||
|
<ShadowDef />
|
||||||
{shapeIdsToRender.map((id) => (
|
{shapeIdsToRender.map((id) => (
|
||||||
<Def key={id} id={id} />
|
<Def key={id} id={id} />
|
||||||
))}
|
))}
|
||||||
|
@ -41,9 +43,22 @@ function Def({ id }: { id: string }) {
|
||||||
|
|
||||||
function ExpandDef() {
|
function ExpandDef() {
|
||||||
const zoom = useSelector((s) => tld.getCurrentCamera(s.data).zoom)
|
const zoom = useSelector((s) => tld.getCurrentCamera(s.data).zoom)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<filter id="expand">
|
<filter id="expand">
|
||||||
<feMorphology operator="dilate" radius={2 / zoom} />
|
<feMorphology operator="dilate" radius={2 / zoom} />
|
||||||
</filter>
|
</filter>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ShadowDef() {
|
||||||
|
return (
|
||||||
|
<filter id="hover">
|
||||||
|
<StyledShadow dx="0" dy="0" stdDeviation="1.2" floodOpacity="1" />
|
||||||
|
</filter>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const StyledShadow = styled('feDropShadow', {
|
||||||
|
floodColor: '$selected',
|
||||||
|
})
|
||||||
|
|
|
@ -37,7 +37,6 @@ function HoveredShape({ id }: { id: string }) {
|
||||||
|
|
||||||
const StyledHoverShape = styled('use', {
|
const StyledHoverShape = styled('use', {
|
||||||
stroke: '$selected',
|
stroke: '$selected',
|
||||||
filter: 'url(#expand)',
|
|
||||||
opacity: 0.1,
|
opacity: 0.1,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,26 +1,34 @@
|
||||||
import Command from './command'
|
import Command from './command'
|
||||||
import history from '../history'
|
import history from '../history'
|
||||||
import { Data, GroupShape, ShapeType } from 'types'
|
import { Data, GroupShape, ShapeType } from 'types'
|
||||||
import { getCommonBounds } from 'utils'
|
import { deepClone, getCommonBounds } from 'utils'
|
||||||
import { current } from 'immer'
|
|
||||||
import tld from 'utils/tld'
|
import tld from 'utils/tld'
|
||||||
import { createShape, getShapeUtils } from 'state/shape-utils'
|
import { createShape, getShapeUtils } from 'state/shape-utils'
|
||||||
import commands from '.'
|
import commands from '.'
|
||||||
|
|
||||||
export default function groupCommand(data: Data): void {
|
export default function groupCommand(data: Data): void {
|
||||||
const cData = current(data)
|
const { currentPageId } = data
|
||||||
const { currentPageId } = cData
|
|
||||||
|
|
||||||
const oldSelectedIds = tld.getSelectedIds(cData)
|
const oldSelectedIds = tld.getSelectedIds(data)
|
||||||
|
|
||||||
const initialShapes = tld
|
const initialShapes = tld
|
||||||
.getSelectedShapes(cData)
|
.getSelectedShapes(data)
|
||||||
.sort((a, b) => a.childIndex - b.childIndex)
|
.sort((a, b) => a.childIndex - b.childIndex)
|
||||||
|
.map((shape) => deepClone(shape))
|
||||||
|
|
||||||
const isAllSameParent = initialShapes.every(
|
const isAllSameParent = initialShapes.every(
|
||||||
(shape, i) => i === 0 || shape.parentId === initialShapes[i - 1].parentId
|
(shape, i) => i === 0 || shape.parentId === initialShapes[i - 1].parentId
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Do we need to ungroup the selected shapes shapes, rather than group them?
|
||||||
|
if (isAllSameParent && initialShapes[0]?.parentId !== currentPageId) {
|
||||||
|
const parent = tld.getShape(data, initialShapes[0]?.parentId) as GroupShape
|
||||||
|
if (parent.children.length === initialShapes.length) {
|
||||||
|
commands.ungroup(data)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let newGroupParentId: string
|
let newGroupParentId: string
|
||||||
|
|
||||||
const initialShapeIds = initialShapes.map((s) => s.id)
|
const initialShapeIds = initialShapes.map((s) => s.id)
|
||||||
|
@ -34,20 +42,12 @@ export default function groupCommand(data: Data): void {
|
||||||
if (isAllSameParent) {
|
if (isAllSameParent) {
|
||||||
const parentId = initialShapes[0].parentId
|
const parentId = initialShapes[0].parentId
|
||||||
if (parentId === currentPageId) {
|
if (parentId === currentPageId) {
|
||||||
|
// Create the new group on the current page
|
||||||
newGroupParentId = currentPageId
|
newGroupParentId = currentPageId
|
||||||
} else {
|
} else {
|
||||||
// Are all of the parent's children selected?
|
// Create the new group as a child of the shapes' current parent group
|
||||||
const parent = tld.getShape(data, parentId) as GroupShape
|
|
||||||
|
|
||||||
if (parent.children.length === initialShapes.length) {
|
|
||||||
// !!! Hey! We're not going any further. We need to ungroup those shapes.
|
|
||||||
commands.ungroup(data)
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
// Make the group inside of the current group
|
|
||||||
newGroupParentId = parentId
|
newGroupParentId = parentId
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Find the least-deep parent among the shapes and add the group as a child
|
// Find the least-deep parent among the shapes and add the group as a child
|
||||||
let minDepth = Infinity
|
let minDepth = Infinity
|
||||||
|
|
|
@ -2,22 +2,20 @@ import Command from './command'
|
||||||
import history from '../history'
|
import history from '../history'
|
||||||
import { Data, ShapeStyles } from 'types'
|
import { Data, ShapeStyles } from 'types'
|
||||||
import tld from 'utils/tld'
|
import tld from 'utils/tld'
|
||||||
import { setToArray } from 'utils'
|
import { deepClone, setToArray } from 'utils'
|
||||||
import { getShapeUtils } from 'state/shape-utils'
|
import { getShapeUtils } from 'state/shape-utils'
|
||||||
import { current } from 'immer'
|
|
||||||
|
|
||||||
export default function styleCommand(
|
export default function styleCommand(
|
||||||
data: Data,
|
data: Data,
|
||||||
styles: Partial<ShapeStyles>
|
styles: Partial<ShapeStyles>
|
||||||
): void {
|
): void {
|
||||||
const cData = current(data)
|
const page = tld.getPage(data)
|
||||||
const page = tld.getPage(cData)
|
|
||||||
|
|
||||||
const selectedIds = setToArray(tld.getSelectedIds(data))
|
const selectedIds = setToArray(tld.getSelectedIds(data))
|
||||||
|
|
||||||
const shapesToStyle = selectedIds
|
const shapesToStyle = selectedIds
|
||||||
.flatMap((id) => tld.getDocumentBranch(data, id))
|
.flatMap((id) => tld.getDocumentBranch(data, id))
|
||||||
.map((id) => page.shapes[id])
|
.map((id) => deepClone(page.shapes[id]))
|
||||||
|
|
||||||
history.execute(
|
history.execute(
|
||||||
data,
|
data,
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import Command from './command'
|
import Command from './command'
|
||||||
import history from '../history'
|
import history from '../history'
|
||||||
import { Data } from 'types'
|
import { Data } from 'types'
|
||||||
import { current } from 'immer'
|
|
||||||
import { TransformSingleSnapshot } from 'state/sessions/transform-single-session'
|
import { TransformSingleSnapshot } from 'state/sessions/transform-single-session'
|
||||||
import tld from 'utils/tld'
|
import tld from 'utils/tld'
|
||||||
|
import { deepClone } from 'utils'
|
||||||
|
|
||||||
export default function transformSingleCommand(
|
export default function transformSingleCommand(
|
||||||
data: Data,
|
data: Data,
|
||||||
|
@ -11,7 +11,7 @@ export default function transformSingleCommand(
|
||||||
after: TransformSingleSnapshot,
|
after: TransformSingleSnapshot,
|
||||||
isCreating: boolean
|
isCreating: boolean
|
||||||
): void {
|
): void {
|
||||||
const shape = current(tld.getPage(data).shapes[after.id])
|
const shape = deepClone(tld.getPage(data).shapes[after.id])
|
||||||
|
|
||||||
history.execute(
|
history.execute(
|
||||||
data,
|
data,
|
||||||
|
|
|
@ -2,8 +2,7 @@ import { ArrowShape, Data } from 'types'
|
||||||
import vec from 'utils/vec'
|
import vec from 'utils/vec'
|
||||||
import BaseSession from './base-session'
|
import BaseSession from './base-session'
|
||||||
import commands from 'state/commands'
|
import commands from 'state/commands'
|
||||||
import { current } from 'immer'
|
import { deepClone, getBoundsFromPoints, setToArray } from 'utils'
|
||||||
import { getBoundsFromPoints, setToArray } from 'utils'
|
|
||||||
import { getShapeUtils } from 'state/shape-utils'
|
import { getShapeUtils } from 'state/shape-utils'
|
||||||
import tld from 'utils/tld'
|
import tld from 'utils/tld'
|
||||||
|
|
||||||
|
@ -110,7 +109,7 @@ export default class ArrowSession extends BaseSession {
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||||
export function getArrowSnapshot(data: Data, id: string) {
|
export function getArrowSnapshot(data: Data, id: string) {
|
||||||
const initialShape = tld.getPage(current(data)).shapes[id] as ArrowShape
|
const initialShape = deepClone(tld.getPage(data).shapes[id]) as ArrowShape
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id,
|
id,
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import { current } from 'immer'
|
|
||||||
import { Bounds, Data, ShapeType } from 'types'
|
import { Bounds, Data, ShapeType } from 'types'
|
||||||
import BaseSession from './base-session'
|
import BaseSession from './base-session'
|
||||||
import { getShapeUtils } from 'state/shape-utils'
|
import { getShapeUtils } from 'state/shape-utils'
|
||||||
import { getBoundsFromPoints, setToArray } from 'utils'
|
import { deepClone, getBoundsFromPoints, setToArray } from 'utils'
|
||||||
import vec from 'utils/vec'
|
import vec from 'utils/vec'
|
||||||
import tld from 'utils/tld'
|
import tld from 'utils/tld'
|
||||||
|
|
||||||
|
@ -67,7 +66,7 @@ export default class BrushSession extends BaseSession {
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||||
export function getBrushSnapshot(data: Data) {
|
export function getBrushSnapshot(data: Data) {
|
||||||
const cData = current(data)
|
const cData = data
|
||||||
const { selectedIds } = tld.getPageState(cData)
|
const { selectedIds } = tld.getPageState(cData)
|
||||||
|
|
||||||
const shapesToTest = tld
|
const shapesToTest = tld
|
||||||
|
@ -76,6 +75,7 @@ export function getBrushSnapshot(data: Data) {
|
||||||
.filter(
|
.filter(
|
||||||
(shape) => !(selectedIds.has(shape.id) || selectedIds.has(shape.parentId))
|
(shape) => !(selectedIds.has(shape.id) || selectedIds.has(shape.parentId))
|
||||||
)
|
)
|
||||||
|
.map(deepClone)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
selectedIds: setToArray(selectedIds),
|
selectedIds: setToArray(selectedIds),
|
||||||
|
@ -84,9 +84,10 @@ export function getBrushSnapshot(data: Data) {
|
||||||
return [
|
return [
|
||||||
shape.id,
|
shape.id,
|
||||||
{
|
{
|
||||||
selectId: tld.getTopParentId(cData, shape.id),
|
selectId: tld.getTopParentId(data, shape.id),
|
||||||
test: (bounds: Bounds) =>
|
test: (bounds: Bounds) => {
|
||||||
getShapeUtils(shape).hitTestBounds(shape, bounds),
|
return getShapeUtils(shape).hitTestBounds(shape, bounds)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import { current } from 'immer'
|
|
||||||
import { Data, DrawShape } from 'types'
|
import { Data, DrawShape } from 'types'
|
||||||
import BaseSession from './base-session'
|
import BaseSession from './base-session'
|
||||||
import { getShapeUtils } from 'state/shape-utils'
|
import { getShapeUtils } from 'state/shape-utils'
|
||||||
import { getBoundsFromPoints } from 'utils'
|
import { deepClone, getBoundsFromPoints } from 'utils'
|
||||||
import tld from 'utils/tld'
|
import tld from 'utils/tld'
|
||||||
import vec from 'utils/vec'
|
import vec from 'utils/vec'
|
||||||
import commands from 'state/commands'
|
import commands from 'state/commands'
|
||||||
|
@ -140,8 +139,8 @@ export default class DrawSession extends BaseSession {
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||||
export function getDrawSnapshot(data: Data, shapeId: string) {
|
export function getDrawSnapshot(data: Data, shapeId: string) {
|
||||||
const page = tld.getPage(current(data))
|
const page = tld.getPage(data)
|
||||||
const { points, point } = page.shapes[shapeId] as DrawShape
|
const { points, point } = deepClone(page.shapes[shapeId]) as DrawShape
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: shapeId,
|
id: shapeId,
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { Data, Shape } from 'types'
|
import { Data, Shape } from 'types'
|
||||||
import BaseSession from './base-session'
|
import BaseSession from './base-session'
|
||||||
import commands from 'state/commands'
|
import commands from 'state/commands'
|
||||||
import { current } from 'immer'
|
|
||||||
import { getShapeUtils } from 'state/shape-utils'
|
import { getShapeUtils } from 'state/shape-utils'
|
||||||
import tld from 'utils/tld'
|
import tld from 'utils/tld'
|
||||||
|
import { deepClone } from 'utils'
|
||||||
|
|
||||||
export default class EditSession extends BaseSession {
|
export default class EditSession extends BaseSession {
|
||||||
snapshot: EditSnapshot
|
snapshot: EditSnapshot
|
||||||
|
@ -35,7 +35,7 @@ export default class EditSession extends BaseSession {
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||||
export function getEditSnapshot(data: Data) {
|
export function getEditSnapshot(data: Data) {
|
||||||
const initialShape = tld.getSelectedShapes(current(data))[0]
|
const initialShape = deepClone(tld.getSelectedShapes(data)[0])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
currentPageId: data.currentPageId,
|
currentPageId: data.currentPageId,
|
||||||
|
|
|
@ -2,9 +2,9 @@ import { Data } from 'types'
|
||||||
import vec from 'utils/vec'
|
import vec from 'utils/vec'
|
||||||
import BaseSession from './base-session'
|
import BaseSession from './base-session'
|
||||||
import commands from 'state/commands'
|
import commands from 'state/commands'
|
||||||
import { current } from 'immer'
|
|
||||||
import tld from 'utils/tld'
|
import tld from 'utils/tld'
|
||||||
import { getShapeUtils } from 'state/shape-utils'
|
import { getShapeUtils } from 'state/shape-utils'
|
||||||
|
import { deepClone } from 'utils'
|
||||||
|
|
||||||
export default class HandleSession extends BaseSession {
|
export default class HandleSession extends BaseSession {
|
||||||
delta = [0, 0]
|
delta = [0, 0]
|
||||||
|
@ -69,7 +69,7 @@ export function getHandleSnapshot(
|
||||||
shapeId: string,
|
shapeId: string,
|
||||||
handleId: string
|
handleId: string
|
||||||
) {
|
) {
|
||||||
const initialShape = tld.getPage(current(data)).shapes[shapeId]
|
const initialShape = deepClone(tld.getShape(data, shapeId))
|
||||||
|
|
||||||
return {
|
return {
|
||||||
currentPageId: data.currentPageId,
|
currentPageId: data.currentPageId,
|
||||||
|
|
|
@ -2,12 +2,10 @@ import { Data, ShapeType } from 'types'
|
||||||
import vec from 'utils/vec'
|
import vec from 'utils/vec'
|
||||||
import BaseSession from './base-session'
|
import BaseSession from './base-session'
|
||||||
import commands from 'state/commands'
|
import commands from 'state/commands'
|
||||||
import { current } from 'immer'
|
|
||||||
import {
|
import {
|
||||||
clampToRotationToSegments,
|
clampToRotationToSegments,
|
||||||
getBoundsCenter,
|
getBoundsCenter,
|
||||||
getCommonBounds,
|
getCommonBounds,
|
||||||
setToArray,
|
|
||||||
} from 'utils'
|
} from 'utils'
|
||||||
import tld from 'utils/tld'
|
import tld from 'utils/tld'
|
||||||
import { getShapeUtils } from 'state/shape-utils'
|
import { getShapeUtils } from 'state/shape-utils'
|
||||||
|
@ -95,14 +93,7 @@ export default class RotateSession extends BaseSession {
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||||
export function getRotateSnapshot(data: Data) {
|
export function getRotateSnapshot(data: Data) {
|
||||||
const cData = current(data)
|
const initialShapes = tld.getSelectedBranchSnapshot(data)
|
||||||
const page = tld.getPage(cData)
|
|
||||||
|
|
||||||
const initialShapes = setToArray(tld.getSelectedIds(data))
|
|
||||||
.flatMap((id) =>
|
|
||||||
tld.getDocumentBranch(cData, id).map((id) => page.shapes[id])
|
|
||||||
)
|
|
||||||
.filter((shape) => !shape.isLocked)
|
|
||||||
|
|
||||||
const hasUnlockedShapes = initialShapes.length > 0
|
const hasUnlockedShapes = initialShapes.length > 0
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ import {
|
||||||
getCommonBounds,
|
getCommonBounds,
|
||||||
getRelativeTransformedBoundingBox,
|
getRelativeTransformedBoundingBox,
|
||||||
getTransformedBoundingBox,
|
getTransformedBoundingBox,
|
||||||
setToArray,
|
|
||||||
} from 'utils'
|
} from 'utils'
|
||||||
|
|
||||||
export default class TransformSession extends BaseSession {
|
export default class TransformSession extends BaseSession {
|
||||||
|
@ -117,14 +116,8 @@ export default class TransformSession extends BaseSession {
|
||||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||||
export function getTransformSnapshot(data: Data, transformType: Edge | Corner) {
|
export function getTransformSnapshot(data: Data, transformType: Edge | Corner) {
|
||||||
const { currentPageId } = data
|
const { currentPageId } = data
|
||||||
const page = tld.getPage(data)
|
|
||||||
|
|
||||||
const initialShapes = setToArray(tld.getSelectedIds(data))
|
const initialShapes = tld.getSelectedBranchSnapshot(data)
|
||||||
.flatMap((id) =>
|
|
||||||
tld.getDocumentBranch(data, id).map((id) => page.shapes[id])
|
|
||||||
)
|
|
||||||
.filter((shape) => !shape.isLocked)
|
|
||||||
.map((shape) => deepClone(shape))
|
|
||||||
|
|
||||||
const hasUnlockedShapes = initialShapes.length > 0
|
const hasUnlockedShapes = initialShapes.length > 0
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,8 @@ import { Data, Edge, Corner } from 'types'
|
||||||
import vec from 'utils/vec'
|
import vec from 'utils/vec'
|
||||||
import BaseSession from './base-session'
|
import BaseSession from './base-session'
|
||||||
import commands from 'state/commands'
|
import commands from 'state/commands'
|
||||||
import { current } from 'immer'
|
|
||||||
import { getShapeUtils } from 'state/shape-utils'
|
import { getShapeUtils } from 'state/shape-utils'
|
||||||
import { getTransformedBoundingBox } from 'utils'
|
import { deepClone, getTransformedBoundingBox } from 'utils'
|
||||||
import tld from 'utils/tld'
|
import tld from 'utils/tld'
|
||||||
|
|
||||||
export default class TransformSingleSession extends BaseSession {
|
export default class TransformSingleSession extends BaseSession {
|
||||||
|
@ -85,7 +84,7 @@ export function getTransformSingleSnapshot(
|
||||||
data: Data,
|
data: Data,
|
||||||
transformType: Edge | Corner
|
transformType: Edge | Corner
|
||||||
) {
|
) {
|
||||||
const shape = tld.getSelectedShapes(current(data))[0]
|
const shape = deepClone(tld.getSelectedShapes(data)[0])
|
||||||
const bounds = getShapeUtils(shape).getBounds(shape)
|
const bounds = getShapeUtils(shape).getBounds(shape)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -2,7 +2,6 @@ import { Data, GroupShape, Shape, ShapeType } from 'types'
|
||||||
import vec from 'utils/vec'
|
import vec from 'utils/vec'
|
||||||
import BaseSession from './base-session'
|
import BaseSession from './base-session'
|
||||||
import commands from 'state/commands'
|
import commands from 'state/commands'
|
||||||
import { current } from 'immer'
|
|
||||||
import { uniqueId } from 'utils'
|
import { uniqueId } from 'utils'
|
||||||
import { getShapeUtils } from 'state/shape-utils'
|
import { getShapeUtils } from 'state/shape-utils'
|
||||||
import tld from 'utils/tld'
|
import tld from 'utils/tld'
|
||||||
|
@ -174,32 +173,28 @@ export default class TranslateSession extends BaseSession {
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||||
export function getTranslateSnapshot(data: Data) {
|
export function getTranslateSnapshot(data: Data) {
|
||||||
const cData = current(data)
|
const page = tld.getPage(data)
|
||||||
|
|
||||||
// Get selected shapes
|
const selectedShapes = tld.getSelectedShapeSnapshot(data)
|
||||||
// Filter out the locked shapes
|
|
||||||
// Collect the branch children for each remaining shape
|
|
||||||
// Filter out doubles using a set
|
|
||||||
// End up with an array of ids for all of the shapes that will change
|
|
||||||
// Map into shapes from data snapshot
|
|
||||||
|
|
||||||
const page = tld.getPage(cData)
|
|
||||||
const selectedShapes = tld
|
|
||||||
.getSelectedShapes(cData)
|
|
||||||
.filter((shape) => !shape.isLocked)
|
|
||||||
|
|
||||||
const hasUnlockedShapes = selectedShapes.length > 0
|
const hasUnlockedShapes = selectedShapes.length > 0
|
||||||
|
|
||||||
const parents = Array.from(
|
const initialParents = Array.from(
|
||||||
new Set(selectedShapes.map((s) => s.parentId)).values()
|
new Set(selectedShapes.map((s) => s.parentId)).values()
|
||||||
)
|
)
|
||||||
.filter((id) => id !== data.currentPageId)
|
.filter((id) => id !== data.currentPageId)
|
||||||
.map((id) => page.shapes[id])
|
.map((id) => {
|
||||||
|
const shape = page.shapes[id]
|
||||||
|
return {
|
||||||
|
id: shape.id,
|
||||||
|
children: shape.children,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
hasUnlockedShapes,
|
hasUnlockedShapes,
|
||||||
currentPageId: data.currentPageId,
|
currentPageId: data.currentPageId,
|
||||||
initialParents: parents.map(({ id, children }) => ({ id, children })),
|
initialParents,
|
||||||
initialShapes: selectedShapes.map(({ id, point, parentId }) => ({
|
initialShapes: selectedShapes.map(({ id, point, parentId }) => ({
|
||||||
id,
|
id,
|
||||||
point,
|
point,
|
||||||
|
@ -211,9 +206,8 @@ export function getTranslateSnapshot(data: Data) {
|
||||||
const clone: Shape = {
|
const clone: Shape = {
|
||||||
...shape,
|
...shape,
|
||||||
id: uniqueId(),
|
id: uniqueId(),
|
||||||
|
|
||||||
parentId: shape.parentId,
|
parentId: shape.parentId,
|
||||||
childIndex: tld.getChildIndexAbove(cData, shape.id),
|
childIndex: tld.getChildIndexAbove(data, shape.id),
|
||||||
isGenerated: false,
|
isGenerated: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import history from './history'
|
||||||
import storage from './storage'
|
import storage from './storage'
|
||||||
import clipboard from './clipboard'
|
import clipboard from './clipboard'
|
||||||
import * as Sessions from './sessions'
|
import * as Sessions from './sessions'
|
||||||
import pusher from './coop/client-supa'
|
import coopClient from './coop/client-pusher'
|
||||||
import commands from './commands'
|
import commands from './commands'
|
||||||
import {
|
import {
|
||||||
getCommonBounds,
|
getCommonBounds,
|
||||||
|
@ -1162,7 +1162,7 @@ const state = createState({
|
||||||
},
|
},
|
||||||
sendRtCursorMove(data, payload: PointerInfo) {
|
sendRtCursorMove(data, payload: PointerInfo) {
|
||||||
const point = tld.screenToWorld(payload.point, data)
|
const point = tld.screenToWorld(payload.point, data)
|
||||||
pusher.moveCursor(data.currentPageId, point)
|
coopClient.moveCursor(data.currentPageId, point)
|
||||||
},
|
},
|
||||||
moveRtCursor(
|
moveRtCursor(
|
||||||
data,
|
data,
|
||||||
|
@ -1214,7 +1214,7 @@ const state = createState({
|
||||||
},
|
},
|
||||||
connectToRoom(data, payload: { id: string }) {
|
connectToRoom(data, payload: { id: string }) {
|
||||||
data.room = { id: payload.id, status: 'connecting', peers: {} }
|
data.room = { id: payload.id, status: 'connecting', peers: {} }
|
||||||
pusher.connect(payload.id)
|
coopClient.connect(payload.id)
|
||||||
},
|
},
|
||||||
|
|
||||||
resetPageState(data) {
|
resetPageState(data) {
|
||||||
|
|
47
utils/tld.ts
47
utils/tld.ts
|
@ -326,6 +326,40 @@ export default class ProjectUtils {
|
||||||
|
|
||||||
/* ----------------- Shapes Related ----------------- */
|
/* ----------------- Shapes Related ----------------- */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a deep-cloned
|
||||||
|
* @param data
|
||||||
|
* @param fn
|
||||||
|
*/
|
||||||
|
static getSelectedBranchSnapshot<K>(
|
||||||
|
data: Data,
|
||||||
|
fn: <T extends Shape>(shape: T) => K
|
||||||
|
): ({ id: string } & K)[]
|
||||||
|
static getSelectedBranchSnapshot(data: Data): Shape[]
|
||||||
|
static getSelectedBranchSnapshot<
|
||||||
|
K,
|
||||||
|
F extends <T extends Shape>(shape: T) => K
|
||||||
|
>(data: Data, fn?: F): (Shape | K)[] {
|
||||||
|
const page = this.getPage(data)
|
||||||
|
|
||||||
|
const copies = setToArray(this.getSelectedIds(data))
|
||||||
|
.flatMap((id) =>
|
||||||
|
this.getDocumentBranch(data, id).map((id) => page.shapes[id])
|
||||||
|
)
|
||||||
|
.filter((shape) => !shape.isLocked)
|
||||||
|
.map(deepClone)
|
||||||
|
|
||||||
|
if (fn !== undefined) {
|
||||||
|
return copies.map((shape) => ({ id: shape.id, ...fn(shape) }))
|
||||||
|
}
|
||||||
|
|
||||||
|
return copies
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a deep-cloned array of shapes
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
static getSelectedShapeSnapshot(data: Data): Shape[]
|
static getSelectedShapeSnapshot(data: Data): Shape[]
|
||||||
static getSelectedShapeSnapshot<K>(
|
static getSelectedShapeSnapshot<K>(
|
||||||
data: Data,
|
data: Data,
|
||||||
|
@ -337,7 +371,7 @@ export default class ProjectUtils {
|
||||||
>(data: Data, fn?: F): (Shape | K)[] {
|
>(data: Data, fn?: F): (Shape | K)[] {
|
||||||
const copies = this.getSelectedShapes(data)
|
const copies = this.getSelectedShapes(data)
|
||||||
.filter((shape) => !shape.isLocked)
|
.filter((shape) => !shape.isLocked)
|
||||||
.map((shape) => deepClone(shape))
|
.map(deepClone)
|
||||||
|
|
||||||
if (fn !== undefined) {
|
if (fn !== undefined) {
|
||||||
return copies.map((shape) => ({ id: shape.id, ...fn(shape) }))
|
return copies.map((shape) => ({ id: shape.id, ...fn(shape) }))
|
||||||
|
@ -346,6 +380,17 @@ export default class ProjectUtils {
|
||||||
return copies
|
return copies
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an array of all unique parentIds among a set of shapes.
|
||||||
|
* @param data
|
||||||
|
* @param shapes
|
||||||
|
*/
|
||||||
|
static getUniqueParentIds(data: Data, shapes: Shape[]): string[] {
|
||||||
|
return Array.from(new Set(shapes.map((s) => s.parentId)).values()).filter(
|
||||||
|
(id) => id !== data.currentPageId
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make an arbitrary change to shape.
|
* Make an arbitrary change to shape.
|
||||||
* @param data
|
* @param data
|
||||||
|
|
Loading…
Reference in a new issue