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