import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react'; import { FiDownload } from 'react-icons/fi'; import { PiImageSquare } from 'react-icons/pi'; import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'; import { truncateFileName } from './lib/utils'; import { useFaceLandmarkDetection } from './hooks/useFaceLandmarkDetection'; import { About } from './components/About'; import { Spinner } from './components/Spinner'; import { useFacePokeAPI } from './hooks/useFacePokeAPI'; import { Layout } from './layout'; import { useMainStore } from './hooks/useMainStore'; 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 isGazingAtCursor = useMainStore(s => s.isGazingAtCursor); const setIsGazingAtCursor = useMainStore(s => s.setIsGazingAtCursor); const isFollowingCursor = useMainStore(s => s.isFollowingCursor); const setIsFollowingCursor = useMainStore(s => s.setIsFollowingCursor); const previewImage = useMainStore(s => s.previewImage); const status = useMainStore(s => s.status); const blendShapes = useMainStore(s => s.blendShapes); const { isDebugMode, setIsDebugMode, interruptMessage, } = useFacePokeAPI() const { canvasRefCallback, isMediaPipeReady, handleMouseDown, handleMouseUp, handleMouseMove, handleTouchStart, handleTouchMove, handleTouchEnd, currentOpacity } = useFaceLandmarkDetection() // Refs const videoRef = useRef(null); // Handle file change const handleFileChange = useCallback((event: React.ChangeEvent) => { const files = event.target.files; setImageFile(files?.[0] || undefined) }, [setImageFile]); const handleDownload = useCallback(() => { if (previewImage) { const link = document.createElement('a'); link.href = previewImage; link.download = 'result.webp'; document.body.appendChild(link); link.click(); document.body.removeChild(link); } }, [previewImage]); 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 &&
{/* experimental features, not active yet */} {/* */}
}
{previewImage && (
Preview { e.preventDefault(); // Prevent default touch behavior on canvas handleTouchStart(e); }} onTouchMove={(e) => { e.preventDefault(); // Prevent default touch behavior on canvas handleTouchMove(e); }} onTouchEnd={(e) => { e.preventDefault(); // Prevent default touch behavior on canvas handleTouchEnd(e); }} style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%', opacity: isDebugMode ? currentOpacity : 0.0, transition: 'opacity 0.2s ease-in-out' }} />
)} {canDisplayBlendShapes && displayBlendShapes}
); }