import PropTypes from 'prop-types' import { ApiServerContext } from '../context/ApiServerContext' import { useCallback, useContext, useEffect, useState, memo } from 'react' import LoadingPlaceholder from './LoadingPlaceholder' import GCodePreview from './GCodePreview' import ThreeDPreview from './ThreeDPreview' import { AuthContext } from '../context/AuthContext' const FilePreview = ({ file, style = {} }) => { const { token } = useContext(AuthContext) const { fetchFileContent } = useContext(ApiServerContext) const [fileObjectUrl, setFileObjectUrl] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const fetchPreview = useCallback(async () => { if (error != null) { return } setLoading(true) console.log('fetching file content', file) const objectUrl = await fetchFileContent(file, false) if (objectUrl == null) { setLoading(false) console.error('Failed to fetch file content', file) setError('Failed to fetch file content') return } setFileObjectUrl(objectUrl) setLoading(false) }, [file, fetchFileContent]) useEffect(() => { if (file?.type && token != null) { fetchPreview() } }, [file._id, file?.type, fetchPreview, token]) if (loading == true || !file?.type) { return } if (error != null) { return
{error}
} const isGcode = ['.g', '.gcode'].includes( (file?.extension || '').toLowerCase() ) const is3DModel = ['.stl', '.3mf'].includes( (file?.extension || '').toLowerCase() ) const isImage = file?.type.startsWith('image/') if (isGcode && fileObjectUrl) { return ( ) } if (is3DModel && fileObjectUrl) { return ( ) } if (isImage && fileObjectUrl) { return } return null } FilePreview.propTypes = { file: PropTypes.object.isRequired, style: PropTypes.object } // Custom comparison function to only re-render when file._id changes const areEqual = (prevProps, nextProps) => { return ( prevProps.file?._id === nextProps.file?._id && JSON.stringify(prevProps.style) === JSON.stringify(nextProps.style) ) } export default memo(FilePreview, areEqual)