Skip to content

Commit

Permalink
No more stateful grid strategies (#6490)
Browse files Browse the repository at this point in the history
**Description:**
I removed custom state strategy usage from grid reparent strategy:
- the target cell was cached in custom strategy state to make sure we
can reparent over gaps between cells. I removed this and just reparent
into the closest cell.

Removed custom strategy state usage from grid controls, and moved the
necessary information to `EditorStateCanvasControls`. Instead of custom
strategy state patches i needed to return showGridControls commands.

Removed all fields from `GridCustomStrategyState` except
`metadataCacheForGrids`, which is still necessary

**Manual Tests:**
I hereby swear that:

- [x] I opened a hydrogen project and it loaded
- [x] I could navigate to various routes in Play mode
  • Loading branch information
gbalint authored Oct 8, 2024
1 parent 2779ddd commit ddc54cb
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 135 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import type { AllElementProps } from '../../editor/store/editor-state'
import type { CanvasCommand } from '../commands/commands'
import type { ActiveFrameAction } from '../commands/set-active-frames-command'
import type { StrategyApplicationStatus } from './interaction-state'
import type { TargetGridCellData } from './strategies/grid-helpers'
import type { GridCellCoordinates } from './strategies/grid-cell-bounds'

// TODO: fill this in, maybe make it an ADT for different strategies
export interface CustomStrategyState {
Expand All @@ -29,8 +27,6 @@ export interface CustomStrategyState {
}

export type GridCustomStrategyState = {
targetCellData: TargetGridCellData | null
currentRootCell: GridCellCoordinates | null
metadataCacheForGrids: { [gridPath: string]: ElementInstanceMetadata }
}

Expand All @@ -45,8 +41,6 @@ export function defaultCustomStrategyState(): CustomStrategyState {
elementsToRerender: [],
action: null,
grid: {
targetCellData: null,
currentRootCell: null,
metadataCacheForGrids: {},
},
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,27 +161,21 @@ const gridDrawToInsertStrategyInner =
const newTargetCell = getGridCellUnderMouseFromMetadata(parent, canvasPointToUse)

if (strategyLifecycle === 'mid-interaction' && interactionData.type === 'HOVER') {
const baseCustomState = updatedCustomState ?? customStrategyState
const customStatePatch = {
...baseCustomState,
grid: {
...baseCustomState.grid,
// this is added here during the hover interaction so that
// `GridControls` can render the hover highlight based on the
// coordinates in `targetCellData`
targetCellData: newTargetCell ?? customStrategyState.grid.targetCellData,
},
}
return strategyApplicationResult(
[
wildcardPatch('mid-interaction', {
selectedViews: { $set: [] },
}),
showGridControls('mid-interaction', targetParent),
showGridControls(
'mid-interaction',
targetParent,
newTargetCell?.gridCellCoordinates ?? null,
null,
),
updateHighlightedViews('mid-interaction', [targetParent]),
],
[targetParent],
customStatePatch,
updatedCustomState ?? undefined,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,61 +44,52 @@ import {
} from './grid-cell-bounds'
import { mapDropNulls } from '../../../../core/shared/array-utils'
import { assertNever } from '../../../../core/shared/utils'

const emptyGridRearrangeMoveResult = {
commands: [],
targetCell: null,
targetRootCell: null,
}
import { showGridControls } from '../../commands/show-grid-controls-command'

export function runGridRearrangeMove(
targetElement: ElementPath,
selectedElement: ElementPath,
jsxMetadata: ElementInstanceMetadataMap,
interactionData: DragInteractionData,
): {
commands: CanvasCommand[]
targetCell: TargetGridCellData | null
targetRootCell: GridCellCoordinates | null
} {
): CanvasCommand[] {
if (interactionData.drag == null) {
return emptyGridRearrangeMoveResult
return []
}

const parentGridPath = EP.parentPath(selectedElement)
const grid = MetadataUtils.findElementByElementPath(jsxMetadata, parentGridPath)

if (grid == null) {
return emptyGridRearrangeMoveResult
return []
}

const { gridCellGlobalFrames, containerGridProperties: gridTemplate } =
grid.specialSizeMeasurements
if (gridCellGlobalFrames == null) {
return emptyGridRearrangeMoveResult
return []
}

const mousePos = offsetPoint(interactionData.dragStart, interactionData.drag)
const targetCellData = getClosestGridCellToPoint(gridCellGlobalFrames, mousePos)
const targetCellCoords = targetCellData?.gridCellCoordinates
if (targetCellCoords == null) {
return emptyGridRearrangeMoveResult
return []
}

const draggingFromCellCoords = getClosestGridCellToPoint(
gridCellGlobalFrames,
interactionData.dragStart,
)?.gridCellCoordinates
if (draggingFromCellCoords == null) {
return emptyGridRearrangeMoveResult
return []
}

const originalElementMetadata = MetadataUtils.findElementByElementPath(
jsxMetadata,
selectedElement,
)
if (originalElementMetadata == null) {
return emptyGridRearrangeMoveResult
return []
}

// measured cell coord bounds on the canvas, this is the default when the cell position is not explicitly set
Expand Down Expand Up @@ -180,18 +171,21 @@ export function runGridRearrangeMove(
cellsSortedByPosition: cellsSortedByPosition,
})

const updateGridControlsCommand = showGridControls(
'mid-interaction',
parentGridPath,
targetCellData?.gridCellCoordinates ?? null,
gridCellCoordinates(row, column),
)

switch (moveType) {
case 'absolute': {
const absoluteMoveCommands = gridChildAbsoluteMoveCommands(
MetadataUtils.findElementByElementPath(jsxMetadata, targetElement),
MetadataUtils.getFrameOrZeroRectInCanvasCoords(grid.elementPath, jsxMetadata),
interactionData,
)
return {
commands: absoluteMoveCommands,
targetCell: targetCellData,
targetRootCell: gridCellCoordinates(row, column),
}
return [...absoluteMoveCommands, updateGridControlsCommand]
}
case 'rearrange': {
const targetRootCell = gridCellCoordinates(row, column)
Expand All @@ -204,36 +198,30 @@ export function runGridRearrangeMove(
canvasRect,
interactionData,
)
return {
commands: [
...gridCellMoveCommands,
...absoluteMoveCommands,
reorderElement(
'always',
selectedElement,
absolute(Math.max(indexInSortedCellsForRearrange, 0)),
),
],
targetCell: targetCellData,
targetRootCell: gridCellCoordinates(row, column),
}
return [
...gridCellMoveCommands,
...absoluteMoveCommands,
reorderElement(
'always',
selectedElement,
absolute(Math.max(indexInSortedCellsForRearrange, 0)),
),
updateGridControlsCommand,
]
}
case 'reorder': {
return {
commands: [
reorderElement('always', selectedElement, absolute(possiblyReorderIndex)),
deleteProperties('always', selectedElement, [
PP.create('style', 'gridColumn'),
PP.create('style', 'gridRow'),
PP.create('style', 'gridColumnStart'),
PP.create('style', 'gridColumnEnd'),
PP.create('style', 'gridRowStart'),
PP.create('style', 'gridRowEnd'),
]),
],
targetCell: targetCellData,
targetRootCell: targetCellCoords,
}
return [
reorderElement('always', selectedElement, absolute(possiblyReorderIndex)),
deleteProperties('always', selectedElement, [
PP.create('style', 'gridColumn'),
PP.create('style', 'gridRow'),
PP.create('style', 'gridColumnStart'),
PP.create('style', 'gridColumnEnd'),
PP.create('style', 'gridRowStart'),
PP.create('style', 'gridRowEnd'),
]),
updateGridControlsCommand,
]
}
default:
assertNever(moveType)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,7 @@ export const gridRearrangeMoveDuplicateStrategy: CanvasStrategyFactory = (

const targetElement = EP.appendToPath(EP.parentPath(selectedElement), newUid)

const {
commands: moveCommands,
targetCell,
targetRootCell,
} = runGridRearrangeMove(
const moveCommands = runGridRearrangeMove(
targetElement,
selectedElement,
canvasState.startingMetadata,
Expand All @@ -96,11 +92,6 @@ export const gridRearrangeMoveDuplicateStrategy: CanvasStrategyFactory = (
],
[...selectedElements, targetElement],
{
grid: {
...customState.grid,
targetCellData: targetCell,
currentRootCell: targetRootCell,
},
duplicatedElementNewUids: duplicatedElementNewUids,
},
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ export const gridRearrangeMoveStrategy: CanvasStrategyFactory = (
? getCommandsAndPatchForGridRearrange(
canvasState,
interactionSession.interactionData,
customState,
selectedElement,
)
: getCommandsAndPatchForReparent(
Expand Down Expand Up @@ -165,7 +164,6 @@ export const gridRearrangeMoveStrategy: CanvasStrategyFactory = (
function getCommandsAndPatchForGridRearrange(
canvasState: InteractionCanvasState,
interactionData: DragInteractionData,
customState: CustomStrategyState,
selectedElement: ElementPath,
): {
commands: CanvasCommand[]
Expand All @@ -176,7 +174,7 @@ function getCommandsAndPatchForGridRearrange(
return { commands: [], patch: {}, elementsToRerender: [] }
}

const { commands, targetCell, targetRootCell } = runGridRearrangeMove(
const commands = runGridRearrangeMove(
selectedElement,
selectedElement,
canvasState.startingMetadata,
Expand All @@ -185,13 +183,7 @@ function getCommandsAndPatchForGridRearrange(

return {
commands: commands,
patch: {
grid: {
...customState.grid,
targetCellData: targetCell,
currentRootCell: targetRootCell,
},
},
patch: {},
elementsToRerender: [EP.parentPath(selectedElement)],
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ import { removeAbsolutePositioningProps } from './reparent-helpers/reparent-prop
import type { ReparentTarget } from './reparent-helpers/reparent-strategy-helpers'
import { getReparentOutcome, pathToReparent } from './reparent-utils'
import { flattenSelection } from './shared-move-strategies-helpers'
import { getGridCellUnderMouseFromMetadata, type GridCellCoordinates } from './grid-cell-bounds'
import {
getClosestGridCellToPointFromMetadata,
getGridCellUnderMouseFromMetadata,
type GridCellCoordinates,
} from './grid-cell-bounds'

export function gridReparentStrategy(
reparentTarget: ReparentTarget,
Expand Down Expand Up @@ -195,9 +199,7 @@ export function applyGridReparent(
interactionData.drag ?? canvasVector({ x: 0, y: 0 }),
)

const targetCellData =
getGridCellUnderMouseFromMetadata(grid, mousePos) ??
customStrategyState.grid.targetCellData
const targetCellData = getClosestGridCellToPointFromMetadata(grid, mousePos)

if (targetCellData == null) {
return strategyApplicationResult([], [newParent.intendedParentPath])
Expand Down Expand Up @@ -247,10 +249,6 @@ export function applyGridReparent(
const customStrategyStatePatch = {
...baseCustomState,
elementsToRerender: elementsToRerender,
grid: {
...baseCustomState.grid,
targetCellData: targetCellData,
},
}

return strategyApplicationResult(
Expand All @@ -259,7 +257,12 @@ export function applyGridReparent(
gridContainerCommands,
updateSelectedViews('always', newPaths),
setCursorCommand(CSSCursor.Reparent),
showGridControls('mid-interaction', reparentTarget.newParent.intendedParentPath),
showGridControls(
'mid-interaction',
reparentTarget.newParent.intendedParentPath,
targetCellData.gridCellCoordinates,
null,
),
],
elementsToRerender,
customStrategyStatePatch,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
import type { ElementPath } from 'utopia-shared/src/types'
import type { BaseCommand, CommandFunction, WhenToRun } from './commands'
import type { EditorState, EditorStatePatch } from '../../editor/store/editor-state'
import type { GridCellCoordinates } from '../canvas-strategies/strategies/grid-cell-bounds'

export interface ShowGridControlsCommand extends BaseCommand {
type: 'SHOW_GRID_CONTROLS'
target: ElementPath
targetCell: GridCellCoordinates | null
rootCell: GridCellCoordinates | null
}

export function showGridControls(
whenToRun: WhenToRun,
target: ElementPath,
targetCell: GridCellCoordinates | null,
rootCell: GridCellCoordinates | null,
): ShowGridControlsCommand {
return {
type: 'SHOW_GRID_CONTROLS',
whenToRun: whenToRun,
target: target,
targetCell: targetCell,
rootCell: rootCell,
}
}

Expand All @@ -25,7 +32,13 @@ export const runShowGridControlsCommand: CommandFunction<ShowGridControlsCommand
const editorStatePatch: EditorStatePatch = {
canvas: {
controls: {
gridControls: { $set: command.target },
gridControlData: {
$set: {
grid: command.target,
targetCell: command.targetCell,
rootCell: command.rootCell,
},
},
},
},
}
Expand Down
Loading

0 comments on commit ddc54cb

Please sign in to comment.