Skip to content

Commit

Permalink
feat(composer): add runtime tag settings change support
Browse files Browse the repository at this point in the history
  • Loading branch information
sheilaXu authored and mumanity committed Mar 10, 2023
1 parent bcf37ea commit eeda501
Show file tree
Hide file tree
Showing 26 changed files with 566 additions and 394 deletions.
2 changes: 1 addition & 1 deletion packages/scene-composer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"fix": "eslint --fix .",
"test": "jest --config jest.config.ts --coverage --silent",
"test:dev": "jest --config jest.config.ts --coverage",
"posttest": "jest-coverage-ratchet",
"test:update-threashold": "jest-coverage-ratchet",
"test:coverage": "npm test -- --updateSnapshot --coverage",
"test:update": "jest --config jest.config.ts --updateSnapshot",
"test:unit": "jest --config jest.config.ts",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import { getSceneResourceInfo } from '../../../../utils/sceneResourceUtils';
import svgIconToWidgetSprite from '../common/SvgIconToWidgetSprite';
import { findComponentByType } from '../../../../utils/nodeUtils';
import { Layers } from '../../../../common/constants';
import { componentSettingsSelector } from '../../../../utils/componentSettingsUtils';
import useTagSettings from '../../../../hooks/useTagSettings';

export interface AnchorWidgetProps {
node: ISceneNodeInternal;
Expand Down Expand Up @@ -61,9 +61,7 @@ export function AsyncLoadedAnchorWidget({
dataBindingTemplate,
} = useStore(sceneComposerId)((state) => state);
const isViewing = useStore(sceneComposerId)((state) => state.isViewing());
const tagSettings: ITagSettings = useStore(sceneComposerId)((state) =>
componentSettingsSelector(state, KnownComponentType.Tag),
);
const tagSettings: ITagSettings = useTagSettings();
const autoRescale = useMemo(() => {
return tagSettings.autoRescale;
}, [tagSettings.autoRescale]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ import * as THREE from 'three';
import { useLoader } from '@react-three/fiber';

import { AnchorWidget } from '../AnchorWidget';
import { DefaultAnchorStatus } from '../../../../..';
import { DefaultAnchorStatus, DEFAULT_TAG_GLOBAL_SETTINGS } from '../../../../..';
import { useStore } from '../../../../../store';
import useTagSettings from '../../../../../hooks/useTagSettings';

jest.mock('../../../three-fiber/common/SvgIconToWidgetSprite', () =>
jest.mock('../../common/SvgIconToWidgetSprite', () =>
jest.fn(((data, name, alwaysVisible, props) => <div data-test-id={name} {...props} />) as any),
);

jest.mock('../../../../../hooks/useTagSettings', () => jest.fn());

jest.mock('@react-three/fiber', () => {
const originalModule = jest.requireActual('@react-three/fiber');
return {
Expand All @@ -27,7 +30,6 @@ describe('AnchorWidget', () => {
const setHighlightedSceneNodeRef = jest.fn();
const setSelectedSceneNodeRef = jest.fn();
const getObject3DBySceneNodeRef = jest.fn();
const getSceneProperty = jest.fn();

const node = {
ref: 'test-ref',
Expand All @@ -52,13 +54,12 @@ describe('AnchorWidget', () => {
getEditorConfig: () => ({ onWidgetClick }),
dataInput: 'dataInput' as any,
getObject3DBySceneNodeRef,
getSceneProperty,
} as any);
};

beforeEach(() => {
(useLoader as unknown as jest.Mock).mockReturnValue(['TestSvgData']);
getSceneProperty.mockReturnValue(undefined);
(useTagSettings as jest.Mock).mockReturnValue(DEFAULT_TAG_GLOBAL_SETTINGS);
jest.clearAllMocks();
});

Expand Down Expand Up @@ -98,7 +99,7 @@ describe('AnchorWidget', () => {

it('should render correctly with non default tag settings', () => {
setStore('test-ref', 'test-ref');
getSceneProperty.mockReturnValue({ Tag: { scale: 3, autoRescale: true } });
(useTagSettings as jest.Mock).mockReturnValue({ scale: 3, autoRescale: true });
const container = renderer.create(<AnchorWidget node={node as any} defaultIcon={DefaultAnchorStatus.Info} />);

expect(container).toMatchSnapshot();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ exports[`SceneComposerInternal should render correctly with an empty scene in vi
leftPanel={
<LeftPanel
Hierarchy={<SceneHierarchyPanel />}
Settings={<SettingsPanel />}
/>
}
mainContent={
Expand Down
74 changes: 45 additions & 29 deletions packages/scene-composer/src/components/panels/SettingsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,19 @@ import { getGlobalSettings } from '../../common/GlobalSettings';

import { ExpandableInfoSection } from './CommonPanelComponents';
import { SceneDataBindingTemplateEditor, SceneTagSettingsEditor } from './scene-settings';
import { MotionIndicatorVisibilityToggle } from './scene-settings/MotionIndicatorVisibilityToggle';

export interface SettingsPanelProps {
valueDataBindingProvider?: IValueDataBindingProvider;
}

const NO_PRESET_VALUE = 'n/a';

export const SettingsPanel: React.FC<SettingsPanelProps> = ({ valueDataBindingProvider }) => {
const log = useLifecycleLogging('SettingsPanel');
const sceneComposerId = useContext(sceneComposerIdContext);
const setSceneProperty = useStore(sceneComposerId)((state) => state.setSceneProperty);
const isEditing = useStore(sceneComposerId)((state) => state.isEditing());
const intl = useIntl();

const tagResizeEnabled = getGlobalSettings().featureConfig[COMPOSER_FEATURES.TagResize];
Expand Down Expand Up @@ -51,7 +55,7 @@ export const SettingsPanel: React.FC<SettingsPanelProps> = ({ valueDataBindingPr
});

const presetOptions = [
{ label: intl.formatMessage(i18nPresetsStrings['No Preset']), value: 'n/a' },
{ label: intl.formatMessage(i18nPresetsStrings['No Preset']), value: NO_PRESET_VALUE },
...Object.keys(presets).map((preset) => ({
label: intl.formatMessage(i18nPresetsStrings[preset]) || pascalCase(preset),
value: preset,
Expand All @@ -67,51 +71,63 @@ export const SettingsPanel: React.FC<SettingsPanelProps> = ({ valueDataBindingPr
return (
<Fragment>
<ExpandableInfoSection
title={intl.formatMessage({ description: 'ExpandableInfoSection Title', defaultMessage: 'Scene Settings' })}
title={intl.formatMessage({
description: 'ExpandableInfoSection Title',
defaultMessage: 'Current View Settings',
})}
defaultExpanded
>
<SpaceBetween size='s'>
<FormField
label={intl.formatMessage({ description: 'Form Field label', defaultMessage: 'Environment Preset' })}
>
<Select
selectedOption={selectedOption}
onChange={(e) => {
if (e.detail.selectedOption.value === 'n/a') {
setSceneProperty(KnownSceneProperty.EnvironmentPreset, undefined);
} else {
setSceneProperty(KnownSceneProperty.EnvironmentPreset, e.detail.selectedOption.value);
}
}}
options={presetOptions}
selectedAriaLabel={intl.formatMessage({ defaultMessage: 'Selected', description: 'label' })}
disabled={presetOptions.length === 0}
placeholder={intl.formatMessage({
defaultMessage: 'Choose an environment',
description: 'choose environment placeholder',
})}
expandToViewport
/>
</FormField>
</SpaceBetween>
<MotionIndicatorVisibilityToggle />
</ExpandableInfoSection>

{isEditing && (
<ExpandableInfoSection
title={intl.formatMessage({ description: 'ExpandableInfoSection Title', defaultMessage: 'Scene Settings' })}
defaultExpanded={false}
>
<SpaceBetween size='s'>
<FormField
label={intl.formatMessage({ description: 'Form Field label', defaultMessage: 'Environment Preset' })}
>
<Select
selectedOption={selectedOption}
onChange={(e) => {
if (e.detail.selectedOption.value === NO_PRESET_VALUE) {
setSceneProperty(KnownSceneProperty.EnvironmentPreset, undefined);
} else {
setSceneProperty(KnownSceneProperty.EnvironmentPreset, e.detail.selectedOption.value);
}
}}
options={presetOptions}
selectedAriaLabel={intl.formatMessage({ defaultMessage: 'Selected', description: 'label' })}
disabled={presetOptions.length === 0}
placeholder={intl.formatMessage({
defaultMessage: 'Choose an environment',
description: 'choose environment placeholder',
})}
expandToViewport
/>
</FormField>
</SpaceBetween>
</ExpandableInfoSection>
)}

{tagResizeEnabled && (
<ExpandableInfoSection
title={intl.formatMessage({ description: 'ExpandableInfoSection Title', defaultMessage: 'Tag Settings' })}
defaultExpanded
defaultExpanded={false}
>
<SceneTagSettingsEditor />
</ExpandableInfoSection>
)}

{valueDataBindingProvider && (
{valueDataBindingProvider && isEditing && (
<ExpandableInfoSection
title={intl.formatMessage({
description: 'ExpandableInfoSection Title',
defaultMessage: 'Data Binding Template',
})}
defaultExpanded
defaultExpanded={false}
>
<SceneDataBindingTemplateEditor valueDataBindingProvider={valueDataBindingProvider} />
</ExpandableInfoSection>
Expand Down
37 changes: 2 additions & 35 deletions packages/scene-composer/src/components/panels/TopBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import { useIntl } from 'react-intl';

import { KnownComponentType } from '../../interfaces';
import { sceneComposerIdContext } from '../../common/sceneComposerIdContext';
import { ICameraComponentInternal, useStore, useViewOptionState } from '../../store';
import { Checked } from '../../assets/auto-gen/icons';
import { ICameraComponentInternal, useStore } from '../../store';
import useActiveCamera from '../../hooks/useActiveCamera';
import { findComponentByType } from '../../utils/nodeUtils';
import { getCameraSettings } from '../../utils/cameraUtils';
Expand All @@ -20,10 +19,8 @@ const StyledSpaceBetween = styled(SpaceBetween)`

export const TopBar: FC = () => {
const sceneComposerId = useContext(sceneComposerIdContext);
const { motionIndicatorVisible, toggleMotionIndicatorVisibility } = useViewOptionState(sceneComposerId);
const nodeMap = useStore(sceneComposerId)((state) => state.document.nodeMap);
const getSceneNodeByRef = useStore(sceneComposerId)((state) => state.getSceneNodeByRef);
const getComponentRefByType = useStore(sceneComposerId)((state) => state.getComponentRefByType);
const getObject3DBySceneNodeRef = useStore(sceneComposerId)((state) => state.getObject3DBySceneNodeRef);
const { setActiveCameraSettings } = useActiveCamera();
const intl = useIntl();
Expand All @@ -42,19 +39,7 @@ export const TopBar: FC = () => {
}, [nodeMap]);

const hasCameraView = cameraItems.length > 0;
const hasMotionIndicator = Object.keys(getComponentRefByType(KnownComponentType.MotionIndicator)).length > 0;
const showTopBar = hasMotionIndicator || hasCameraView;

const settingsOnItemClick = useCallback(
({ detail }) => {
switch (detail.id) {
case KnownComponentType.MotionIndicator:
toggleMotionIndicatorVisibility();
break;
}
},
[toggleMotionIndicatorVisibility],
);
const showTopBar = hasCameraView;

const setActiveCameraOnItemClick = useCallback(
({ detail }) => {
Expand All @@ -70,24 +55,6 @@ export const TopBar: FC = () => {
if (showTopBar) {
return (
<StyledSpaceBetween direction='horizontal' size='xxs'>
{hasMotionIndicator && (
<ButtonDropdown
data-testid='view-options'
items={[
{
id: KnownComponentType.MotionIndicator,
text: intl.formatMessage({
defaultMessage: 'Motion indicator',
description: 'dropdown button option text for motion indicator component',
}),
iconSvg: motionIndicatorVisible ? <Checked /> : <></>,
},
]}
onItemClick={settingsOnItemClick}
>
{intl.formatMessage({ defaultMessage: 'View Options', description: 'view options dropdown button text' })}
</ButtonDropdown>
)}
{hasCameraView && (
<ButtonDropdown data-testid='camera-views' items={cameraItems} onItemClick={setActiveCameraOnItemClick}>
{intl.formatMessage({ defaultMessage: 'Camera View', description: 'camera views dropdown button text' })}
Expand Down
Loading

0 comments on commit eeda501

Please sign in to comment.