diff --git a/editor/src/components/canvas/controls/new-canvas-controls.tsx b/editor/src/components/canvas/controls/new-canvas-controls.tsx
index 9dacd48d7ad5..1d705eff25fc 100644
--- a/editor/src/components/canvas/controls/new-canvas-controls.tsx
+++ b/editor/src/components/canvas/controls/new-canvas-controls.tsx
@@ -66,9 +66,10 @@ import {
import { useSelectionArea } from './selection-area-hooks'
import { RemixSceneLabelControl } from './select-mode/remix-scene-label'
import { NO_OP } from '../../../core/shared/utils'
+import { useIsMyProject } from '../../editor/store/collaborative-editing'
+import { useStatus } from '../../../../liveblocks.config'
import { MultiplayerWrapper } from '../../../utils/multiplayer-wrapper'
import { MultiplayerPresence } from '../multiplayer-presence'
-import { useStatus } from '../../../../liveblocks.config'
export const CanvasControlsContainerID = 'new-canvas-controls-container'
@@ -501,6 +502,8 @@ const NewCanvasControlsInner = (props: NewCanvasControlsInnerProps) => {
})
}
+ const isMyProject = useIsMyProject()
+
const resizeStatus = getResizeStatus()
return (
@@ -531,42 +534,56 @@ const NewCanvasControlsInner = (props: NewCanvasControlsInnerProps) => {
{when(
resizeStatus !== 'disabled',
<>
- {inspectorFocusedControls.map((c) => (
-
- ))}
- {inspectorHoveredControls.map((c) => (
-
- ))}
- {when(
- isSelectMode(editorMode),
- ,
- )}
- {when(isSelectMode(editorMode) && !anyStrategyActive, )}
- {when(isSelectMode(editorMode), )}
{renderHighlightControls()}
- {renderTextEditableControls()}
{unless(dragInteractionActive, )}
- {when(isSelectMode(editorMode), )}
+
{when(
- isSelectOrInsertMode(editorMode) &&
- !EP.multiplePathsAllWithTheSameUID(localSelectedViews),
+ isMyProject,
<>
- {strategyControls.map((c) => (
+ {inspectorFocusedControls.map((c) => (
+
+ ))}
+ {inspectorHoveredControls.map((c) => (
))}
+ {when(
+ isSelectMode(editorMode),
+ ,
+ )}
+ {when(isSelectMode(editorMode) && !anyStrategyActive, )}
+ {when(isSelectMode(editorMode), )}
+ {renderTextEditableControls()}
+ {when(isSelectMode(editorMode), )}
+ {when(
+ isSelectOrInsertMode(editorMode) &&
+ !EP.multiplePathsAllWithTheSameUID(localSelectedViews),
+ <>
+ {strategyControls.map((c) => (
+
+ ))}
+ >,
+ )}
+ {when(isSelectMode(editorMode), )}
+
>,
)}
- {when(isSelectMode(editorMode), )}
-
{when(
roomStatus === 'connected',
diff --git a/editor/src/components/canvas/design-panel-root.tsx b/editor/src/components/canvas/design-panel-root.tsx
index c50b27f8da25..124a88253e5e 100644
--- a/editor/src/components/canvas/design-panel-root.tsx
+++ b/editor/src/components/canvas/design-panel-root.tsx
@@ -20,7 +20,7 @@ import {
import { ConsoleAndErrorsPane } from '../code-editor/console-and-errors-pane'
import { CanvasStrategyInspector } from './canvas-strategies/canvas-strategy-inspector'
import { getQueryParam } from '../../common/env-vars'
-import { unless, when } from '../../utils/react-conditionals'
+import { when } from '../../utils/react-conditionals'
import { InsertMenuPane } from '../navigator/insert-menu-pane'
import { VariablesMenuPane } from '../navigator/variables-menu-pane'
import { useDispatch } from '../editor/store/dispatch-context'
@@ -31,9 +31,7 @@ import { SettingsPane } from '../navigator/left-pane/settings-pane'
import { MenuTab } from '../../uuiui/menu-tab'
import { FlexRow } from 'utopia-api'
import type { StoredPanel } from './stored-layout'
-import { MultiplayerPresence } from './multiplayer-presence'
import { useRoom, useStatus } from '../../../liveblocks.config'
-import { MultiplayerWrapper } from '../../utils/multiplayer-wrapper'
import { isFeatureEnabled } from '../../utils/feature-switches'
import { CommentsPane } from '../inspector/comments-pane'
import { EditorModes, isCommentMode } from '../editor/editor-modes'
diff --git a/editor/src/components/editor/global-shortcuts.tsx b/editor/src/components/editor/global-shortcuts.tsx
index 90d532d60996..8ac03db4f830 100644
--- a/editor/src/components/editor/global-shortcuts.tsx
+++ b/editor/src/components/editor/global-shortcuts.tsx
@@ -686,6 +686,9 @@ export function handleKeyDown(
)
},
[INSERT_DIV_SHORTCUT]: () => {
+ if (!allowedToEdit) {
+ return []
+ }
if (!isSelectMode(editor.mode) && !isInsertMode(editor.mode)) {
return []
}
diff --git a/editor/src/components/editor/store/collaborative-editing.ts b/editor/src/components/editor/store/collaborative-editing.ts
index 2882d09a650b..ba2200e3ac08 100644
--- a/editor/src/components/editor/store/collaborative-editing.ts
+++ b/editor/src/components/editor/store/collaborative-editing.ts
@@ -790,3 +790,11 @@ export function useAllowedToEditProject(): boolean {
'useAllowedToEditProject',
)
}
+
+export function useIsMyProject(): boolean {
+ return useEditorState(
+ Substores.projectServerState,
+ (store) => store.projectServerState.isMyProject === 'yes',
+ 'useIsMyProject',
+ )
+}
diff --git a/editor/src/components/inspector/controls/color-control.tsx b/editor/src/components/inspector/controls/color-control.tsx
index c0dc93c8623f..ea65f96cb403 100644
--- a/editor/src/components/inspector/controls/color-control.tsx
+++ b/editor/src/components/inspector/controls/color-control.tsx
@@ -8,6 +8,7 @@ import type { ControlStyles } from '../common/control-styles'
import type { ControlStatus } from '../common/control-status'
import { useColorTheme, UtopiaTheme } from '../../../uuiui'
import Utils from '../../../utils/utils'
+import { useIsMyProject } from '../../editor/store/collaborative-editing'
export interface ColorControlProps {
value: CSSColor
@@ -81,6 +82,8 @@ export const ColorControl = React.memo((props: ColorControlProps) => {
const closePopup = React.useCallback(() => setPopupOpen(false), [setPopupOpen])
+ const isMyProject = useIsMyProject()
+
const picker = !popupOpen ? null : (
{
value={props.value}
onSubmitValue={props.onSubmitValue}
onTransientSubmitValue={props.onTransientSubmitValue}
+ disabled={!isMyProject}
/>
)
diff --git a/editor/src/components/inspector/controls/color-picker-swatches.tsx b/editor/src/components/inspector/controls/color-picker-swatches.tsx
index 455147947192..7057ec8118d2 100644
--- a/editor/src/components/inspector/controls/color-picker-swatches.tsx
+++ b/editor/src/components/inspector/controls/color-picker-swatches.tsx
@@ -15,6 +15,7 @@ import { useDispatch } from '../../editor/store/dispatch-context'
import type { ColorSwatch } from '../../editor/store/editor-state'
import { Substores, useEditorState } from '../../editor/store/store-hook'
import { cssColorToChromaColorOrDefault } from '../common/css-utils'
+import { useIsMyProject } from '../../editor/store/collaborative-editing'
const { checkerboardBackground } = UtopiaStyles.backgrounds
@@ -53,9 +54,14 @@ export const ColorPickerSwatches = React.memo((props: ColorPickerSwatchesProps)
}
}, [colorSwatches])
+ const isMyProject = useIsMyProject()
+
const toggleEditing = React.useCallback(() => {
+ if (!isMyProject) {
+ return
+ }
setEditing(!editing)
- }, [editing])
+ }, [editing, isMyProject])
const onAddColor = React.useCallback(() => {
if (currentColor == null) {
@@ -106,6 +112,7 @@ export const ColorPickerSwatches = React.memo((props: ColorPickerSwatchesProps)
style={{
padding: '0 6px',
}}
+ disabled={!isMyProject}
onMouseDown={toggleEditing}
>
{when(editing, )}
diff --git a/editor/src/components/inspector/controls/color-picker.tsx b/editor/src/components/inspector/controls/color-picker.tsx
index d01eb28057d6..837564412a84 100644
--- a/editor/src/components/inspector/controls/color-picker.tsx
+++ b/editor/src/components/inspector/controls/color-picker.tsx
@@ -31,6 +31,7 @@ const checkerboardBackground = UtopiaStyles.backgrounds.checkerboardBackground
export interface ColorPickerProps extends ColorPickerInnerProps {
closePopup: () => void
portalTarget?: HTMLElement
+ disabled: boolean
}
export const colorPickerWidth = 290
@@ -96,6 +97,7 @@ export interface ColorPickerInnerProps {
offsetY: number
id: string
testId: string
+ disabled: boolean
}
function toPassedInColorType(
@@ -340,6 +342,9 @@ export class ColorPickerInner extends React.Component<
onMouseDownSV = (e: React.MouseEvent) => {
e.stopPropagation()
+ if (this.props.disabled) {
+ return
+ }
this.setState({
isScrubbing: true,
})
@@ -399,6 +404,9 @@ export class ColorPickerInner extends React.Component<
onHueSliderMouseDown = (e: React.MouseEvent) => {
e.stopPropagation()
+ if (this.props.disabled) {
+ return
+ }
if (this.HueControlRef.current != null) {
this.HueOriginLeft = this.HueControlRef.current.getBoundingClientRect().left
@@ -437,6 +445,10 @@ export class ColorPickerInner extends React.Component<
onAlphaSliderMouseDown = (e: React.MouseEvent) => {
e.stopPropagation()
+ if (this.props.disabled) {
+ return
+ }
+
if (this.AlphaControlRef.current != null) {
this.setState({
isScrubbing: true,
diff --git a/editor/src/components/inspector/controls/option-control.tsx b/editor/src/components/inspector/controls/option-control.tsx
index df1b3518c818..a5c3ad26cee2 100644
--- a/editor/src/components/inspector/controls/option-control.tsx
+++ b/editor/src/components/inspector/controls/option-control.tsx
@@ -6,6 +6,7 @@ import type { DEPRECATEDControlProps, DEPRECATEDGenericControlOptions } from './
import { colorTheme } from '../../../uuiui'
import type { IcnProps } from '../../../uuiui'
import { UtopiaTheme, Tooltip, Icn } from '../../../uuiui'
+import { useIsMyProject } from '../../editor/store/collaborative-editing'
export interface DEPRECATEDOptionControlOptions extends DEPRECATEDGenericControlOptions {
icon?: IcnProps
@@ -60,7 +61,7 @@ export const OptionControl: React.FunctionComponent<
}
}
- const rc = controlOptions.roundCorners
+ const isMyProject = useIsMyProject()
const background = (() => {
if (props.controlStatus === 'overridden' && props.value) {
@@ -133,7 +134,7 @@ export const OptionControl: React.FunctionComponent<
}}
type='checkbox'
checked={isChecked}
- disabled={!props.controlStyles.interactive}
+ disabled={!props.controlStyles.interactive || !isMyProject}
onChange={onSubmitValue}
/>
((props: InspectorProps) => {
'Inspector anyKnownElements',
)
+ const isMyProject = useIsMyProject()
+
function renderInspectorContents() {
return (
@@ -378,18 +380,20 @@ export const Inspector = React.memo((props: InspectorProps) => {
)}
-
{unless(
hideAllSections,
<>
-
+ {when(
+ isMyProject,
+ ,
+ )}
{when(multiselectedContract === 'fragment', )}
{unless(
multiselectedContract === 'fragment',
diff --git a/editor/src/components/inspector/sections/style-section/background-subsection/background-picker.tsx b/editor/src/components/inspector/sections/style-section/background-subsection/background-picker.tsx
index f1e14a0a3704..85b1bcd2d32f 100644
--- a/editor/src/components/inspector/sections/style-section/background-subsection/background-picker.tsx
+++ b/editor/src/components/inspector/sections/style-section/background-subsection/background-picker.tsx
@@ -73,6 +73,7 @@ import { GradientStopsEditor } from './gradient-stop-editor'
import { getIndexedUpdateCSSBackgroundLayerLinearGradientAngle } from './linear-gradient-layer'
import { PickerImagePreview } from './picker-image-preview'
import { setProp_UNSAFE } from '../../../../editor/actions/action-creators'
+import { useIsMyProject } from '../../../../editor/store/collaborative-editing'
const backgroundLayerOptionsByValue: {
[key in CSSBackgroundLayerType]: CSSBackgroundLayerTypeSelectOption
@@ -545,6 +546,8 @@ export const BackgroundPicker: React.FunctionComponent<
}
})()
+ const isMyProject = useIsMyProject()
+
return (
) : (
)
) : null}
diff --git a/editor/src/components/user-bar.tsx b/editor/src/components/user-bar.tsx
index 2da2ed0b3102..f8c63e1afa36 100644
--- a/editor/src/components/user-bar.tsx
+++ b/editor/src/components/user-bar.tsx
@@ -21,6 +21,7 @@ import { showToast, switchEditorMode } from './editor/actions/action-creators'
import { EditorModes, isFollowMode } from './editor/editor-modes'
import { useDispatch } from './editor/store/dispatch-context'
import { Substores, useEditorState } from './editor/store/store-hook'
+import { useIsMyProject } from './editor/store/collaborative-editing'
const MAX_VISIBLE_OTHER_PLAYERS = 4
@@ -58,11 +59,8 @@ export const SinglePlayerUserBar = React.memo(() => {
(store) => getUserPicture(store.userState.loginState),
'SinglePlayerUserBar userPicture',
)
- const amIOwner = useEditorState(
- Substores.projectServerState,
- (store) => store.projectServerState.isMyProject === 'yes',
- 'SinglePlayerUserBar amIOwner',
- )
+ const isMyProject = useIsMyProject()
+
return (
{
}}
>
- {amIOwner ?
: null}
+ {isMyProject ?
: null}
)
})
diff --git a/editor/src/core/performance/__snapshots__/performance-regression-tests.spec.tsx.snap b/editor/src/core/performance/__snapshots__/performance-regression-tests.spec.tsx.snap
index ace17ae7bcdc..121a2b457902 100644
--- a/editor/src/core/performance/__snapshots__/performance-regression-tests.spec.tsx.snap
+++ b/editor/src/core/performance/__snapshots__/performance-regression-tests.spec.tsx.snap
@@ -33,6 +33,7 @@ Array [
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/UtopiaSpiedExoticType(Symbol(react.fragment))",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)()",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)()",
+ "/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/UtopiaSpiedExoticType(Symbol(react.fragment))",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)(MultiplayerPresence)",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)(MultiplayerWrapper)",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/UtopiaSpiedExoticType(Symbol(react.fragment))",
@@ -40,14 +41,14 @@ Array [
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)(SelectionAreaRectangle)",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/UtopiaSpiedExoticType(Symbol(react.fragment))",
"/div/UtopiaSpiedExoticType(Symbol(react.fragment))//Symbol(react.memo)()",
- "/div/UtopiaSpiedExoticType(Symbol(react.fragment))//UtopiaSpiedExoticType(Symbol(react.fragment))",
- "/div/UtopiaSpiedExoticType(Symbol(react.fragment))//Symbol(react.memo)()",
"/div/UtopiaSpiedExoticType(Symbol(react.fragment))//Symbol(react.memo)()",
"/div/UtopiaSpiedExoticType(Symbol(react.fragment))//Symbol(react.memo)()",
"/UtopiaSpiedExoticType(Symbol(react.fragment))///div",
"//div//div:data-testid='multiselect-outline'",
"//div//div:data-testid='multiselect-element-outline-utopia-storyboard-uid/scene-aaa/app-entity:parent/ccc'",
"/div/UtopiaSpiedExoticType(Symbol(react.fragment))//UtopiaSpiedExoticType(Symbol(react.fragment))",
+ "/UtopiaSpiedExoticType(Symbol(react.fragment))/UtopiaSpiedExoticType(Symbol(react.fragment))//Symbol(react.memo)()",
+ "/UtopiaSpiedExoticType(Symbol(react.fragment))/UtopiaSpiedExoticType(Symbol(react.fragment))//UtopiaSpiedExoticType(Symbol(react.fragment))",
"/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)()//Symbol(react.memo)()",
"/Symbol(react.memo)()///Symbol(react.memo)(Symbol(react.forward_ref)())",
"/Symbol(react.memo)()///Symbol(react.memo)(Symbol(react.forward_ref)())",
@@ -645,6 +646,7 @@ Array [
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/UtopiaSpiedExoticType(Symbol(react.fragment))",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)()",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)()",
+ "/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/UtopiaSpiedExoticType(Symbol(react.fragment))",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)(MultiplayerPresence)",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)(MultiplayerWrapper)",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/UtopiaSpiedExoticType(Symbol(react.fragment))",
@@ -652,14 +654,14 @@ Array [
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)(SelectionAreaRectangle)",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/UtopiaSpiedExoticType(Symbol(react.fragment))",
"/div/UtopiaSpiedExoticType(Symbol(react.fragment))//Symbol(react.memo)()",
- "/div/UtopiaSpiedExoticType(Symbol(react.fragment))//UtopiaSpiedExoticType(Symbol(react.fragment))",
- "/div/UtopiaSpiedExoticType(Symbol(react.fragment))//Symbol(react.memo)()",
"/div/UtopiaSpiedExoticType(Symbol(react.fragment))//Symbol(react.memo)()",
"/div/UtopiaSpiedExoticType(Symbol(react.fragment))//Symbol(react.memo)()",
"/UtopiaSpiedExoticType(Symbol(react.fragment))///div",
"//div//div:data-testid='multiselect-outline'",
"//div//div:data-testid='multiselect-element-outline-utopia-storyboard-uid/scene-aaa/app-entity:parent/ccc'",
"/div/UtopiaSpiedExoticType(Symbol(react.fragment))//UtopiaSpiedExoticType(Symbol(react.fragment))",
+ "/UtopiaSpiedExoticType(Symbol(react.fragment))/UtopiaSpiedExoticType(Symbol(react.fragment))//Symbol(react.memo)()",
+ "/UtopiaSpiedExoticType(Symbol(react.fragment))/UtopiaSpiedExoticType(Symbol(react.fragment))//UtopiaSpiedExoticType(Symbol(react.fragment))",
"/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)()//Symbol(react.memo)()",
"/Symbol(react.memo)()///Symbol(react.memo)(Symbol(react.forward_ref)())",
"/Symbol(react.memo)()///Symbol(react.memo)(Symbol(react.forward_ref)())",
@@ -1198,6 +1200,7 @@ Array [
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/UtopiaSpiedExoticType(Symbol(react.fragment))",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)()",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)()",
+ "/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/UtopiaSpiedExoticType(Symbol(react.fragment))",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)(MultiplayerPresence)",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)(MultiplayerWrapper)",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/UtopiaSpiedExoticType(Symbol(react.fragment))",
@@ -1508,6 +1511,7 @@ Array [
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/UtopiaSpiedExoticType(Symbol(react.fragment))",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)()",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)()",
+ "/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/UtopiaSpiedExoticType(Symbol(react.fragment))",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)(MultiplayerPresence)",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)(MultiplayerWrapper)",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/UtopiaSpiedExoticType(Symbol(react.fragment))",
@@ -1952,6 +1956,7 @@ Array [
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/UtopiaSpiedExoticType(Symbol(react.fragment))",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)()",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)()",
+ "/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/UtopiaSpiedExoticType(Symbol(react.fragment))",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)(MultiplayerPresence)",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)(MultiplayerWrapper)",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/UtopiaSpiedExoticType(Symbol(react.fragment))",
@@ -2251,6 +2256,7 @@ Array [
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/UtopiaSpiedExoticType(Symbol(react.fragment))",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)()",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)()",
+ "/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/UtopiaSpiedExoticType(Symbol(react.fragment))",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)(MultiplayerPresence)",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/Symbol(react.memo)(MultiplayerWrapper)",
"/div/div/UtopiaSpiedFunctionComponent(NewCanvasControlsInner)/UtopiaSpiedExoticType(Symbol(react.fragment))",
diff --git a/editor/src/core/performance/performance-regression-tests.spec.tsx b/editor/src/core/performance/performance-regression-tests.spec.tsx
index 07edcc7e4de8..4e1a16d9608d 100644
--- a/editor/src/core/performance/performance-regression-tests.spec.tsx
+++ b/editor/src/core/performance/performance-regression-tests.spec.tsx
@@ -65,7 +65,7 @@ describe('React Render Count Tests -', () => {
const renderCountAfter = renderResult.getNumberOfRenders()
// if this breaks, GREAT NEWS but update the test please :)
- expect(renderCountAfter - renderCountBefore).toMatchInlineSnapshot(`704`)
+ expect(renderCountAfter - renderCountBefore).toMatchInlineSnapshot(`706`)
expect(renderResult.getRenderInfo()).toMatchSnapshot()
})
@@ -127,7 +127,7 @@ describe('React Render Count Tests -', () => {
const renderCountAfter = renderResult.getNumberOfRenders()
// if this breaks, GREAT NEWS but update the test please :)
- expect(renderCountAfter - renderCountBefore).toMatchInlineSnapshot(`749`)
+ expect(renderCountAfter - renderCountBefore).toMatchInlineSnapshot(`751`)
expect(renderResult.getRenderInfo()).toMatchSnapshot()
})
@@ -183,7 +183,7 @@ describe('React Render Count Tests -', () => {
const renderCountAfter = renderResult.getNumberOfRenders()
// if this breaks, GREAT NEWS but update the test please :)
- expect(renderCountAfter - renderCountBefore).toMatchInlineSnapshot(`535`)
+ expect(renderCountAfter - renderCountBefore).toMatchInlineSnapshot(`536`)
expect(renderResult.getRenderInfo()).toMatchSnapshot()
})
@@ -249,7 +249,7 @@ describe('React Render Count Tests -', () => {
const renderCountAfter = renderResult.getNumberOfRenders()
// if this breaks, GREAT NEWS but update the test please :)
- expect(renderCountAfter - renderCountBefore).toMatchInlineSnapshot(`607`)
+ expect(renderCountAfter - renderCountBefore).toMatchInlineSnapshot(`608`)
expect(renderResult.getRenderInfo()).toMatchSnapshot()
})
})
diff --git a/editor/src/uuiui/inputs/number-input.tsx b/editor/src/uuiui/inputs/number-input.tsx
index 20f0adfe78cb..db5e7cf393b0 100644
--- a/editor/src/uuiui/inputs/number-input.tsx
+++ b/editor/src/uuiui/inputs/number-input.tsx
@@ -50,6 +50,7 @@ import {
InspectorInput,
} from './base-input'
import { usePropControlledStateV2 } from '../../components/inspector/common/inspector-utils'
+import { useIsMyProject } from '../../components/editor/store/collaborative-editing'
export type LabelDragDirection = 'horizontal' | 'vertical'
@@ -188,6 +189,8 @@ export const NumberInput = React.memo(
const ref = React.useRef(null)
const colorTheme = useColorTheme()
+ const isMyProject = useIsMyProject()
+
const controlStyles = React.useMemo((): ControlStyles => {
return {
...getControlStyles(controlStatus),
@@ -553,6 +556,9 @@ export const NumberInput = React.memo(
const onIncrementMouseDown = React.useCallback(
(e: React.MouseEvent) => {
+ if (!isMyProject) {
+ return
+ }
if (e.button === 0) {
e.stopPropagation()
setIsFauxcused(true)
@@ -564,7 +570,7 @@ export const NumberInput = React.memo(
}, repeatThreshold)
}
},
- [incrementBy, stepSize, repeatIncrement, onIncrementMouseUp],
+ [incrementBy, stepSize, repeatIncrement, onIncrementMouseUp, isMyProject],
)
const onDecrementMouseUp = React.useCallback(() => {
@@ -596,6 +602,9 @@ export const NumberInput = React.memo(
const onDecrementMouseDown = React.useCallback(
(e: React.MouseEvent) => {
+ if (!isMyProject) {
+ return
+ }
if (e.button === 0) {
e.stopPropagation()
setIsFauxcused(true)
@@ -608,11 +617,14 @@ export const NumberInput = React.memo(
)
}
},
- [incrementBy, stepSize, repeatIncrement, onDecrementMouseUp],
+ [incrementBy, stepSize, repeatIncrement, onDecrementMouseUp, isMyProject],
)
const onLabelMouseDown = React.useCallback(
(e: React.MouseEvent) => {
+ if (!isMyProject) {
+ return
+ }
if (e.button === 0) {
e.stopPropagation()
setIsFauxcused(true)
@@ -625,7 +637,7 @@ export const NumberInput = React.memo(
setGlobalCursor?.(CSSCursor.ResizeEW)
}
},
- [scrubOnMouseMove, scrubOnMouseUp, setGlobalCursor, value],
+ [scrubOnMouseMove, scrubOnMouseUp, setGlobalCursor, value, isMyProject],
)
const placeholder = getControlStylesAwarePlaceholder(controlStyles)
@@ -678,6 +690,7 @@ export const NumberInput = React.memo(
controlStyles={controlStyles}
controlStatus={controlStatus}
testId={testId}
+ disabled={!isMyProject}
focused={isFocused}
hasLabel={labelInner != null}
roundCorners={roundCorners}
diff --git a/editor/src/uuiui/inputs/string-input.spec.browser2.tsx b/editor/src/uuiui/inputs/string-input.spec.browser2.tsx
index 5be069859643..862b30a9f3ff 100644
--- a/editor/src/uuiui/inputs/string-input.spec.browser2.tsx
+++ b/editor/src/uuiui/inputs/string-input.spec.browser2.tsx
@@ -3,6 +3,10 @@ import type { RenderResult } from '@testing-library/react'
import { render } from '@testing-library/react'
import React from 'react'
import { StringInput } from './string-input'
+import {
+ TestInspectorContextProvider,
+ getStoreHook,
+} from '../../components/inspector/common/inspector.test-utils'
describe('StringInput', () => {
function checkPlaceholder(renderResult: RenderResult, expectedPlaceholder: string | null): void {
@@ -14,36 +18,62 @@ describe('StringInput', () => {
}
}
it('ensures that no placeholder property shows in the input field by default', () => {
- const result = render()
+ const storeHookForTest = getStoreHook()
+ const result = render(
+
+
+ ,
+ )
checkPlaceholder(result, null)
})
it('ensures that the placeholder property shows in the input field', () => {
+ const storeHookForTest = getStoreHook()
const result = render(
- ,
+
+
+ ,
)
checkPlaceholder(result, 'this is a placeholder')
})
it('ensures that the unknown control styles property shows in the input field', () => {
+ const storeHookForTest = getStoreHook()
const result = render(
- ,
+
+
+ ,
)
checkPlaceholder(result, 'Unknown')
})
it('ensures that the mixed control styles property shows in the input field', () => {
+ const storeHookForTest = getStoreHook()
const result = render(
- ,
+
+
+ ,
)
checkPlaceholder(result, 'Mixed')
})
diff --git a/editor/src/uuiui/inputs/string-input.tsx b/editor/src/uuiui/inputs/string-input.tsx
index 6091078de75d..670e7f9d68b3 100644
--- a/editor/src/uuiui/inputs/string-input.tsx
+++ b/editor/src/uuiui/inputs/string-input.tsx
@@ -10,6 +10,7 @@ import { getControlStyles } from '../../components/inspector/common/control-styl
import { preventDefault, stopPropagation } from '../../components/inspector/common/inspector-utils'
import { useColorTheme } from '../styles/theme'
import { InspectorInputEmotionStyle, getControlStylesAwarePlaceholder } from './base-input'
+import { useIsMyProject } from '../../components/editor/store/collaborative-editing'
interface StringInputOptions {
focusOnMount?: boolean
@@ -50,8 +51,10 @@ export const StringInput = React.memo(
}
}, [focusOnMount, ref])
+ const isMyProject = useIsMyProject()
+
const controlStyles: ControlStyles = getControlStyles(controlStatus)
- const disabled = !controlStyles.interactive
+ const disabled = !controlStyles.interactive || !isMyProject
const inputPropsKeyDown = inputProps.onKeyDown
diff --git a/editor/src/uuiui/widgets/popup-list/popup-list.tsx b/editor/src/uuiui/widgets/popup-list/popup-list.tsx
index 42772638e642..d938c2ea8771 100644
--- a/editor/src/uuiui/widgets/popup-list/popup-list.tsx
+++ b/editor/src/uuiui/widgets/popup-list/popup-list.tsx
@@ -27,6 +27,7 @@ import type { ControlStyles, SelectOption } from '../../../uuiui-deps'
import { CommonUtils, getControlStyles } from '../../../uuiui-deps'
import { SmallerIcons } from '../../../uuiui/icons'
import { Tooltip } from '../../tooltip'
+import { useIsMyProject } from '../../../components/editor/store/collaborative-editing'
type ContainerMode = 'default' | 'showBorderOnHover' | 'noBorder'
@@ -587,10 +588,13 @@ export const PopupList = React.memo(
style,
containerMode = 'default',
controlStyles = getControlStyles('simple'),
- disabled = !controlStyles.interactive,
+ disabled: initialDisabled,
},
ref,
) => {
+ const isMyProject = useIsMyProject()
+ const disabled = initialDisabled || !controlStyles.interactive || !isMyProject
+
const selectOnSubmitValue = React.useCallback(
(newValue: ValueType) => {
if (isOptionType(newValue)) {