Skip to content

Commit

Permalink
feat: Add Visibility action (#762)
Browse files Browse the repository at this point in the history
* feat: Add Visibility action

* feat: Add visibility component

* feat: Add Triggers OnPlayerTriggerArea

* fix: Remove unnecessary replacement for component

* feat: Update @dcl/asset-packs package

* feat: Refactor VisibilityComponent

* refactor: ActionInspector

* fix: Update label text
  • Loading branch information
cyaiox authored Oct 5, 2023
1 parent 5f33809 commit 6a85a0f
Show file tree
Hide file tree
Showing 14 changed files with 302 additions and 107 deletions.
28 changes: 21 additions & 7 deletions packages/@dcl/inspector/package-lock.json

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

2 changes: 1 addition & 1 deletion packages/@dcl/inspector/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"@babylonjs/inspector": "^6.18.0",
"@babylonjs/loaders": "^6.18.0",
"@babylonjs/materials": "^6.18.0",
"@dcl/asset-packs": "^0.0.0-20231004150938.commit-91b2f7d",
"@dcl/asset-packs": "^0.0.0-20231004215238.commit-830aa6e",
"@dcl/ecs": "file:../ecs",
"@dcl/ecs-math": "2.0.2",
"@dcl/mini-rpc": "^1.0.7",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,16 @@
width: 100%;
}

