import React, { memo, useCallback, useEffect } from 'react' import { useTranslation } from 'react-i18next' import AutoSizer from 'react-virtualized-auto-sizer' import { areEqual, FixedSizeList } from 'react-window' import { MeshBasicMaterial } from 'three' import exportMaterialsGLTF from '@xrengine/engine/src/assets/functions/exportMaterialsGLTF' import { Engine } from '@xrengine/engine/src/ecs/classes/Engine' import { SourceType } from '@xrengine/engine/src/renderer/materials/components/MaterialSource' import { LibraryEntryType } from '@xrengine/engine/src/renderer/materials/constants/LibraryEntry' import { entryId, hashMaterialSource, materialFromId, registerMaterial } from '@xrengine/engine/src/renderer/materials/functions/MaterialLibraryFunctions' import { useMaterialLibrary } from '@xrengine/engine/src/renderer/materials/MaterialLibrary' import { createActionQueue, getState, removeActionQueue, useState } from '@xrengine/hyperflux' import { Divider, Grid, Stack } from '@mui/material' import { uploadProjectFiles } from '../../functions/assetFunctions' import { EditorControlFunctions } from '../../functions/EditorControlFunctions' import { useEditorState } from '../../services/EditorServices' import { useSelectionState } from '../../services/SelectionServices' import { HeirarchyTreeCollapsedNodeType } from '../hierarchy/HeirarchyTreeWalker' import styles from '../hierarchy/styles.module.scss' import { Button } from '../inputs/Button' import MaterialLibraryEntry, { MaterialLibraryEntryType } from './MaterialLibraryEntry' export default function MaterialLibraryPanel() { const { t } = useTranslation() const editorState = useEditorState() const selectionState = useSelectionState() const materialLibrary = useMaterialLibrary() const MemoMatLibEntry = memo(MaterialLibraryEntry, areEqual) const nodeChanges = useState(0) const createSrcs = useCallback(() => Object.values(materialLibrary.sources.value), [materialLibrary.sources]) const srcs = useState(createSrcs()) useEffect(srcs.set.bind({}, createSrcs), [materialLibrary.sources]) const collapsedSrcs = useCallback( () => new Set(srcs.value.map((src) => entryId(src, LibraryEntryType.MATERIAL_SOURCE))), [srcs] ) const collapsedNodes = useState(collapsedSrcs()) const createNodes = useCallback((): MaterialLibraryEntryType[] => { const result = srcs.value.flatMap((srcComp) => { const uuid = entryId(srcComp, LibraryEntryType.MATERIAL_SOURCE) const isCollapsed = collapsedNodes.value.has(uuid) return [ { uuid, type: LibraryEntryType.MATERIAL_SOURCE, entry: srcComp, selected: selectionState.selectedEntities.value.some( (entity) => typeof entity === 'string' && entity === uuid ), active: selectionState.selectedEntities.value.at(-1) === uuid, isCollapsed }, ...(isCollapsed ? [] : srcComp.entries .filter((uuid) => !!materialLibrary.materials[uuid].value) .map((uuid) => { return { uuid, type: LibraryEntryType.MATERIAL, entry: materialFromId(uuid), selected: selectionState.selectedEntities.value.some( (entity) => typeof entity === 'string' && entity === uuid ), active: selectionState.selectedEntities.value.at(-1) === uuid } })) ] }) return result }, [nodeChanges, srcs, selectionState.selectedEntities]) const nodes = useState(createNodes()) const onClick = useCallback((e: MouseEvent, node: MaterialLibraryEntryType) => { if (!editorState.lockPropertiesPanel.get()) { EditorControlFunctions.replaceSelection([entryId(node.entry, node.type)]) selectionState.objectChangeCounter.set(selectionState.objectChangeCounter.value + 1) } }, []) const onCollapse = useCallback((e: MouseEvent, node: MaterialLibraryEntryType) => { const isCollapsed = collapsedNodes.value.has(node.uuid) if (isCollapsed) { collapsedNodes.merge((_collapsedNodes) => { _collapsedNodes.delete(node.uuid) return _collapsedNodes }) } else { collapsedNodes.merge((_collapsedNodes) => { _collapsedNodes.add(node.uuid) return _collapsedNodes }) } nodeChanges.set(nodeChanges.get() + 1) }, []) useEffect(() => { nodes.set(createNodes()) }, [nodeChanges, selectionState.selectedEntities, srcs]) return ( <>
{({ width, height }) => ( index} innerElementType="ul" > {MemoMatLibEntry} )}
) }