Spaces:
Sleeping
Sleeping
File size: 4,933 Bytes
8608e55 a1c083f 8608e55 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
/**
* Popup.jsx
*
* This component displays a popup box with information about a selected shape (circle or text).
* - For circles: shows page number and circle text, with a button to navigate to the corresponding page.
* - For text: fetches additional info from the LLM backend and displays it.
* - Supports zoomed image coordinates without scaling the popup itself.
* - Provides a close button to dismiss the popup.
*/
import { useState, useEffect } from "react";
function Popup({ selectedShape, onClose, zoom = 1 }) {
const [info, setInfo] = useState(null);
useEffect(() => {
if (!selectedShape || selectedShape.r) return;
setInfo("Loading...");
fetch("/llm/generate_info", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ content: selectedShape.text || "Unlabeled text" }),
})
.then((res) => {
if (!res.ok) throw new Error(`HTTP error! status: ${res.status}`);
return res.json();
})
.then((data) => setInfo(data.info))
.catch((error) => {
console.error("LLM fetch error:", error);
setInfo("Error generating info");
});
}, [selectedShape]);
if (!selectedShape) return null;
// ✅ Apply zoom only to coordinates, not to popup size
const left =
(selectedShape.r
? selectedShape.x + selectedShape.r + 10
: selectedShape.x2 + 10) * zoom;
const top =
(selectedShape.r
? selectedShape.y - selectedShape.r / 2
: selectedShape.y1) * zoom;
// Redirect handler
const handleRedirect = (e, pageNumber, circleText) => {
e.preventDefault();
e.stopPropagation();
if (!pageNumber) {
console.log("Missing navigation data:", { pageNumber });
return;
}
const pageImageUrl = `/images/${pageNumber}.png`;
let targetUrl = `/page?image=${encodeURIComponent(pageImageUrl)}`;
if (circleText) {
targetUrl += `&circle=${encodeURIComponent(circleText)}`;
}
window.open(targetUrl, "_blank", "noopener,noreferrer");
onClose();
};
return (
<div
className="popup-box"
onClick={(e) => e.stopPropagation()}
style={{
position: "absolute",
left: `${left}px`,
top: `${top}px`,
zIndex: 1001,
backgroundColor: "orange",
border: "1px solid #ccc",
borderRadius: "8px",
padding: "10px",
boxShadow: "0 2px 10px rgba(0,0,0,0.1)",
minWidth: "200px",
transform: "scale(1)",
}}
>
{selectedShape.r ? (
<div>
<h4>Circle Information</h4>
{selectedShape.page_number ? (
<ul style={{ listStyle: "none", padding: 0 }}>
<li style={{ marginBottom: "8px" }}>
<strong>Page Number:</strong> {selectedShape.page_number}
</li>
{selectedShape.circle_text && (
<li>
<strong>Circle Text:</strong> {selectedShape.circle_text}
</li>
)}
<li style={{ marginTop: "5px" }}>
<button
style={{
cursor: "pointer",
color: "white",
backgroundColor: "#007bff",
border: "none",
padding: "5px 10px",
borderRadius: "4px",
}}
onClick={(e) =>
handleRedirect(
e,
selectedShape.page_number,
selectedShape.circle_text
)
}
>
Go to page {selectedShape.page_number}
</button>
</li>
</ul>
) : (
<p>No page number available for navigation.</p>
)}
<button
onClick={onClose}
style={{
marginTop: "10px",
padding: "5px 10px",
backgroundColor: "#6c757d",
color: "white",
border: "none",
borderRadius: "4px",
cursor: "pointer",
}}
>
Close
</button>
</div>
) : (
<div>
<h4>Detected Text</h4>
<p>
<strong>Text:</strong> {selectedShape.text || "Text"}
</p>
<p>
<strong>Info:</strong> {info || "Click to generate info"}
</p>
<button
onClick={onClose}
style={{
marginTop: "10px",
padding: "5px 10px",
backgroundColor: "#6c757d",
color: "white",
border: "none",
borderRadius: "4px",
cursor: "pointer",
}}
>
Close
</button>
</div>
)}
</div>
);
}
export default Popup;
|