// src/components/SorlangPage.tsx "use client"; // For Next.js App Router, if applicable import React, { useState, useRef, useTransition, useEffect, useCallback, startTransition, } from "react"; import { Button } from "@/components/ui/button"; import { Textarea } from "@/components/ui/textarea"; import { Card, CardContent, CardFooter, CardHeader, CardTitle, } from "@/components/ui/card"; import { Loader2 } from "lucide-react"; // Loading spinner const SorlangPage: React.FC = () => { const [textValue, setTextValue] = useState(""); const [pastedImageUrl, setPastedImageUrl] = useState(null); const [pastedImageFile, setPastedImageFile] = useState(null); // Store the file for extraction const [isExtracting, setIsExtracting] = useState(false); const [extractedTextResult, setExtractedTextResult] = useState( null, ); const textareaRef = useRef(null); // Cleanup object URL when component unmounts or image changes useEffect(() => { return () => { if (pastedImageUrl) { URL.revokeObjectURL(pastedImageUrl); } }; }, [pastedImageUrl]); const handlePaste = useCallback( (event: React.ClipboardEvent) => { const items = event.clipboardData?.items; console.log({ items }); if (!items) return; let imageFound = false; for (let i = 0; i < items.length; i++) { const item = items[i]; if (!item) return; if (item.kind === "file" && item.type.startsWith("image/")) { event.preventDefault(); // Prevent pasting image data as text const file = item.getAsFile(); if (file) { if (pastedImageUrl) { URL.revokeObjectURL(pastedImageUrl); // Revoke previous if any } const newImageUrl = URL.createObjectURL(file); setPastedImageUrl(newImageUrl); setPastedImageFile(file); setTextValue(""); // Clear textarea when image is pasted, or decide on desired behavior setExtractedTextResult(null); // Clear previous extraction results imageFound = true; } break; // Handle first image found } } // If no image was found, let the default text paste happen // Or, if you want to explicitly handle text paste: if (!imageFound) { // Let the default textarea paste handle it, or: // event.preventDefault(); // const text = event.clipboardData.getData('text/plain'); // setTextValue(prev => prev + text); // Or replace, depending on desired behavior // setPastedImageUrl(null); // Clear image if text is pasted // setPastedImageFile(null); } }, [pastedImageUrl], ); const handleProcessText = () => { if (!textValue.trim()) { alert("Text area is empty!"); return; } console.log("Processing text:", textValue); // Add your text processing logic here alert( `Text submitted: "${textValue.substring(0, 50)}${textValue.length > 50 ? "..." : ""}"`, ); }; const [isPending, startTransition] = useTransition(); const onClick = () => { startTransition(async () => { const lol = "lmao"; }); }; const handleExtractTextFromImage = async () => { if (!pastedImageFile) { alert("No image to extract text from!"); return; } setIsExtracting(true); setExtractedTextResult(null); console.log("Extracting text from image:", pastedImageFile.name); // --- SIMULATE OCR API CALL --- // In a real app, you would send `pastedImageFile` to a backend // or use a client-side OCR library like Tesseract.js await new Promise((resolve) => setTimeout(resolve, 2000)); // Simulate network delay // Example: Simulate successful extraction const mockExtractedText = `This is simulated extracted text from "${pastedImageFile.name}".\nIt could be multiple lines.`; // Example: Simulate an error // const mockExtractedText = null; // alert("Failed to extract text (simulated)."); if (mockExtractedText) { setTextValue(mockExtractedText); // Put extracted text into the textarea setExtractedTextResult( `Successfully extracted text and placed it in the textarea.`, ); } else { setExtractedTextResult("Failed to extract text (simulated)."); } // --- END SIMULATION --- setIsExtracting(false); // Optionally clear the image after attempting extraction // setPastedImageUrl(null); // setPastedImageFile(null); }; const handleClearImage = () => { if (pastedImageUrl) { URL.revokeObjectURL(pastedImageUrl); } setPastedImageUrl(null); setPastedImageFile(null); setExtractedTextResult(null); }; return (
Sorlang