diff --git a/editor/src/components/canvas/canvas-strategies/canvas-strategies.spec.browser2.tsx b/editor/src/components/canvas/canvas-strategies/canvas-strategies.spec.browser2.tsx index 3239dcd9cee1..c3dad1aac9a2 100644 --- a/editor/src/components/canvas/canvas-strategies/canvas-strategies.spec.browser2.tsx +++ b/editor/src/components/canvas/canvas-strategies/canvas-strategies.spec.browser2.tsx @@ -176,6 +176,7 @@ describe('Strategy Fitness', () => { const canvasStrategy = findCanvasStrategy( RegisteredCanvasStrategies, pickCanvasStateFromEditorState( + renderResult.getEditorState().editor.selectedViews, renderResult.getEditorState().editor, renderResult.getEditorState().builtInDependencies, ), @@ -226,6 +227,7 @@ describe('Strategy Fitness', () => { const canvasStrategy = findCanvasStrategy( RegisteredCanvasStrategies, pickCanvasStateFromEditorState( + renderResult.getEditorState().editor.selectedViews, renderResult.getEditorState().editor, renderResult.getEditorState().builtInDependencies, ), @@ -313,6 +315,7 @@ describe('Strategy Fitness', () => { const canvasStrategy = findCanvasStrategy( RegisteredCanvasStrategies, pickCanvasStateFromEditorState( + renderResult.getEditorState().editor.selectedViews, renderResult.getEditorState().editor, renderResult.getEditorState().builtInDependencies, ), @@ -363,6 +366,7 @@ describe('Strategy Fitness', () => { const canvasStrategy = findCanvasStrategy( RegisteredCanvasStrategies, pickCanvasStateFromEditorState( + renderResult.getEditorState().editor.selectedViews, renderResult.getEditorState().editor, renderResult.getEditorState().builtInDependencies, ), diff --git a/editor/src/components/canvas/canvas-strategies/canvas-strategies.tsx b/editor/src/components/canvas/canvas-strategies/canvas-strategies.tsx index a43af7b2c7dc..29d4ae683ffc 100644 --- a/editor/src/components/canvas/canvas-strategies/canvas-strategies.tsx +++ b/editor/src/components/canvas/canvas-strategies/canvas-strategies.tsx @@ -81,6 +81,7 @@ import type { ElementPath } from 'utopia-shared/src/types' import { reparentSubjectsForInteractionTarget } from './strategies/reparent-helpers/reparent-strategy-helpers' import { getReparentTargetUnified } from './strategies/reparent-helpers/reparent-strategy-parent-lookup' import { gridRearrangeResizeKeyboardStrategy } from './strategies/grid-rearrange-keyboard-strategy' +import createCachedSelector from 're-reselect' export type CanvasStrategyFactory = ( canvasState: InteractionCanvasState, @@ -197,12 +198,13 @@ export const RegisteredCanvasStrategies: Array = [ ] export function pickCanvasStateFromEditorState( + localSelectedViews: Array, editorState: EditorState, builtInDependencies: BuiltInDependencies, ): InteractionCanvasState { return { builtInDependencies: builtInDependencies, - interactionTarget: getInteractionTargetFromEditorState(editorState), + interactionTarget: getInteractionTargetFromEditorState(editorState, localSelectedViews), projectContents: editorState.projectContents, nodeModules: editorState.nodeModules.files, openFile: editorState.canvas.openFile?.filename, @@ -216,6 +218,7 @@ export function pickCanvasStateFromEditorState( } export function pickCanvasStateFromEditorStateWithMetadata( + localSelectedViews: Array, editorState: EditorState, builtInDependencies: BuiltInDependencies, metadata: ElementInstanceMetadataMap, @@ -223,7 +226,7 @@ export function pickCanvasStateFromEditorStateWithMetadata( ): InteractionCanvasState { return { builtInDependencies: builtInDependencies, - interactionTarget: getInteractionTargetFromEditorState(editorState), + interactionTarget: getInteractionTargetFromEditorState(editorState, localSelectedViews), projectContents: editorState.projectContents, nodeModules: editorState.nodeModules.files, openFile: editorState.canvas.openFile?.filename, @@ -236,7 +239,10 @@ export function pickCanvasStateFromEditorStateWithMetadata( } } -function getInteractionTargetFromEditorState(editor: EditorState): InteractionTarget { +function getInteractionTargetFromEditorState( + editor: EditorState, + localSelectedViews: Array, +): InteractionTarget { switch (editor.mode.type) { case 'insert': return insertionSubjects(editor.mode.subjects) @@ -245,7 +251,7 @@ function getInteractionTargetFromEditorState(editor: EditorState): InteractionTa case 'textEdit': case 'comment': case 'follow': - return targetPaths(editor.selectedViews) + return targetPaths(localSelectedViews) default: assertNever(editor.mode) } @@ -288,17 +294,21 @@ export function getApplicableStrategies( return strategies.flatMap((s) => s(canvasState, interactionSession, customStrategyState)) } -const getApplicableStrategiesSelector = createSelector( - (store: EditorStorePatched) => +const getApplicableStrategiesSelector = createCachedSelector( + (store: EditorStorePatched, _) => optionalMap( (sas) => sas.map((s) => s.strategy), store.strategyState.sortedApplicableStrategies, ), - (store: EditorStorePatched): InteractionCanvasState => { - return pickCanvasStateFromEditorState(store.editor, store.builtInDependencies) + (store: EditorStorePatched, localSelectedViews: Array): InteractionCanvasState => { + return pickCanvasStateFromEditorState( + localSelectedViews, + store.editor, + store.builtInDependencies, + ) }, - (store: EditorStorePatched) => store.editor.canvas.interactionSession, - (store: EditorStorePatched) => store.strategyState.customStrategyState, + (store: EditorStorePatched, _) => store.editor.canvas.interactionSession, + (store: EditorStorePatched, _) => store.strategyState.customStrategyState, ( applicableStrategiesFromStrategyState: Array | null, canvasState: InteractionCanvasState, @@ -316,12 +326,12 @@ const getApplicableStrategiesSelector = createSelector( ) } }, -) +)((_, localSelectedViews: Array) => localSelectedViews.map(EP.toString).join(',')) -function useGetApplicableStrategies(): Array { +function useGetApplicableStrategies(localSelectedViews: Array): Array { return useEditorState( Substores.fullStore, - getApplicableStrategiesSelector, + (store) => getApplicableStrategiesSelector(store, localSelectedViews), 'useGetApplicableStrategies', arrayEqualsByReference, ) @@ -624,8 +634,10 @@ function controlPriorityToNumber(prio: ControlWithProps['priority']): numbe } } -export function useGetApplicableStrategyControls(): Array> { - const applicableStrategies = useGetApplicableStrategies() +export function useGetApplicableStrategyControls( + localSelectedViews: Array, +): Array> { + const applicableStrategies = useGetApplicableStrategies(localSelectedViews) const currentStrategy = useDelayedCurrentStrategy() const currentlyInProgress = useEditorState( Substores.canvas, diff --git a/editor/src/components/canvas/canvas-strategies/strategies/absolute-duplicate-strategy.spec.tsx b/editor/src/components/canvas/canvas-strategies/strategies/absolute-duplicate-strategy.spec.tsx index 39f4ab07acaa..8db594de244a 100644 --- a/editor/src/components/canvas/canvas-strategies/strategies/absolute-duplicate-strategy.spec.tsx +++ b/editor/src/components/canvas/canvas-strategies/strategies/absolute-duplicate-strategy.spec.tsx @@ -74,6 +74,7 @@ function dragByPixelsIsApplicable( return ( absoluteDuplicateStrategy( pickCanvasStateFromEditorStateWithMetadata( + editorState.selectedViews, editorState, createBuiltInDependenciesList(null), metadata, diff --git a/editor/src/components/canvas/canvas-strategies/strategies/absolute-reparent-strategy-canvas.spec.tsx b/editor/src/components/canvas/canvas-strategies/strategies/absolute-reparent-strategy-canvas.spec.tsx index 5031daf5b2b3..e7c5460c10c9 100644 --- a/editor/src/components/canvas/canvas-strategies/strategies/absolute-reparent-strategy-canvas.spec.tsx +++ b/editor/src/components/canvas/canvas-strategies/strategies/absolute-reparent-strategy-canvas.spec.tsx @@ -133,6 +133,7 @@ function reparentElement( } const canvasState = pickCanvasStateFromEditorStateWithMetadata( + editorState.selectedViews, editorState, createBuiltInDependenciesList(null), startingMetadata, diff --git a/editor/src/components/canvas/canvas-strategies/strategies/absolute-reparent-strategy.spec.tsx b/editor/src/components/canvas/canvas-strategies/strategies/absolute-reparent-strategy.spec.tsx index 77328c3d5894..b1832b2f795b 100644 --- a/editor/src/components/canvas/canvas-strategies/strategies/absolute-reparent-strategy.spec.tsx +++ b/editor/src/components/canvas/canvas-strategies/strategies/absolute-reparent-strategy.spec.tsx @@ -202,6 +202,7 @@ function reparentElement( } const canvasState = pickCanvasStateFromEditorStateWithMetadata( + editorState.selectedViews, editorState, createBuiltInDependenciesList(null), startingMetadata, diff --git a/editor/src/components/canvas/canvas-strategies/strategies/absolute-resize-bounding-box-strategy.spec.tsx b/editor/src/components/canvas/canvas-strategies/strategies/absolute-resize-bounding-box-strategy.spec.tsx index dc38cee0ac73..c159ff9fa5c5 100644 --- a/editor/src/components/canvas/canvas-strategies/strategies/absolute-resize-bounding-box-strategy.spec.tsx +++ b/editor/src/components/canvas/canvas-strategies/strategies/absolute-resize-bounding-box-strategy.spec.tsx @@ -52,6 +52,7 @@ function multiselectResizeElements( const strategyResult = absoluteResizeBoundingBoxStrategy( pickCanvasStateFromEditorStateWithMetadata( + initialEditor.selectedViews, initialEditor, createBuiltInDependenciesList(null), metadata, diff --git a/editor/src/components/canvas/canvas-strategies/strategies/convert-to-absolute-and-move-strategy.spec.tsx b/editor/src/components/canvas/canvas-strategies/strategies/convert-to-absolute-and-move-strategy.spec.tsx index 4fac80bc13c9..1d5682e256bd 100644 --- a/editor/src/components/canvas/canvas-strategies/strategies/convert-to-absolute-and-move-strategy.spec.tsx +++ b/editor/src/components/canvas/canvas-strategies/strategies/convert-to-absolute-and-move-strategy.spec.tsx @@ -175,6 +175,7 @@ function dragByPixels( const strategyResultCommands = convertToAbsoluteAndMoveStrategy( pickCanvasStateFromEditorStateWithMetadata( + editorState.selectedViews, editorState, createBuiltInDependenciesList(null), metadata, diff --git a/editor/src/components/canvas/canvas-strategies/strategies/drag-to-insert-metastrategy.tsx b/editor/src/components/canvas/canvas-strategies/strategies/drag-to-insert-metastrategy.tsx index 2804f0f5302d..031162699ef6 100644 --- a/editor/src/components/canvas/canvas-strategies/strategies/drag-to-insert-metastrategy.tsx +++ b/editor/src/components/canvas/canvas-strategies/strategies/drag-to-insert-metastrategy.tsx @@ -394,6 +394,7 @@ function runTargetStrategiesForFreshlyInsertedElement( // because that element is inserted to the storyboard before reparenting to the correct location, // so its index amongst its starting siblings isn't relevant. const canvasState = pickCanvasStateFromEditorStateWithMetadata( + editorState.selectedViews, editorState, builtInDependencies, patchedMetadata, diff --git a/editor/src/components/canvas/canvas-strategies/strategies/draw-to-insert-metastrategy.tsx b/editor/src/components/canvas/canvas-strategies/strategies/draw-to-insert-metastrategy.tsx index 907b6178eed7..0da5cf8ca11a 100644 --- a/editor/src/components/canvas/canvas-strategies/strategies/draw-to-insert-metastrategy.tsx +++ b/editor/src/components/canvas/canvas-strategies/strategies/draw-to-insert-metastrategy.tsx @@ -590,7 +590,11 @@ function runTargetStrategiesForFreshlyInsertedElementToReparent( strategyLifecycle: InteractionLifecycle, startingMetadata: ElementInstanceMetadataMap, ): Array { - const canvasState = pickCanvasStateFromEditorState(editorState, builtInDependencies) + const canvasState = pickCanvasStateFromEditorState( + editorState.selectedViews, + editorState, + builtInDependencies, + ) const rootPath = getRootPath(startingMetadata) if (rootPath == null) { @@ -679,6 +683,7 @@ function runTargetStrategiesForFreshlyInsertedElementToResize( // when actually applying the strategies. If we ever need to pick a resize strategy based on the target // element's index, we will need to update the elementPathTree with the new element and pass it in here. const canvasState = pickCanvasStateFromEditorStateWithMetadata( + editorState.selectedViews, editorState, builtInDependencies, patchedMetadata, diff --git a/editor/src/components/canvas/canvas-strategies/strategies/flex-reparent-to-absolute-strategy.tsx b/editor/src/components/canvas/canvas-strategies/strategies/flex-reparent-to-absolute-strategy.tsx index 39d6fe1b8255..e94bdc502612 100644 --- a/editor/src/components/canvas/canvas-strategies/strategies/flex-reparent-to-absolute-strategy.tsx +++ b/editor/src/components/canvas/canvas-strategies/strategies/flex-reparent-to-absolute-strategy.tsx @@ -109,6 +109,7 @@ export function baseFlexReparentToAbsoluteStrategy( 'always', (editorState, commandLifecycle): Array => { const updatedCanvasState = pickCanvasStateFromEditorState( + editorState.selectedViews, editorState, canvasState.builtInDependencies, ) diff --git a/editor/src/components/canvas/canvas-strategies/strategies/keyboard-interaction.test-utils.tsx b/editor/src/components/canvas/canvas-strategies/strategies/keyboard-interaction.test-utils.tsx index 70478e0390d7..457a84ac9304 100644 --- a/editor/src/components/canvas/canvas-strategies/strategies/keyboard-interaction.test-utils.tsx +++ b/editor/src/components/canvas/canvas-strategies/strategies/keyboard-interaction.test-utils.tsx @@ -80,6 +80,7 @@ export function pressKeys( const strategy = strategyFactoryFunction( pickCanvasStateFromEditorStateWithMetadata( + editorState.selectedViews, editorState, createBuiltInDependenciesList(null), metadata, diff --git a/editor/src/components/canvas/controls/new-canvas-controls.tsx b/editor/src/components/canvas/controls/new-canvas-controls.tsx index b6cead1192f7..be85b3261131 100644 --- a/editor/src/components/canvas/controls/new-canvas-controls.tsx +++ b/editor/src/components/canvas/controls/new-canvas-controls.tsx @@ -274,9 +274,16 @@ interface NewCanvasControlsInnerProps { } const NewCanvasControlsInner = (props: NewCanvasControlsInnerProps) => { + const { + localSelectedViews, + localHighlightedViews, + setLocalSelectedViews, + setLocalHighlightedViews, + } = props + const dispatch = useDispatch() const colorTheme = useColorTheme() - const strategyControls = useGetApplicableStrategyControls() + const strategyControls = useGetApplicableStrategyControls(localSelectedViews) const [inspectorHoveredControls] = useAtom(InspectorHoveredCanvasControls) const [inspectorFocusedControls] = useAtom(InspectorFocusedCanvasControls) @@ -331,12 +338,6 @@ const NewCanvasControlsInner = (props: NewCanvasControlsInnerProps) => { 'NewCanvasControlsInner', ) - const { - localSelectedViews, - localHighlightedViews, - setLocalSelectedViews, - setLocalHighlightedViews, - } = props const cmdKeyPressed = keysPressed['cmd'] ?? false const contextMenuEnabled = !isLiveMode(editorMode) diff --git a/editor/src/components/canvas/controls/select-mode/select-mode-hooks.tsx b/editor/src/components/canvas/controls/select-mode/select-mode-hooks.tsx index 32852623061f..83047c82baf1 100644 --- a/editor/src/components/canvas/controls/select-mode/select-mode-hooks.tsx +++ b/editor/src/components/canvas/controls/select-mode/select-mode-hooks.tsx @@ -1,4 +1,5 @@ import React from 'react' +import ReactDOM from 'react-dom' import { MetadataUtils } from '../../../../core/model/element-metadata-utils' import { uniqBy } from '../../../../core/shared/array-utils' import type { ElementInstanceMetadataMap } from '../../../../core/shared/element-template' @@ -17,6 +18,7 @@ import { selectComponents, setHoveredView, clearHoveredViews, + runDOMWalker, } from '../../../editor/actions/action-creators' import { cancelInsertModeActions } from '../../../editor/actions/meta-actions' import { @@ -58,6 +60,9 @@ import { getAllLockedElementPaths } from '../../../../core/shared/element-lockin import { treatElementAsGroupLike } from '../../canvas-strategies/strategies/group-helpers' import { useCommentModeSelectAndHover } from '../comment-mode/comment-mode-hooks' import { useFollowModeSelectAndHover } from '../follow-mode/follow-mode-hooks' +import { wait } from '../../../../core/model/performance-scripts' +import { IS_TEST_ENVIRONMENT } from '../../../../common/env-vars' +import { isFeatureEnabled } from '../../../../utils/feature-switches' export function isDragInteractionActive(editorState: EditorState): boolean { return editorState.canvas.interactionSession?.interactionData.type === 'DRAG' @@ -640,7 +645,7 @@ function useSelectOrLiveModeSelectAndHover( [innerOnMouseMove, editorStoreRef], ) const mouseHandler = React.useCallback( - (event: React.MouseEvent) => { + async (event: React.MouseEvent) => { const isLeftClick = event.button === 0 const isRightClick = event.type === 'contextmenu' && event.detail === 0 const isCanvasPanIntention = @@ -773,8 +778,10 @@ function useSelectOrLiveModeSelectAndHover( } if (!foundTargetIsSelected) { - // first we only set the selected views for the canvas controls - setSelectedViewsForCanvasControlsOnly(updatedSelection) + // first we only set the selected views for the canvas controls. however this will be clumped together with the dispatch, unless we wait asynchronously before we dispatch + ReactDOM.flushSync(() => { + setSelectedViewsForCanvasControlsOnly(updatedSelection) + }) // In either case cancel insert mode. if (isInsertMode(editorStoreRef.current.editor.mode)) { @@ -789,7 +796,19 @@ function useSelectOrLiveModeSelectAndHover( } } } - dispatch(editorActions) + + if (event.detail === 1 && isFeatureEnabled('Canvas Fast Selection Hack')) { + // If event.detail is 1 that means this is a first click, where it is safe to delay dispatching actions + // to allow the localSelectedViews to be updated. + // For subsequent clicks, we want to dispatch immediately to avoid out of sync event handlers queueing up + + dispatch(editorActions, 'canvas-fast-selection-hack') // first we dispatch only to update the editor state, but not run the expensive parts + await new Promise((resolve) => requestAnimationFrame(resolve)) // the first requestAnimationFrame fires in the same animation frame we are in, so we need to wait one more + await new Promise((resolve) => requestAnimationFrame(resolve)) // the second requestAnimationFrame is fired in the next actual animation frame, at which point it is safe to run the expensive parts + dispatch([runDOMWalker()], 'resume-canvas-fast-selection-hack') // then we dispatch to run the expensive parts + } else { + dispatch(editorActions) + } }, [ dispatch, diff --git a/editor/src/components/editor/action-types.ts b/editor/src/components/editor/action-types.ts index 9ad3c9a4ac96..94190c524369 100644 --- a/editor/src/components/editor/action-types.ts +++ b/editor/src/components/editor/action-types.ts @@ -1446,6 +1446,9 @@ export type DispatchPriority = | 'topmenu' | 'contextmenu' | 'noone' + | 'canvas-fast-selection-hack' + | 'resume-canvas-fast-selection-hack' + export type EditorDispatch = ( actions: ReadonlyArray, priority?: DispatchPriority, diff --git a/editor/src/components/editor/actions/actions.tsx b/editor/src/components/editor/actions/actions.tsx index 4b02829f691a..dc5a7ed77b80 100644 --- a/editor/src/components/editor/actions/actions.tsx +++ b/editor/src/components/editor/actions/actions.tsx @@ -5767,7 +5767,11 @@ export const UPDATE_FNS = { editor: EditorModel, builtInDependencies: BuiltInDependencies, ): EditorModel => { - const canvasState = pickCanvasStateFromEditorState(editor, builtInDependencies) + const canvasState = pickCanvasStateFromEditorState( + editor.selectedViews, + editor, + builtInDependencies, + ) if (areAllSelectedElementsNonAbsolute(action.targets, editor.jsxMetadata)) { const commands = getEscapeHatchCommands( action.targets, diff --git a/editor/src/components/editor/store/dispatch-strategies.tsx b/editor/src/components/editor/store/dispatch-strategies.tsx index 7801ff49e943..0d902f940f66 100644 --- a/editor/src/components/editor/store/dispatch-strategies.tsx +++ b/editor/src/components/editor/store/dispatch-strategies.tsx @@ -79,6 +79,7 @@ export function interactionFinished( newEditorState.elementPathTree, ) const canvasState: InteractionCanvasState = pickCanvasStateFromEditorState( + newEditorState.selectedViews, newEditorState, result.builtInDependencies, ) @@ -156,6 +157,7 @@ export function interactionHardReset( startingMetadata: storedState.unpatchedEditor.jsxMetadata, } const canvasState: InteractionCanvasState = pickCanvasStateFromEditorState( + newEditorState.selectedViews, newEditorState, result.builtInDependencies, ) @@ -244,6 +246,7 @@ export function interactionUpdate( ): HandleStrategiesResult { const newEditorState = result.unpatchedEditor const canvasState: InteractionCanvasState = pickCanvasStateFromEditorState( + newEditorState.selectedViews, newEditorState, result.builtInDependencies, ) @@ -326,6 +329,7 @@ export function interactionStart( newEditorState.elementPathTree, ) const canvasState: InteractionCanvasState = pickCanvasStateFromEditorState( + newEditorState.selectedViews, newEditorState, result.builtInDependencies, ) @@ -437,6 +441,7 @@ function handleUserChangedStrategy( sortedApplicableStrategies: Array, ): HandleStrategiesResult { const canvasState: InteractionCanvasState = pickCanvasStateFromEditorState( + newEditorState.selectedViews, newEditorState, builtInDependencies, ) @@ -517,6 +522,7 @@ function handleAccumulatingKeypresses( sortedApplicableStrategies: Array, ): HandleStrategiesResult { const canvasState: InteractionCanvasState = pickCanvasStateFromEditorState( + newEditorState.selectedViews, newEditorState, builtInDependencies, ) @@ -602,6 +608,7 @@ function handleUpdate( sortedApplicableStrategies: Array, ): HandleStrategiesResult { const canvasState: InteractionCanvasState = pickCanvasStateFromEditorState( + newEditorState.selectedViews, newEditorState, builtInDependencies, ) diff --git a/editor/src/templates/editor.tsx b/editor/src/templates/editor.tsx index da7f5d0b2c6c..0d2aa892c21d 100644 --- a/editor/src/templates/editor.tsx +++ b/editor/src/templates/editor.tsx @@ -424,12 +424,24 @@ export class Editor { ) } + // This is used to temporarily disable updates to the store, for example when we are in the middle of a fast selection hack + temporarilyDisableStoreUpdates = false + boundDispatch = ( dispatchedActions: readonly EditorAction[], priority?: DispatchPriority, ): { entireUpdateFinished: Promise } => { + if ( + priority === 'canvas-fast-selection-hack' && + isFeatureEnabled('Canvas Fast Selection Hack') + ) { + this.temporarilyDisableStoreUpdates = true + } else if (priority === 'resume-canvas-fast-selection-hack') { + this.temporarilyDisableStoreUpdates = false + } + resetDomSamplerExecutionCounts() const Measure = createPerformanceMeasure() Measure.logActions(dispatchedActions) @@ -463,7 +475,8 @@ export class Editor { const shouldUpdateCanvasStore = !dispatchResult.nothingChanged && - !anyCodeAhead(dispatchResult.unpatchedEditor.projectContents) + !anyCodeAhead(dispatchResult.unpatchedEditor.projectContents) && + !this.temporarilyDisableStoreUpdates const updateId = canvasUpdateId++ if (shouldUpdateCanvasStore) { @@ -482,7 +495,9 @@ export class Editor { }) } - const runDomWalker = shouldRunDOMWalker(dispatchedActions, oldEditorState, this.storedState) + const runDomWalker = + shouldRunDOMWalker(dispatchedActions, oldEditorState, this.storedState) && + !this.temporarilyDisableStoreUpdates // run the dom-walker if (runDomWalker) { @@ -603,7 +618,8 @@ export class Editor { shouldUpdateLowPriorityUI( this.storedState.strategyState, ElementsToRerenderGLOBAL.current, - ) + ) && + !this.temporarilyDisableStoreUpdates ) { Measure.taskTime(`Update Low Prio Store ${updateId}`, () => { this.lowPriorityStore.setState( diff --git a/editor/src/utils/feature-switches.ts b/editor/src/utils/feature-switches.ts index 4d48a1772df5..cce2962ef6c7 100644 --- a/editor/src/utils/feature-switches.ts +++ b/editor/src/utils/feature-switches.ts @@ -15,6 +15,7 @@ export type FeatureName = | 'Debug - Print UIDs' | 'Debug – Connections' | 'Condensed Navigator Entries' + | 'Canvas Fast Selection Hack' | 'Roll Your Own' export const AllFeatureNames: FeatureName[] = [ @@ -31,6 +32,7 @@ export const AllFeatureNames: FeatureName[] = [ 'Debug - Print UIDs', 'Debug – Connections', 'Condensed Navigator Entries', + 'Canvas Fast Selection Hack', 'Roll Your Own', ] @@ -47,6 +49,7 @@ let FeatureSwitches: { [feature in FeatureName]: boolean } = { 'Debug - Print UIDs': false, 'Debug – Connections': false, 'Condensed Navigator Entries': !IS_TEST_ENVIRONMENT, + 'Canvas Fast Selection Hack': true, 'Roll Your Own': false, }