@diegotsi/flint-react 0.6.0 → 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 +604 -669
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -8
- package/dist/index.d.ts +31 -8
- package/dist/index.js +589 -664
- 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 = 50;
|
|
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 (res.status >= 400 && !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 (this.status >= 400 && !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) {
|
|
@@ -1371,7 +1265,17 @@ function WidgetContent({
|
|
|
1371
1265
|
buttonLabel,
|
|
1372
1266
|
theme = "dark",
|
|
1373
1267
|
zIndex = 9999,
|
|
1374
|
-
|
|
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
|
|
1375
1279
|
}) {
|
|
1376
1280
|
const globalState = useFlintStore();
|
|
1377
1281
|
const resolvedUser = user ?? globalState.user;
|
|
@@ -1385,9 +1289,9 @@ function WidgetContent({
|
|
|
1385
1289
|
const ddRum = window.DD_RUM;
|
|
1386
1290
|
const ctx = ddRum?.getInternalContext?.();
|
|
1387
1291
|
if (ctx?.session_id) {
|
|
1388
|
-
const now = Date.now();
|
|
1389
|
-
const fromTs = now -
|
|
1390
|
-
const toTs = now +
|
|
1292
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
1293
|
+
const fromTs = now - 30;
|
|
1294
|
+
const toTs = now + 5;
|
|
1391
1295
|
return `https://${datadogSite}/rum/replay/sessions/${ctx.session_id}?from_ts=${fromTs}&to_ts=${toTs}&tab=replay&live=false`;
|
|
1392
1296
|
}
|
|
1393
1297
|
} catch {
|
|
@@ -1399,7 +1303,7 @@ function WidgetContent({
|
|
|
1399
1303
|
const [open, setOpen] = (0, import_react4.useState)(false);
|
|
1400
1304
|
const [hovered, setHovered] = (0, import_react4.useState)(false);
|
|
1401
1305
|
const pendingSelection = (0, import_react4.useRef)("");
|
|
1402
|
-
const colors = resolveTheme(theme);
|
|
1306
|
+
const colors = (0, import_core2.resolveTheme)(theme);
|
|
1403
1307
|
const [selectionTooltip, setSelectionTooltip] = (0, import_react4.useState)(null);
|
|
1404
1308
|
const tooltipRef = (0, import_react4.useRef)(null);
|
|
1405
1309
|
const triggerRef = (0, import_react4.useRef)(null);
|
|
@@ -1440,16 +1344,17 @@ function WidgetContent({
|
|
|
1440
1344
|
pendingSelection.current = text;
|
|
1441
1345
|
setSelectionTooltip(null);
|
|
1442
1346
|
setOpen(true);
|
|
1347
|
+
onOpen?.();
|
|
1443
1348
|
};
|
|
1444
1349
|
const consoleCollector = (0, import_react4.useRef)(null);
|
|
1445
1350
|
const networkCollector = (0, import_react4.useRef)(null);
|
|
1446
1351
|
const replayEvents = (0, import_react4.useRef)([]);
|
|
1447
1352
|
const stopReplay = (0, import_react4.useRef)(null);
|
|
1448
|
-
if (!consoleCollector.current) {
|
|
1449
|
-
consoleCollector.current = createConsoleCollector();
|
|
1353
|
+
if (enableConsole && !consoleCollector.current) {
|
|
1354
|
+
consoleCollector.current = (0, import_core3.createConsoleCollector)();
|
|
1450
1355
|
consoleCollector.current.start();
|
|
1451
1356
|
}
|
|
1452
|
-
if (!networkCollector.current) {
|
|
1357
|
+
if (enableNetwork && !networkCollector.current) {
|
|
1453
1358
|
const flintHost = (() => {
|
|
1454
1359
|
try {
|
|
1455
1360
|
return new URL(serverUrl).hostname;
|
|
@@ -1457,26 +1362,33 @@ function WidgetContent({
|
|
|
1457
1362
|
return "";
|
|
1458
1363
|
}
|
|
1459
1364
|
})();
|
|
1460
|
-
networkCollector.current = createNetworkCollector(flintHost ? [flintHost] : []);
|
|
1365
|
+
networkCollector.current = (0, import_core5.createNetworkCollector)(flintHost ? [flintHost] : []);
|
|
1461
1366
|
networkCollector.current.start();
|
|
1462
1367
|
}
|
|
1463
1368
|
(0, import_react4.useEffect)(() => {
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
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
|
+
}
|
|
1474
1385
|
return () => {
|
|
1386
|
+
cancelled = true;
|
|
1475
1387
|
consoleCollector.current?.stop();
|
|
1476
1388
|
networkCollector.current?.stop();
|
|
1477
1389
|
stopReplay.current?.();
|
|
1478
1390
|
};
|
|
1479
|
-
}, []);
|
|
1391
|
+
}, [enableReplay]);
|
|
1480
1392
|
const label = buttonLabel ?? t("buttonLabel");
|
|
1481
1393
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
1482
1394
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
@@ -1486,7 +1398,10 @@ function WidgetContent({
|
|
|
1486
1398
|
onMouseDown: () => {
|
|
1487
1399
|
pendingSelection.current = window.getSelection()?.toString().trim() ?? "";
|
|
1488
1400
|
},
|
|
1489
|
-
onClick: () =>
|
|
1401
|
+
onClick: () => {
|
|
1402
|
+
setOpen(true);
|
|
1403
|
+
onOpen?.();
|
|
1404
|
+
},
|
|
1490
1405
|
onMouseEnter: () => setHovered(true),
|
|
1491
1406
|
onMouseLeave: () => setHovered(false),
|
|
1492
1407
|
"aria-label": label,
|
|
@@ -1567,25 +1482,45 @@ function WidgetContent({
|
|
|
1567
1482
|
zIndex,
|
|
1568
1483
|
onClose: () => {
|
|
1569
1484
|
setOpen(false);
|
|
1485
|
+
onClose?.();
|
|
1570
1486
|
pendingSelection.current = "";
|
|
1571
1487
|
},
|
|
1572
|
-
getEnvironment: collectEnvironment,
|
|
1488
|
+
getEnvironment: import_core4.collectEnvironment,
|
|
1573
1489
|
getConsoleLogs: () => consoleCollector.current?.getEntries() ?? [],
|
|
1574
1490
|
getNetworkErrors: () => networkCollector.current?.getEntries() ?? [],
|
|
1575
1491
|
getReplayEvents: () => [...replayEvents.current],
|
|
1576
1492
|
getExternalReplayUrl,
|
|
1577
|
-
initialSelection: pendingSelection.current
|
|
1493
|
+
initialSelection: pendingSelection.current,
|
|
1494
|
+
enableScreenshot,
|
|
1495
|
+
statusPageUrl,
|
|
1496
|
+
onBeforeSubmit,
|
|
1497
|
+
onSuccess,
|
|
1498
|
+
onError
|
|
1578
1499
|
}
|
|
1579
1500
|
)
|
|
1580
1501
|
] });
|
|
1581
1502
|
}
|
|
1582
1503
|
function TextIcon() {
|
|
1583
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
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
|
+
);
|
|
1589
1524
|
}
|
|
1590
1525
|
function SparkIcon2() {
|
|
1591
1526
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|