Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions editor/src/components/canvas/canvas-external-store.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from 'react'
import { DefaultThirdPartyControlDefinitions } from '../../core/third-party/third-party-controls'
import type { PropertyControlsInfo } from '../custom-code/code-file'
import { Substores, useEditorState } from '../editor/store/store-hook'
import { useDispatch } from '../editor/store/dispatch-context'
import { updatePropertyControlsInfo } from '../editor/actions/action-creators'

export const PropertyControlsExportedForTestInspection: { current: PropertyControlsInfo } = {
current: {},
}

let listeners: Array<() => void> = []

export const propControlsStore = {
setPropertyControls(propertyControls: PropertyControlsInfo) {
PropertyControlsExportedForTestInspection.current = propertyControls
emitChange()
},
subscribe(listener: () => void) {
listeners = [...listeners, listener]
return () => {
listeners = listeners.filter((l) => l !== listener)
}
},
getSnapshot(): PropertyControlsInfo {
return PropertyControlsExportedForTestInspection.current
},
}

function emitChange() {
for (let listener of listeners) {
listener()
}
}

export function usePropertyControlsInfo(): PropertyControlsInfo {
// TODO don't forget about DefaultThirdPartyControlDefinitions
return React.useSyncExternalStore(propControlsStore.subscribe, propControlsStore.getSnapshot)
}

export function useDispatchWhenPropertyControlsInfoChanges() {
const dispatch = useDispatch()

const previousPropControls = React.useRef<PropertyControlsInfo | null>(null)
const propControls = usePropertyControlsInfo()
if (previousPropControls.current !== propControls) {
dispatch([updatePropertyControlsInfo(propControls)])
}

previousPropControls.current = propControls
}
23 changes: 22 additions & 1 deletion editor/src/components/canvas/canvas-globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ import type { Either } from '../../core/shared/either'
import { forEachRight } from '../../core/shared/either'
import { mapArrayToDictionary } from '../../core/shared/array-utils'
import { fastForEach } from '../../core/shared/utils'
import {
PropertyControlsInfoKeepDeepEquality,
PropertyControlsKeepDeepEquality,
} from '../editor/store/store-deep-equality-instances'
import { propControlsStore } from './canvas-external-store'

export type ControlsToCheck = Promise<Either<string, Array<ComponentDescriptorWithName>>>

Expand All @@ -25,6 +30,7 @@ let controlsRegisteredByFileInLastRender: Map<
string,
Array<PropertyControlsInfoToCheck>
> = new Map()
export let registeredPropertyControlsInfo: PropertyControlsInfo = {}

export function addRegisteredControls(
sourceFile: string,
Expand Down Expand Up @@ -126,6 +132,21 @@ export async function validateControlsToCheck(

previousRegisteredModules = allRegisteredModules
if (shouldDispatch) {
dispatch([updatePropertyControlsInfo(updatedPropertyControlsInfo, moduleNamesOrPathsToDelete)])
// dispatch([updatePropertyControlsInfo(updatedPropertyControlsInfo, moduleNamesOrPathsToDelete)])

let wipPropertyControlsInfo: PropertyControlsInfo = {
...registeredPropertyControlsInfo,
...updatedPropertyControlsInfo,
}
for (const moduleNameOrPathToDelete of moduleNamesOrPathsToDelete) {
delete wipPropertyControlsInfo[moduleNameOrPathToDelete]
}

registeredPropertyControlsInfo = PropertyControlsInfoKeepDeepEquality(
registeredPropertyControlsInfo,
wipPropertyControlsInfo,
).value

propControlsStore.setPropertyControls(registeredPropertyControlsInfo)
}
}
1 change: 0 additions & 1 deletion editor/src/components/editor/action-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -860,7 +860,6 @@ export interface SetShortcut {
export interface UpdatePropertyControlsInfo {
action: 'UPDATE_PROPERTY_CONTROLS_INFO'
propertyControlsInfo: PropertyControlsInfo
moduleNamesOrPathsToDelete: Array<string>
}

export interface UpdateText {
Expand Down
2 changes: 0 additions & 2 deletions editor/src/components/editor/actions/action-creators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1352,12 +1352,10 @@ export function setShortcut(shortcutName: string, newKey: Key): SetShortcut {

export function updatePropertyControlsInfo(
propertyControlsInfo: PropertyControlsInfo,
moduleNamesOrPathsToDelete: Array<string>,
): UpdatePropertyControlsInfo {
return {
action: 'UPDATE_PROPERTY_CONTROLS_INFO',
propertyControlsInfo: propertyControlsInfo,
moduleNamesOrPathsToDelete: moduleNamesOrPathsToDelete,
}
}

Expand Down
9 changes: 1 addition & 8 deletions editor/src/components/editor/actions/actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4387,16 +4387,9 @@ export const UPDATE_FNS = {
action: UpdatePropertyControlsInfo,
editor: EditorState,
): EditorState => {
let updatedPropertyControlsInfo: PropertyControlsInfo = {
...editor.propertyControlsInfo,
...action.propertyControlsInfo,
}
for (const moduleNameOrPathToDelete of action.moduleNamesOrPathsToDelete) {
delete updatedPropertyControlsInfo[moduleNameOrPathToDelete]
}
return {
...editor,
propertyControlsInfo: updatedPropertyControlsInfo,
propertyControlsInfo: action.propertyControlsInfo,
}
},
UPDATE_TEXT: (action: UpdateText, editorStore: EditorStoreUnpatched): EditorStoreUnpatched => {
Expand Down
4 changes: 4 additions & 0 deletions editor/src/components/editor/editor-component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ import { CommentMaintainer } from '../../core/commenting/comment-maintainer'
import { useIsLoggedIn, useLiveblocksConnectionListener } from '../../core/shared/multiplayer-hooks'
import { ForkSearchParamKey, ProjectForkFlow } from './project-fork-flow'
import { isRoomId, projectIdToRoomId } from '../../utils/room-id'
import { useDispatchWhenPropertyControlsInfoChanges } from '../canvas/canvas-external-store'

const liveModeToastId = 'play-mode-toast'

Expand Down Expand Up @@ -102,6 +103,9 @@ export interface EditorProps {}
export const EditorComponentInner = React.memo((props: EditorProps) => {
const room = useRoom()
const dispatch = useDispatch()

useDispatchWhenPropertyControlsInfoChanges()

const editorStoreRef = useRefEditorState((store) => store)
const metadataRef = useRefEditorState((store) => store.editor.jsxMetadata)
const navigatorTargetsRef = useRefEditorState((store) => store.derived.navigatorTargets)
Expand Down