Skip to content

Commit

Permalink
fix(composer): matterport integration bug fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
mukeshsahay committed Apr 17, 2023
1 parent d84db01 commit 701531f
Show file tree
Hide file tree
Showing 14 changed files with 213 additions and 66 deletions.
34 changes: 17 additions & 17 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions packages/scene-composer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@
"@formatjs/ts-transformer": "3.9.11",
"@iot-app-kit/core": "5.5.1",
"@iot-app-kit/related-table": "5.5.1",
"@matterport/r3f": "^0.1.0",
"@matterport/webcomponent": "^0.1.2",
"@matterport/r3f": "^0.2.1",
"@matterport/webcomponent": "^0.1.21",
"@react-three/drei": "9.56.27",
"@react-three/fiber": "^8.11.5",
"@react-three/postprocessing": "2.6.2",
Expand Down
4 changes: 2 additions & 2 deletions packages/scene-composer/src/common/GlobalSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const globalSettings: {
featureConfig: FeatureConfig;
getSceneObjectFunction: GetSceneObjectFunction | undefined;
twinMakerSceneMetadataModule: TwinMakerSceneMetadataModule | undefined;
matterportSdks: Record<string, MpSdk>;
matterportSdks: Record<string, MpSdk | undefined>;
} = {
debugMode: false,
dracoDecoder: { enable: true },
Expand Down Expand Up @@ -66,7 +66,7 @@ export const setTwinMakerSceneMetadataModule = (twinMakerSceneMetadataModule: Tw
notifySubscribers();
};

export const setMatterportSdk = (sceneId: string, sdk: MpSdk): void => {
export const setMatterportSdk = (sceneId: string, sdk?: MpSdk): void => {
globalSettings.matterportSdks[sceneId] = sdk;
notifySubscribers();
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ import { MatterportTagSync } from './MatterportTagSync';
export const MatterportIntegration: React.FC = () => {
const intl = useIntl();
const sceneComposerId = useContext(sceneComposerIdContext);

const getSceneProperty = useStore(sceneComposerId)((state) => state.getSceneProperty);
const setSceneProperty = useStore(sceneComposerId)((state) => state.setSceneProperty);

const [focusInput, setFocusInput] = useState(false);
const [matterportModelId, setMatterportModelId] = useState(getSceneProperty(KnownSceneProperty.MatterportModelId));
const matterportModelId = useStore(sceneComposerId)((state) =>
state.getSceneProperty(KnownSceneProperty.MatterportModelId),
);
const [matterportModelIdInternal, setMatterportModelIdInternal] = useState(matterportModelId);

const [connectionOptions, setConnectionOptions] = useState<{ label: string; value: string }[]>([
{
Expand Down Expand Up @@ -67,6 +68,13 @@ export const MatterportIntegration: React.FC = () => {
return () => unsubscribe(onUpdated);
}, []);

// Update internal when matterportModelId in store is changed
useEffect(() => {
if (matterportModelId !== matterportModelIdInternal) {
setMatterportModelIdInternal(matterportModelId);
}
}, [matterportModelId]);

const onConnectionNameChange = useCallback(
async (event) => {
const newConnection = event.detail.selectedOption.value;
Expand All @@ -91,29 +99,33 @@ export const MatterportIntegration: React.FC = () => {
}, [connectionOptions, selectedConnectionName]);

const onInputBlur = useCallback(() => {
if (getSceneProperty(KnownSceneProperty.MatterportModelId) !== matterportModelId) {
setSceneProperty(KnownSceneProperty.MatterportModelId, matterportModelId !== '' ? matterportModelId : undefined);
if (matterportModelId !== matterportModelIdInternal) {
setSceneProperty(
KnownSceneProperty.MatterportModelId,
matterportModelIdInternal !== '' ? matterportModelIdInternal : undefined,
);
}
setFocusInput(false);
}, [matterportModelId, setFocusInput]);
}, [matterportModelIdInternal, setFocusInput]);

const onMatterportModelIdChange = useCallback(
(event) => {
const value = event.detail.value;
if (value !== matterportModelId) {
setMatterportModelId(value);
if (value !== matterportModelIdInternal) {
setMatterportModelIdInternal(value);
}
},
[matterportModelId],
[matterportModelIdInternal],
);

const enableMatterportViewer = !isEmpty(matterportModelId) && selectedConnectionName !== OPTIONS_PLACEHOLDER_VALUE;
const enableMatterportViewer =
!isEmpty(matterportModelIdInternal) && selectedConnectionName !== OPTIONS_PLACEHOLDER_VALUE;

useEffect(() => {
if (!focusInput) {
setMatterportViewerEnabled(enableMatterportViewer);
}
}, [focusInput, matterportModelId, selectedConnectionName]);
}, [focusInput, matterportModelIdInternal, selectedConnectionName]);

return (
<React.Fragment>
Expand Down Expand Up @@ -145,7 +157,7 @@ export const MatterportIntegration: React.FC = () => {
label={intl.formatMessage({ description: 'Form Field label', defaultMessage: 'Matterport Model Id' })}
>
<Input
value={matterportModelId || ''}
value={matterportModelIdInternal || ''}
type='text'
onFocus={() => setFocusInput(true)}
onBlur={onInputBlur}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useCallback } from 'react';
import { useIntl } from 'react-intl';
import { Button } from '@awsui/components-react';
import { Button, Popover, StatusIndicator } from '@awsui/components-react';

import { KnownComponentType } from '../../../interfaces';
import { useSceneComposerId } from '../../../common/sceneComposerIdContext';
Expand All @@ -21,8 +21,8 @@ export const MatterportTagSync: React.FC = () => {
const { mattertagObserver, tagObserver } = useMatterportObserver();

const doSync = useCallback(() => {
const mattertags = mattertagObserver.getMattertags();
const tags = tagObserver.getTags();
const mattertags = mattertagObserver.getMattertags(); // Matterport tags v1
const tags = tagObserver.getTags(); // Matterport tags v2

const tagRecords = getComponentRefByType(KnownComponentType.Tag);
const oldTagMap: Record<string, { nodeRef: string; node: ISceneNodeInternal }> = {};
Expand All @@ -33,10 +33,9 @@ export const MatterportTagSync: React.FC = () => {
}
}

if (mattertags) {
// matterport dictionary is a customer matterport type that doesn't inherit other javascript properties like
// enumerable so use this exact iterable for it only
for (const [key, value] of mattertags) {
// Process Matterport tags v2
if (tags) {
for (const [key, value] of tags) {
if (oldTagMap[key]) {
handleUpdateMatterportTag(oldTagMap[key].nodeRef, oldTagMap[key].node, value);
} else {
Expand All @@ -46,8 +45,16 @@ export const MatterportTagSync: React.FC = () => {
}
}

if (tags) {
for (const [key, value] of tags) {
// Process Matterport tags v1
if (mattertags) {
// matterport dictionary is a customer matterport type that doesn't inherit other javascript properties like
// enumerable so use this exact iterable for it only
for (const [key, value] of mattertags) {
// Process only those tags which are not already taken care by v2 tags version
if (tags && tags[key]) {
continue;
}

if (oldTagMap[key]) {
handleUpdateMatterportTag(oldTagMap[key].nodeRef, oldTagMap[key].node, value);
} else {
Expand All @@ -71,9 +78,21 @@ export const MatterportTagSync: React.FC = () => {

return (
<React.Fragment>
<Button data-testid='matterport-tag-sync-button' onClick={doSync}>
{intl.formatMessage({ defaultMessage: 'Sync Matterport Tags', description: 'matterport tag sync button' })}
</Button>
<Popover
dismissButton={false}
position='top'
size='small'
triggerType='custom'
content={
<StatusIndicator type='success'>
{intl.formatMessage({ defaultMessage: 'Tags sync successful', description: 'Status indicator label' })}
</StatusIndicator>
}
>
<Button data-testid='matterport-tag-sync-button' onClick={doSync}>
{intl.formatMessage({ defaultMessage: 'Sync Matterport Tags', description: 'matterport tag sync button' })}
</Button>
</Popover>
</React.Fragment>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,24 @@
exports[`MatterportIntegration should render correctly 1`] = `
<div>
<div
data-mocked="Button"
data-testid="matterport-tag-sync-button"
data-mocked="Popover"
position="top"
triggertype="custom"
>
Sync Matterport Tags
<div>
<div
data-mocked="StatusIndicator"
type="success"
>
Tags sync successful
</div>
</div>
<div
data-mocked="Button"
data-testid="matterport-tag-sync-button"
>
Sync Matterport Tags
</div>
</div>
</div>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { Html } from '@react-three/drei';

import { ISceneNodeInternal } from '../../../store';
import { sceneComposerIdContext } from '../../../common/sceneComposerIdContext';
import { IDataOverlayComponentInternal } from '../../../store/internalInterfaces';
import { IAnchorComponentInternal, IDataOverlayComponentInternal } from '../../../store/internalInterfaces';
import { KnownComponentType } from '../../../interfaces';

import { DataOverlayContainer } from './DataOverlayContainer';

Expand All @@ -15,12 +16,21 @@ export interface DataOverlayComponentProps {
export const DataOverlayComponent = ({ node, component }: DataOverlayComponentProps): ReactElement => {
const sceneComposerId = useContext(sceneComposerIdContext);

const getOffsetFromTag = () => {
const tagComponent: IAnchorComponentInternal | undefined = node.components.find(
(elem) => elem.type === KnownComponentType.Tag,
);
if (tagComponent) {
return tagComponent.offset;
}
};

return (
<group>
<Html
className='tm-html-wrapper'
// TODO: add position after finding proper way to always display overlay right above tag
// position={position}
position={getOffsetFromTag()}
style={{
transform: 'translate3d(-50%,-100%,0)', // make the center of 3D transform the middle of bottom edge
}}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { ReactElement, useCallback, useContext, useEffect, useRef, useState } from 'react';
import { Button } from '@awsui/components-react';

import { IDataOverlayComponentInternal, ISceneNodeInternal } from '../../../store/internalInterfaces';
import { Component } from '../../../models/SceneModels';
Expand All @@ -14,6 +13,7 @@ import {
tmArrowInner,
tmArrowOuter,
tmCloseButton,
tmCloseButtonDiv,
tmContainer,
tmPanelContainer,
} from './styles';
Expand Down Expand Up @@ -79,8 +79,10 @@ export const DataOverlayContainer = ({ component, node }: DataOverlayContainerPr
style={{ ...tmContainer, ...(isAnnotation ? tmAnnotationContainer : tmPanelContainer) }}
>
{!isAnnotation && !componentVisible && (
<div style={tmCloseButton}>
<Button iconName='close' variant='icon' iconAlign='right' onClick={onClickCloseButton} />
<div style={tmCloseButtonDiv}>
<button style={tmCloseButton} onClick={onClickCloseButton}>
X
</button>
</div>
)}
<DataOverlayRows component={component} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,11 @@ exports[`DataOverlayContainer should render with panel visible correctly when th
<div
style="float: right; margin-top: 8px; margin-right: 8px;"
>
<div
data-mocked="Button"
iconalign="right"
iconname="close"
variant="icon"
/>
<button
style="background-color: transparent; border-color: transparent; color: white;"
>
X
</button>
</div>
<div
data-testid="rows"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,16 @@ export const tmAnnotationContainer: CSSProperties = {
paddingLeft: '12px',
paddingRight: '12px',
};
export const tmCloseButton: CSSProperties = {
export const tmCloseButtonDiv: CSSProperties = {
float: 'right',
marginTop: '8px',
marginRight: '8px',
};
export const tmCloseButton: CSSProperties = {
backgroundColor: 'transparent',
borderColor: 'transparent',
color: 'white',
};

// Overlay panel arrow
export const tmArrow: CSSProperties = {
Expand Down

0 comments on commit 701531f

Please sign in to comment.