import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react'; import { RotateCcw } from 'lucide-react'; import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'; import { truncateFileName } from './lib/utils'; import { useFaceLandmarkDetection } from './hooks/useFaceLandmarkDetection'; import { PoweredBy } from './components/PoweredBy'; import { Spinner } from './components/Spinner'; import { DoubleCard } from './components/DoubleCard'; import { useFacePokeAPI } from './hooks/useFacePokeAPI'; import { Layout } from './layout'; import { useMainStore } from './hooks/useMainStore'; import { convertImageToBase64 } from './lib/convertImageToBase64'; export function App() { const error = useMainStore(s => s.error); const setError = useMainStore(s => s.setError); const imageFile = useMainStore(s => s.imageFile); const setImageFile = useMainStore(s => s.setImageFile); const originalImage = useMainStore(s => s.originalImage); const setOriginalImage = useMainStore(s => s.setOriginalImage); const previewImage = useMainStore(s => s.previewImage); const setPreviewImage = useMainStore(s => s.setPreviewImage); const resetImage = useMainStore(s => s.resetImage); const { status, setStatus, isDebugMode, setIsDebugMode, interruptMessage, } = useFacePokeAPI() // State for face detection const { canvasRef, canvasRefCallback, mediaPipeRef, faceLandmarks, isMediaPipeReady, blendShapes, setFaceLandmarks, setBlendShapes, handleMouseDown, handleMouseUp, handleMouseMove, handleMouseEnter, handleMouseLeave, currentOpacity } = useFaceLandmarkDetection() // Refs const videoRef = useRef(null); // Handle file change const handleFileChange = useCallback(async (event: React.ChangeEvent) => { const files = event.target.files; if (files && files[0]) { setImageFile(files[0]); setStatus(`File selected: ${truncateFileName(files[0].name, 16)}`); try { const image = await convertImageToBase64(files[0]); setPreviewImage(image); setOriginalImage(image); } catch (err) { console.log(`failed to convert the image: `, err); setImageFile(null); setStatus(''); setPreviewImage(''); setOriginalImage(''); setFaceLandmarks([]); setBlendShapes([]); } } else { setImageFile(null); setStatus(''); setPreviewImage(''); setOriginalImage(''); setFaceLandmarks([]); setBlendShapes([]); } }, [isMediaPipeReady, setImageFile, setPreviewImage, setOriginalImage, setFaceLandmarks, setBlendShapes, setStatus]); const canDisplayBlendShapes = false // Display blend shapes const displayBlendShapes = useMemo(() => (

Blend Shapes

    {(blendShapes?.[0]?.categories || []).map((shape, index) => (
  • {shape.categoryName || shape.displayName}
    {shape.score.toFixed(2)}
  • ))}
), [JSON.stringify(blendShapes)]) // JSX return ( {error && ( Error {error} )} {interruptMessage && ( Notice {interruptMessage} )}
{previewImage && }
{previewImage && (
Preview
)} {canDisplayBlendShapes && displayBlendShapes}
); }