@david-xpn/llm-ui-feedback 0.1.1 → 0.1.2
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 -65
- 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());
|
|
@@ -977,7 +1040,7 @@ var import_react6 = require("react");
|
|
|
977
1040
|
var import_meta = {};
|
|
978
1041
|
var SESSION_TOKEN_KEY = "llm_feedback_session_token";
|
|
979
1042
|
var USER_KEY = "llm_feedback_user";
|
|
980
|
-
var AUTH_BYPASS = typeof import_meta !== "undefined" && import_meta.env?.VITE_AUTH_BYPASS === "true";
|
|
1043
|
+
var AUTH_BYPASS = typeof globalThis !== "undefined" && globalThis.__FEEDBACK_AUTH_BYPASS__ || typeof import_meta !== "undefined" && import_meta.env?.VITE_AUTH_BYPASS === "true";
|
|
981
1044
|
function getSessionToken() {
|
|
982
1045
|
if (AUTH_BYPASS) return "bypass-token";
|
|
983
1046
|
return localStorage.getItem(SESSION_TOKEN_KEY);
|
|
@@ -1340,10 +1403,13 @@ function FeedbackWidget({
|
|
|
1340
1403
|
clickX: centerX,
|
|
1341
1404
|
clickY: centerY
|
|
1342
1405
|
};
|
|
1406
|
+
const isDrag = rect.width > 20 && rect.height > 20;
|
|
1343
1407
|
let screenshot = null;
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1408
|
+
if (isDrag) {
|
|
1409
|
+
try {
|
|
1410
|
+
screenshot = await captureScreenshot(rect);
|
|
1411
|
+
} catch {
|
|
1412
|
+
}
|
|
1347
1413
|
}
|
|
1348
1414
|
dispatch({ type: "ELEMENT_PICKED", context, screenshot });
|
|
1349
1415
|
}, []);
|