@david-xpn/llm-ui-feedback 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +131 -66
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +140 -74
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -136,9 +136,7 @@ function getElementsBeneathRect(rect) {
|
|
|
136
136
|
for (let x = rect.x; x <= rect.x + rect.width; x += step) {
|
|
137
137
|
for (let y = rect.y; y <= rect.y + rect.height; y += step) {
|
|
138
138
|
const el = document.elementFromPoint(x, y);
|
|
139
|
-
if (el && !seen.has(el))
|
|
140
|
-
seen.add(el);
|
|
141
|
-
}
|
|
139
|
+
if (el && !seen.has(el)) seen.add(el);
|
|
142
140
|
}
|
|
143
141
|
}
|
|
144
142
|
for (const [x, y] of [
|
|
@@ -154,55 +152,95 @@ function getElementsBeneathRect(rect) {
|
|
|
154
152
|
if (container) container.style.display = "";
|
|
155
153
|
return Array.from(seen).filter((el) => !container?.contains(el));
|
|
156
154
|
}
|
|
155
|
+
function getElementAtPoint(x, y) {
|
|
156
|
+
const container = document.getElementById(WIDGET_CONTAINER_ID);
|
|
157
|
+
if (container) container.style.display = "none";
|
|
158
|
+
const el = document.elementFromPoint(x, y);
|
|
159
|
+
if (container) container.style.display = "";
|
|
160
|
+
if (el && container?.contains(el)) return null;
|
|
161
|
+
return el;
|
|
162
|
+
}
|
|
163
|
+
var DRAG_THRESHOLD = 10;
|
|
157
164
|
function PickOverlay({ onPick, onCancel }) {
|
|
158
|
-
const
|
|
159
|
-
const
|
|
160
|
-
const
|
|
161
|
-
const
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
165
|
+
const activeRef = (0, import_react.useRef)(false);
|
|
166
|
+
const startRef = (0, import_react.useRef)(null);
|
|
167
|
+
const isDragRef = (0, import_react.useRef)(false);
|
|
168
|
+
const [hoverRect, setHoverRect] = (0, import_react.useState)(null);
|
|
169
|
+
const [selRect, setSelRect] = (0, import_react.useState)(null);
|
|
170
|
+
const onPickRef = (0, import_react.useRef)(onPick);
|
|
171
|
+
onPickRef.current = onPick;
|
|
172
|
+
const onCancelRef = (0, import_react.useRef)(onCancel);
|
|
173
|
+
onCancelRef.current = onCancel;
|
|
174
|
+
(0, import_react.useEffect)(() => {
|
|
175
|
+
function handleMouseMove(e) {
|
|
176
|
+
if (activeRef.current && startRef.current) {
|
|
177
|
+
const dx = Math.abs(e.clientX - startRef.current.x);
|
|
178
|
+
const dy = Math.abs(e.clientY - startRef.current.y);
|
|
179
|
+
if (dx >= DRAG_THRESHOLD || dy >= DRAG_THRESHOLD) {
|
|
180
|
+
isDragRef.current = true;
|
|
181
|
+
}
|
|
182
|
+
if (isDragRef.current) {
|
|
183
|
+
setHoverRect(null);
|
|
184
|
+
setSelRect({
|
|
185
|
+
left: Math.min(startRef.current.x, e.clientX),
|
|
186
|
+
top: Math.min(startRef.current.y, e.clientY),
|
|
187
|
+
width: Math.abs(e.clientX - startRef.current.x),
|
|
188
|
+
height: Math.abs(e.clientY - startRef.current.y)
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
e.preventDefault();
|
|
192
|
+
} else {
|
|
193
|
+
const el = getElementAtPoint(e.clientX, e.clientY);
|
|
194
|
+
if (el) {
|
|
195
|
+
const r = el.getBoundingClientRect();
|
|
196
|
+
setHoverRect({ x: r.left, y: r.top, width: r.width, height: r.height });
|
|
197
|
+
} else {
|
|
198
|
+
setHoverRect(null);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
190
201
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
202
|
+
function handleMouseDown(e) {
|
|
203
|
+
if (e.button !== 0) return;
|
|
204
|
+
e.preventDefault();
|
|
205
|
+
e.stopPropagation();
|
|
206
|
+
startRef.current = { x: e.clientX, y: e.clientY };
|
|
207
|
+
isDragRef.current = false;
|
|
208
|
+
activeRef.current = true;
|
|
209
|
+
}
|
|
210
|
+
function handleMouseUp(e) {
|
|
211
|
+
if (!activeRef.current || !startRef.current) return;
|
|
212
|
+
e.preventDefault();
|
|
213
|
+
e.stopPropagation();
|
|
214
|
+
const start = startRef.current;
|
|
215
|
+
activeRef.current = false;
|
|
216
|
+
startRef.current = null;
|
|
217
|
+
setSelRect(null);
|
|
218
|
+
setHoverRect(null);
|
|
219
|
+
if (!isDragRef.current) {
|
|
220
|
+
const el = getElementAtPoint(e.clientX, e.clientY);
|
|
221
|
+
if (el) {
|
|
222
|
+
const r = el.getBoundingClientRect();
|
|
223
|
+
onPickRef.current({ x: r.left, y: r.top, width: r.width, height: r.height }, [el]);
|
|
224
|
+
}
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
const x = Math.min(start.x, e.clientX);
|
|
228
|
+
const y = Math.min(start.y, e.clientY);
|
|
229
|
+
const width = Math.abs(e.clientX - start.x);
|
|
230
|
+
const height = Math.abs(e.clientY - start.y);
|
|
231
|
+
const rect = { x, y, width, height };
|
|
232
|
+
const elements = getElementsBeneathRect(rect);
|
|
233
|
+
onPickRef.current(rect, elements);
|
|
234
|
+
}
|
|
235
|
+
function handleKeyDown(e) {
|
|
236
|
+
if (e.key === "Escape") {
|
|
237
|
+
activeRef.current = false;
|
|
238
|
+
startRef.current = null;
|
|
239
|
+
setSelRect(null);
|
|
240
|
+
setHoverRect(null);
|
|
241
|
+
onCancelRef.current();
|
|
242
|
+
}
|
|
203
243
|
}
|
|
204
|
-
}, [onCancel]);
|
|
205
|
-
(0, import_react.useEffect)(() => {
|
|
206
244
|
document.addEventListener("mousedown", handleMouseDown, true);
|
|
207
245
|
document.addEventListener("mousemove", handleMouseMove, true);
|
|
208
246
|
document.addEventListener("mouseup", handleMouseUp, true);
|
|
@@ -213,21 +251,11 @@ function PickOverlay({ onPick, onCancel }) {
|
|
|
213
251
|
document.removeEventListener("mouseup", handleMouseUp, true);
|
|
214
252
|
document.removeEventListener("keydown", handleKeyDown, true);
|
|
215
253
|
};
|
|
216
|
-
}, [
|
|
217
|
-
let selRect = null;
|
|
218
|
-
if (start && current && dragging) {
|
|
219
|
-
selRect = {
|
|
220
|
-
left: Math.min(start.x, current.x),
|
|
221
|
-
top: Math.min(start.y, current.y),
|
|
222
|
-
width: Math.abs(current.x - start.x),
|
|
223
|
-
height: Math.abs(current.y - start.y)
|
|
224
|
-
};
|
|
225
|
-
}
|
|
254
|
+
}, []);
|
|
226
255
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
227
256
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
228
257
|
"div",
|
|
229
258
|
{
|
|
230
|
-
ref: overlayRef,
|
|
231
259
|
style: {
|
|
232
260
|
position: "fixed",
|
|
233
261
|
top: 0,
|
|
@@ -257,12 +285,30 @@ function PickOverlay({ onPick, onCancel }) {
|
|
|
257
285
|
pointerEvents: "none"
|
|
258
286
|
},
|
|
259
287
|
children: [
|
|
260
|
-
"
|
|
288
|
+
"Click an element or drag to select an area. Press ",
|
|
261
289
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: "Esc" }),
|
|
262
290
|
" to cancel."
|
|
263
291
|
]
|
|
264
292
|
}
|
|
265
293
|
),
|
|
294
|
+
hoverRect && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
295
|
+
"div",
|
|
296
|
+
{
|
|
297
|
+
style: {
|
|
298
|
+
position: "fixed",
|
|
299
|
+
left: hoverRect.x,
|
|
300
|
+
top: hoverRect.y,
|
|
301
|
+
width: hoverRect.width,
|
|
302
|
+
height: hoverRect.height,
|
|
303
|
+
border: "2px solid #3b82f6",
|
|
304
|
+
background: "rgba(59, 130, 246, 0.08)",
|
|
305
|
+
zIndex: 99998,
|
|
306
|
+
pointerEvents: "none",
|
|
307
|
+
borderRadius: 2,
|
|
308
|
+
transition: "all 0.1s ease-out"
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
),
|
|
266
312
|
selRect && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
267
313
|
"div",
|
|
268
314
|
{
|
|
@@ -623,8 +669,25 @@ function SidePanel({
|
|
|
623
669
|
// src/components/DraftModal.tsx
|
|
624
670
|
var import_react4 = require("react");
|
|
625
671
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
672
|
+
var WIDGET_CONTAINER_ID2 = "llm-ui-feedback-root";
|
|
626
673
|
function DraftModal({ pendingContext, addingDraft, onAdd, onCancel }) {
|
|
627
674
|
const [comment, setComment] = (0, import_react4.useState)("");
|
|
675
|
+
(0, import_react4.useEffect)(() => {
|
|
676
|
+
const container = document.getElementById(WIDGET_CONTAINER_ID2);
|
|
677
|
+
const inerted = [];
|
|
678
|
+
for (const child of Array.from(document.body.children)) {
|
|
679
|
+
if (child === container || child.id === WIDGET_CONTAINER_ID2) continue;
|
|
680
|
+
if (!child.hasAttribute("inert")) {
|
|
681
|
+
child.setAttribute("inert", "");
|
|
682
|
+
inerted.push(child);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
return () => {
|
|
686
|
+
for (const el of inerted) {
|
|
687
|
+
el.removeAttribute("inert");
|
|
688
|
+
}
|
|
689
|
+
};
|
|
690
|
+
}, []);
|
|
628
691
|
const handleAdd = () => {
|
|
629
692
|
if (comment.trim() && !addingDraft) {
|
|
630
693
|
onAdd(comment.trim());
|
|
@@ -974,10 +1037,9 @@ function dataUrlToBlob(dataUrl) {
|
|
|
974
1037
|
|
|
975
1038
|
// src/hooks/useSession.ts
|
|
976
1039
|
var import_react6 = require("react");
|
|
977
|
-
var import_meta = {};
|
|
978
1040
|
var SESSION_TOKEN_KEY = "llm_feedback_session_token";
|
|
979
1041
|
var USER_KEY = "llm_feedback_user";
|
|
980
|
-
var AUTH_BYPASS = typeof
|
|
1042
|
+
var AUTH_BYPASS = !!(typeof globalThis !== "undefined" && globalThis.__FEEDBACK_AUTH_BYPASS__);
|
|
981
1043
|
function getSessionToken() {
|
|
982
1044
|
if (AUTH_BYPASS) return "bypass-token";
|
|
983
1045
|
return localStorage.getItem(SESSION_TOKEN_KEY);
|
|
@@ -1340,10 +1402,13 @@ function FeedbackWidget({
|
|
|
1340
1402
|
clickX: centerX,
|
|
1341
1403
|
clickY: centerY
|
|
1342
1404
|
};
|
|
1405
|
+
const isDrag = rect.width > 20 && rect.height > 20;
|
|
1343
1406
|
let screenshot = null;
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1407
|
+
if (isDrag) {
|
|
1408
|
+
try {
|
|
1409
|
+
screenshot = await captureScreenshot(rect);
|
|
1410
|
+
} catch {
|
|
1411
|
+
}
|
|
1347
1412
|
}
|
|
1348
1413
|
dispatch({ type: "ELEMENT_PICKED", context, screenshot });
|
|
1349
1414
|
}, []);
|