your personal website on atproto - mirror blento.app
at pages 60 lines 1.6 kB view raw
1import { uploadBlob } from '$lib/atproto'; 2import type { CardDefinition } from '../../types'; 3import CreateModel3DCardModal from './CreateModel3DCardModal.svelte'; 4import Model3DCard from './Model3DCard.svelte'; 5 6export const Model3DCardDefinition = { 7 type: 'model3d', 8 contentComponent: Model3DCard, 9 creationModalComponent: CreateModel3DCardModal, 10 createNew: (card) => { 11 card.w = 4; 12 card.h = 4; 13 card.mobileW = 4; 14 card.mobileH = 4; 15 card.cardData = { 16 modelType: 'gltf' // 'gltf' | 'stl' 17 }; 18 }, 19 20 upload: async (item) => { 21 // Handle file upload 22 if (item.cardData.modelFile?.blob) { 23 let blob: Blob = item.cardData.modelFile.blob; 24 const modelType = item.cardData.modelFile.type || 'glb'; 25 26 // Ensure blob has a MIME type (STL/FBX files often have empty type) 27 if (!blob.type) { 28 const mimeTypes: Record<string, string> = { 29 stl: 'model/stl', 30 glb: 'model/gltf-binary', 31 gltf: 'model/gltf+json', 32 fbx: 'application/octet-stream' 33 }; 34 const mimeType = mimeTypes[modelType] || 'application/octet-stream'; 35 blob = new Blob([blob], { type: mimeType }); 36 } 37 38 // Upload the blob to the PDS 39 const uploadedBlob = await uploadBlob({ blob }); 40 41 if (uploadedBlob) { 42 item.cardData.modelBlob = uploadedBlob; 43 item.cardData.modelType = modelType; 44 } 45 46 // Clean up the temporary file data 47 if (item.cardData.modelFile.objectUrl) { 48 URL.revokeObjectURL(item.cardData.modelFile.objectUrl); 49 } 50 delete item.cardData.modelFile; 51 } 52 53 return item; 54 }, 55 56 minW: 2, 57 minH: 2, 58 59 name: '3D Model Card' 60} as CardDefinition & { type: 'model3d' };