UNPKG

cube-parameters

Version:

A sophisticated 3D model viewer built with React, TypeScript, and Three.js, featuring advanced visualization tools, measurement capabilities, and lighting controls.

171 lines (145 loc) 5.24 kB
import { useToast } from '@/hooks/use-toast'; import { useNotifications } from '@/contexts/NotificationContext'; import { useSceneState } from '../store/useAppStore'; import type { LoadedModel } from '../types/model'; import { logger } from '../lib/logger'; import { useModelViewerContext } from '../contexts/ModelViewerContext'; export const useFileHandlers = () => { const { toast } = useToast(); const { addMessage } = useNotifications(); const { loadedModels, setLoadedModels, setCurrentModel, setUploading, setUploadError } = useSceneState(); const { onFileUpload, onModelSelect, onModelRemove } = useModelViewerContext(); const handleFileUpload = async (file: File) => { logger.info('Starting file upload process:', { name: file.name, type: file.type, size: file.size }); // Use context-based handler if available if (onFileUpload) { return onFileUpload(file); } try { setUploading(true); setUploadError(null); addMessage({ type: 'info', title: 'Loading model...', description: `Processing ${file.name}`, }); // Determine file type and use appropriate loader const fileName = file.name.toLowerCase(); let uploadHandler = null; if (fileName.endsWith('.fbx')) { uploadHandler = (window as any).__fbxUploadHandler; logger.debug('Using FBX loader for:', file.name); } else if (fileName.endsWith('.gltf') || fileName.endsWith('.glb')) { uploadHandler = (window as any).__gltfUploadHandler; logger.debug('Using GLTF loader for:', file.name); } else if (fileName.endsWith('.obj')) { uploadHandler = (window as any).__objUploadHandler || (window as any).__fbxUploadHandler; logger.debug('Using OBJ loader (fallback to FBX) for:', file.name); } else { throw new Error('Unsupported file format. Please select FBX, GLTF, GLB, or OBJ files.'); } if (uploadHandler) { logger.debug('Upload handler found, processing file...'); await uploadHandler(file); addMessage({ type: 'success', title: 'Model loaded successfully', description: `${file.name} is now ready`, }); logger.info('File upload completed successfully'); } else { throw new Error('No suitable loader found for this file type'); } } catch (error) { logger.error('Upload failed:', error); const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred'; setUploadError(`Failed to load ${file.name}: ${errorMessage}`); addMessage({ type: 'error', title: 'Upload failed', description: `Failed to load ${file.name}. ${errorMessage}`, }); } finally { setUploading(false); } }; const handleModelsChange = (models: LoadedModel[], current: LoadedModel | null) => { logger.info('Models changed:', { modelCount: models.length, currentModel: current?.name }); setLoadedModels(models); setCurrentModel(current); }; const handleModelSelect = (modelId: string) => { const model = loadedModels.find((m: LoadedModel) => m.id === modelId); if (model) { logger.info('Selecting model:', model.name); // Use context-based handler if available, fallback to global handlers if (onModelSelect) { onModelSelect(modelId); } else { const fbxSwitchHandler = (window as any).__fbxSwitchHandler; const gltfSwitchHandler = (window as any).__gltfSwitchHandler; if (fbxSwitchHandler) { fbxSwitchHandler(modelId); } else if (gltfSwitchHandler) { gltfSwitchHandler(modelId); } } addMessage({ type: 'success', title: 'Model selected', description: `Now viewing ${model.name}`, }); } }; const handleModelRemove = (modelId: string) => { const model = loadedModels.find((m: LoadedModel) => m.id === modelId); if (model) { logger.info('Removing model:', model.name); // Use context-based handler if available, fallback to global handlers if (onModelRemove) { onModelRemove(modelId); } else { const fbxRemoveHandler = (window as any).__fbxRemoveHandler; const gltfRemoveHandler = (window as any).__gltfRemoveHandler; if (fbxRemoveHandler) { fbxRemoveHandler(modelId); } else if (gltfRemoveHandler) { gltfRemoveHandler(modelId); } } addMessage({ type: 'warning', title: 'Model removed', description: `${model.name} has been removed`, }); } }; const handlePrimitiveSelect = (type: string) => { if (type === 'box') { logger.info('Selecting box primitive'); setCurrentModel(null); addMessage({ type: 'info', title: 'Primitive selected', description: 'Now showing box primitive', }); } }; return { handleFileUpload, handleModelsChange, handleModelSelect, handleModelRemove, handlePrimitiveSelect }; };