Skip to content

Commit a1c5020

Browse files
authored
Remove self-contained GLTF/GLB asset (#569)
* feat: add assset removal * feat: add Modal component + use it on ProjectAssetExplorer * fix: comments
1 parent f7826d6 commit a1c5020

File tree

27 files changed

+280
-40
lines changed

27 files changed

+280
-40
lines changed

packages/@dcl/inspector/package-lock.json

Lines changed: 51 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@dcl/inspector/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"@types/node": "^18.11.18",
1717
"@types/react": "^18.0.27",
1818
"@types/react-dom": "^18.0.10",
19+
"@types/react-modal": "^3.16.0",
1920
"@vscode/webview-ui-toolkit": "^1.2.2",
2021
"@well-known-components/pushable-channel": "^1.0.3",
2122
"classnames": "^2.3.2",
@@ -30,6 +31,7 @@
3031
"react-dnd-html5-backend": "^16.0.1",
3132
"react-dom": "^18.2.0",
3233
"react-icons": "^4.7.1",
34+
"react-modal": "^3.16.1",
3335
"typescript": "^5.0.2"
3436
},
3537
"files": [

packages/@dcl/inspector/src/components/App/App.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { Toolbar } from '../Toolbar'
1515
import './App.css'
1616
import { Resizable } from '../Resizable'
1717
import ImportAsset from '../ImportAsset'
18+
import { fileSystemEvent } from '../../hooks/catalog/useFileSystem'
1819

1920
enum Tab {
2021
FileSystem = 'FileSystem',
@@ -33,6 +34,11 @@ const App = () => {
3334
[tab]
3435
)
3536

37+
const handleSave = useCallback(() => {
38+
setTab(Tab.FileSystem)
39+
fileSystemEvent.emit('change')
40+
}, [])
41+
3642
return (
3743
<Resizable type="horizontal" min={300} initial={300}>
3844
<Box>
@@ -56,7 +62,7 @@ const App = () => {
5662
<div className="footer-content">
5763
{tab === Tab.AssetsPack && catalog && <AssetsCatalog value={catalog} />}
5864
{tab === Tab.FileSystem && <ProjectAssetExplorer onImportAsset={handleTabClick(Tab.Import)} />}
59-
{tab === Tab.Import && <ImportAsset onSave={handleTabClick(Tab.FileSystem)} />}
65+
{tab === Tab.Import && <ImportAsset onSave={handleSave} />}
6066
</div>
6167
)}
6268
<div className="footer-buttons">

packages/@dcl/inspector/src/components/Block/Block.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,9 @@
1414
flex-direction: row;
1515
flex-grow: 1;
1616
}
17+
18+
.Block.error {
19+
border: 1px var(--primary) dashed;
20+
padding: 0 5px 8px 5px;
21+
border-radius: 2px;
22+
}

packages/@dcl/inspector/src/components/Block/Block.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import React from 'react'
2+
import cx from 'classnames'
23

34
import { Props } from './types'
45

56
import './Block.css'
67

7-
const Block = React.forwardRef<null, React.PropsWithChildren<Props>>(({ label, children }, ref) => {
8+
const Block = React.forwardRef<null, React.PropsWithChildren<Props>>(({ label, error, children }, ref) => {
89
return (
9-
<div ref={ref} className="Block">
10+
<div ref={ref} className={cx("Block", { error })}>
1011
{label && <label>{label}</label>}
1112
<div className="content">{children}</div>
1213
</div>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export type Props = {
22
label?: string
3+
error?: boolean
34
}

packages/@dcl/inspector/src/components/Button/Button.css

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,17 @@
2424
width: 24px;
2525
height: 24px;
2626
}
27+
28+
.Button.big {
29+
padding: 16px;
30+
font-size: 16px;
31+
}
32+
33+
.Button.danger {
34+
background-color: var(--primary);
35+
}
36+
37+
.Button.danger:hover,
38+
.Button.danger.active {
39+
background-color: var(--primary-darker)
40+
}
Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
import React from 'react'
2-
import classNames from 'classnames'
1+
import cx from 'classnames'
32

43
import { PropTypes } from './types'
54
import './Button.css'
65

7-
function Button(props: PropTypes) {
6+
function Button({ size, type, ...props }: PropTypes) {
87
return (
9-
<button {...props} className={classNames('Button', props.className)}>
8+
<button {...props} className={cx('Button', size, type, props.className)}>
109
{props.children}
1110
</button>
1211
)
1312
}
1413

15-
export default Button
14+
export default Button
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
1-
export type PropTypes = React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
1+
type Button = React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
2+
3+
export type PropTypes = Omit<Button, 'type' | 'size'> & {
4+
type?: 'danger' | 'etc'
5+
size?: 'big' | 'etc'
6+
}

packages/@dcl/inspector/src/components/EntityInspector/GltfInspector/GltfInspector.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,19 @@ const DROP_TYPES = ['project-asset-gltf']
2121

2222
export default withSdk<Props>(
2323
withContextMenu<WithSdkProps & Props>(({ sdk, entity, contextMenuId }) => {
24-
const [files] = useFileSystem()
24+
const [files, init] = useFileSystem()
2525
const { handleAction } = useContextMenu()
2626
const { GltfContainer } = sdk.components
2727

2828
const hasGltf = useHasComponent(entity, GltfContainer)
2929
const handleInputValidation = useCallback(({ src }: { src: string }) => isValidInput(files, src), [files])
30-
const getInputProps = useComponentInput(entity, GltfContainer, fromGltf, toGltf, handleInputValidation)
30+
const { getInputProps, isValid } = useComponentInput(entity, GltfContainer, fromGltf, toGltf, handleInputValidation, [files])
3131

3232
const handleRemove = useCallback(() => GltfContainer.deleteFrom(entity), [])
33-
const handleDrop = useCallback((src: string) => {
34-
GltfContainer.createOrReplace(entity, { src })
33+
const handleDrop = useCallback(async (src: string) => {
34+
const { operations } = sdk
35+
operations.updateValue(GltfContainer, entity, { src })
36+
await operations.dispatch()
3537
}, [])
3638

3739
const [{ isHover }, drop] = useDrop(
@@ -56,15 +58,17 @@ export default withSdk<Props>(
5658

5759
if (!hasGltf) return null
5860

61+
const inputProps = getInputProps('src')
62+
5963
return (
6064
<Container label="Gltf" className={cx('Gltf', { hover: isHover })}>
6165
<Menu id={contextMenuId}>
6266
<Item id="delete" onClick={handleAction(handleRemove)}>
6367
<DeleteIcon /> Delete
6468
</Item>
6569
</Menu>
66-
<Block label="Path" ref={drop}>
67-
<TextField type="text" {...getInputProps('src')} />
70+
<Block label="Path" ref={drop} error={init && !isValid}>
71+
<TextField type="text" {...inputProps} />
6872
</Block>
6973
</Container>
7074
)

packages/@dcl/inspector/src/components/EntityInspector/SceneInspector/SceneInspector.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export default withSdk<Props>(({ sdk, entity }) => {
1111
const { Scene } = sdk.components
1212

1313
const hasScene = useHasComponent(entity, Scene)
14-
const getInputProps = useComponentInput(entity, Scene, fromScene, toScene, isValidInput)
14+
const { getInputProps } = useComponentInput(entity, Scene, fromScene, toScene, isValidInput)
1515

1616
if (!hasScene) {
1717
return null

packages/@dcl/inspector/src/components/EntityInspector/TextField/TextField.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@
2121
.TextField>input {
2222
width: 100%;
2323
color: var(--text);
24-
background-color: var(--transparent-color);
24+
background-color: var(--transparent);
2525
outline: none;
2626
border: none;
2727
}
2828

2929
.TextField:last-child {
3030
margin-right: 0px;
31-
}
31+
}

packages/@dcl/inspector/src/components/EntityInspector/TransformInspector/TransformInspector.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export default withSdk<Props>(
1919
const { Transform } = sdk.components
2020

2121
const hasTransform = useHasComponent(entity, Transform)
22-
const getInputProps = useComponentInput(entity, Transform, fromTransform, toTransform, isValidNumericInput)
22+
const { getInputProps } = useComponentInput(entity, Transform, fromTransform, toTransform, isValidNumericInput)
2323
const { handleAction } = useContextMenu()
2424

2525
const handleRemove = useCallback(() => Transform.deleteFrom(entity), [])
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
.Modal {
2+
position: absolute;
3+
top: 50%;
4+
left: 50%;
5+
margin-right: -50%;
6+
transform: translate(-50%, -50%);
7+
border: 1px solid var(--modal-content-border-color);
8+
background: var(--modal-content-bg-color);
9+
overflow: auto;
10+
border-radius: 3px;
11+
outline: none;
12+
padding: 20px;
13+
min-width: 500px;
14+
min-height: 200px;
15+
display: flex;
16+
flex-direction: column;
17+
justify-content: space-between;
18+
}
19+
20+
.ModalOverlay {
21+
position: fixed;
22+
inset: 0px;
23+
background-color: var(--modal-overlay-bg-color);
24+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import React from 'react'
2+
import _Modal from 'react-modal'
3+
4+
import { Props } from './types'
5+
6+
import './Modal.css'
7+
8+
const Modal = ({
9+
children,
10+
className = '',
11+
overlayClassName = '',
12+
...props
13+
}: Props) => {
14+
return (
15+
<_Modal
16+
ariaHideApp={false}
17+
className={`${className} Modal`}
18+
overlayClassName={`${overlayClassName} ModalOverlay`}
19+
{...props}
20+
>
21+
{children}
22+
</_Modal>
23+
)
24+
}
25+
26+
export default React.memo(Modal)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import Modal from './Modal'
2+
export { Modal }
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import React from 'react'
2+
import Modal from 'react-modal'
3+
4+
export type Props = React.PropsWithChildren<Modal.Props>

packages/@dcl/inspector/src/components/ProjectAssetExplorer/ContextMenu.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
1-
import React from 'react'
21
import { Item } from 'react-contexify'
32
import { AiOutlineFileAdd } from 'react-icons/ai'
43
import { IoIosImage } from 'react-icons/io'
54

65
import { useContextMenu } from '../../hooks/sdk/useContextMenu'
76
import { ROOT, TreeNode } from './ProjectView'
87

9-
function ContextMenu({ value, onImportAsset }: { value: TreeNode | undefined; onImportAsset(): void }) {
8+
interface Props {
9+
value: TreeNode | undefined
10+
onImportAsset(): void
11+
}
12+
13+
function ContextMenu({ value, onImportAsset }: Props) {
1014
const { handleAction } = useContextMenu()
1115

16+
if (value?.type === 'asset') return null
17+
1218
return (
1319
<>
14-
<Item hidden={false} id="new-asset-pack" onClick={handleAction(onImportAsset)}>
20+
<Item id="new-asset-pack" onClick={handleAction(onImportAsset)}>
1521
<AiOutlineFileAdd /> Import new asset
1622
</Item>
1723
<Item hidden={true || value?.name === ROOT} id="new-asset-texture" onClick={handleAction(onImportAsset)}>

packages/@dcl/inspector/src/components/ProjectAssetExplorer/ProjectAssetExplorer.css

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,8 @@
1818

1919
.ProjectView .with-context-menu {
2020
height: 100%;
21-
}
21+
}
22+
23+
.RemoveAsset.Modal > div button {
24+
margin-right: 12px;
25+
}

0 commit comments

Comments
 (0)