.ActionInspector > .content > .Block > .content > .TweenActionContainer > .row .field.relative {
.ActionInspector > .content > .Block > .content .row .field.inline {
display: flex;
flex-direction: row;
align-items: center;
}

.ActionInspector > .content > .Block > .content > .TweenActionContainer > .row .field.relative input[type='checkbox'] {
.ActionInspector > .content > .Block > .content .row .field.inline input[type='checkbox'] {
margin-right: 9px;
}

.ActionInspector > .content > .Block > .content > .TweenActionContainer > .row .field.relative label {
.ActionInspector > .content > .Block > .content .row .field.inline label {
margin-bottom: 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react'
import { Item } from 'react-contexify'
import { AiFillDelete as DeleteIcon } from 'react-icons/ai'
import { VscQuestion as QuestionIcon, VscTrash as RemoveIcon, VscInfo as InfoIcon } from 'react-icons/vsc'
import {
Action,
ActionType,
getActionTypes,
getPayload,
getJson,
ActionPayload,
getActionSchema
} from '@dcl/asset-packs'
import { Action, ActionType, getActionTypes, getJson, ActionPayload, getActionSchema } from '@dcl/asset-packs'
import { ReadWriteByteBuffer } from '@dcl/ecs/dist/serialization/ByteBuffer'
import { Popup } from 'decentraland-ui/dist/components/Popup/Popup'

Expand All @@ -20,6 +12,7 @@ import { useComponentValue } from '../../../hooks/sdk/useComponentValue'
import { useHasComponent } from '../../../hooks/sdk/useHasComponent'
import { useContextMenu } from '../../../hooks/sdk/useContextMenu'
import { useChange } from '../../../hooks/sdk/useChange'
import { useArrayState } from '../../../hooks/useArrayState'
import { EditorComponentsTypes } from '../../../lib/sdk/components'

import { Block } from '../../Block'
Expand All @@ -34,18 +27,11 @@ import { Button } from '../../Button'
import { PlaySoundAction } from './PlaySoundAction'
import { TweenAction } from './TweenAction'
import { isValidTween } from './TweenAction/utils'
import { getDefaultPayload, getPartialPayload, isStates } from './utils'
import { Props } from './types'

import './ActionInspector.css'

function isStates(maybeStates: any): maybeStates is EditorComponentsTypes['States'] {
return !!maybeStates && 'value' in maybeStates && Array.isArray(maybeStates.value)
}

function getPartialPayload<T extends ActionType>(action: Action) {
return getPayload<T>(action) as Partial<ActionPayload<T>>
}

export default withSdk<Props>(
withContextMenu<Props & WithSdkProps>(({ sdk, entity: entityId, contextMenuId }) => {
const { Actions, States, Counter } = sdk.components
Expand All @@ -56,7 +42,9 @@ export default withSdk<Props>(

const entity = sdk.sceneContext.getEntityOrNull(entityId)
const { handleAction } = useContextMenu()
const [actions, setActions] = useState<Action[]>(componentValue === null ? [] : componentValue.value)
const [actions, addAction, modifyAction, removeAction] = useArrayState<Action>(
componentValue === null ? [] : componentValue.value
)
const [isFocused, setIsFocused] = useState(false)
const [isLoaded, setIsLoaded] = useState(false)
const [states, setStates] = useState<string[]>(States.getOrNull(entityId)?.value || [])
Expand Down Expand Up @@ -109,6 +97,10 @@ export default withSdk<Props>(
const payload = getPartialPayload<ActionType.DECREASE_COUNTER>(action)
return !!payload
}
case ActionType.SET_VISIBILITY: {
const payload = getPartialPayload<ActionType.SET_VISIBILITY>(action)
return !!payload
}
default: {
try {
const payload = getPartialPayload(action)
Expand Down Expand Up @@ -198,114 +190,97 @@ export default withSdk<Props>(
}, [])

const handleAddNewAction = useCallback(() => {
setActions((prev: Action[]) => {
return [...prev, { type: '', name: '', jsonPayload: '{}' }]
})
}, [setActions])
addAction({ type: '', name: '', jsonPayload: '{}' })
}, [addAction])

const handleChangeAnimation = useCallback(
({ target: { value } }: React.ChangeEvent<HTMLSelectElement>, idx: number) => {
setActions((prev: Action[]) => {
const data = [...prev]
data[idx] = {
...data[idx],
jsonPayload: getJson<ActionType.PLAY_ANIMATION>({
animation: value
})
}
return data
modifyAction(idx, {
...actions[idx],
jsonPayload: getJson<ActionType.PLAY_ANIMATION>({
animation: value
})
})
},
[setActions]
[modifyAction, actions]
)

const handleChangeState = useCallback(
({ target: { value } }: React.ChangeEvent<HTMLSelectElement>, idx: number) => {
setActions((prev: Action[]) => {
const data = [...prev]
data[idx] = {
...data[idx],
jsonPayload: getJson<ActionType.SET_STATE>({
state: value
})
}
return data
modifyAction(idx, {
...actions[idx],
jsonPayload: getJson<ActionType.SET_STATE>({
state: value
})
})
},
[setActions]
[modifyAction, actions]
)

const handleChangeTween = useCallback(
(tween: ActionPayload<ActionType.START_TWEEN>, idx: number) => {
setActions((prev: Action[]) => {
const data = [...prev]
data[idx] = {
...data[idx],
jsonPayload: getJson<ActionType.START_TWEEN>(tween)
}
return data
modifyAction(idx, {
...actions[idx],
jsonPayload: getJson<ActionType.START_TWEEN>(tween)
})
},
[setActions]
[modifyAction, actions]
)

const handleChangeSound = useCallback(
(value: ActionPayload<ActionType.PLAY_SOUND>, idx: number) => {
setActions((prev: Action[]) => {
const data = [...prev]
data[idx] = {
...data[idx],
jsonPayload: getJson<ActionType.PLAY_SOUND>(value)
}
return data
modifyAction(idx, {
...actions[idx],
jsonPayload: getJson<ActionType.PLAY_SOUND>(value)
})
},
[setActions]
[modifyAction, actions]
)

const handleChangeCounter = useCallback(
({ target: { value } }: React.ChangeEvent<HTMLInputElement>, idx: number) => {
setActions((prev: Action[]) => {
const data = [...prev]
data[idx] = {
...data[idx],
jsonPayload: getJson<ActionType.SET_COUNTER>({
counter: parseInt(value)
})
}
return data
modifyAction(idx, {
...actions[idx],
jsonPayload: getJson<ActionType.SET_COUNTER>({
counter: parseInt(value)
})
})
},
[setActions]
[modifyAction, actions]
)

const handleChangeType = useCallback(
({ target: { value } }: React.ChangeEvent<HTMLSelectElement>, idx: number) => {
setActions((prev: Action[]) => {
const data = [...prev]
data[idx] = {
...data[idx],
type: value
}
return data
modifyAction(idx, {
...actions[idx],
type: value,
jsonPayload: getDefaultPayload(value)
})
},
[setActions]
[modifyAction, actions]
)

const handleChangeName = useCallback(
(e: React.ChangeEvent<HTMLElement>, idx: number) => {
const { value } = e.target as HTMLInputElement
setActions((prev: Action[]) => {
const data = [...prev]
data[idx] = {
...data[idx],
name: value
}
return data
modifyAction(idx, {
...actions[idx],
name: value
})
},
[modifyAction, actions]
)

const handleSetVisible = useCallback(
({ target: { value } }: React.ChangeEvent<HTMLSelectElement>, idx: number) => {
modifyAction(idx, {
...actions[idx],
jsonPayload: getJson<ActionType.SET_VISIBILITY>({
visible: value === 'true'
})
})
},
[setActions]
[modifyAction, actions]
)

const handleFocusInput = useCallback(
Expand All @@ -322,13 +297,9 @@ export default withSdk<Props>(
const handleRemoveAction = useCallback(
(e: React.MouseEvent, idx: number) => {
e.stopPropagation()
setActions((prev: Action[]) => {
const data = [...prev]
data.splice(idx, 1)
return data
})
removeAction(idx)
},
[setActions]
[removeAction]
)

if (!hasActions || !isLoaded) {
Expand Down Expand Up @@ -435,6 +406,23 @@ export default withSdk<Props>(
/>
)
}
case ActionType.SET_VISIBILITY: {
return (
<div className="row">
<div className="field">
<label>Select Visibility</label>
<Dropdown
options={[
{ value: 'true', text: 'Visible' },
{ value: 'false', text: 'Invisible' }
]}
value={(getPartialPayload<ActionType.SET_VISIBILITY>(action)?.visible ?? true).toString()}
onChange={(e) => handleSetVisible(e, idx)}
/>
</div>
</div>
)
}
default: {
// TODO: handle generic schemas with something like <JsonSchemaField/>
return null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ const TweenAction: React.FC<Props> = ({ tween: tweenProp, onUpdateTween }: Props
</div>
</div>
<div className="row">
<div className="field relative">
<div className="field inline">
<input type="checkbox" checked={tween.relative} onChange={handleChangeRelative} />
<label>Relative {renderRelativeInfo()}</label>
</div>
Expand Down
Loading

0 comments on commit 6a85a0f

Please sign in to comment.