import React, { MouseEventHandler, MutableRefObject, useEffect, useState } from 'react' import { useDrag, useDrop } from 'react-dnd' import { getEmptyImage } from 'react-dnd-html5-backend' import { useTranslation } from 'react-i18next' import { KTX2EncodeArguments } from '@xrengine/engine/src/assets/constants/CompressionParms' import { getComponent } from '@xrengine/engine/src/ecs/functions/ComponentFunctions' import { TransformComponent } from '@xrengine/engine/src/transform/components/TransformComponent' import { State } from '@xrengine/hyperflux' import DescriptionIcon from '@mui/icons-material/Description' import FolderIcon from '@mui/icons-material/Folder' import InputBase from '@mui/material/InputBase' import MenuItem from '@mui/material/MenuItem' import Paper from '@mui/material/Paper' import { PopoverPosition } from '@mui/material/Popover' import { SupportedFileTypes } from '../../constants/AssetTypes' import { addMediaNode } from '../../functions/addMediaNode' import { getSpawnPositionAtCenter } from '../../functions/screenSpaceFunctions' import { ContextMenu } from '../layout/ContextMenu' import { FileDataType } from './FileDataType' import styles from './styles.module.scss' type FileListItemProps = { item: FileDataType isRenaming: boolean onDoubleClick?: MouseEventHandler onClick?: MouseEventHandler onNameChanged: (newName: string) => void } export const FileListItem: React.FC = (props) => { const [newFileName, setNewFileName] = React.useState(props.item.name) const handleChange = (e) => { setNewFileName(e.target.value) } return !props.isRenaming ? (
{props.item.isFolder ? ( ) : props.item.Icon ? ( ) : ( )}
{props.item.fullName}
) : ( handleChange(e)} onKeyPress={async (e) => { if (e.key == 'Enter') { props.onNameChanged(newFileName) } }} /> ) } type FileBrowserItemType = { contextMenuId: string item: FileDataType disableDnD?: boolean currentContent: MutableRefObject<{ item: FileDataType; isCopy: boolean }> setFileProperties: any setOpenPropertiesModal: any setOpenCompress: any deleteContent: (contentPath: string, type: string) => void onClick: (params: FileDataType) => void dropItemsOnPanel: (data: any, dropOn?: FileDataType) => void moveContent: (oldName: string, newName: string, oldPath: string, newPath: string, isCopy?: boolean) => Promise } export function FileBrowserItem({ contextMenuId, item, disableDnD, currentContent, setOpenPropertiesModal, setFileProperties, setOpenCompress, deleteContent, onClick, dropItemsOnPanel, moveContent }: FileBrowserItemType) { const { t } = useTranslation() const [anchorPosition, setAnchorPosition] = React.useState(undefined) const [anchorEl, setAnchorEl] = React.useState(null) const open = Boolean(anchorEl) const [renamingAsset, setRenamingAsset] = useState(false) const handleContextMenu = (event: React.MouseEvent) => { event.preventDefault() event.stopPropagation() setAnchorEl(event.currentTarget) setAnchorPosition({ left: event.clientX + 2, top: event.clientY - 6 }) } const handleClose = () => { setAnchorEl(null) setAnchorPosition(undefined) } const onClickItem = (_) => onClick(item) const placeObject = () => { addMediaNode(item.url) handleClose() } const placeObjectAtOrigin = async () => { const node = await addMediaNode(item.url) if (!node) return const transformComponent = getComponent(node, TransformComponent) if (transformComponent) getSpawnPositionAtCenter(transformComponent.position) handleClose() } const copyURL = () => { if (navigator.clipboard) { navigator.clipboard.writeText(item.url) } handleClose() } const openURL = () => { window.open(item.url) handleClose() } const Copy = () => { currentContent.current = { item: item, isCopy: true } handleClose() } const Cut = () => { currentContent.current = { item: item, isCopy: false } handleClose() } const viewAssetProperties = () => { if (item.isFolder) { setFileProperties({ ...item, url: item.url + '/' + item.key }) } else { setFileProperties(item) } setOpenPropertiesModal(true) handleClose() } const viewCompress = () => { if (item.isFolder) { //todo: add folder compress } else { setFileProperties(item) setOpenCompress(true) } handleClose() } const deleteContentCallback = () => { deleteContent(item.key, item.type) handleClose() } const onNameChanged = async (fileName: string): Promise => { setRenamingAsset(false) await moveContent(item.fullName, item.isFolder ? fileName : `${fileName}.${item.type}`, item.path, item.path, false) } const rename = () => { setRenamingAsset(true) handleClose() } const [_dragProps, drag, preview] = disableDnD ? [undefined, undefined, undefined] : useDrag(() => ({ type: item.type, item, multiple: false })) const [{ isOver }, drop] = disableDnD ? [{ isOver: false }, undefined] : useDrop({ accept: [...SupportedFileTypes], drop: (dropItem) => dropItemsOnPanel(dropItem, item), collect: (monitor) => ({ isOver: monitor.isOver(), canDrop: !!monitor.canDrop(), moni: monitor.getItemType() }) }) //showing the object in viewport once it drag and droped useEffect(() => { if (preview) preview(getEmptyImage(), { captureDraggingState: true }) }, [preview]) return (
{item.isFolder && {t('editor:layout.assetGrid.placeObject')}} {item.isFolder && ( {t('editor:layout.assetGrid.placeObjectAtOrigin')} )} {item.isFolder && {t('editor:layout.assetGrid.openInNewTab')}} {t('editor:layout.assetGrid.copyURL')} {t('editor:layout.filebrowser.cutAsset')} {t('editor:layout.filebrowser.copyAsset')} {t('editor:layout.filebrowser.renameAsset')} {t('editor:layout.assetGrid.deleteAsset')} {t('editor:layout.filebrowser.viewAssetProperties')} {t('editor:layout.filebrowser.compress')}
) }