59 lines
1.5 KiB
TypeScript
59 lines
1.5 KiB
TypeScript
import React, { useState, useEffect } from 'react'
|
|
import { invoke } from '@tauri-apps/api/core'
|
|
import { Video } from 'lucide-react'
|
|
|
|
interface ProjectImageProps {
|
|
imagePath: string
|
|
alt: string
|
|
className: string
|
|
}
|
|
import { convertFileSrc } from '@tauri-apps/api/core'
|
|
|
|
const ProjectImage: React.FC<ProjectImageProps> = ({ imagePath, alt, className }) => {
|
|
const [imageSrc, setImageSrc] = useState<string>('')
|
|
const [imageLoading, setImageLoading] = useState(true)
|
|
|
|
useEffect(() => {
|
|
const loadImage = async () => {
|
|
if (!imagePath) {
|
|
setImageLoading(false)
|
|
return
|
|
}
|
|
|
|
if (imagePath.startsWith('http') || imagePath.startsWith('data:')) {
|
|
setImageSrc(imagePath)
|
|
setImageLoading(false)
|
|
return
|
|
}
|
|
|
|
try {
|
|
const dataUrl = convertFileSrc(imagePath)
|
|
console.log({ dataUrl, imagePath })
|
|
setImageSrc(dataUrl)
|
|
} catch (error) {
|
|
console.error('Failed to read image:', error)
|
|
} finally {
|
|
setImageLoading(false)
|
|
}
|
|
}
|
|
|
|
loadImage()
|
|
}, [imagePath])
|
|
|
|
if (imageLoading) {
|
|
return <div className={`${className} bg-secondary-200 animate-pulse`}></div>
|
|
}
|
|
|
|
if (!imageSrc) {
|
|
return (
|
|
<div className={`${className} bg-secondary-200 flex items-center justify-center`}>
|
|
<Video className="text-secondary-400" size={48} />
|
|
</div>
|
|
)
|
|
}
|
|
|
|
return <img src={imageSrc} alt={alt} className={className} />
|
|
}
|
|
|
|
export default ProjectImage
|