diff --git a/packages/@dcl/inspector/.vscode/settings.json b/packages/@dcl/inspector/.vscode/settings.json new file mode 100644 index 000000000..25fa6215f --- /dev/null +++ b/packages/@dcl/inspector/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "typescript.tsdk": "node_modules/typescript/lib" +} diff --git a/packages/@dcl/inspector/src/components/FileInput/FileInput.tsx b/packages/@dcl/inspector/src/components/FileInput/FileInput.tsx index 0fc2ed9ec..65f0ca9bb 100644 --- a/packages/@dcl/inspector/src/components/FileInput/FileInput.tsx +++ b/packages/@dcl/inspector/src/components/FileInput/FileInput.tsx @@ -16,7 +16,7 @@ export interface InputRef { } export const FileInput = React.forwardRef>((props, parentRef) => { - const { onDrop } = props + const { disabled, onDrop } = props const acceptExtensions = Object.values(props.accept ?? []).flat() const inputRef = useRef(null) @@ -27,7 +27,7 @@ export const FileInput = React.forwardRef !!acceptExtensions.find((ext) => file.name.endsWith(ext))) + return !disabled && item.files.every((file) => !!acceptExtensions.find((ext) => file.name.endsWith(ext))) }, collect: (monitor) => ({ isHover: monitor.canDrop() && monitor.isOver() @@ -60,7 +60,7 @@ export const FileInput = React.forwardRef ([]) + const [screenshots, setScreenshots] = useState>(new Map()) const [isHover, setIsHover] = useState(false) const { basePath, assets } = catalog ?? { basePath: '', assets: [] } @@ -68,10 +71,20 @@ const ImportAsset = React.forwardRef { // e.stopPropagation() setFiles(files.filter((file) => file.name !== asset.name)) - } + }, []) + + const handleCloseModal = useCallback(() => { + setFiles([]) + setScreenshots(new Map()) + }, []) + + const handleScreenshot = useCallback((file: Asset) => (thumbnail: string) => { + const map = screenshots.set(formatFileName(file), thumbnail) + setScreenshots(new Map(map)) + }, []) return (
@@ -83,7 +96,47 @@ const ImportAsset = React.forwardRef Drop {ACCEPTED_FILE_TYPES_STR} files - ) : children} + ) : ( + <> + {files.map(($, i) => { + const resources = getAssetResources($) + return ( +
+ +
+ ) + })} + {children} + + )} + +

Import Assets

+
+ {files.length > 1 && {files.length}} +
+ {files.length > 1 && } +
+ {files.map(($, i) => { + const name = formatFileName($) + return ( +
+ + + {getAssetSize($)} +
+ ) + })} +
+ {files.length > 1 && } +
+
+ +
) diff --git a/packages/@dcl/inspector/src/components/ImportAsset/types.ts b/packages/@dcl/inspector/src/components/ImportAsset/types.ts index c39508fe2..d11f6b337 100644 --- a/packages/@dcl/inspector/src/components/ImportAsset/types.ts +++ b/packages/@dcl/inspector/src/components/ImportAsset/types.ts @@ -26,3 +26,8 @@ export type BabylonValidationIssue = { message: string pointer: string } + +export const isGltfAsset = (asset: Asset): asset is GltfAsset => { + const _asset = asset as any + return _asset.buffers && _asset.images +} diff --git a/packages/@dcl/inspector/src/components/ImportAsset/utils.ts b/packages/@dcl/inspector/src/components/ImportAsset/utils.ts index d7414852f..50b48c259 100644 --- a/packages/@dcl/inspector/src/components/ImportAsset/utils.ts +++ b/packages/@dcl/inspector/src/components/ImportAsset/utils.ts @@ -1,6 +1,6 @@ import { GLTFValidation } from '@babylonjs/loaders' -import { FileAsset, GltfAsset, BabylonValidationIssue, ValidationError, Asset, Uri, GltfFile } from './types' +import { FileAsset, GltfAsset, BabylonValidationIssue, ValidationError, Asset, Uri, GltfFile, isGltfAsset } from './types' const sampleIndex = (list: any[]) => Math.floor(Math.random() * list.length) @@ -148,7 +148,7 @@ function extractFileInfo(fileName: string): [string, string] { return match ? [match[1], match[2]?.toLowerCase() || ""] : [fileName, ""] } -function formatFileName(file: FileAsset): string { +export function formatFileName(file: FileAsset): string { return `${file.name}.${file.extension}` } @@ -225,3 +225,28 @@ export async function processAssets(files: File[]): Promise { const processedFiles = await Promise.all(files.map(processFile)) return processGltfAssets(processedFiles) } + +export function normalizeBytes(bytes: number): string { + const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']; + let value = bytes; + let unitIndex = 0; + + while (value >= 1024 && unitIndex < units.length - 1) { + value /= 1024; + unitIndex++; + } + + const roundedValue = Math.round(value * 100) / 100; + return `${roundedValue} ${units[unitIndex]}`; +} + +export function getAssetSize(asset: Asset): string { + const resources = getAssetResources(asset) + const sumSize = resources.reduce((size, resource) => size + resource.size, asset.blob.size) + return normalizeBytes(sumSize) +} + +export function getAssetResources(asset: Asset): File[] { + if (!isGltfAsset(asset)) return [] + return [...asset.buffers, ...asset.images].map(($) => $.blob) +}