@diegotsi/flint-react 0.5.1 → 1.0.0
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.cjs +618 -667
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -8
- package/dist/index.d.ts +38 -8
- package/dist/index.js +603 -662
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
@@ -22,21 +32,20 @@ var index_exports = {};
|
|
|
22
32
|
__export(index_exports, {
|
|
23
33
|
FlintModal: () => FlintModal,
|
|
24
34
|
FlintWidget: () => FlintWidget,
|
|
25
|
-
flint: () => flint
|
|
35
|
+
flint: () => import_core7.flint
|
|
26
36
|
});
|
|
27
37
|
module.exports = __toCommonJS(index_exports);
|
|
28
38
|
|
|
29
|
-
// src/FlintWidget.tsx
|
|
30
|
-
var import_react4 = require("react");
|
|
31
|
-
var import_react_i18next3 = require("react-i18next");
|
|
32
|
-
|
|
33
39
|
// src/FlintModal.tsx
|
|
34
40
|
var import_react2 = require("react");
|
|
35
41
|
var import_react_i18next = require("react-i18next");
|
|
36
42
|
|
|
43
|
+
// src/api.ts
|
|
44
|
+
var import_core = require("@flint/core");
|
|
45
|
+
|
|
37
46
|
// src/ScreenAnnotator.tsx
|
|
38
|
-
var import_react = require("react");
|
|
39
47
|
var import_modern_screenshot = require("modern-screenshot");
|
|
48
|
+
var import_react = require("react");
|
|
40
49
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
41
50
|
function normalizeRect(startX, startY, endX, endY) {
|
|
42
51
|
return {
|
|
@@ -81,9 +90,7 @@ function ScreenAnnotator({ zIndex, onCapture, onCancel }) {
|
|
|
81
90
|
const dpr = window.devicePixelRatio ?? 1;
|
|
82
91
|
const vw = window.innerWidth;
|
|
83
92
|
const vh = window.innerHeight;
|
|
84
|
-
await new Promise(
|
|
85
|
-
(resolve) => requestAnimationFrame(() => requestAnimationFrame(() => resolve()))
|
|
86
|
-
);
|
|
93
|
+
await new Promise((resolve) => requestAnimationFrame(() => requestAnimationFrame(() => resolve())));
|
|
87
94
|
try {
|
|
88
95
|
const fullCanvas = await (0, import_modern_screenshot.domToCanvas)(document.documentElement, {
|
|
89
96
|
scale: dpr,
|
|
@@ -98,17 +105,7 @@ function ScreenAnnotator({ zIndex, onCapture, onCancel }) {
|
|
|
98
105
|
canvas.width = vw * dpr;
|
|
99
106
|
canvas.height = vh * dpr;
|
|
100
107
|
const ctx = canvas.getContext("2d");
|
|
101
|
-
ctx.drawImage(
|
|
102
|
-
fullCanvas,
|
|
103
|
-
0,
|
|
104
|
-
0,
|
|
105
|
-
vw * dpr,
|
|
106
|
-
vh * dpr,
|
|
107
|
-
0,
|
|
108
|
-
0,
|
|
109
|
-
vw * dpr,
|
|
110
|
-
vh * dpr
|
|
111
|
-
);
|
|
108
|
+
ctx.drawImage(fullCanvas, 0, 0, vw * dpr, vh * dpr, 0, 0, vw * dpr, vh * dpr);
|
|
112
109
|
ctx.fillStyle = "rgba(255,200,0,0.25)";
|
|
113
110
|
ctx.fillRect(finalRect.x * dpr, finalRect.y * dpr, finalRect.w * dpr, finalRect.h * dpr);
|
|
114
111
|
ctx.strokeStyle = "#f97316";
|
|
@@ -146,123 +143,50 @@ function ScreenAnnotator({ zIndex, onCapture, onCancel }) {
|
|
|
146
143
|
pointerEvents: isCapturing ? "none" : "auto"
|
|
147
144
|
},
|
|
148
145
|
children: [
|
|
149
|
-
!isCapturing && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
146
|
+
!isCapturing && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
147
|
+
"div",
|
|
148
|
+
{
|
|
149
|
+
style: {
|
|
150
|
+
position: "absolute",
|
|
151
|
+
top: 16,
|
|
152
|
+
left: "50%",
|
|
153
|
+
transform: "translateX(-50%)",
|
|
154
|
+
background: "rgba(0,0,0,0.75)",
|
|
155
|
+
color: "#fff",
|
|
156
|
+
padding: "8px 18px",
|
|
157
|
+
borderRadius: 8,
|
|
158
|
+
fontSize: 14,
|
|
159
|
+
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
|
|
160
|
+
pointerEvents: "none",
|
|
161
|
+
whiteSpace: "nowrap",
|
|
162
|
+
backdropFilter: "blur(4px)"
|
|
163
|
+
},
|
|
164
|
+
children: "Drag to highlight the problem area \xA0\xB7\xA0 Esc to cancel"
|
|
165
|
+
}
|
|
166
|
+
),
|
|
167
|
+
rect && phase === "selecting" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
168
|
+
"div",
|
|
169
|
+
{
|
|
170
|
+
style: {
|
|
171
|
+
position: "absolute",
|
|
172
|
+
left: rect.x,
|
|
173
|
+
top: rect.y,
|
|
174
|
+
width: rect.w,
|
|
175
|
+
height: rect.h,
|
|
176
|
+
background: "rgba(255,200,0,0.2)",
|
|
177
|
+
border: "2px dashed #f97316",
|
|
178
|
+
boxSizing: "border-box",
|
|
179
|
+
pointerEvents: "none"
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
)
|
|
175
183
|
]
|
|
176
184
|
}
|
|
177
185
|
);
|
|
178
186
|
}
|
|
179
187
|
|
|
180
|
-
// src/api.ts
|
|
181
|
-
var import_fflate = require("fflate");
|
|
182
|
-
async function submitReport(serverUrl, projectKey, payload, screenshot) {
|
|
183
|
-
const url = `${serverUrl.replace(/\/$/, "")}/api/v1/bug-reports`;
|
|
184
|
-
let body;
|
|
185
|
-
let headers = {
|
|
186
|
-
"x-project-key": projectKey
|
|
187
|
-
};
|
|
188
|
-
if (screenshot) {
|
|
189
|
-
const form = new FormData();
|
|
190
|
-
form.append("reporterId", payload.reporterId);
|
|
191
|
-
form.append("reporterName", payload.reporterName);
|
|
192
|
-
form.append("description", payload.description);
|
|
193
|
-
if (payload.expectedBehavior) form.append("expectedBehavior", payload.expectedBehavior);
|
|
194
|
-
if (payload.stepsToReproduce) form.append("stepsToReproduce", JSON.stringify(payload.stepsToReproduce));
|
|
195
|
-
if (payload.externalReplayUrl) form.append("externalReplayUrl", payload.externalReplayUrl);
|
|
196
|
-
if (payload.additionalContext) form.append("additionalContext", payload.additionalContext);
|
|
197
|
-
form.append("severity", payload.severity);
|
|
198
|
-
if (payload.url) form.append("url", payload.url);
|
|
199
|
-
if (payload.meta) form.append("meta", JSON.stringify(payload.meta));
|
|
200
|
-
form.append("screenshot", screenshot);
|
|
201
|
-
body = form;
|
|
202
|
-
} else {
|
|
203
|
-
body = JSON.stringify(payload);
|
|
204
|
-
headers["Content-Type"] = "application/json";
|
|
205
|
-
}
|
|
206
|
-
const res = await fetch(url, { method: "POST", headers, body });
|
|
207
|
-
if (!res.ok) {
|
|
208
|
-
const err = await res.json().catch(() => ({ error: "Unknown error" }));
|
|
209
|
-
throw new Error(err.error ?? `HTTP ${res.status}`);
|
|
210
|
-
}
|
|
211
|
-
return res.json();
|
|
212
|
-
}
|
|
213
|
-
async function submitReplay(serverUrl, projectKey, reportId, events) {
|
|
214
|
-
const json = JSON.stringify(events);
|
|
215
|
-
const encoded = new TextEncoder().encode(json);
|
|
216
|
-
const compressed = (0, import_fflate.gzipSync)(encoded);
|
|
217
|
-
const url = `${serverUrl.replace(/\/$/, "")}/api/v1/bug-reports/${reportId}/replay`;
|
|
218
|
-
await fetch(url, {
|
|
219
|
-
method: "POST",
|
|
220
|
-
headers: {
|
|
221
|
-
"x-project-key": projectKey,
|
|
222
|
-
"Content-Type": "application/octet-stream"
|
|
223
|
-
},
|
|
224
|
-
body: compressed.buffer
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
|
|
228
188
|
// src/theme.ts
|
|
229
|
-
var
|
|
230
|
-
background: "rgba(255,255,255,0.90)",
|
|
231
|
-
backgroundSecondary: "rgba(249,250,251,0.75)",
|
|
232
|
-
accent: "#2563eb",
|
|
233
|
-
accentHover: "#1d4ed8",
|
|
234
|
-
text: "#111827",
|
|
235
|
-
textMuted: "#6b7280",
|
|
236
|
-
border: "rgba(255,255,255,0.9)",
|
|
237
|
-
shadow: "0 32px 80px rgba(0,0,0,0.18), 0 8px 32px rgba(0,0,0,0.1), 0 0 0 1px rgba(0,0,0,0.04)",
|
|
238
|
-
buttonText: "#ffffff",
|
|
239
|
-
backdropFilter: "blur(32px) saturate(1.8)"
|
|
240
|
-
};
|
|
241
|
-
var dark = {
|
|
242
|
-
background: "rgba(15,20,35,0.88)",
|
|
243
|
-
backgroundSecondary: "rgba(5,8,18,0.65)",
|
|
244
|
-
accent: "#f97316",
|
|
245
|
-
accentHover: "#ea6c0a",
|
|
246
|
-
text: "#dde3ef",
|
|
247
|
-
textMuted: "#6b7a93",
|
|
248
|
-
border: "rgba(255,255,255,0.08)",
|
|
249
|
-
shadow: "0 24px 60px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,255,255,0.04)",
|
|
250
|
-
buttonText: "#ffffff",
|
|
251
|
-
backdropFilter: "blur(32px) saturate(1.6)"
|
|
252
|
-
};
|
|
253
|
-
function resolveTheme(theme) {
|
|
254
|
-
if (theme === "dark") return dark;
|
|
255
|
-
if (theme === "light") return light;
|
|
256
|
-
const override = theme;
|
|
257
|
-
return {
|
|
258
|
-
...light,
|
|
259
|
-
background: override.background ?? light.background,
|
|
260
|
-
accent: override.accent ?? light.accent,
|
|
261
|
-
accentHover: override.accent ?? light.accentHover,
|
|
262
|
-
text: override.text ?? light.text,
|
|
263
|
-
border: override.border ?? light.border
|
|
264
|
-
};
|
|
265
|
-
}
|
|
189
|
+
var import_core2 = require("@flint/core");
|
|
266
190
|
|
|
267
191
|
// src/FlintModal.tsx
|
|
268
192
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
@@ -322,10 +246,15 @@ function FlintModal({
|
|
|
322
246
|
getNetworkErrors,
|
|
323
247
|
getReplayEvents,
|
|
324
248
|
getExternalReplayUrl,
|
|
325
|
-
initialSelection = ""
|
|
249
|
+
initialSelection = "",
|
|
250
|
+
enableScreenshot = true,
|
|
251
|
+
statusPageUrl,
|
|
252
|
+
onBeforeSubmit,
|
|
253
|
+
onSuccess,
|
|
254
|
+
onError
|
|
326
255
|
}) {
|
|
327
256
|
const { t } = (0, import_react_i18next.useTranslation)();
|
|
328
|
-
const colors = resolveTheme(theme);
|
|
257
|
+
const colors = (0, import_core2.resolveTheme)(theme);
|
|
329
258
|
const isDark = theme === "dark";
|
|
330
259
|
const [severity, setSeverity] = (0, import_react2.useState)("P2");
|
|
331
260
|
const [description, setDescription] = (0, import_react2.useState)("");
|
|
@@ -382,33 +311,40 @@ function FlintModal({
|
|
|
382
311
|
lang: textLang
|
|
383
312
|
};
|
|
384
313
|
}
|
|
314
|
+
const payload = {
|
|
315
|
+
reporterId: user?.id ?? "anonymous",
|
|
316
|
+
reporterName: user?.name ?? "Anonymous",
|
|
317
|
+
reporterEmail: user?.email,
|
|
318
|
+
description: isText ? `[Text issue] "${textOriginal.trim()}" \u2192 "${textSuggested.trim()}"` : description.trim(),
|
|
319
|
+
expectedBehavior: !isText ? expectedBehavior.trim() || void 0 : void 0,
|
|
320
|
+
externalReplayUrl: getExternalReplayUrl() || void 0,
|
|
321
|
+
severity: isText ? "P3" : severity,
|
|
322
|
+
url: window.location.href,
|
|
323
|
+
meta: collectedMeta,
|
|
324
|
+
label: isText ? "TEXT" : void 0
|
|
325
|
+
};
|
|
326
|
+
if (onBeforeSubmit) {
|
|
327
|
+
const proceed = await onBeforeSubmit(payload);
|
|
328
|
+
if (!proceed) {
|
|
329
|
+
setStatus("idle");
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
385
333
|
try {
|
|
386
|
-
const res = await submitReport(
|
|
387
|
-
serverUrl,
|
|
388
|
-
projectKey,
|
|
389
|
-
{
|
|
390
|
-
reporterId: user?.id ?? "anonymous",
|
|
391
|
-
reporterName: user?.name ?? "Anonymous",
|
|
392
|
-
description: isText ? `[Text issue] "${textOriginal.trim()}" \u2192 "${textSuggested.trim()}"` : description.trim(),
|
|
393
|
-
expectedBehavior: !isText ? expectedBehavior.trim() || void 0 : void 0,
|
|
394
|
-
externalReplayUrl: getExternalReplayUrl() || void 0,
|
|
395
|
-
severity: isText ? "P3" : severity,
|
|
396
|
-
url: window.location.href,
|
|
397
|
-
meta: collectedMeta,
|
|
398
|
-
label: isText ? "TEXT" : void 0
|
|
399
|
-
},
|
|
400
|
-
!isText ? screenshot ?? void 0 : void 0
|
|
401
|
-
);
|
|
334
|
+
const res = await (0, import_core.submitReport)(serverUrl, projectKey, payload, !isText ? screenshot ?? void 0 : void 0);
|
|
402
335
|
setResult(res);
|
|
403
336
|
setStatus("success");
|
|
337
|
+
onSuccess?.(res);
|
|
404
338
|
const events = getReplayEvents();
|
|
405
339
|
if (events.length > 0) {
|
|
406
|
-
submitReplay(serverUrl, projectKey, res.id, events).catch(() => {
|
|
340
|
+
(0, import_core.submitReplay)(serverUrl, projectKey, res.id, events).catch(() => {
|
|
407
341
|
});
|
|
408
342
|
}
|
|
409
343
|
} catch (err) {
|
|
410
|
-
|
|
344
|
+
const error = err instanceof Error ? err : new Error(t("errorLabel"));
|
|
345
|
+
setErrorMsg(error.message);
|
|
411
346
|
setStatus("error");
|
|
347
|
+
onError?.(error);
|
|
412
348
|
}
|
|
413
349
|
};
|
|
414
350
|
const inputBorder = isDark ? "rgba(255,255,255,0.1)" : "rgba(0,0,0,0.1)";
|
|
@@ -458,157 +394,249 @@ function FlintModal({
|
|
|
458
394
|
const isSuccess = status === "success";
|
|
459
395
|
const ringBorder = isSuccess ? "3px solid #22c55e" : `3px solid ${isDark ? "rgba(255,255,255,0.08)" : "rgba(0,0,0,0.08)"}`;
|
|
460
396
|
const ringTopColor = isSuccess ? "#22c55e" : colors.accent;
|
|
461
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: overlayStyle, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
397
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: overlayStyle, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
398
|
+
"div",
|
|
399
|
+
{
|
|
400
|
+
style: modalStyle,
|
|
401
|
+
role: "dialog",
|
|
402
|
+
"aria-modal": "true",
|
|
403
|
+
"aria-label": isSuccess ? t("successTitle") : t("sending"),
|
|
404
|
+
children: [
|
|
405
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ModalHeader, { colors, inputBorder, showClose: false, onClose }),
|
|
406
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
407
|
+
"div",
|
|
408
|
+
{
|
|
409
|
+
style: {
|
|
410
|
+
padding: "40px 32px 48px",
|
|
411
|
+
textAlign: "center",
|
|
412
|
+
display: "flex",
|
|
413
|
+
flexDirection: "column",
|
|
414
|
+
alignItems: "center"
|
|
415
|
+
},
|
|
416
|
+
children: [
|
|
417
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { position: "relative", width: 80, height: 80, marginBottom: 28 }, children: [
|
|
418
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
419
|
+
"div",
|
|
420
|
+
{
|
|
421
|
+
style: {
|
|
422
|
+
position: "absolute",
|
|
423
|
+
inset: -10,
|
|
424
|
+
borderRadius: "50%",
|
|
425
|
+
border: `1.5px solid ${colors.accent}`,
|
|
426
|
+
animation: "_flint_ripple 1.8s ease-out infinite",
|
|
427
|
+
opacity: isSuccess ? 0 : 1,
|
|
428
|
+
transition: "opacity 0.3s ease"
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
),
|
|
432
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
433
|
+
"div",
|
|
434
|
+
{
|
|
435
|
+
style: {
|
|
436
|
+
position: "absolute",
|
|
437
|
+
inset: -10,
|
|
438
|
+
borderRadius: "50%",
|
|
439
|
+
border: `1.5px solid ${colors.accent}`,
|
|
440
|
+
animation: "_flint_ripple 1.8s ease-out infinite 0.6s",
|
|
441
|
+
opacity: isSuccess ? 0 : 1,
|
|
442
|
+
transition: "opacity 0.3s ease"
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
),
|
|
446
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
447
|
+
"div",
|
|
448
|
+
{
|
|
449
|
+
style: {
|
|
450
|
+
position: "absolute",
|
|
451
|
+
inset: 0,
|
|
452
|
+
borderRadius: "50%",
|
|
453
|
+
border: ringBorder,
|
|
454
|
+
borderTopColor: ringTopColor,
|
|
455
|
+
animation: isSuccess ? "none" : "_flint_spin 0.85s linear infinite",
|
|
456
|
+
transition: "border-color 0.45s ease, border-top-color 0.45s ease"
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
),
|
|
460
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { position: "absolute", inset: 14, borderRadius: "50%" }, children: [
|
|
461
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
462
|
+
"div",
|
|
463
|
+
{
|
|
464
|
+
style: {
|
|
465
|
+
position: "absolute",
|
|
466
|
+
inset: 0,
|
|
467
|
+
borderRadius: "50%",
|
|
468
|
+
background: `linear-gradient(135deg, ${colors.accent}30, ${colors.accentHover}50)`,
|
|
469
|
+
display: "flex",
|
|
470
|
+
alignItems: "center",
|
|
471
|
+
justifyContent: "center",
|
|
472
|
+
animation: isSuccess ? "none" : "_flint_pulse 2s ease-in-out infinite",
|
|
473
|
+
opacity: isSuccess ? 0 : 1,
|
|
474
|
+
transition: "opacity 0.3s ease"
|
|
475
|
+
},
|
|
476
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SparkIcon, { color: colors.accent, size: 20 })
|
|
477
|
+
}
|
|
478
|
+
),
|
|
479
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
480
|
+
"div",
|
|
481
|
+
{
|
|
482
|
+
style: {
|
|
483
|
+
position: "absolute",
|
|
484
|
+
inset: 0,
|
|
485
|
+
borderRadius: "50%",
|
|
486
|
+
background: "rgba(34,197,94,0.15)",
|
|
487
|
+
display: "flex",
|
|
488
|
+
alignItems: "center",
|
|
489
|
+
justifyContent: "center",
|
|
490
|
+
opacity: isSuccess ? 1 : 0,
|
|
491
|
+
transform: isSuccess ? "scale(1)" : "scale(0.65)",
|
|
492
|
+
transition: "opacity 0.35s ease 0.2s, transform 0.4s cubic-bezier(0.16,1,0.3,1) 0.2s"
|
|
493
|
+
},
|
|
494
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(CheckIcon, { size: 20 })
|
|
495
|
+
}
|
|
496
|
+
)
|
|
497
|
+
] })
|
|
498
|
+
] }),
|
|
499
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { position: "relative", height: 26, width: "100%", marginBottom: 10 }, children: [
|
|
500
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
501
|
+
"div",
|
|
502
|
+
{
|
|
503
|
+
style: {
|
|
504
|
+
position: "absolute",
|
|
505
|
+
inset: 0,
|
|
506
|
+
display: "flex",
|
|
507
|
+
alignItems: "center",
|
|
508
|
+
justifyContent: "center",
|
|
509
|
+
fontSize: 19,
|
|
510
|
+
fontWeight: 700,
|
|
511
|
+
color: colors.text,
|
|
512
|
+
letterSpacing: "-0.02em",
|
|
513
|
+
opacity: isSuccess ? 0 : 1,
|
|
514
|
+
transition: "opacity 0.25s ease",
|
|
515
|
+
pointerEvents: "none"
|
|
516
|
+
},
|
|
517
|
+
children: t("sending")
|
|
518
|
+
}
|
|
519
|
+
),
|
|
520
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
521
|
+
"div",
|
|
522
|
+
{
|
|
523
|
+
style: {
|
|
524
|
+
position: "absolute",
|
|
525
|
+
inset: 0,
|
|
526
|
+
display: "flex",
|
|
527
|
+
alignItems: "center",
|
|
528
|
+
justifyContent: "center",
|
|
529
|
+
fontSize: 19,
|
|
530
|
+
fontWeight: 700,
|
|
531
|
+
color: colors.text,
|
|
532
|
+
letterSpacing: "-0.02em",
|
|
533
|
+
opacity: isSuccess ? 1 : 0,
|
|
534
|
+
transform: isSuccess ? "translateY(0)" : "translateY(6px)",
|
|
535
|
+
transition: "opacity 0.35s ease 0.25s, transform 0.35s ease 0.25s",
|
|
536
|
+
pointerEvents: isSuccess ? "auto" : "none"
|
|
537
|
+
},
|
|
538
|
+
children: t("successTitle")
|
|
539
|
+
}
|
|
540
|
+
)
|
|
541
|
+
] }),
|
|
542
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { position: "relative", minHeight: 76, width: "100%" }, children: [
|
|
543
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
544
|
+
"div",
|
|
545
|
+
{
|
|
546
|
+
style: {
|
|
547
|
+
position: "absolute",
|
|
548
|
+
inset: 0,
|
|
549
|
+
display: "flex",
|
|
550
|
+
alignItems: "center",
|
|
551
|
+
justifyContent: "center",
|
|
552
|
+
gap: 6,
|
|
553
|
+
color: colors.textMuted,
|
|
554
|
+
fontSize: 15,
|
|
555
|
+
opacity: isSuccess ? 0 : 1,
|
|
556
|
+
transition: "opacity 0.2s ease",
|
|
557
|
+
pointerEvents: "none"
|
|
558
|
+
},
|
|
559
|
+
children: [
|
|
560
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: t("capturingContext") }),
|
|
561
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SendingDots, { color: colors.accent })
|
|
562
|
+
]
|
|
563
|
+
}
|
|
564
|
+
),
|
|
565
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
566
|
+
"div",
|
|
567
|
+
{
|
|
568
|
+
style: {
|
|
569
|
+
position: "absolute",
|
|
570
|
+
inset: 0,
|
|
571
|
+
display: "flex",
|
|
572
|
+
flexDirection: "column",
|
|
573
|
+
alignItems: "center",
|
|
574
|
+
gap: 10,
|
|
575
|
+
opacity: isSuccess ? 1 : 0,
|
|
576
|
+
transform: isSuccess ? "translateY(0)" : "translateY(8px)",
|
|
577
|
+
transition: "opacity 0.35s ease 0.35s, transform 0.35s ease 0.35s",
|
|
578
|
+
pointerEvents: isSuccess ? "auto" : "none"
|
|
579
|
+
},
|
|
580
|
+
children: [
|
|
581
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { style: { fontSize: 15, color: colors.textMuted, margin: 0 }, children: result ? `ID: ${result.id}` : "" }),
|
|
582
|
+
statusPageUrl && user?.id && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
583
|
+
"a",
|
|
584
|
+
{
|
|
585
|
+
href: `${statusPageUrl}/status?project_key=${encodeURIComponent(projectKey)}&reporter_id=${encodeURIComponent(user.id)}&server_url=${encodeURIComponent(serverUrl)}`,
|
|
586
|
+
target: "_blank",
|
|
587
|
+
rel: "noreferrer",
|
|
588
|
+
style: {
|
|
589
|
+
fontSize: 14,
|
|
590
|
+
color: colors.accent,
|
|
591
|
+
textDecoration: "none",
|
|
592
|
+
fontWeight: 600,
|
|
593
|
+
animation: "_flint_success_up 0.35s ease 0.4s both"
|
|
594
|
+
},
|
|
595
|
+
children: [
|
|
596
|
+
"\u{1F4CB}",
|
|
597
|
+
" Track your bugs ",
|
|
598
|
+
"\u2192"
|
|
599
|
+
]
|
|
600
|
+
}
|
|
601
|
+
),
|
|
602
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
603
|
+
"button",
|
|
604
|
+
{
|
|
605
|
+
onClick: onClose,
|
|
606
|
+
style: {
|
|
607
|
+
width: "100%",
|
|
608
|
+
padding: "13px 20px",
|
|
609
|
+
borderRadius: 12,
|
|
610
|
+
border: "none",
|
|
611
|
+
background: `linear-gradient(135deg, ${colors.accent}, ${colors.accentHover})`,
|
|
612
|
+
color: colors.buttonText,
|
|
613
|
+
fontSize: 17,
|
|
614
|
+
fontWeight: 700,
|
|
615
|
+
cursor: "pointer",
|
|
616
|
+
letterSpacing: "-0.01em",
|
|
617
|
+
boxShadow: accentGlow,
|
|
618
|
+
fontFamily: "inherit",
|
|
619
|
+
display: "flex",
|
|
620
|
+
alignItems: "center",
|
|
621
|
+
justifyContent: "center",
|
|
622
|
+
gap: 8
|
|
623
|
+
},
|
|
624
|
+
children: t("close")
|
|
625
|
+
}
|
|
626
|
+
)
|
|
627
|
+
]
|
|
628
|
+
}
|
|
629
|
+
)
|
|
630
|
+
] })
|
|
631
|
+
]
|
|
632
|
+
}
|
|
633
|
+
)
|
|
634
|
+
]
|
|
635
|
+
}
|
|
636
|
+
) });
|
|
609
637
|
}
|
|
610
638
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
611
|
-
annotating && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
639
|
+
enableScreenshot && annotating && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
612
640
|
ScreenAnnotator,
|
|
613
641
|
{
|
|
614
642
|
zIndex: zIndex + 1,
|
|
@@ -632,37 +660,43 @@ function FlintModal({
|
|
|
632
660
|
}
|
|
633
661
|
),
|
|
634
662
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { onSubmit: handleSubmit, style: { padding: "20px 24px 24px" }, children: [
|
|
635
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
636
|
-
|
|
637
|
-
gap: 4,
|
|
638
|
-
marginBottom: 20,
|
|
639
|
-
background: colors.backgroundSecondary,
|
|
640
|
-
borderRadius: 12,
|
|
641
|
-
padding: 4,
|
|
642
|
-
border: `1px solid ${inputBorder}`
|
|
643
|
-
}, children: ["bug", "text"].map((m) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
644
|
-
"button",
|
|
663
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
664
|
+
"div",
|
|
645
665
|
{
|
|
646
|
-
type: "button",
|
|
647
|
-
onClick: () => setMode(m),
|
|
648
666
|
style: {
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
fontFamily: "inherit",
|
|
657
|
-
transition: "background 0.15s, color 0.15s",
|
|
658
|
-
background: mode === m ? `linear-gradient(135deg, ${colors.accent}, ${colors.accentHover})` : "transparent",
|
|
659
|
-
color: mode === m ? colors.buttonText : colors.textMuted,
|
|
660
|
-
boxShadow: mode === m ? `0 2px 8px ${colors.accent}30` : "none"
|
|
667
|
+
display: "flex",
|
|
668
|
+
gap: 4,
|
|
669
|
+
marginBottom: 20,
|
|
670
|
+
background: colors.backgroundSecondary,
|
|
671
|
+
borderRadius: 12,
|
|
672
|
+
padding: 4,
|
|
673
|
+
border: `1px solid ${inputBorder}`
|
|
661
674
|
},
|
|
662
|
-
children:
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
675
|
+
children: ["bug", "text"].map((m) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
676
|
+
"button",
|
|
677
|
+
{
|
|
678
|
+
type: "button",
|
|
679
|
+
onClick: () => setMode(m),
|
|
680
|
+
style: {
|
|
681
|
+
flex: 1,
|
|
682
|
+
padding: "8px 10px",
|
|
683
|
+
borderRadius: 9,
|
|
684
|
+
border: "none",
|
|
685
|
+
cursor: "pointer",
|
|
686
|
+
fontSize: 13,
|
|
687
|
+
fontWeight: mode === m ? 700 : 500,
|
|
688
|
+
fontFamily: "inherit",
|
|
689
|
+
transition: "background 0.15s, color 0.15s",
|
|
690
|
+
background: mode === m ? `linear-gradient(135deg, ${colors.accent}, ${colors.accentHover})` : "transparent",
|
|
691
|
+
color: mode === m ? colors.buttonText : colors.textMuted,
|
|
692
|
+
boxShadow: mode === m ? `0 2px 8px ${colors.accent}30` : "none"
|
|
693
|
+
},
|
|
694
|
+
children: m === "bug" ? "\u{1F41B} Bug" : "\u{1F524} Text / Translation"
|
|
695
|
+
},
|
|
696
|
+
m
|
|
697
|
+
))
|
|
698
|
+
}
|
|
699
|
+
),
|
|
666
700
|
mode === "text" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
667
701
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { marginBottom: 14 }, children: [
|
|
668
702
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FieldLabel, { colors, htmlFor: "flint-text-original", children: "Original text" }),
|
|
@@ -759,7 +793,7 @@ function FlintModal({
|
|
|
759
793
|
}
|
|
760
794
|
)
|
|
761
795
|
] }),
|
|
762
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { marginBottom: 20, display: mode === "text" ? "none" : void 0 }, children: [
|
|
796
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { marginBottom: 20, display: mode === "text" || !enableScreenshot ? "none" : void 0 }, children: [
|
|
763
797
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(FieldLabel, { colors, children: t("screenshotLabel") }),
|
|
764
798
|
screenshot ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 10 }, children: [
|
|
765
799
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
@@ -770,7 +804,20 @@ function FlintModal({
|
|
|
770
804
|
style: { height: 60, borderRadius: 8, objectFit: "cover", border: `1px solid ${inputBorder}` }
|
|
771
805
|
}
|
|
772
806
|
),
|
|
773
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
807
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
808
|
+
"span",
|
|
809
|
+
{
|
|
810
|
+
style: {
|
|
811
|
+
fontSize: 13,
|
|
812
|
+
color: colors.textMuted,
|
|
813
|
+
flex: 1,
|
|
814
|
+
overflow: "hidden",
|
|
815
|
+
textOverflow: "ellipsis",
|
|
816
|
+
whiteSpace: "nowrap"
|
|
817
|
+
},
|
|
818
|
+
children: screenshot.name
|
|
819
|
+
}
|
|
820
|
+
),
|
|
774
821
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
775
822
|
"button",
|
|
776
823
|
{
|
|
@@ -857,31 +904,43 @@ function FlintModal({
|
|
|
857
904
|
}
|
|
858
905
|
)
|
|
859
906
|
] }),
|
|
860
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
907
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
908
|
+
"div",
|
|
909
|
+
{
|
|
910
|
+
style: {
|
|
911
|
+
display: "flex",
|
|
912
|
+
alignItems: "center",
|
|
913
|
+
gap: 8,
|
|
914
|
+
padding: "9px 12px",
|
|
915
|
+
borderRadius: 10,
|
|
916
|
+
background: isDark ? "rgba(255,255,255,0.04)" : "rgba(0,77,240,0.04)",
|
|
917
|
+
border: `1px solid ${isDark ? "rgba(255,255,255,0.08)" : "rgba(0,77,240,0.1)"}`,
|
|
918
|
+
marginBottom: 16
|
|
919
|
+
},
|
|
920
|
+
children: [
|
|
921
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: 16 }, children: "\u{1F3A5}" }),
|
|
922
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: 14, color: colors.textMuted, lineHeight: 1.4 }, children: t("replayInfo") })
|
|
923
|
+
]
|
|
924
|
+
}
|
|
925
|
+
),
|
|
926
|
+
status === "error" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
927
|
+
"div",
|
|
928
|
+
{
|
|
929
|
+
style: {
|
|
930
|
+
padding: "10px 13px",
|
|
931
|
+
borderRadius: 10,
|
|
932
|
+
background: "rgba(239,68,68,0.08)",
|
|
933
|
+
border: "1px solid rgba(239,68,68,0.2)",
|
|
934
|
+
color: "#f87171",
|
|
935
|
+
fontSize: 14,
|
|
936
|
+
marginBottom: 16
|
|
937
|
+
},
|
|
938
|
+
children: [
|
|
939
|
+
"\u26A0\uFE0F ",
|
|
940
|
+
errorMsg || t("errorLabel")
|
|
941
|
+
]
|
|
942
|
+
}
|
|
943
|
+
),
|
|
885
944
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
886
945
|
"button",
|
|
887
946
|
{
|
|
@@ -942,49 +1001,68 @@ function ModalHeader({
|
|
|
942
1001
|
titleId,
|
|
943
1002
|
title
|
|
944
1003
|
}) {
|
|
945
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
1004
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1005
|
+
"div",
|
|
1006
|
+
{
|
|
1007
|
+
style: {
|
|
1008
|
+
display: "flex",
|
|
1009
|
+
alignItems: "center",
|
|
1010
|
+
gap: 10,
|
|
1011
|
+
padding: "16px 20px 14px",
|
|
1012
|
+
borderBottom: `1px solid ${inputBorder}`
|
|
1013
|
+
},
|
|
1014
|
+
children: [
|
|
1015
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1016
|
+
"div",
|
|
1017
|
+
{
|
|
1018
|
+
style: {
|
|
1019
|
+
width: 28,
|
|
1020
|
+
height: 28,
|
|
1021
|
+
borderRadius: 8,
|
|
1022
|
+
background: `linear-gradient(135deg, ${colors.accent}20, ${colors.accentHover}35)`,
|
|
1023
|
+
border: `1px solid ${colors.accent}30`,
|
|
1024
|
+
display: "flex",
|
|
1025
|
+
alignItems: "center",
|
|
1026
|
+
justifyContent: "center",
|
|
1027
|
+
flexShrink: 0
|
|
1028
|
+
},
|
|
1029
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SparkIcon, { color: colors.accent, size: 13 })
|
|
1030
|
+
}
|
|
1031
|
+
),
|
|
1032
|
+
titleId && title ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1033
|
+
"h2",
|
|
1034
|
+
{
|
|
1035
|
+
id: titleId,
|
|
1036
|
+
style: { margin: 0, fontSize: 16, fontWeight: 600, color: colors.text, letterSpacing: "-0.01em", flex: 1 },
|
|
1037
|
+
children: title
|
|
1038
|
+
}
|
|
1039
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { flex: 1, fontSize: 15, fontWeight: 600, color: colors.textMuted }, children: "Flint" }),
|
|
1040
|
+
showClose && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1041
|
+
"button",
|
|
1042
|
+
{
|
|
1043
|
+
onClick: onClose,
|
|
1044
|
+
"aria-label": "Close",
|
|
1045
|
+
style: {
|
|
1046
|
+
background: "none",
|
|
1047
|
+
border: "none",
|
|
1048
|
+
cursor: "pointer",
|
|
1049
|
+
padding: 4,
|
|
1050
|
+
color: colors.textMuted,
|
|
1051
|
+
fontSize: 22,
|
|
1052
|
+
lineHeight: 1,
|
|
1053
|
+
borderRadius: 6,
|
|
1054
|
+
display: "flex",
|
|
1055
|
+
alignItems: "center",
|
|
1056
|
+
justifyContent: "center",
|
|
1057
|
+
opacity: 0.6,
|
|
1058
|
+
fontFamily: "inherit"
|
|
1059
|
+
},
|
|
1060
|
+
children: "\xD7"
|
|
1061
|
+
}
|
|
1062
|
+
)
|
|
1063
|
+
]
|
|
1064
|
+
}
|
|
1065
|
+
);
|
|
988
1066
|
}
|
|
989
1067
|
function FieldLabel({
|
|
990
1068
|
children,
|
|
@@ -1046,19 +1124,71 @@ function SeverityButton({ sev, label, selected, hint, color, accent, border, bg,
|
|
|
1046
1124
|
},
|
|
1047
1125
|
children: [
|
|
1048
1126
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { width: 8, height: 8, borderRadius: "50%", background: color, display: "block" } }),
|
|
1049
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1127
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1128
|
+
"span",
|
|
1129
|
+
{
|
|
1130
|
+
style: {
|
|
1131
|
+
fontSize: 13,
|
|
1132
|
+
fontWeight: selected ? 700 : 500,
|
|
1133
|
+
color: selected ? accent : text,
|
|
1134
|
+
letterSpacing: "0.02em"
|
|
1135
|
+
},
|
|
1136
|
+
children: sev
|
|
1137
|
+
}
|
|
1138
|
+
),
|
|
1050
1139
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontSize: 11, color: selected ? accent : text, opacity: 0.6, letterSpacing: "0.02em" }, children: label })
|
|
1051
1140
|
]
|
|
1052
1141
|
}
|
|
1053
1142
|
);
|
|
1054
1143
|
}
|
|
1055
1144
|
function SparkIcon({ color = "currentColor", size = 14 }) {
|
|
1056
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1145
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1146
|
+
"svg",
|
|
1147
|
+
{
|
|
1148
|
+
width: size,
|
|
1149
|
+
height: size,
|
|
1150
|
+
viewBox: "0 0 24 24",
|
|
1151
|
+
fill: "none",
|
|
1152
|
+
stroke: color,
|
|
1153
|
+
strokeWidth: "2.2",
|
|
1154
|
+
strokeLinecap: "round",
|
|
1155
|
+
strokeLinejoin: "round",
|
|
1156
|
+
"aria-hidden": "true",
|
|
1157
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M13 2L3 14h9l-1 8 10-12h-9l1-8z" })
|
|
1158
|
+
}
|
|
1159
|
+
);
|
|
1057
1160
|
}
|
|
1058
1161
|
function CheckIcon({ size = 20 }) {
|
|
1059
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1162
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1163
|
+
"svg",
|
|
1164
|
+
{
|
|
1165
|
+
width: size,
|
|
1166
|
+
height: size,
|
|
1167
|
+
viewBox: "0 0 24 24",
|
|
1168
|
+
fill: "none",
|
|
1169
|
+
stroke: "#22c55e",
|
|
1170
|
+
strokeWidth: "2.5",
|
|
1171
|
+
strokeLinecap: "round",
|
|
1172
|
+
strokeLinejoin: "round",
|
|
1173
|
+
"aria-hidden": "true",
|
|
1174
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("polyline", { points: "20 6 9 17 4 12" })
|
|
1175
|
+
}
|
|
1176
|
+
);
|
|
1060
1177
|
}
|
|
1061
1178
|
|
|
1179
|
+
// src/FlintWidget.tsx
|
|
1180
|
+
var import_react4 = require("react");
|
|
1181
|
+
var import_react_i18next3 = require("react-i18next");
|
|
1182
|
+
|
|
1183
|
+
// src/collectors/console.ts
|
|
1184
|
+
var import_core3 = require("@flint/core");
|
|
1185
|
+
|
|
1186
|
+
// src/collectors/environment.ts
|
|
1187
|
+
var import_core4 = require("@flint/core");
|
|
1188
|
+
|
|
1189
|
+
// src/collectors/network.ts
|
|
1190
|
+
var import_core5 = require("@flint/core");
|
|
1191
|
+
|
|
1062
1192
|
// src/i18n/index.ts
|
|
1063
1193
|
var import_i18next = require("i18next");
|
|
1064
1194
|
var import_react_i18next2 = require("react-i18next");
|
|
@@ -1108,251 +1238,15 @@ widgetI18n.use(import_react_i18next2.initReactI18next).init({
|
|
|
1108
1238
|
});
|
|
1109
1239
|
var i18n_default = widgetI18n;
|
|
1110
1240
|
|
|
1111
|
-
// src/collectors/environment.ts
|
|
1112
|
-
function collectEnvironment() {
|
|
1113
|
-
const ua = navigator.userAgent;
|
|
1114
|
-
let browser = "Unknown";
|
|
1115
|
-
const chromeM = ua.match(/Chrome\/(\d+)/);
|
|
1116
|
-
const firefoxM = ua.match(/Firefox\/(\d+)/);
|
|
1117
|
-
const edgeM = ua.match(/Edg\/(\d+)/);
|
|
1118
|
-
const safariM = ua.match(/Version\/(\d+)/);
|
|
1119
|
-
const operaM = ua.match(/OPR\/(\d+)/);
|
|
1120
|
-
if (operaM) {
|
|
1121
|
-
browser = `Opera ${operaM[1]}`;
|
|
1122
|
-
} else if (edgeM) {
|
|
1123
|
-
browser = `Edge ${edgeM[1]}`;
|
|
1124
|
-
} else if (chromeM && !/Edg|OPR/.test(ua)) {
|
|
1125
|
-
browser = `Chrome ${chromeM[1]}`;
|
|
1126
|
-
} else if (firefoxM) {
|
|
1127
|
-
browser = `Firefox ${firefoxM[1]}`;
|
|
1128
|
-
} else if (safariM && /Safari\//.test(ua)) {
|
|
1129
|
-
browser = `Safari ${safariM[1]}`;
|
|
1130
|
-
}
|
|
1131
|
-
let os = "Unknown";
|
|
1132
|
-
const macM = ua.match(/Mac OS X (\d+[._]\d+)/);
|
|
1133
|
-
const winM = ua.match(/Windows NT (\d+\.\d+)/);
|
|
1134
|
-
const androidM = ua.match(/Android (\d+)/);
|
|
1135
|
-
const iosM = ua.match(/iPhone OS (\d+[._]\d+)/);
|
|
1136
|
-
if (macM) {
|
|
1137
|
-
os = `macOS ${macM[1].replace("_", ".")}`;
|
|
1138
|
-
} else if (winM) {
|
|
1139
|
-
const winMap = {
|
|
1140
|
-
"10.0": "10/11",
|
|
1141
|
-
"6.3": "8.1",
|
|
1142
|
-
"6.2": "8",
|
|
1143
|
-
"6.1": "7"
|
|
1144
|
-
};
|
|
1145
|
-
os = `Windows ${winMap[winM[1]] ?? winM[1]}`;
|
|
1146
|
-
} else if (androidM) {
|
|
1147
|
-
os = `Android ${androidM[1]}`;
|
|
1148
|
-
} else if (iosM) {
|
|
1149
|
-
os = `iOS ${iosM[1].replace(/_/g, ".")}`;
|
|
1150
|
-
} else if (/Linux/.test(ua)) {
|
|
1151
|
-
os = "Linux";
|
|
1152
|
-
}
|
|
1153
|
-
return {
|
|
1154
|
-
browser,
|
|
1155
|
-
os,
|
|
1156
|
-
viewport: `${window.innerWidth}x${window.innerHeight}`,
|
|
1157
|
-
screen: `${screen.width}x${screen.height}`,
|
|
1158
|
-
language: navigator.language,
|
|
1159
|
-
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
1160
|
-
online: navigator.onLine
|
|
1161
|
-
};
|
|
1162
|
-
}
|
|
1163
|
-
|
|
1164
|
-
// src/collectors/console.ts
|
|
1165
|
-
var MAX_ENTRIES = 50;
|
|
1166
|
-
function createConsoleCollector() {
|
|
1167
|
-
const entries = [];
|
|
1168
|
-
let active = false;
|
|
1169
|
-
const originals = {
|
|
1170
|
-
log: console.log.bind(console),
|
|
1171
|
-
warn: console.warn.bind(console),
|
|
1172
|
-
error: console.error.bind(console)
|
|
1173
|
-
};
|
|
1174
|
-
let origOnerror = null;
|
|
1175
|
-
let origUnhandled = null;
|
|
1176
|
-
function push(level, args) {
|
|
1177
|
-
let str;
|
|
1178
|
-
try {
|
|
1179
|
-
str = args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ");
|
|
1180
|
-
} catch {
|
|
1181
|
-
str = String(args[0]);
|
|
1182
|
-
}
|
|
1183
|
-
if (str.length > 500) str = str.slice(0, 500) + "\u2026";
|
|
1184
|
-
entries.push({ level, args: str, timestamp: Date.now() });
|
|
1185
|
-
if (entries.length > MAX_ENTRIES) entries.shift();
|
|
1186
|
-
}
|
|
1187
|
-
return {
|
|
1188
|
-
start() {
|
|
1189
|
-
if (active) return;
|
|
1190
|
-
active = true;
|
|
1191
|
-
console.log = (...args) => {
|
|
1192
|
-
push("log", args);
|
|
1193
|
-
originals.log(...args);
|
|
1194
|
-
};
|
|
1195
|
-
console.warn = (...args) => {
|
|
1196
|
-
push("warn", args);
|
|
1197
|
-
originals.warn(...args);
|
|
1198
|
-
};
|
|
1199
|
-
console.error = (...args) => {
|
|
1200
|
-
push("error", args);
|
|
1201
|
-
originals.error(...args);
|
|
1202
|
-
};
|
|
1203
|
-
origOnerror = window.onerror;
|
|
1204
|
-
window.onerror = (msg, src, line, col, err) => {
|
|
1205
|
-
push("error", [err?.message ?? String(msg), `${src}:${line}:${col}`]);
|
|
1206
|
-
if (typeof origOnerror === "function")
|
|
1207
|
-
return origOnerror(msg, src, line, col, err);
|
|
1208
|
-
return false;
|
|
1209
|
-
};
|
|
1210
|
-
origUnhandled = window.onunhandledrejection;
|
|
1211
|
-
window.onunhandledrejection = (event) => {
|
|
1212
|
-
const reason = event.reason instanceof Error ? event.reason.message : JSON.stringify(event.reason);
|
|
1213
|
-
push("error", ["UnhandledRejection:", reason]);
|
|
1214
|
-
if (typeof origUnhandled === "function")
|
|
1215
|
-
origUnhandled.call(window, event);
|
|
1216
|
-
};
|
|
1217
|
-
},
|
|
1218
|
-
stop() {
|
|
1219
|
-
if (!active) return;
|
|
1220
|
-
active = false;
|
|
1221
|
-
console.log = originals.log;
|
|
1222
|
-
console.warn = originals.warn;
|
|
1223
|
-
console.error = originals.error;
|
|
1224
|
-
window.onerror = origOnerror;
|
|
1225
|
-
window.onunhandledrejection = origUnhandled;
|
|
1226
|
-
},
|
|
1227
|
-
getEntries() {
|
|
1228
|
-
return [...entries];
|
|
1229
|
-
}
|
|
1230
|
-
};
|
|
1231
|
-
}
|
|
1232
|
-
|
|
1233
|
-
// src/collectors/network.ts
|
|
1234
|
-
var MAX_ENTRIES2 = 20;
|
|
1235
|
-
var BLOCKED_HOSTS = /* @__PURE__ */ new Set([
|
|
1236
|
-
"browser-intake-datadoghq.com",
|
|
1237
|
-
"rum.browser-intake-datadoghq.com",
|
|
1238
|
-
"logs.browser-intake-datadoghq.com",
|
|
1239
|
-
"session-replay.browser-intake-datadoghq.com"
|
|
1240
|
-
]);
|
|
1241
|
-
function isBlockedUrl(url, extra) {
|
|
1242
|
-
try {
|
|
1243
|
-
const host = new URL(url, location.href).hostname;
|
|
1244
|
-
const all = [...BLOCKED_HOSTS, ...extra];
|
|
1245
|
-
return all.some((b) => host === b || host.endsWith("." + b));
|
|
1246
|
-
} catch {
|
|
1247
|
-
return false;
|
|
1248
|
-
}
|
|
1249
|
-
}
|
|
1250
|
-
function truncateUrl(url) {
|
|
1251
|
-
try {
|
|
1252
|
-
const u = new URL(url, location.href);
|
|
1253
|
-
const base = `${u.origin}${u.pathname}`;
|
|
1254
|
-
return base.length > 200 ? base.slice(0, 200) + "\u2026" : base;
|
|
1255
|
-
} catch {
|
|
1256
|
-
return url.length > 200 ? url.slice(0, 200) + "\u2026" : url;
|
|
1257
|
-
}
|
|
1258
|
-
}
|
|
1259
|
-
function createNetworkCollector(extraBlockedHosts = []) {
|
|
1260
|
-
const entries = [];
|
|
1261
|
-
const blocked = new Set(extraBlockedHosts);
|
|
1262
|
-
let origFetch = null;
|
|
1263
|
-
let origXHROpen = null;
|
|
1264
|
-
let active = false;
|
|
1265
|
-
function push(entry) {
|
|
1266
|
-
entries.push(entry);
|
|
1267
|
-
if (entries.length > MAX_ENTRIES2) entries.shift();
|
|
1268
|
-
}
|
|
1269
|
-
return {
|
|
1270
|
-
start() {
|
|
1271
|
-
if (active) return;
|
|
1272
|
-
active = true;
|
|
1273
|
-
origFetch = window.fetch;
|
|
1274
|
-
window.fetch = async (input, init) => {
|
|
1275
|
-
const method = (init?.method ?? "GET").toUpperCase();
|
|
1276
|
-
const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
1277
|
-
const startTime = Date.now();
|
|
1278
|
-
const res = await origFetch.call(window, input, init);
|
|
1279
|
-
if (!isBlockedUrl(url, blocked)) {
|
|
1280
|
-
push({
|
|
1281
|
-
method,
|
|
1282
|
-
url: truncateUrl(url),
|
|
1283
|
-
status: res.status,
|
|
1284
|
-
duration: Date.now() - startTime,
|
|
1285
|
-
timestamp: startTime
|
|
1286
|
-
});
|
|
1287
|
-
}
|
|
1288
|
-
return res;
|
|
1289
|
-
};
|
|
1290
|
-
origXHROpen = XMLHttpRequest.prototype.open;
|
|
1291
|
-
XMLHttpRequest.prototype.open = function(method, url, async, username, password) {
|
|
1292
|
-
const startTime = Date.now();
|
|
1293
|
-
const urlStr = typeof url === "string" ? url : url.href;
|
|
1294
|
-
this.addEventListener("load", () => {
|
|
1295
|
-
if (!isBlockedUrl(urlStr, blocked)) {
|
|
1296
|
-
push({
|
|
1297
|
-
method: method.toUpperCase(),
|
|
1298
|
-
url: truncateUrl(urlStr),
|
|
1299
|
-
status: this.status,
|
|
1300
|
-
duration: Date.now() - startTime,
|
|
1301
|
-
timestamp: startTime
|
|
1302
|
-
});
|
|
1303
|
-
}
|
|
1304
|
-
});
|
|
1305
|
-
return origXHROpen.apply(this, [
|
|
1306
|
-
method,
|
|
1307
|
-
url,
|
|
1308
|
-
async ?? true,
|
|
1309
|
-
username,
|
|
1310
|
-
password
|
|
1311
|
-
]);
|
|
1312
|
-
};
|
|
1313
|
-
},
|
|
1314
|
-
stop() {
|
|
1315
|
-
if (!active) return;
|
|
1316
|
-
active = false;
|
|
1317
|
-
if (origFetch) window.fetch = origFetch;
|
|
1318
|
-
if (origXHROpen) XMLHttpRequest.prototype.open = origXHROpen;
|
|
1319
|
-
},
|
|
1320
|
-
getEntries() {
|
|
1321
|
-
return [...entries];
|
|
1322
|
-
}
|
|
1323
|
-
};
|
|
1324
|
-
}
|
|
1325
|
-
|
|
1326
1241
|
// src/store.ts
|
|
1242
|
+
var import_core6 = require("@flint/core");
|
|
1327
1243
|
var import_react3 = require("react");
|
|
1328
|
-
var
|
|
1329
|
-
var listeners = /* @__PURE__ */ new Set();
|
|
1330
|
-
function emit() {
|
|
1331
|
-
listeners.forEach((fn) => fn());
|
|
1332
|
-
}
|
|
1333
|
-
function subscribeStore(fn) {
|
|
1334
|
-
listeners.add(fn);
|
|
1335
|
-
return () => listeners.delete(fn);
|
|
1336
|
-
}
|
|
1337
|
-
function getSnapshot() {
|
|
1338
|
-
return state;
|
|
1339
|
-
}
|
|
1244
|
+
var import_core7 = require("@flint/core");
|
|
1340
1245
|
function useFlintStore() {
|
|
1341
|
-
return (0, import_react3.useSyncExternalStore)(
|
|
1246
|
+
return (0, import_react3.useSyncExternalStore)(import_core6.subscribe, import_core6.getSnapshot);
|
|
1342
1247
|
}
|
|
1343
|
-
var flint = {
|
|
1344
|
-
setUser(user) {
|
|
1345
|
-
state = { ...state, user: user ?? void 0 };
|
|
1346
|
-
emit();
|
|
1347
|
-
},
|
|
1348
|
-
setSessionReplay(url) {
|
|
1349
|
-
state = { ...state, sessionReplay: url };
|
|
1350
|
-
emit();
|
|
1351
|
-
}
|
|
1352
|
-
};
|
|
1353
1248
|
|
|
1354
1249
|
// src/FlintWidget.tsx
|
|
1355
|
-
var import_rrweb = require("rrweb");
|
|
1356
1250
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1357
1251
|
var REPLAY_WINDOW_MS = 6e4;
|
|
1358
1252
|
function FlintWidget(props) {
|
|
@@ -1370,20 +1264,46 @@ function WidgetContent({
|
|
|
1370
1264
|
extraFields,
|
|
1371
1265
|
buttonLabel,
|
|
1372
1266
|
theme = "dark",
|
|
1373
|
-
zIndex = 9999
|
|
1267
|
+
zIndex = 9999,
|
|
1268
|
+
statusPageUrl,
|
|
1269
|
+
datadogSite,
|
|
1270
|
+
enableReplay = true,
|
|
1271
|
+
enableScreenshot = true,
|
|
1272
|
+
enableConsole = true,
|
|
1273
|
+
enableNetwork = true,
|
|
1274
|
+
onBeforeSubmit,
|
|
1275
|
+
onSuccess,
|
|
1276
|
+
onError,
|
|
1277
|
+
onOpen,
|
|
1278
|
+
onClose
|
|
1374
1279
|
}) {
|
|
1375
1280
|
const globalState = useFlintStore();
|
|
1376
1281
|
const resolvedUser = user ?? globalState.user;
|
|
1377
1282
|
const resolvedSessionReplay = extraFields?.sessionReplay ?? globalState.sessionReplay;
|
|
1378
1283
|
const getExternalReplayUrl = () => {
|
|
1379
1284
|
const src = resolvedSessionReplay;
|
|
1380
|
-
|
|
1285
|
+
const explicit = typeof src === "function" ? src() : src;
|
|
1286
|
+
if (explicit) return explicit;
|
|
1287
|
+
if (datadogSite) {
|
|
1288
|
+
try {
|
|
1289
|
+
const ddRum = window.DD_RUM;
|
|
1290
|
+
const ctx = ddRum?.getInternalContext?.();
|
|
1291
|
+
if (ctx?.session_id) {
|
|
1292
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1293
|
+
const fromTs = now - 30;
|
|
1294
|
+
const toTs = now + 5;
|
|
1295
|
+
return `https://${datadogSite}/rum/replay/sessions/${ctx.session_id}?from_ts=${fromTs}&to_ts=${toTs}&tab=replay&live=false`;
|
|
1296
|
+
}
|
|
1297
|
+
} catch {
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
return void 0;
|
|
1381
1301
|
};
|
|
1382
1302
|
const { t } = (0, import_react_i18next3.useTranslation)();
|
|
1383
1303
|
const [open, setOpen] = (0, import_react4.useState)(false);
|
|
1384
1304
|
const [hovered, setHovered] = (0, import_react4.useState)(false);
|
|
1385
1305
|
const pendingSelection = (0, import_react4.useRef)("");
|
|
1386
|
-
const colors = resolveTheme(theme);
|
|
1306
|
+
const colors = (0, import_core2.resolveTheme)(theme);
|
|
1387
1307
|
const [selectionTooltip, setSelectionTooltip] = (0, import_react4.useState)(null);
|
|
1388
1308
|
const tooltipRef = (0, import_react4.useRef)(null);
|
|
1389
1309
|
const triggerRef = (0, import_react4.useRef)(null);
|
|
@@ -1424,16 +1344,17 @@ function WidgetContent({
|
|
|
1424
1344
|
pendingSelection.current = text;
|
|
1425
1345
|
setSelectionTooltip(null);
|
|
1426
1346
|
setOpen(true);
|
|
1347
|
+
onOpen?.();
|
|
1427
1348
|
};
|
|
1428
1349
|
const consoleCollector = (0, import_react4.useRef)(null);
|
|
1429
1350
|
const networkCollector = (0, import_react4.useRef)(null);
|
|
1430
1351
|
const replayEvents = (0, import_react4.useRef)([]);
|
|
1431
1352
|
const stopReplay = (0, import_react4.useRef)(null);
|
|
1432
|
-
if (!consoleCollector.current) {
|
|
1433
|
-
consoleCollector.current = createConsoleCollector();
|
|
1353
|
+
if (enableConsole && !consoleCollector.current) {
|
|
1354
|
+
consoleCollector.current = (0, import_core3.createConsoleCollector)();
|
|
1434
1355
|
consoleCollector.current.start();
|
|
1435
1356
|
}
|
|
1436
|
-
if (!networkCollector.current) {
|
|
1357
|
+
if (enableNetwork && !networkCollector.current) {
|
|
1437
1358
|
const flintHost = (() => {
|
|
1438
1359
|
try {
|
|
1439
1360
|
return new URL(serverUrl).hostname;
|
|
@@ -1441,26 +1362,33 @@ function WidgetContent({
|
|
|
1441
1362
|
return "";
|
|
1442
1363
|
}
|
|
1443
1364
|
})();
|
|
1444
|
-
networkCollector.current = createNetworkCollector(flintHost ? [flintHost] : []);
|
|
1365
|
+
networkCollector.current = (0, import_core5.createNetworkCollector)(flintHost ? [flintHost] : []);
|
|
1445
1366
|
networkCollector.current.start();
|
|
1446
1367
|
}
|
|
1447
1368
|
(0, import_react4.useEffect)(() => {
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1369
|
+
let cancelled = false;
|
|
1370
|
+
if (enableReplay) {
|
|
1371
|
+
import("rrweb").then(({ record }) => {
|
|
1372
|
+
if (cancelled) return;
|
|
1373
|
+
const stopFn = record({
|
|
1374
|
+
emit(event) {
|
|
1375
|
+
replayEvents.current.push(event);
|
|
1376
|
+
const cutoff = Date.now() - REPLAY_WINDOW_MS;
|
|
1377
|
+
while (replayEvents.current.length > 0 && replayEvents.current[0].timestamp < cutoff) {
|
|
1378
|
+
replayEvents.current.shift();
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
});
|
|
1382
|
+
stopReplay.current = stopFn ?? null;
|
|
1383
|
+
});
|
|
1384
|
+
}
|
|
1458
1385
|
return () => {
|
|
1386
|
+
cancelled = true;
|
|
1459
1387
|
consoleCollector.current?.stop();
|
|
1460
1388
|
networkCollector.current?.stop();
|
|
1461
1389
|
stopReplay.current?.();
|
|
1462
1390
|
};
|
|
1463
|
-
}, []);
|
|
1391
|
+
}, [enableReplay]);
|
|
1464
1392
|
const label = buttonLabel ?? t("buttonLabel");
|
|
1465
1393
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
1466
1394
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
@@ -1470,7 +1398,10 @@ function WidgetContent({
|
|
|
1470
1398
|
onMouseDown: () => {
|
|
1471
1399
|
pendingSelection.current = window.getSelection()?.toString().trim() ?? "";
|
|
1472
1400
|
},
|
|
1473
|
-
onClick: () =>
|
|
1401
|
+
onClick: () => {
|
|
1402
|
+
setOpen(true);
|
|
1403
|
+
onOpen?.();
|
|
1404
|
+
},
|
|
1474
1405
|
onMouseEnter: () => setHovered(true),
|
|
1475
1406
|
onMouseLeave: () => setHovered(false),
|
|
1476
1407
|
"aria-label": label,
|
|
@@ -1551,25 +1482,45 @@ function WidgetContent({
|
|
|
1551
1482
|
zIndex,
|
|
1552
1483
|
onClose: () => {
|
|
1553
1484
|
setOpen(false);
|
|
1485
|
+
onClose?.();
|
|
1554
1486
|
pendingSelection.current = "";
|
|
1555
1487
|
},
|
|
1556
|
-
getEnvironment: collectEnvironment,
|
|
1488
|
+
getEnvironment: import_core4.collectEnvironment,
|
|
1557
1489
|
getConsoleLogs: () => consoleCollector.current?.getEntries() ?? [],
|
|
1558
1490
|
getNetworkErrors: () => networkCollector.current?.getEntries() ?? [],
|
|
1559
1491
|
getReplayEvents: () => [...replayEvents.current],
|
|
1560
1492
|
getExternalReplayUrl,
|
|
1561
|
-
initialSelection: pendingSelection.current
|
|
1493
|
+
initialSelection: pendingSelection.current,
|
|
1494
|
+
enableScreenshot,
|
|
1495
|
+
statusPageUrl,
|
|
1496
|
+
onBeforeSubmit,
|
|
1497
|
+
onSuccess,
|
|
1498
|
+
onError
|
|
1562
1499
|
}
|
|
1563
1500
|
)
|
|
1564
1501
|
] });
|
|
1565
1502
|
}
|
|
1566
1503
|
function TextIcon() {
|
|
1567
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1504
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1505
|
+
"svg",
|
|
1506
|
+
{
|
|
1507
|
+
width: "12",
|
|
1508
|
+
height: "12",
|
|
1509
|
+
viewBox: "0 0 24 24",
|
|
1510
|
+
fill: "none",
|
|
1511
|
+
stroke: "currentColor",
|
|
1512
|
+
strokeWidth: "2.2",
|
|
1513
|
+
strokeLinecap: "round",
|
|
1514
|
+
strokeLinejoin: "round",
|
|
1515
|
+
"aria-hidden": "true",
|
|
1516
|
+
children: [
|
|
1517
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M17 10H3" }),
|
|
1518
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M21 6H3" }),
|
|
1519
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M21 14H3" }),
|
|
1520
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M17 18H3" })
|
|
1521
|
+
]
|
|
1522
|
+
}
|
|
1523
|
+
);
|
|
1573
1524
|
}
|
|
1574
1525
|
function SparkIcon2() {
|
|
1575
1526
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|