From cfd3f9e67b6c92cbfc32c4b2cc776ac1bd5c613f Mon Sep 17 00:00:00 2001 From: Benjamin Lu Date: Tue, 19 May 2026 08:09:02 -0700 Subject: [PATCH] fix: classify PLY assets as 3D media (#12319) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Classify `.ply` as 3D media so PLY outputs are surfaced by queue/assets preview flows. ## Changes - **What**: adds `.ply` to shared 3D extension detection and falls back to the asset `/view` URL when opening 3D assets without `preview_url`. - **Breaking**: none. - **Dependencies**: none. ## Review Focus - This is the tactical FE fix for FE-129; it intentionally does not solve the broader 3D media vs load3d-loadable split. - Assets sidebar 3D viewer still prefers `preview_url`, but now has a usable fallback for assets that only have the normal asset URL. FE-129 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-12319-fix-classify-PLY-assets-as-3D-media-3646d73d365081218f0bde401b1601bd) by [Unito](https://www.unito.io) --- packages/shared-frontend-utils/src/formatUtil.test.ts | 1 + packages/shared-frontend-utils/src/formatUtil.ts | 2 +- src/components/sidebar/tabs/AssetsSidebarTab.vue | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/shared-frontend-utils/src/formatUtil.test.ts b/packages/shared-frontend-utils/src/formatUtil.test.ts index cf64b26ec8..2c38d767d5 100644 --- a/packages/shared-frontend-utils/src/formatUtil.test.ts +++ b/packages/shared-frontend-utils/src/formatUtil.test.ts @@ -112,6 +112,7 @@ describe('formatUtil', () => { expect(getMediaTypeFromFilename('asset.gltf')).toBe('3D') expect(getMediaTypeFromFilename('binary.glb')).toBe('3D') expect(getMediaTypeFromFilename('apple.usdz')).toBe('3D') + expect(getMediaTypeFromFilename('scan.ply')).toBe('3D') }) }) diff --git a/packages/shared-frontend-utils/src/formatUtil.ts b/packages/shared-frontend-utils/src/formatUtil.ts index 99b6bc79f5..01e52cdd4a 100644 --- a/packages/shared-frontend-utils/src/formatUtil.ts +++ b/packages/shared-frontend-utils/src/formatUtil.ts @@ -591,7 +591,7 @@ const IMAGE_EXTENSIONS = [ ] as const const VIDEO_EXTENSIONS = ['mp4', 'm4v', 'webm', 'mov', 'avi', 'mkv'] as const const AUDIO_EXTENSIONS = ['mp3', 'wav', 'ogg', 'flac'] as const -const THREE_D_EXTENSIONS = ['obj', 'fbx', 'gltf', 'glb', 'usdz'] as const +const THREE_D_EXTENSIONS = ['obj', 'fbx', 'gltf', 'glb', 'usdz', 'ply'] as const const TEXT_EXTENSIONS = [ 'txt', 'md', diff --git a/src/components/sidebar/tabs/AssetsSidebarTab.vue b/src/components/sidebar/tabs/AssetsSidebarTab.vue index 20d4814c97..9770d0ffa1 100644 --- a/src/components/sidebar/tabs/AssetsSidebarTab.vue +++ b/src/components/sidebar/tabs/AssetsSidebarTab.vue @@ -246,6 +246,7 @@ import type { OutputAssetMetadata } from '@/platform/assets/schemas/assetMetadat import { getOutputAssetMetadata } from '@/platform/assets/schemas/assetMetadataSchema' import type { AssetItem } from '@/platform/assets/schemas/assetSchema' import { getAssetDisplayName } from '@/platform/assets/utils/assetMetadataUtils' +import { getAssetUrl } from '@/platform/assets/utils/assetUrlUtil' import type { MediaKind } from '@/platform/assets/schemas/mediaAssetSchema' import { resolveOutputAssetItems } from '@/platform/assets/utils/outputAssetUtil' import { isCloud } from '@/platform/distribution/types' @@ -582,7 +583,7 @@ const handleZoomClick = (asset: AssetItem) => { title: getAssetDisplayName(asset), component: Load3dViewerContent, props: { - modelUrl: asset.preview_url || '' + modelUrl: asset.preview_url || getAssetUrl(asset) }, dialogComponentProps: { style: 'width: 80vw; height: 80vh;',