glitchgrab 1.58.0 → 1.58.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -0
- package/dist/index.d.mts +21 -3
- package/dist/index.d.ts +21 -3
- package/dist/index.js +744 -573
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +743 -573
- package/dist/index.mjs.map +1 -1
- package/dist/server.d.mts +36 -3
- package/dist/server.d.ts +36 -3
- package/dist/server.js +44 -13
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +42 -13
- package/dist/server.mjs.map +1 -1
- package/dist/{types-DfVtKZcp.d.mts → types-BpTLWJ1y.d.mts} +8 -0
- package/dist/{types-DfVtKZcp.d.ts → types-BpTLWJ1y.d.ts} +8 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -32,6 +32,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
32
32
|
var index_exports = {};
|
|
33
33
|
__export(index_exports, {
|
|
34
34
|
BookDemoButton: () => BookDemoButton,
|
|
35
|
+
BookingDialog: () => BookingDialog,
|
|
35
36
|
FeedbackButton: () => FeedbackButton,
|
|
36
37
|
GLITCHGRAB_SHORTCUT: () => GLITCHGRAB_SHORTCUT2,
|
|
37
38
|
GLITCHGRAB_SHORTCUT_MAC: () => GLITCHGRAB_SHORTCUT_MAC2,
|
|
@@ -647,6 +648,9 @@ function contextMetadata(context) {
|
|
|
647
648
|
var DEFAULT_BASE_URL = "https://glitchgrab.dev";
|
|
648
649
|
var MAX_RETRIES = 3;
|
|
649
650
|
var RETRY_BASE_MS = 500;
|
|
651
|
+
function reportAttemptTimeoutMs(bodyLength) {
|
|
652
|
+
return 1e4 + Math.ceil(bodyLength / 1e5) * 1e3;
|
|
653
|
+
}
|
|
650
654
|
async function sendReport(payload, baseUrl) {
|
|
651
655
|
var _a;
|
|
652
656
|
try {
|
|
@@ -657,13 +661,18 @@ async function sendReport(payload, baseUrl) {
|
|
|
657
661
|
Authorization: `Bearer ${payload.token}`
|
|
658
662
|
};
|
|
659
663
|
const useKeepalive = body.length < 6e4;
|
|
664
|
+
const timeoutMs = reportAttemptTimeoutMs(body.length);
|
|
660
665
|
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
|
|
666
|
+
const isLast = attempt === MAX_RETRIES - 1;
|
|
667
|
+
const controller = !isLast && typeof AbortController === "function" ? new AbortController() : null;
|
|
668
|
+
const timer = controller ? setTimeout(() => controller.abort(), timeoutMs) : null;
|
|
661
669
|
try {
|
|
662
670
|
const response = await fetch(url, {
|
|
663
671
|
method: "POST",
|
|
664
672
|
headers,
|
|
665
673
|
body,
|
|
666
|
-
...useKeepalive ? { keepalive: true } : {}
|
|
674
|
+
...useKeepalive ? { keepalive: true } : {},
|
|
675
|
+
...controller ? { signal: controller.signal } : {}
|
|
667
676
|
});
|
|
668
677
|
if (response.ok) {
|
|
669
678
|
const envelope = await response.json();
|
|
@@ -673,6 +682,8 @@ async function sendReport(payload, baseUrl) {
|
|
|
673
682
|
return null;
|
|
674
683
|
}
|
|
675
684
|
} catch (e) {
|
|
685
|
+
} finally {
|
|
686
|
+
if (timer) clearTimeout(timer);
|
|
676
687
|
}
|
|
677
688
|
if (attempt < MAX_RETRIES - 1) {
|
|
678
689
|
await new Promise(
|
|
@@ -789,7 +800,7 @@ async function enhanceText(text, token, baseUrl, screenshot, context, identity)
|
|
|
789
800
|
return text;
|
|
790
801
|
}
|
|
791
802
|
}
|
|
792
|
-
async function findSimilarIssues(description, token, baseUrl, identity) {
|
|
803
|
+
async function findSimilarIssues(description, token, baseUrl, identity, files) {
|
|
793
804
|
var _a;
|
|
794
805
|
try {
|
|
795
806
|
const url = `${baseUrl != null ? baseUrl : DEFAULT_BASE_URL}/api/v1/reports/similar`;
|
|
@@ -799,7 +810,11 @@ async function findSimilarIssues(description, token, baseUrl, identity) {
|
|
|
799
810
|
"Content-Type": "application/json",
|
|
800
811
|
Authorization: `Bearer ${token}`
|
|
801
812
|
},
|
|
802
|
-
body: JSON.stringify({
|
|
813
|
+
body: JSON.stringify({
|
|
814
|
+
text: description,
|
|
815
|
+
...(files == null ? void 0 : files.length) ? { files } : {},
|
|
816
|
+
...signedFields(identity)
|
|
817
|
+
})
|
|
803
818
|
});
|
|
804
819
|
const envelope = await response.json().catch(() => null);
|
|
805
820
|
if (!response.ok || !(envelope == null ? void 0 : envelope.success)) return null;
|
|
@@ -809,6 +824,25 @@ async function findSimilarIssues(description, token, baseUrl, identity) {
|
|
|
809
824
|
return null;
|
|
810
825
|
}
|
|
811
826
|
}
|
|
827
|
+
async function readAttachment(file, token, baseUrl, identity) {
|
|
828
|
+
var _a;
|
|
829
|
+
try {
|
|
830
|
+
const url = `${baseUrl != null ? baseUrl : DEFAULT_BASE_URL}/api/v1/ai/read-file`;
|
|
831
|
+
const response = await fetch(url, {
|
|
832
|
+
method: "POST",
|
|
833
|
+
headers: {
|
|
834
|
+
"Content-Type": "application/json",
|
|
835
|
+
Authorization: `Bearer ${token}`
|
|
836
|
+
},
|
|
837
|
+
body: JSON.stringify({ name: file.name, data: file.dataUrl, ...signedFields(identity) })
|
|
838
|
+
});
|
|
839
|
+
const envelope = await response.json().catch(() => null);
|
|
840
|
+
if (!response.ok || !(envelope == null ? void 0 : envelope.success) || !((_a = envelope.data) == null ? void 0 : _a.enabled)) return null;
|
|
841
|
+
return typeof envelope.data.text === "string" ? envelope.data.text : null;
|
|
842
|
+
} catch (e) {
|
|
843
|
+
return null;
|
|
844
|
+
}
|
|
845
|
+
}
|
|
812
846
|
async function assistTurn(params, token, baseUrl) {
|
|
813
847
|
const offline = assistOffline();
|
|
814
848
|
try {
|
|
@@ -1410,6 +1444,9 @@ var MAX_ASSIST_IMAGE_CHARS = 35e5;
|
|
|
1410
1444
|
var MAX_ASSIST_FILES = 3;
|
|
1411
1445
|
var MAX_ASSIST_FILE_CHARS = 3e5;
|
|
1412
1446
|
var MAX_ASSIST_FILE_CHARS_EACH = 2e5;
|
|
1447
|
+
var MAX_SIMILAR_FILE_CHARS = 2e4;
|
|
1448
|
+
var MAX_SIMILAR_FILES_TOTAL_CHARS = 4e4;
|
|
1449
|
+
var MAX_READABLE_PDF_BYTES = 3 * 1024 * 1024;
|
|
1413
1450
|
var TEXT_ATTACHMENT_EXTENSIONS = [
|
|
1414
1451
|
".html",
|
|
1415
1452
|
".htm",
|
|
@@ -1440,6 +1477,10 @@ var ATTACHMENT_ACCEPT = [
|
|
|
1440
1477
|
...BINARY_ATTACHMENT_EXTENSIONS
|
|
1441
1478
|
].join(",");
|
|
1442
1479
|
var ASSIST_ATTACHMENT_ACCEPT = ["image/*", ...TEXT_ATTACHMENT_EXTENSIONS].join(",");
|
|
1480
|
+
var ASSIST_ATTACHMENT_ACCEPT_WITH_PDF = [ASSIST_ATTACHMENT_ACCEPT, ".pdf"].join(",");
|
|
1481
|
+
function isPdfFile(name) {
|
|
1482
|
+
return name.toLowerCase().endsWith(".pdf");
|
|
1483
|
+
}
|
|
1443
1484
|
function isAssistReadableFile(name) {
|
|
1444
1485
|
const lower = name.toLowerCase();
|
|
1445
1486
|
return TEXT_ATTACHMENT_EXTENSIONS.some((ext) => lower.endsWith(ext));
|
|
@@ -1460,6 +1501,27 @@ function decodeTextDataUrl(dataUrl) {
|
|
|
1460
1501
|
return null;
|
|
1461
1502
|
}
|
|
1462
1503
|
}
|
|
1504
|
+
function heldFileKey(file) {
|
|
1505
|
+
return `${file.name}:${file.size}`;
|
|
1506
|
+
}
|
|
1507
|
+
function heldFileText(file) {
|
|
1508
|
+
if (isPdfFile(file.name)) return typeof file.text === "string" && file.text.trim() ? file.text : null;
|
|
1509
|
+
if (!isAssistReadableFile(file.name)) return null;
|
|
1510
|
+
const text = decodeTextDataUrl(file.dataUrl);
|
|
1511
|
+
return text && text.trim() ? text : null;
|
|
1512
|
+
}
|
|
1513
|
+
function filesForSimilar(files, each, total) {
|
|
1514
|
+
const picked = [];
|
|
1515
|
+
let used = 0;
|
|
1516
|
+
for (let i = files.length - 1; i >= 0 && used < total; i--) {
|
|
1517
|
+
const text = heldFileText(files[i]);
|
|
1518
|
+
if (!text) continue;
|
|
1519
|
+
const content = text.slice(0, Math.min(each, total - used));
|
|
1520
|
+
picked.unshift({ name: files[i].name, content });
|
|
1521
|
+
used += content.length;
|
|
1522
|
+
}
|
|
1523
|
+
return picked;
|
|
1524
|
+
}
|
|
1463
1525
|
function getTypeLabel(type) {
|
|
1464
1526
|
switch (type) {
|
|
1465
1527
|
case "RATING":
|
|
@@ -1903,9 +1965,8 @@ function pickAssistFiles(files) {
|
|
|
1903
1965
|
let total = 0;
|
|
1904
1966
|
for (let i = files.length - 1; i >= 0 && picked.length < MAX_ASSIST_FILES; i--) {
|
|
1905
1967
|
const attached = files[i];
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
if (!text || !text.trim()) continue;
|
|
1968
|
+
const text = heldFileText(attached);
|
|
1969
|
+
if (!text) continue;
|
|
1909
1970
|
const content = text.slice(0, MAX_ASSIST_FILE_CHARS_EACH);
|
|
1910
1971
|
if (total + content.length > MAX_ASSIST_FILE_CHARS) continue;
|
|
1911
1972
|
picked.unshift({ index: i, file: { name: attached.name, content } });
|
|
@@ -2002,6 +2063,7 @@ function AssistSheet({
|
|
|
2002
2063
|
pageShot = null,
|
|
2003
2064
|
onAddFiles,
|
|
2004
2065
|
files = NO_FILES,
|
|
2066
|
+
canReadPdf = false,
|
|
2005
2067
|
onRemoveFile,
|
|
2006
2068
|
onRemoveImage,
|
|
2007
2069
|
attachmentCount,
|
|
@@ -2029,6 +2091,8 @@ function AssistSheet({
|
|
|
2029
2091
|
isSubmitting,
|
|
2030
2092
|
submitted,
|
|
2031
2093
|
onSend,
|
|
2094
|
+
similarSlot,
|
|
2095
|
+
submittedText,
|
|
2032
2096
|
onDegrade,
|
|
2033
2097
|
onClose,
|
|
2034
2098
|
onFinish,
|
|
@@ -2052,6 +2116,7 @@ function AssistSheet({
|
|
|
2052
2116
|
const [autoFileLeft, setAutoFileLeft] = (0, import_react3.useState)(null);
|
|
2053
2117
|
const scrollRef = (0, import_react3.useRef)(null);
|
|
2054
2118
|
const draftRef = (0, import_react3.useRef)(null);
|
|
2119
|
+
const composerRef = (0, import_react3.useRef)(null);
|
|
2055
2120
|
const seededRef = (0, import_react3.useRef)(false);
|
|
2056
2121
|
const seedPendingRef = (0, import_react3.useRef)(false);
|
|
2057
2122
|
const eventsRef = (0, import_react3.useRef)([]);
|
|
@@ -2093,6 +2158,12 @@ function AssistSheet({
|
|
|
2093
2158
|
var _a;
|
|
2094
2159
|
if (phase === "draft") (_a = draftRef.current) == null ? void 0 : _a.focus();
|
|
2095
2160
|
}, [phase]);
|
|
2161
|
+
(0, import_react3.useEffect)(() => {
|
|
2162
|
+
const el = composerRef.current;
|
|
2163
|
+
if (!el) return;
|
|
2164
|
+
el.style.height = "auto";
|
|
2165
|
+
el.style.height = `${el.scrollHeight + 2}px`;
|
|
2166
|
+
}, [input]);
|
|
2096
2167
|
(0, import_react3.useEffect)(() => {
|
|
2097
2168
|
if (autoFileLeft === null) return;
|
|
2098
2169
|
if (isSubmitting || submitted || phase !== "draft") {
|
|
@@ -2319,6 +2390,7 @@ function AssistSheet({
|
|
|
2319
2390
|
@keyframes gg-sheet-up{from{transform:translateY(24px);opacity:0}to{transform:translateY(0);opacity:1}}
|
|
2320
2391
|
@keyframes gg-sheet-fade{from{opacity:0}to{opacity:1}}
|
|
2321
2392
|
@keyframes gg-autofile{from{transform:scaleX(0)}to{transform:scaleX(1)}}
|
|
2393
|
+
@keyframes gg-spin{to{transform:rotate(360deg)}}
|
|
2322
2394
|
@keyframes gg-dot{0%,80%,100%{transform:translateY(0);opacity:.4}40%{transform:translateY(-3px);opacity:1}}
|
|
2323
2395
|
[data-gg-sheet-send]:focus-visible,[data-gg-chip]:focus-visible,[data-gg-assist-remove]:focus-visible,[data-gg-stop-auto-file]:focus-visible{outline:2px solid currentColor;outline-offset:2px}
|
|
2324
2396
|
` }),
|
|
@@ -3193,7 +3265,7 @@ function AssistSheet({
|
|
|
3193
3265
|
}
|
|
3194
3266
|
)
|
|
3195
3267
|
] }),
|
|
3196
|
-
submitted && /* @__PURE__ */ (0, import_jsx_runtime3.
|
|
3268
|
+
submitted && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3197
3269
|
"div",
|
|
3198
3270
|
{
|
|
3199
3271
|
style: {
|
|
@@ -3203,10 +3275,7 @@ function AssistSheet({
|
|
|
3203
3275
|
fontSize: "14px",
|
|
3204
3276
|
fontWeight: 600
|
|
3205
3277
|
},
|
|
3206
|
-
children:
|
|
3207
|
-
reportTypeLabel,
|
|
3208
|
-
" sent. Thank you!"
|
|
3209
|
-
]
|
|
3278
|
+
children: submittedText != null ? submittedText : `${reportTypeLabel} sent. Thank you!`
|
|
3210
3279
|
}
|
|
3211
3280
|
)
|
|
3212
3281
|
]
|
|
@@ -3272,342 +3341,363 @@ function AssistSheet({
|
|
|
3272
3341
|
// instead of remounting, and a draft is something you can
|
|
3273
3342
|
// still reply to (#360), not a form that replaced the chat.
|
|
3274
3343
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3344
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: similarSlot ? "none" : "contents" }, children: [
|
|
3345
|
+
(screenshots.length > 0 || files.length > 0 || onAddFiles) && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
3346
|
+
"div",
|
|
3347
|
+
{
|
|
3348
|
+
style: {
|
|
3349
|
+
display: "flex",
|
|
3350
|
+
gap: "8px",
|
|
3351
|
+
alignItems: "center",
|
|
3352
|
+
flexWrap: "wrap",
|
|
3353
|
+
marginBottom: "8px"
|
|
3354
|
+
},
|
|
3355
|
+
children: [
|
|
3356
|
+
screenshots.map((shot, i) => {
|
|
3357
|
+
const read = readShots.has(shot);
|
|
3358
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
3359
|
+
"div",
|
|
3360
|
+
{
|
|
3361
|
+
style: {
|
|
3362
|
+
position: "relative",
|
|
3363
|
+
width: "40px",
|
|
3364
|
+
height: "40px",
|
|
3365
|
+
flexShrink: 0
|
|
3366
|
+
},
|
|
3367
|
+
children: [
|
|
3368
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3369
|
+
"img",
|
|
3370
|
+
{
|
|
3371
|
+
src: shot,
|
|
3372
|
+
alt: read ? "Attached image the assistant reads" : "Attached image",
|
|
3373
|
+
"data-gg-assist-thumb": "",
|
|
3374
|
+
style: {
|
|
3375
|
+
display: "block",
|
|
3376
|
+
width: "100%",
|
|
3377
|
+
height: "100%",
|
|
3378
|
+
objectFit: "cover",
|
|
3379
|
+
borderRadius: "8px",
|
|
3380
|
+
border: `1px solid ${read ? t.accent : t.inputBorder}`,
|
|
3381
|
+
opacity: read ? 1 : 0.45,
|
|
3382
|
+
boxSizing: "border-box"
|
|
3383
|
+
}
|
|
3313
3384
|
}
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
}
|
|
3370
|
-
|
|
3385
|
+
),
|
|
3386
|
+
onRemoveImage && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3387
|
+
"button",
|
|
3388
|
+
{
|
|
3389
|
+
type: "button",
|
|
3390
|
+
"data-gg-assist-remove": "",
|
|
3391
|
+
"aria-label": `Remove image ${i + 1}`,
|
|
3392
|
+
title: "Remove this image",
|
|
3393
|
+
onClick: () => {
|
|
3394
|
+
stopAutoFile("changed attachments");
|
|
3395
|
+
logEvent(
|
|
3396
|
+
"image_removed",
|
|
3397
|
+
pageShot && shot === pageShot ? "page capture" : "attached"
|
|
3398
|
+
);
|
|
3399
|
+
onRemoveImage(i);
|
|
3400
|
+
},
|
|
3401
|
+
style: {
|
|
3402
|
+
position: "absolute",
|
|
3403
|
+
top: "-13px",
|
|
3404
|
+
right: "-13px",
|
|
3405
|
+
width: "32px",
|
|
3406
|
+
height: "32px",
|
|
3407
|
+
border: "none",
|
|
3408
|
+
background: "transparent",
|
|
3409
|
+
padding: 0,
|
|
3410
|
+
cursor: "pointer",
|
|
3411
|
+
display: "flex",
|
|
3412
|
+
alignItems: "center",
|
|
3413
|
+
justifyContent: "center",
|
|
3414
|
+
borderRadius: "50%"
|
|
3415
|
+
},
|
|
3416
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3417
|
+
"span",
|
|
3418
|
+
{
|
|
3419
|
+
"aria-hidden": "true",
|
|
3420
|
+
style: {
|
|
3421
|
+
width: "20px",
|
|
3422
|
+
height: "20px",
|
|
3423
|
+
boxSizing: "border-box",
|
|
3424
|
+
borderRadius: "50%",
|
|
3425
|
+
border: `2px solid ${t.bg}`,
|
|
3426
|
+
background: "#ef4444",
|
|
3427
|
+
color: "#fff",
|
|
3428
|
+
display: "flex",
|
|
3429
|
+
alignItems: "center",
|
|
3430
|
+
justifyContent: "center"
|
|
3431
|
+
},
|
|
3432
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "8", height: "8", viewBox: "0 0 10 10", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3433
|
+
"path",
|
|
3434
|
+
{
|
|
3435
|
+
d: "M1 1L9 9M9 1L1 9",
|
|
3436
|
+
stroke: "currentColor",
|
|
3437
|
+
strokeWidth: "1.6",
|
|
3438
|
+
strokeLinecap: "round"
|
|
3439
|
+
}
|
|
3440
|
+
) })
|
|
3441
|
+
}
|
|
3442
|
+
)
|
|
3443
|
+
}
|
|
3444
|
+
)
|
|
3445
|
+
]
|
|
3446
|
+
},
|
|
3447
|
+
`${i}-${shot.slice(-16)}`
|
|
3448
|
+
);
|
|
3449
|
+
}),
|
|
3450
|
+
files.map((file, i) => {
|
|
3451
|
+
const read = readFiles.has(i);
|
|
3452
|
+
const pdf = isPdfFile(file.name);
|
|
3453
|
+
const why = read ? "the assistant reads this file" : pdf && file.reading ? "reading the text in this PDF\u2026" : pdf && file.text !== void 0 ? file.text === null ? file.tooLarge ? "attached to the report \u2014 too large for the assistant to read (over 3 MB)" : "attached to the report \u2014 couldn't read this PDF" : file.text.trim() ? "attached, but more than one message can carry, so the assistant is not reading it" : "attached to the report \u2014 this PDF has no text to read (a scan?)" : isAssistReadableFile(file.name) ? "attached, but more than one message can carry, so the assistant is not reading it" : "attached to the report \u2014 the assistant can't read this kind of file";
|
|
3454
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
3455
|
+
"div",
|
|
3456
|
+
{
|
|
3457
|
+
"data-gg-assist-file": "",
|
|
3458
|
+
"data-gg-assist-file-read": read ? "" : void 0,
|
|
3459
|
+
"data-gg-assist-file-reading": pdf && file.reading ? "" : void 0,
|
|
3460
|
+
title: `${file.name} \u2014 ${why}`,
|
|
3461
|
+
style: {
|
|
3462
|
+
position: "relative",
|
|
3463
|
+
height: "40px",
|
|
3464
|
+
maxWidth: "170px",
|
|
3465
|
+
display: "flex",
|
|
3466
|
+
alignItems: "center",
|
|
3467
|
+
gap: "6px",
|
|
3468
|
+
padding: "0 10px",
|
|
3469
|
+
borderRadius: "8px",
|
|
3470
|
+
border: `1px solid ${read ? t.accent : t.inputBorder}`,
|
|
3471
|
+
opacity: read || pdf && file.reading ? 1 : 0.55,
|
|
3472
|
+
boxSizing: "border-box",
|
|
3473
|
+
flexShrink: 0
|
|
3474
|
+
},
|
|
3475
|
+
children: [
|
|
3476
|
+
pdf && file.reading ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3477
|
+
"span",
|
|
3478
|
+
{
|
|
3479
|
+
role: "status",
|
|
3480
|
+
"aria-label": "Reading this PDF",
|
|
3481
|
+
style: {
|
|
3482
|
+
width: "12px",
|
|
3483
|
+
height: "12px",
|
|
3484
|
+
flexShrink: 0,
|
|
3485
|
+
borderRadius: "50%",
|
|
3486
|
+
border: `1.5px solid ${t.inputBorder}`,
|
|
3487
|
+
borderTopColor: t.accent,
|
|
3488
|
+
boxSizing: "border-box",
|
|
3489
|
+
animation: "gg-spin .8s linear infinite"
|
|
3371
3490
|
}
|
|
3372
|
-
|
|
3373
|
-
}
|
|
3374
|
-
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3491
|
+
}
|
|
3492
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", style: { flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3493
|
+
"path",
|
|
3494
|
+
{
|
|
3495
|
+
d: "M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z M14 2v6h6",
|
|
3496
|
+
stroke: t.textMuted,
|
|
3497
|
+
strokeWidth: "1.5",
|
|
3498
|
+
strokeLinecap: "round",
|
|
3499
|
+
strokeLinejoin: "round"
|
|
3500
|
+
}
|
|
3501
|
+
) }),
|
|
3502
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3503
|
+
"span",
|
|
3504
|
+
{
|
|
3505
|
+
style: {
|
|
3506
|
+
fontSize: "11.5px",
|
|
3507
|
+
color: t.text,
|
|
3508
|
+
overflow: "hidden",
|
|
3509
|
+
textOverflow: "ellipsis",
|
|
3510
|
+
whiteSpace: "nowrap"
|
|
3511
|
+
},
|
|
3512
|
+
children: file.name
|
|
3513
|
+
}
|
|
3514
|
+
),
|
|
3515
|
+
onRemoveFile && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3516
|
+
"button",
|
|
3517
|
+
{
|
|
3518
|
+
type: "button",
|
|
3519
|
+
"data-gg-assist-remove-file": "",
|
|
3520
|
+
"aria-label": `Remove file ${file.name}`,
|
|
3521
|
+
title: "Remove this file",
|
|
3522
|
+
onClick: () => {
|
|
3523
|
+
stopAutoFile("changed attachments");
|
|
3524
|
+
logEvent("file_removed", read ? "read" : "not read");
|
|
3525
|
+
onRemoveFile(i);
|
|
3526
|
+
},
|
|
3527
|
+
style: {
|
|
3528
|
+
position: "absolute",
|
|
3529
|
+
top: "-13px",
|
|
3530
|
+
right: "-13px",
|
|
3531
|
+
width: "32px",
|
|
3532
|
+
height: "32px",
|
|
3533
|
+
border: "none",
|
|
3534
|
+
background: "transparent",
|
|
3535
|
+
padding: 0,
|
|
3536
|
+
cursor: "pointer",
|
|
3537
|
+
display: "flex",
|
|
3538
|
+
alignItems: "center",
|
|
3539
|
+
justifyContent: "center",
|
|
3540
|
+
borderRadius: "50%"
|
|
3541
|
+
},
|
|
3542
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3543
|
+
"span",
|
|
3544
|
+
{
|
|
3545
|
+
"aria-hidden": "true",
|
|
3546
|
+
style: {
|
|
3547
|
+
width: "20px",
|
|
3548
|
+
height: "20px",
|
|
3549
|
+
boxSizing: "border-box",
|
|
3550
|
+
borderRadius: "50%",
|
|
3551
|
+
border: `2px solid ${t.bg}`,
|
|
3552
|
+
background: "#ef4444",
|
|
3553
|
+
color: "#fff",
|
|
3554
|
+
display: "flex",
|
|
3555
|
+
alignItems: "center",
|
|
3556
|
+
justifyContent: "center"
|
|
3557
|
+
},
|
|
3558
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "8", height: "8", viewBox: "0 0 10 10", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3559
|
+
"path",
|
|
3560
|
+
{
|
|
3561
|
+
d: "M1 1L9 9M9 1L1 9",
|
|
3562
|
+
stroke: "currentColor",
|
|
3563
|
+
strokeWidth: "1.6",
|
|
3564
|
+
strokeLinecap: "round"
|
|
3565
|
+
}
|
|
3566
|
+
) })
|
|
3567
|
+
}
|
|
3568
|
+
)
|
|
3569
|
+
}
|
|
3570
|
+
)
|
|
3571
|
+
]
|
|
3572
|
+
},
|
|
3573
|
+
`file-${i}-${file.name}`
|
|
3574
|
+
);
|
|
3575
|
+
}),
|
|
3576
|
+
onAddFiles && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
3577
|
+
"label",
|
|
3385
3578
|
{
|
|
3386
|
-
"data-gg-assist-
|
|
3387
|
-
"
|
|
3388
|
-
title: `${file.name} \u2014 ${why}`,
|
|
3579
|
+
"data-gg-assist-attach": "",
|
|
3580
|
+
title: "Attach an image or a file (html, json, log\u2026) \u2014 or paste one",
|
|
3389
3581
|
style: {
|
|
3390
|
-
|
|
3582
|
+
width: "40px",
|
|
3391
3583
|
height: "40px",
|
|
3392
|
-
maxWidth: "170px",
|
|
3393
|
-
display: "flex",
|
|
3394
|
-
alignItems: "center",
|
|
3395
|
-
gap: "6px",
|
|
3396
|
-
padding: "0 10px",
|
|
3397
3584
|
borderRadius: "8px",
|
|
3398
|
-
border: `1px
|
|
3399
|
-
|
|
3400
|
-
|
|
3585
|
+
border: `1px dashed ${t.inputBorder}`,
|
|
3586
|
+
display: "inline-flex",
|
|
3587
|
+
alignItems: "center",
|
|
3588
|
+
justifyContent: "center",
|
|
3589
|
+
color: t.textMuted,
|
|
3590
|
+
fontSize: "18px",
|
|
3591
|
+
cursor: "pointer",
|
|
3401
3592
|
flexShrink: 0
|
|
3402
3593
|
},
|
|
3403
3594
|
children: [
|
|
3404
|
-
|
|
3405
|
-
"path",
|
|
3406
|
-
{
|
|
3407
|
-
d: "M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z M14 2v6h6",
|
|
3408
|
-
stroke: t.textMuted,
|
|
3409
|
-
strokeWidth: "1.5",
|
|
3410
|
-
strokeLinecap: "round",
|
|
3411
|
-
strokeLinejoin: "round"
|
|
3412
|
-
}
|
|
3413
|
-
) }),
|
|
3595
|
+
"+",
|
|
3414
3596
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3415
|
-
"
|
|
3416
|
-
{
|
|
3417
|
-
style: {
|
|
3418
|
-
fontSize: "11.5px",
|
|
3419
|
-
color: t.text,
|
|
3420
|
-
overflow: "hidden",
|
|
3421
|
-
textOverflow: "ellipsis",
|
|
3422
|
-
whiteSpace: "nowrap"
|
|
3423
|
-
},
|
|
3424
|
-
children: file.name
|
|
3425
|
-
}
|
|
3426
|
-
),
|
|
3427
|
-
onRemoveFile && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3428
|
-
"button",
|
|
3597
|
+
"input",
|
|
3429
3598
|
{
|
|
3430
|
-
type: "
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
height: "32px",
|
|
3445
|
-
border: "none",
|
|
3446
|
-
background: "transparent",
|
|
3447
|
-
padding: 0,
|
|
3448
|
-
cursor: "pointer",
|
|
3449
|
-
display: "flex",
|
|
3450
|
-
alignItems: "center",
|
|
3451
|
-
justifyContent: "center",
|
|
3452
|
-
borderRadius: "50%"
|
|
3453
|
-
},
|
|
3454
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3455
|
-
"span",
|
|
3456
|
-
{
|
|
3457
|
-
"aria-hidden": "true",
|
|
3458
|
-
style: {
|
|
3459
|
-
width: "20px",
|
|
3460
|
-
height: "20px",
|
|
3461
|
-
boxSizing: "border-box",
|
|
3462
|
-
borderRadius: "50%",
|
|
3463
|
-
border: `2px solid ${t.bg}`,
|
|
3464
|
-
background: "#ef4444",
|
|
3465
|
-
color: "#fff",
|
|
3466
|
-
display: "flex",
|
|
3467
|
-
alignItems: "center",
|
|
3468
|
-
justifyContent: "center"
|
|
3469
|
-
},
|
|
3470
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "8", height: "8", viewBox: "0 0 10 10", fill: "none", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3471
|
-
"path",
|
|
3472
|
-
{
|
|
3473
|
-
d: "M1 1L9 9M9 1L1 9",
|
|
3474
|
-
stroke: "currentColor",
|
|
3475
|
-
strokeWidth: "1.6",
|
|
3476
|
-
strokeLinecap: "round"
|
|
3477
|
-
}
|
|
3478
|
-
) })
|
|
3599
|
+
type: "file",
|
|
3600
|
+
accept: canReadPdf ? ASSIST_ATTACHMENT_ACCEPT_WITH_PDF : ASSIST_ATTACHMENT_ACCEPT,
|
|
3601
|
+
multiple: true,
|
|
3602
|
+
onChange: (e) => {
|
|
3603
|
+
var _a;
|
|
3604
|
+
const picked = Array.from((_a = e.target.files) != null ? _a : []);
|
|
3605
|
+
if (picked.length) {
|
|
3606
|
+
stopAutoFile("changed attachments");
|
|
3607
|
+
const images = picked.filter((f) => f.type.startsWith("image/")).length;
|
|
3608
|
+
if (images) logEvent("image_added", String(images));
|
|
3609
|
+
if (picked.length > images) {
|
|
3610
|
+
logEvent("file_added", String(picked.length - images));
|
|
3611
|
+
}
|
|
3612
|
+
onAddFiles(picked);
|
|
3479
3613
|
}
|
|
3480
|
-
|
|
3614
|
+
e.target.value = "";
|
|
3615
|
+
},
|
|
3616
|
+
style: { display: "none" }
|
|
3481
3617
|
}
|
|
3482
3618
|
)
|
|
3483
3619
|
]
|
|
3484
|
-
}
|
|
3485
|
-
|
|
3486
|
-
)
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
style: {
|
|
3494
|
-
width: "40px",
|
|
3495
|
-
height: "40px",
|
|
3496
|
-
borderRadius: "8px",
|
|
3497
|
-
border: `1px dashed ${t.inputBorder}`,
|
|
3498
|
-
display: "inline-flex",
|
|
3499
|
-
alignItems: "center",
|
|
3500
|
-
justifyContent: "center",
|
|
3501
|
-
color: t.textMuted,
|
|
3502
|
-
fontSize: "18px",
|
|
3503
|
-
cursor: "pointer",
|
|
3504
|
-
flexShrink: 0
|
|
3505
|
-
},
|
|
3506
|
-
children: [
|
|
3507
|
-
"+",
|
|
3508
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3509
|
-
"input",
|
|
3510
|
-
{
|
|
3511
|
-
type: "file",
|
|
3512
|
-
accept: ASSIST_ATTACHMENT_ACCEPT,
|
|
3513
|
-
multiple: true,
|
|
3514
|
-
onChange: (e) => {
|
|
3515
|
-
var _a;
|
|
3516
|
-
const picked = Array.from((_a = e.target.files) != null ? _a : []);
|
|
3517
|
-
if (picked.length) {
|
|
3518
|
-
stopAutoFile("changed attachments");
|
|
3519
|
-
const images = picked.filter((f) => f.type.startsWith("image/")).length;
|
|
3520
|
-
if (images) logEvent("image_added", String(images));
|
|
3521
|
-
if (picked.length > images) {
|
|
3522
|
-
logEvent("file_added", String(picked.length - images));
|
|
3523
|
-
}
|
|
3524
|
-
onAddFiles(picked);
|
|
3525
|
-
}
|
|
3526
|
-
e.target.value = "";
|
|
3527
|
-
},
|
|
3528
|
-
style: { display: "none" }
|
|
3529
|
-
}
|
|
3530
|
-
)
|
|
3531
|
-
]
|
|
3532
|
-
}
|
|
3533
|
-
),
|
|
3534
|
-
readShots.size < screenshots.length && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { style: { color: t.textMuted, fontSize: "11px" }, children: [
|
|
3535
|
-
readShots.size,
|
|
3536
|
-
" of ",
|
|
3537
|
-
screenshots.length,
|
|
3538
|
-
" read"
|
|
3539
|
-
] })
|
|
3540
|
-
]
|
|
3541
|
-
}
|
|
3542
|
-
),
|
|
3543
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex", gap: "8px", alignItems: "flex-end" }, children: [
|
|
3544
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3545
|
-
"textarea",
|
|
3546
|
-
{
|
|
3547
|
-
value: input,
|
|
3548
|
-
onChange: (e) => {
|
|
3549
|
-
stopAutoFile("typing a change");
|
|
3550
|
-
setInput(e.target.value);
|
|
3551
|
-
},
|
|
3552
|
-
onKeyDown: (e) => {
|
|
3553
|
-
if (e.key === "Enter" && !e.shiftKey) {
|
|
3554
|
-
e.preventDefault();
|
|
3555
|
-
sendTyped(input);
|
|
3556
|
-
}
|
|
3557
|
-
},
|
|
3558
|
-
placeholder: phase === "draft" ? "Anything to change? Tell me here\u2026" : "Type your answer\u2026",
|
|
3559
|
-
rows: 1,
|
|
3560
|
-
disabled: busy,
|
|
3561
|
-
autoFocus: true,
|
|
3562
|
-
style: {
|
|
3563
|
-
flex: 1,
|
|
3564
|
-
minHeight: "42px",
|
|
3565
|
-
maxHeight: "120px",
|
|
3566
|
-
padding: "11px 12px",
|
|
3567
|
-
borderRadius: "10px",
|
|
3568
|
-
border: `1px solid ${t.inputBorder}`,
|
|
3569
|
-
backgroundColor: t.inputBg,
|
|
3570
|
-
color: t.text,
|
|
3571
|
-
fontSize: "13px",
|
|
3572
|
-
lineHeight: 1.4,
|
|
3573
|
-
fontFamily: "inherit",
|
|
3574
|
-
resize: "none",
|
|
3575
|
-
outline: "none",
|
|
3576
|
-
boxSizing: "border-box"
|
|
3577
|
-
}
|
|
3620
|
+
}
|
|
3621
|
+
),
|
|
3622
|
+
readShots.size < screenshots.length && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { style: { color: t.textMuted, fontSize: "11px" }, children: [
|
|
3623
|
+
readShots.size,
|
|
3624
|
+
" of ",
|
|
3625
|
+
screenshots.length,
|
|
3626
|
+
" read"
|
|
3627
|
+
] })
|
|
3628
|
+
]
|
|
3578
3629
|
}
|
|
3579
3630
|
),
|
|
3580
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3631
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex", gap: "8px", alignItems: "flex-end" }, children: [
|
|
3632
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3633
|
+
"textarea",
|
|
3634
|
+
{
|
|
3635
|
+
ref: composerRef,
|
|
3636
|
+
value: input,
|
|
3637
|
+
onChange: (e) => {
|
|
3638
|
+
stopAutoFile("typing a change");
|
|
3639
|
+
setInput(e.target.value);
|
|
3640
|
+
},
|
|
3641
|
+
onKeyDown: (e) => {
|
|
3642
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
3643
|
+
e.preventDefault();
|
|
3644
|
+
sendTyped(input);
|
|
3645
|
+
}
|
|
3646
|
+
},
|
|
3647
|
+
placeholder: phase === "draft" ? "Anything to change? Tell me here\u2026" : "Type your answer\u2026",
|
|
3648
|
+
rows: 3,
|
|
3649
|
+
disabled: busy,
|
|
3650
|
+
autoFocus: true,
|
|
3651
|
+
style: {
|
|
3652
|
+
flex: 1,
|
|
3653
|
+
minHeight: "72px",
|
|
3654
|
+
maxHeight: "220px",
|
|
3655
|
+
padding: "11px 12px",
|
|
3656
|
+
borderRadius: "10px",
|
|
3657
|
+
border: `1px solid ${t.inputBorder}`,
|
|
3658
|
+
backgroundColor: t.inputBg,
|
|
3659
|
+
color: t.text,
|
|
3660
|
+
fontSize: "13px",
|
|
3661
|
+
lineHeight: 1.4,
|
|
3662
|
+
fontFamily: "inherit",
|
|
3663
|
+
resize: "none",
|
|
3664
|
+
outline: "none",
|
|
3665
|
+
boxSizing: "border-box"
|
|
3607
3666
|
}
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3667
|
+
}
|
|
3668
|
+
),
|
|
3669
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3670
|
+
"button",
|
|
3671
|
+
{
|
|
3672
|
+
type: "button",
|
|
3673
|
+
"data-gg-sheet-send": "",
|
|
3674
|
+
onClick: () => sendTyped(input),
|
|
3675
|
+
disabled: busy || !input.trim(),
|
|
3676
|
+
"aria-label": "Send message",
|
|
3677
|
+
"data-gg-send-message": "",
|
|
3678
|
+
style: {
|
|
3679
|
+
flexShrink: 0,
|
|
3680
|
+
width: "42px",
|
|
3681
|
+
height: "42px",
|
|
3682
|
+
borderRadius: "10px",
|
|
3683
|
+
border: "none",
|
|
3684
|
+
display: "inline-flex",
|
|
3685
|
+
alignItems: "center",
|
|
3686
|
+
justifyContent: "center",
|
|
3687
|
+
backgroundColor: busy || !input.trim() ? t.bgSecondary : t.accent,
|
|
3688
|
+
color: busy || !input.trim() ? t.textMuted : t.accentText,
|
|
3689
|
+
cursor: busy || !input.trim() ? "default" : "pointer"
|
|
3690
|
+
},
|
|
3691
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "17", height: "17", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3692
|
+
"path",
|
|
3693
|
+
{
|
|
3694
|
+
d: "M3 20.5L21.5 12 3 3.5V10l12 2-12 2v6.5z",
|
|
3695
|
+
fill: "currentColor"
|
|
3696
|
+
}
|
|
3697
|
+
) })
|
|
3698
|
+
}
|
|
3699
|
+
)
|
|
3700
|
+
] })
|
|
3611
3701
|
] }),
|
|
3612
3702
|
phase === "draft" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
3613
3703
|
validationError && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
@@ -3621,7 +3711,7 @@ function AssistSheet({
|
|
|
3621
3711
|
children: validationError
|
|
3622
3712
|
}
|
|
3623
3713
|
),
|
|
3624
|
-
autoFileLeft !== null ? (
|
|
3714
|
+
similarSlot ? similarSlot : autoFileLeft !== null ? (
|
|
3625
3715
|
// #402: "Yes, that's it" was the confirmation. The draft
|
|
3626
3716
|
// files itself unless they stop it — the bar shows how
|
|
3627
3717
|
// long is left, the button sends now, the × on its right
|
|
@@ -4677,6 +4767,7 @@ function ReportDialog({
|
|
|
4677
4767
|
enhanceText: enhanceText2,
|
|
4678
4768
|
assist,
|
|
4679
4769
|
findSimilarIssues: findSimilarIssues2,
|
|
4770
|
+
readFile,
|
|
4680
4771
|
assistContext = null,
|
|
4681
4772
|
transcribeAudio: transcribeAudio2,
|
|
4682
4773
|
types,
|
|
@@ -4730,6 +4821,15 @@ function ReportDialog({
|
|
|
4730
4821
|
const pendingShotRef = (0, import_react.useRef)(null);
|
|
4731
4822
|
const openGenRef = (0, import_react.useRef)(0);
|
|
4732
4823
|
const [attachments, setAttachments] = (0, import_react.useState)([]);
|
|
4824
|
+
const [pdfTexts, setPdfTexts] = (0, import_react.useState)({});
|
|
4825
|
+
const heldFiles = (0, import_react.useMemo)(
|
|
4826
|
+
() => attachments.map((a) => {
|
|
4827
|
+
const read = pdfTexts[heldFileKey(a)];
|
|
4828
|
+
if (!read) return a;
|
|
4829
|
+
return "reading" in read ? { ...a, reading: true } : { ...a, text: read.text, ...read.tooLarge ? { tooLarge: true } : {} };
|
|
4830
|
+
}),
|
|
4831
|
+
[attachments, pdfTexts]
|
|
4832
|
+
);
|
|
4733
4833
|
const [previewIndex, setPreviewIndex] = (0, import_react.useState)(null);
|
|
4734
4834
|
const [annotatingIndex, setAnnotatingIndex] = (0, import_react.useState)(null);
|
|
4735
4835
|
const [previewZoomed, setPreviewZoomed] = (0, import_react.useState)(false);
|
|
@@ -4890,10 +4990,16 @@ function ReportDialog({
|
|
|
4890
4990
|
files.filter((file) => !file.type.startsWith("image/")).forEach((file) => {
|
|
4891
4991
|
const reader = new FileReader();
|
|
4892
4992
|
reader.onload = () => {
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
]);
|
|
4993
|
+
const dataUrl = reader.result;
|
|
4994
|
+
setAttachments((prev) => [...prev, { name: file.name, size: file.size, dataUrl }]);
|
|
4995
|
+
const key = heldFileKey(file);
|
|
4996
|
+
if (!readFile || !isPdfFile(file.name) || pdfTexts[key]) return;
|
|
4997
|
+
if (file.size > MAX_READABLE_PDF_BYTES) {
|
|
4998
|
+
setPdfTexts((prev) => ({ ...prev, [key]: { text: null, tooLarge: true } }));
|
|
4999
|
+
return;
|
|
5000
|
+
}
|
|
5001
|
+
setPdfTexts((prev) => ({ ...prev, [key]: { reading: true } }));
|
|
5002
|
+
void Promise.resolve().then(() => readFile({ name: file.name, dataUrl })).catch(() => null).then((text) => setPdfTexts((prev) => ({ ...prev, [key]: { text } })));
|
|
4897
5003
|
};
|
|
4898
5004
|
reader.readAsDataURL(file);
|
|
4899
5005
|
});
|
|
@@ -5329,6 +5435,10 @@ function ReportDialog({
|
|
|
5329
5435
|
stopListeningAndTranscribe();
|
|
5330
5436
|
}
|
|
5331
5437
|
};
|
|
5438
|
+
(0, import_react.useEffect)(() => {
|
|
5439
|
+
setSimilarIssues(null);
|
|
5440
|
+
setPickedSimilar(null);
|
|
5441
|
+
}, [description]);
|
|
5332
5442
|
const handleSubmit = async (opts) => {
|
|
5333
5443
|
var _a2, _b, _c;
|
|
5334
5444
|
try {
|
|
@@ -5369,11 +5479,17 @@ function ReportDialog({
|
|
|
5369
5479
|
}
|
|
5370
5480
|
const duplicateOf = (_a2 = opts == null ? void 0 : opts.duplicateOf) != null ? _a2 : duplicateIssueNumber;
|
|
5371
5481
|
const attachKind = (opts == null ? void 0 : opts.duplicateOf) ? (_b = opts.kind) != null ? _b : "duplicate" : duplicateKind;
|
|
5372
|
-
if (findSimilarIssues2 && !(opts == null ? void 0 : opts.skipSimilar) && !duplicateOf
|
|
5482
|
+
if (findSimilarIssues2 && !(opts == null ? void 0 : opts.skipSimilar) && !duplicateOf) {
|
|
5483
|
+
const similarFiles = filesForSimilar(
|
|
5484
|
+
heldFiles,
|
|
5485
|
+
MAX_SIMILAR_FILE_CHARS,
|
|
5486
|
+
MAX_SIMILAR_FILES_TOTAL_CHARS
|
|
5487
|
+
);
|
|
5373
5488
|
setIsSubmitting(true);
|
|
5374
5489
|
setCheckingSimilar(true);
|
|
5375
5490
|
const matches = await Promise.race([
|
|
5376
|
-
|
|
5491
|
+
// A PDF still being read is left out rather than waited for.
|
|
5492
|
+
(similarFiles.length ? findSimilarIssues2(description.trim(), similarFiles) : findSimilarIssues2(description.trim())).catch(() => null),
|
|
5377
5493
|
new Promise((resolve) => setTimeout(() => resolve(null), SIMILAR_WAIT_MS))
|
|
5378
5494
|
]);
|
|
5379
5495
|
setCheckingSimilar(false);
|
|
@@ -5405,6 +5521,8 @@ function ReportDialog({
|
|
|
5405
5521
|
if (duplicateOf) {
|
|
5406
5522
|
metadata.duplicateIssueNumber = String(duplicateOf);
|
|
5407
5523
|
if (attachKind === "related") metadata.duplicateKind = "related";
|
|
5524
|
+
} else if (opts == null ? void 0 : opts.possiblyRelated) {
|
|
5525
|
+
metadata.possiblyRelatedIssue = String(opts.possiblyRelated);
|
|
5408
5526
|
}
|
|
5409
5527
|
if (aiConversationId) {
|
|
5410
5528
|
metadata.aiConversationId = aiConversationId;
|
|
@@ -5418,7 +5536,9 @@ function ReportDialog({
|
|
|
5418
5536
|
Object.keys(metadata).length > 0 ? metadata : void 0
|
|
5419
5537
|
);
|
|
5420
5538
|
if (result) {
|
|
5421
|
-
setAddedToIssue(
|
|
5539
|
+
setAddedToIssue(
|
|
5540
|
+
duplicateOf && result.issueNumber === duplicateOf ? duplicateOf : result.status === "DUPLICATE" && result.issueNumber ? result.issueNumber : null
|
|
5541
|
+
);
|
|
5422
5542
|
setAddedAsRelated(!!duplicateOf && result.issueNumber === duplicateOf && attachKind === "related");
|
|
5423
5543
|
const queued = result.status === "QUEUED" && !!result.message;
|
|
5424
5544
|
setQueuedMessage(queued ? (_c = result.message) != null ? _c : null : null);
|
|
@@ -5426,6 +5546,7 @@ function ReportDialog({
|
|
|
5426
5546
|
setDescription("");
|
|
5427
5547
|
setScreenshots([]);
|
|
5428
5548
|
setAttachments([]);
|
|
5549
|
+
setPdfTexts({});
|
|
5429
5550
|
setAiConversationId(null);
|
|
5430
5551
|
setIssueTitle("");
|
|
5431
5552
|
setDuplicateIssueNumber(null);
|
|
@@ -5446,6 +5567,220 @@ function ReportDialog({
|
|
|
5446
5567
|
setAttachingTo(null);
|
|
5447
5568
|
}
|
|
5448
5569
|
};
|
|
5570
|
+
const similarCard = similarIssues ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
5571
|
+
"div",
|
|
5572
|
+
{
|
|
5573
|
+
"data-gg-similar": "",
|
|
5574
|
+
style: {
|
|
5575
|
+
marginTop: "12px",
|
|
5576
|
+
display: "flex",
|
|
5577
|
+
flexDirection: "column",
|
|
5578
|
+
gap: "10px",
|
|
5579
|
+
padding: "12px",
|
|
5580
|
+
borderRadius: "10px",
|
|
5581
|
+
border: "1px solid rgba(245,158,11,0.4)",
|
|
5582
|
+
backgroundColor: "rgba(245,158,11,0.08)"
|
|
5583
|
+
},
|
|
5584
|
+
children: [
|
|
5585
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "2px" }, children: [
|
|
5586
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: { color: t.text, fontWeight: 600, fontSize: "13px" }, children: "Our team may already have this, or something close" }),
|
|
5587
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: { color: t.textMuted, fontSize: "12px", lineHeight: 1.5 }, children: similarIssues.length > 1 ? "Pick the one that matches. Same problem, or a different request for the same feature \u2014 it's added to that issue, so the team has it in one place." : "Same problem, or a different request for the same feature? Pick it \u2014 it's added to that issue, so the team has it in one place." })
|
|
5588
|
+
] }),
|
|
5589
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
5590
|
+
"div",
|
|
5591
|
+
{
|
|
5592
|
+
role: "radiogroup",
|
|
5593
|
+
"aria-label": "Existing issues",
|
|
5594
|
+
style: { display: "flex", flexDirection: "column", gap: "6px" },
|
|
5595
|
+
children: similarIssues.map((issue) => {
|
|
5596
|
+
const picked = pickedSimilar === issue.number;
|
|
5597
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
5598
|
+
"button",
|
|
5599
|
+
{
|
|
5600
|
+
type: "button",
|
|
5601
|
+
role: "radio",
|
|
5602
|
+
"aria-checked": picked,
|
|
5603
|
+
disabled: isSubmitting,
|
|
5604
|
+
onClick: () => setPickedSimilar(issue.number),
|
|
5605
|
+
style: {
|
|
5606
|
+
display: "flex",
|
|
5607
|
+
alignItems: "flex-start",
|
|
5608
|
+
gap: "10px",
|
|
5609
|
+
width: "100%",
|
|
5610
|
+
minHeight: "44px",
|
|
5611
|
+
padding: "9px 10px",
|
|
5612
|
+
borderRadius: "8px",
|
|
5613
|
+
border: `1px solid ${picked ? t.accent : t.border}`,
|
|
5614
|
+
boxShadow: picked ? `0 0 0 1px ${t.accent}` : "none",
|
|
5615
|
+
backgroundColor: t.bg,
|
|
5616
|
+
color: t.text,
|
|
5617
|
+
textAlign: "left",
|
|
5618
|
+
cursor: isSubmitting ? "not-allowed" : "pointer",
|
|
5619
|
+
fontFamily: "inherit"
|
|
5620
|
+
},
|
|
5621
|
+
children: [
|
|
5622
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
5623
|
+
"span",
|
|
5624
|
+
{
|
|
5625
|
+
"aria-hidden": "true",
|
|
5626
|
+
style: {
|
|
5627
|
+
flexShrink: 0,
|
|
5628
|
+
marginTop: "2px",
|
|
5629
|
+
width: "14px",
|
|
5630
|
+
height: "14px",
|
|
5631
|
+
boxSizing: "border-box",
|
|
5632
|
+
borderRadius: "50%",
|
|
5633
|
+
border: `2px solid ${picked ? t.accent : t.textMuted}`,
|
|
5634
|
+
backgroundColor: picked ? t.accent : "transparent",
|
|
5635
|
+
boxShadow: picked ? `inset 0 0 0 2px ${t.bg}` : "none"
|
|
5636
|
+
}
|
|
5637
|
+
}
|
|
5638
|
+
),
|
|
5639
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
5640
|
+
"span",
|
|
5641
|
+
{
|
|
5642
|
+
style: {
|
|
5643
|
+
display: "flex",
|
|
5644
|
+
flexDirection: "column",
|
|
5645
|
+
gap: "3px",
|
|
5646
|
+
minWidth: 0
|
|
5647
|
+
},
|
|
5648
|
+
children: [
|
|
5649
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
5650
|
+
"span",
|
|
5651
|
+
{
|
|
5652
|
+
title: issue.title,
|
|
5653
|
+
style: {
|
|
5654
|
+
fontSize: "12.5px",
|
|
5655
|
+
lineHeight: 1.45,
|
|
5656
|
+
wordBreak: "break-word",
|
|
5657
|
+
overflow: "hidden",
|
|
5658
|
+
display: "-webkit-box",
|
|
5659
|
+
WebkitLineClamp: 3,
|
|
5660
|
+
WebkitBoxOrient: "vertical"
|
|
5661
|
+
},
|
|
5662
|
+
children: [
|
|
5663
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { style: { color: t.textMuted, fontWeight: 600 }, children: [
|
|
5664
|
+
"#",
|
|
5665
|
+
issue.number
|
|
5666
|
+
] }),
|
|
5667
|
+
" ",
|
|
5668
|
+
issue.title
|
|
5669
|
+
]
|
|
5670
|
+
}
|
|
5671
|
+
),
|
|
5672
|
+
issue.status && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: { fontSize: "11.5px", color: t.textMuted }, children: issue.status })
|
|
5673
|
+
]
|
|
5674
|
+
}
|
|
5675
|
+
)
|
|
5676
|
+
]
|
|
5677
|
+
},
|
|
5678
|
+
issue.number
|
|
5679
|
+
);
|
|
5680
|
+
})
|
|
5681
|
+
}
|
|
5682
|
+
),
|
|
5683
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
5684
|
+
"button",
|
|
5685
|
+
{
|
|
5686
|
+
type: "button",
|
|
5687
|
+
disabled: isSubmitting || !pickedSimilar,
|
|
5688
|
+
onClick: () => {
|
|
5689
|
+
if (!pickedSimilar) return;
|
|
5690
|
+
setAttachingTo(pickedSimilar);
|
|
5691
|
+
setDuplicateIssueNumber(pickedSimilar);
|
|
5692
|
+
setDuplicateKind("duplicate");
|
|
5693
|
+
void handleSubmit({ duplicateOf: pickedSimilar, kind: "duplicate" });
|
|
5694
|
+
},
|
|
5695
|
+
style: {
|
|
5696
|
+
width: "100%",
|
|
5697
|
+
minHeight: "40px",
|
|
5698
|
+
padding: "10px",
|
|
5699
|
+
borderRadius: "8px",
|
|
5700
|
+
border: "none",
|
|
5701
|
+
backgroundColor: isSubmitting || !pickedSimilar ? t.bgSecondary : t.accent,
|
|
5702
|
+
color: isSubmitting || !pickedSimilar ? t.textMuted : t.accentText,
|
|
5703
|
+
fontSize: "14px",
|
|
5704
|
+
fontWeight: 600,
|
|
5705
|
+
cursor: isSubmitting || !pickedSimilar ? "not-allowed" : "pointer",
|
|
5706
|
+
fontFamily: "inherit"
|
|
5707
|
+
},
|
|
5708
|
+
children: typeof attachingTo === "number" && duplicateKind !== "related" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
5709
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ButtonSpinner, {}),
|
|
5710
|
+
"Adding to #",
|
|
5711
|
+
attachingTo,
|
|
5712
|
+
"\u2026"
|
|
5713
|
+
] }) : pickedSimilar ? `Add to #${pickedSimilar}` : "Pick the matching issue"
|
|
5714
|
+
}
|
|
5715
|
+
),
|
|
5716
|
+
pickedSimilar && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
5717
|
+
"button",
|
|
5718
|
+
{
|
|
5719
|
+
type: "button",
|
|
5720
|
+
disabled: isSubmitting,
|
|
5721
|
+
onClick: () => {
|
|
5722
|
+
setAttachingTo(pickedSimilar);
|
|
5723
|
+
setDuplicateIssueNumber(pickedSimilar);
|
|
5724
|
+
setDuplicateKind("related");
|
|
5725
|
+
void handleSubmit({ duplicateOf: pickedSimilar, kind: "related" });
|
|
5726
|
+
},
|
|
5727
|
+
style: {
|
|
5728
|
+
width: "100%",
|
|
5729
|
+
minHeight: "40px",
|
|
5730
|
+
marginTop: "-4px",
|
|
5731
|
+
padding: "9px 10px",
|
|
5732
|
+
borderRadius: "8px",
|
|
5733
|
+
border: "1px solid rgba(245,158,11,0.4)",
|
|
5734
|
+
backgroundColor: "transparent",
|
|
5735
|
+
color: isSubmitting ? t.textMuted : t.text,
|
|
5736
|
+
fontSize: "13px",
|
|
5737
|
+
fontWeight: 600,
|
|
5738
|
+
cursor: isSubmitting ? "not-allowed" : "pointer",
|
|
5739
|
+
fontFamily: "inherit"
|
|
5740
|
+
},
|
|
5741
|
+
children: typeof attachingTo === "number" && duplicateKind === "related" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
5742
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ButtonSpinner, {}),
|
|
5743
|
+
"Adding to #",
|
|
5744
|
+
attachingTo,
|
|
5745
|
+
"\u2026"
|
|
5746
|
+
] }) : `Related request \u2014 add to #${pickedSimilar}`
|
|
5747
|
+
}
|
|
5748
|
+
),
|
|
5749
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
5750
|
+
"button",
|
|
5751
|
+
{
|
|
5752
|
+
type: "button",
|
|
5753
|
+
disabled: isSubmitting,
|
|
5754
|
+
onClick: () => {
|
|
5755
|
+
var _a2;
|
|
5756
|
+
setAttachingTo("new");
|
|
5757
|
+
void handleSubmit({ skipSimilar: true, possiblyRelated: (_a2 = similarIssues[0]) == null ? void 0 : _a2.number });
|
|
5758
|
+
},
|
|
5759
|
+
style: {
|
|
5760
|
+
width: "100%",
|
|
5761
|
+
minHeight: "40px",
|
|
5762
|
+
marginTop: "-4px",
|
|
5763
|
+
padding: "8px",
|
|
5764
|
+
borderRadius: "8px",
|
|
5765
|
+
border: "none",
|
|
5766
|
+
backgroundColor: "transparent",
|
|
5767
|
+
color: isSubmitting ? t.textMuted : t.text,
|
|
5768
|
+
fontSize: "13px",
|
|
5769
|
+
fontWeight: 500,
|
|
5770
|
+
textDecoration: "underline",
|
|
5771
|
+
textUnderlineOffset: "3px",
|
|
5772
|
+
cursor: isSubmitting ? "not-allowed" : "pointer",
|
|
5773
|
+
fontFamily: "inherit"
|
|
5774
|
+
},
|
|
5775
|
+
children: attachingTo === "new" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
5776
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ButtonSpinner, {}),
|
|
5777
|
+
"Sending as new\u2026"
|
|
5778
|
+
] }) : "No, mine is different \u2014 send as new"
|
|
5779
|
+
}
|
|
5780
|
+
)
|
|
5781
|
+
]
|
|
5782
|
+
}
|
|
5783
|
+
) : null;
|
|
5449
5784
|
if (!mounted) return null;
|
|
5450
5785
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
5451
5786
|
isOpen && (0, import_react_dom.createPortal)(
|
|
@@ -6984,224 +7319,7 @@ function ReportDialog({
|
|
|
6984
7319
|
children: validationError
|
|
6985
7320
|
}
|
|
6986
7321
|
),
|
|
6987
|
-
|
|
6988
|
-
// Same visual language as the assistant's "Our team is
|
|
6989
|
-
// already on this" card, so both routes to a duplicate
|
|
6990
|
-
// read as one feature.
|
|
6991
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
6992
|
-
"div",
|
|
6993
|
-
{
|
|
6994
|
-
"data-gg-similar": "",
|
|
6995
|
-
style: {
|
|
6996
|
-
marginTop: "12px",
|
|
6997
|
-
display: "flex",
|
|
6998
|
-
flexDirection: "column",
|
|
6999
|
-
gap: "10px",
|
|
7000
|
-
padding: "12px",
|
|
7001
|
-
borderRadius: "10px",
|
|
7002
|
-
border: "1px solid rgba(245,158,11,0.4)",
|
|
7003
|
-
backgroundColor: "rgba(245,158,11,0.08)"
|
|
7004
|
-
},
|
|
7005
|
-
children: [
|
|
7006
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "2px" }, children: [
|
|
7007
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: { color: t.text, fontWeight: 600, fontSize: "13px" }, children: "Our team may already have this, or something close" }),
|
|
7008
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: { color: t.textMuted, fontSize: "12px", lineHeight: 1.5 }, children: similarIssues.length > 1 ? "Pick the one that matches. Same problem, or a different request for the same feature \u2014 it's added to that issue, so the team has it in one place." : "Same problem, or a different request for the same feature? Pick it \u2014 it's added to that issue, so the team has it in one place." })
|
|
7009
|
-
] }),
|
|
7010
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
7011
|
-
"div",
|
|
7012
|
-
{
|
|
7013
|
-
role: "radiogroup",
|
|
7014
|
-
"aria-label": "Existing issues",
|
|
7015
|
-
style: { display: "flex", flexDirection: "column", gap: "6px" },
|
|
7016
|
-
children: similarIssues.map((issue) => {
|
|
7017
|
-
const picked = pickedSimilar === issue.number;
|
|
7018
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
7019
|
-
"button",
|
|
7020
|
-
{
|
|
7021
|
-
type: "button",
|
|
7022
|
-
role: "radio",
|
|
7023
|
-
"aria-checked": picked,
|
|
7024
|
-
disabled: isSubmitting,
|
|
7025
|
-
onClick: () => setPickedSimilar(issue.number),
|
|
7026
|
-
style: {
|
|
7027
|
-
display: "flex",
|
|
7028
|
-
alignItems: "flex-start",
|
|
7029
|
-
gap: "10px",
|
|
7030
|
-
width: "100%",
|
|
7031
|
-
minHeight: "44px",
|
|
7032
|
-
padding: "9px 10px",
|
|
7033
|
-
borderRadius: "8px",
|
|
7034
|
-
border: `1px solid ${picked ? t.accent : t.border}`,
|
|
7035
|
-
boxShadow: picked ? `0 0 0 1px ${t.accent}` : "none",
|
|
7036
|
-
backgroundColor: t.bg,
|
|
7037
|
-
color: t.text,
|
|
7038
|
-
textAlign: "left",
|
|
7039
|
-
cursor: isSubmitting ? "not-allowed" : "pointer",
|
|
7040
|
-
fontFamily: "inherit"
|
|
7041
|
-
},
|
|
7042
|
-
children: [
|
|
7043
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
7044
|
-
"span",
|
|
7045
|
-
{
|
|
7046
|
-
"aria-hidden": "true",
|
|
7047
|
-
style: {
|
|
7048
|
-
flexShrink: 0,
|
|
7049
|
-
marginTop: "2px",
|
|
7050
|
-
width: "14px",
|
|
7051
|
-
height: "14px",
|
|
7052
|
-
boxSizing: "border-box",
|
|
7053
|
-
borderRadius: "50%",
|
|
7054
|
-
border: `2px solid ${picked ? t.accent : t.textMuted}`,
|
|
7055
|
-
backgroundColor: picked ? t.accent : "transparent",
|
|
7056
|
-
boxShadow: picked ? `inset 0 0 0 2px ${t.bg}` : "none"
|
|
7057
|
-
}
|
|
7058
|
-
}
|
|
7059
|
-
),
|
|
7060
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
7061
|
-
"span",
|
|
7062
|
-
{
|
|
7063
|
-
style: {
|
|
7064
|
-
display: "flex",
|
|
7065
|
-
flexDirection: "column",
|
|
7066
|
-
gap: "3px",
|
|
7067
|
-
minWidth: 0
|
|
7068
|
-
},
|
|
7069
|
-
children: [
|
|
7070
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
7071
|
-
"span",
|
|
7072
|
-
{
|
|
7073
|
-
title: issue.title,
|
|
7074
|
-
style: {
|
|
7075
|
-
fontSize: "12.5px",
|
|
7076
|
-
lineHeight: 1.45,
|
|
7077
|
-
wordBreak: "break-word",
|
|
7078
|
-
overflow: "hidden",
|
|
7079
|
-
display: "-webkit-box",
|
|
7080
|
-
WebkitLineClamp: 3,
|
|
7081
|
-
WebkitBoxOrient: "vertical"
|
|
7082
|
-
},
|
|
7083
|
-
children: [
|
|
7084
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { style: { color: t.textMuted, fontWeight: 600 }, children: [
|
|
7085
|
-
"#",
|
|
7086
|
-
issue.number
|
|
7087
|
-
] }),
|
|
7088
|
-
" ",
|
|
7089
|
-
issue.title
|
|
7090
|
-
]
|
|
7091
|
-
}
|
|
7092
|
-
),
|
|
7093
|
-
issue.status && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { style: { fontSize: "11.5px", color: t.textMuted }, children: issue.status })
|
|
7094
|
-
]
|
|
7095
|
-
}
|
|
7096
|
-
)
|
|
7097
|
-
]
|
|
7098
|
-
},
|
|
7099
|
-
issue.number
|
|
7100
|
-
);
|
|
7101
|
-
})
|
|
7102
|
-
}
|
|
7103
|
-
),
|
|
7104
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
7105
|
-
"button",
|
|
7106
|
-
{
|
|
7107
|
-
type: "button",
|
|
7108
|
-
disabled: isSubmitting || !pickedSimilar,
|
|
7109
|
-
onClick: () => {
|
|
7110
|
-
if (!pickedSimilar) return;
|
|
7111
|
-
setAttachingTo(pickedSimilar);
|
|
7112
|
-
setDuplicateIssueNumber(pickedSimilar);
|
|
7113
|
-
setDuplicateKind("duplicate");
|
|
7114
|
-
void handleSubmit({ duplicateOf: pickedSimilar, kind: "duplicate" });
|
|
7115
|
-
},
|
|
7116
|
-
style: {
|
|
7117
|
-
width: "100%",
|
|
7118
|
-
minHeight: "40px",
|
|
7119
|
-
padding: "10px",
|
|
7120
|
-
borderRadius: "8px",
|
|
7121
|
-
border: "none",
|
|
7122
|
-
backgroundColor: isSubmitting || !pickedSimilar ? t.bgSecondary : t.accent,
|
|
7123
|
-
color: isSubmitting || !pickedSimilar ? t.textMuted : t.accentText,
|
|
7124
|
-
fontSize: "14px",
|
|
7125
|
-
fontWeight: 600,
|
|
7126
|
-
cursor: isSubmitting || !pickedSimilar ? "not-allowed" : "pointer",
|
|
7127
|
-
fontFamily: "inherit"
|
|
7128
|
-
},
|
|
7129
|
-
children: typeof attachingTo === "number" && duplicateKind !== "related" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
7130
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ButtonSpinner, {}),
|
|
7131
|
-
"Adding to #",
|
|
7132
|
-
attachingTo,
|
|
7133
|
-
"\u2026"
|
|
7134
|
-
] }) : pickedSimilar ? `Add to #${pickedSimilar}` : "Pick the matching issue"
|
|
7135
|
-
}
|
|
7136
|
-
),
|
|
7137
|
-
pickedSimilar && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
7138
|
-
"button",
|
|
7139
|
-
{
|
|
7140
|
-
type: "button",
|
|
7141
|
-
disabled: isSubmitting,
|
|
7142
|
-
onClick: () => {
|
|
7143
|
-
setAttachingTo(pickedSimilar);
|
|
7144
|
-
setDuplicateIssueNumber(pickedSimilar);
|
|
7145
|
-
setDuplicateKind("related");
|
|
7146
|
-
void handleSubmit({ duplicateOf: pickedSimilar, kind: "related" });
|
|
7147
|
-
},
|
|
7148
|
-
style: {
|
|
7149
|
-
width: "100%",
|
|
7150
|
-
minHeight: "40px",
|
|
7151
|
-
marginTop: "-4px",
|
|
7152
|
-
padding: "9px 10px",
|
|
7153
|
-
borderRadius: "8px",
|
|
7154
|
-
border: "1px solid rgba(245,158,11,0.4)",
|
|
7155
|
-
backgroundColor: "transparent",
|
|
7156
|
-
color: isSubmitting ? t.textMuted : t.text,
|
|
7157
|
-
fontSize: "13px",
|
|
7158
|
-
fontWeight: 600,
|
|
7159
|
-
cursor: isSubmitting ? "not-allowed" : "pointer",
|
|
7160
|
-
fontFamily: "inherit"
|
|
7161
|
-
},
|
|
7162
|
-
children: typeof attachingTo === "number" && duplicateKind === "related" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
7163
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ButtonSpinner, {}),
|
|
7164
|
-
"Adding to #",
|
|
7165
|
-
attachingTo,
|
|
7166
|
-
"\u2026"
|
|
7167
|
-
] }) : `Related request \u2014 add to #${pickedSimilar}`
|
|
7168
|
-
}
|
|
7169
|
-
),
|
|
7170
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
7171
|
-
"button",
|
|
7172
|
-
{
|
|
7173
|
-
type: "button",
|
|
7174
|
-
disabled: isSubmitting,
|
|
7175
|
-
onClick: () => {
|
|
7176
|
-
setAttachingTo("new");
|
|
7177
|
-
void handleSubmit({ skipSimilar: true });
|
|
7178
|
-
},
|
|
7179
|
-
style: {
|
|
7180
|
-
width: "100%",
|
|
7181
|
-
minHeight: "40px",
|
|
7182
|
-
marginTop: "-4px",
|
|
7183
|
-
padding: "8px",
|
|
7184
|
-
borderRadius: "8px",
|
|
7185
|
-
border: "none",
|
|
7186
|
-
backgroundColor: "transparent",
|
|
7187
|
-
color: isSubmitting ? t.textMuted : t.text,
|
|
7188
|
-
fontSize: "13px",
|
|
7189
|
-
fontWeight: 500,
|
|
7190
|
-
textDecoration: "underline",
|
|
7191
|
-
textUnderlineOffset: "3px",
|
|
7192
|
-
cursor: isSubmitting ? "not-allowed" : "pointer",
|
|
7193
|
-
fontFamily: "inherit"
|
|
7194
|
-
},
|
|
7195
|
-
children: attachingTo === "new" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
7196
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ButtonSpinner, {}),
|
|
7197
|
-
"Sending as new\u2026"
|
|
7198
|
-
] }) : "No, mine is different \u2014 send as new"
|
|
7199
|
-
}
|
|
7200
|
-
)
|
|
7201
|
-
]
|
|
7202
|
-
}
|
|
7203
|
-
)
|
|
7204
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
7322
|
+
similarCard != null ? similarCard : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
7205
7323
|
"button",
|
|
7206
7324
|
{
|
|
7207
7325
|
type: "button",
|
|
@@ -7500,7 +7618,8 @@ function ReportDialog({
|
|
|
7500
7618
|
pageShot,
|
|
7501
7619
|
onAddFiles: addFiles,
|
|
7502
7620
|
onRemoveImage: (index) => setScreenshots((prev) => prev.filter((_, i) => i !== index)),
|
|
7503
|
-
files:
|
|
7621
|
+
files: heldFiles,
|
|
7622
|
+
canReadPdf: !!readFile,
|
|
7504
7623
|
onRemoveFile: (index) => setAttachments((prev) => prev.filter((_, i) => i !== index)),
|
|
7505
7624
|
attachmentCount: screenshots.length + attachments.length,
|
|
7506
7625
|
context: { ...assistContext != null ? assistContext : {}, reportType },
|
|
@@ -7514,6 +7633,10 @@ function ReportDialog({
|
|
|
7514
7633
|
setStep(2);
|
|
7515
7634
|
},
|
|
7516
7635
|
onDuplicateChange: (issueNumber, kind) => {
|
|
7636
|
+
if (issueNumber) {
|
|
7637
|
+
setSimilarIssues(null);
|
|
7638
|
+
setPickedSimilar(null);
|
|
7639
|
+
}
|
|
7517
7640
|
setDuplicateIssueNumber(issueNumber);
|
|
7518
7641
|
setDuplicateKind(issueNumber && kind === "related" ? "related" : "duplicate");
|
|
7519
7642
|
},
|
|
@@ -7543,7 +7666,9 @@ function ReportDialog({
|
|
|
7543
7666
|
severityRefused: needsSeverity,
|
|
7544
7667
|
isSubmitting,
|
|
7545
7668
|
submitted,
|
|
7546
|
-
onSend: () => void handleSubmit(
|
|
7669
|
+
onSend: () => void handleSubmit(),
|
|
7670
|
+
similarSlot: similarCard,
|
|
7671
|
+
submittedText: addedToIssue ? `Added to #${addedToIssue}${addedAsRelated ? " as a related request" : ""}. Thank you!` : null,
|
|
7547
7672
|
onReportGlitchgrabProblem: reportGlitchgrabProblem ? (prefill) => {
|
|
7548
7673
|
setSelfReportPrefill(prefill != null ? prefill : "");
|
|
7549
7674
|
setSelfReportFrom("assist");
|
|
@@ -7837,7 +7962,9 @@ function BookingDialog({
|
|
|
7837
7962
|
token,
|
|
7838
7963
|
baseUrl,
|
|
7839
7964
|
open,
|
|
7840
|
-
onClose
|
|
7965
|
+
onClose,
|
|
7966
|
+
preview = false,
|
|
7967
|
+
availabilityUrl
|
|
7841
7968
|
}) {
|
|
7842
7969
|
var _a, _b, _c, _d, _e;
|
|
7843
7970
|
const wide = useMediaQuery(WIDE_QUERY, true);
|
|
@@ -7865,15 +7992,18 @@ function BookingDialog({
|
|
|
7865
7992
|
const [answers, setAnswers] = (0, import_react5.useState)({});
|
|
7866
7993
|
const [pageLoaded, setPageLoaded] = (0, import_react5.useState)(false);
|
|
7867
7994
|
const [asked, setAsked] = (0, import_react5.useState)(false);
|
|
7995
|
+
const [requireOtp, setRequireOtp] = (0, import_react5.useState)(true);
|
|
7868
7996
|
const [code, setCode] = (0, import_react5.useState)("");
|
|
7869
7997
|
const [bookingId, setBookingId] = (0, import_react5.useState)(null);
|
|
7870
7998
|
const [meetUrl, setMeetUrl] = (0, import_react5.useState)(null);
|
|
7871
7999
|
const [busy, setBusy] = (0, import_react5.useState)(false);
|
|
7872
8000
|
const [error, setError] = (0, import_react5.useState)(null);
|
|
7873
|
-
const
|
|
7874
|
-
|
|
7875
|
-
|
|
7876
|
-
|
|
8001
|
+
const [previewEnded, setPreviewEnded] = (0, import_react5.useState)(false);
|
|
8002
|
+
const headers = (0, import_react5.useMemo)(() => {
|
|
8003
|
+
const out = { "Content-Type": "application/json" };
|
|
8004
|
+
if (token) out.Authorization = `Bearer ${token}`;
|
|
8005
|
+
return out;
|
|
8006
|
+
}, [token]);
|
|
7877
8007
|
const loadMonth = (0, import_react5.useCallback)(
|
|
7878
8008
|
async (target) => {
|
|
7879
8009
|
var _a2, _b2, _c2;
|
|
@@ -7885,8 +8015,9 @@ function BookingDialog({
|
|
|
7885
8015
|
return;
|
|
7886
8016
|
}
|
|
7887
8017
|
try {
|
|
8018
|
+
const source = availabilityUrl != null ? availabilityUrl : `${baseUrl}/api/v1/sdk/booking/availability`;
|
|
7888
8019
|
const res = await fetch(
|
|
7889
|
-
`${
|
|
8020
|
+
`${source}${source.includes("?") ? "&" : "?"}from=${encodeURIComponent(new Date(from).toISOString())}&to=${encodeURIComponent(new Date(to).toISOString())}${preview ? "&preview=1" : ""}`,
|
|
7890
8021
|
{ headers }
|
|
7891
8022
|
);
|
|
7892
8023
|
const json = await res.json();
|
|
@@ -7907,6 +8038,7 @@ function BookingDialog({
|
|
|
7907
8038
|
});
|
|
7908
8039
|
setWhatsappUrl((_c2 = data.whatsappUrl) != null ? _c2 : null);
|
|
7909
8040
|
setQuestions(readQuestions(data.questions));
|
|
8041
|
+
setRequireOtp(data.requireOtp !== false);
|
|
7910
8042
|
setPageLoaded(true);
|
|
7911
8043
|
} catch (e) {
|
|
7912
8044
|
setError("Couldn't reach the booking service");
|
|
@@ -7914,7 +8046,7 @@ function BookingDialog({
|
|
|
7914
8046
|
setPageLoaded(true);
|
|
7915
8047
|
}
|
|
7916
8048
|
},
|
|
7917
|
-
[baseUrl, headers]
|
|
8049
|
+
[baseUrl, headers, availabilityUrl, preview]
|
|
7918
8050
|
);
|
|
7919
8051
|
(0, import_react5.useEffect)(() => {
|
|
7920
8052
|
if (!open) return;
|
|
@@ -7928,6 +8060,7 @@ function BookingDialog({
|
|
|
7928
8060
|
setCode("");
|
|
7929
8061
|
setBookingId(null);
|
|
7930
8062
|
setError(null);
|
|
8063
|
+
setPreviewEnded(false);
|
|
7931
8064
|
setAvatarFailed(false);
|
|
7932
8065
|
setPageLoaded(false);
|
|
7933
8066
|
setAsked(false);
|
|
@@ -7964,8 +8097,12 @@ function BookingDialog({
|
|
|
7964
8097
|
const view = step !== "slots" ? step : !pageLoaded ? "loading" : questions.length > 0 && !asked ? "questions" : "slots";
|
|
7965
8098
|
const roomy = step === "slots";
|
|
7966
8099
|
async function startBooking() {
|
|
7967
|
-
var _a2;
|
|
8100
|
+
var _a2, _b2;
|
|
7968
8101
|
if (!selected) return;
|
|
8102
|
+
if (preview) {
|
|
8103
|
+
setPreviewEnded(true);
|
|
8104
|
+
return;
|
|
8105
|
+
}
|
|
7969
8106
|
setBusy(true);
|
|
7970
8107
|
setError(null);
|
|
7971
8108
|
try {
|
|
@@ -7980,7 +8117,10 @@ function BookingDialog({
|
|
|
7980
8117
|
answers: Object.fromEntries(given.map((q) => [q.id, q.answer])),
|
|
7981
8118
|
startsAt: selected.startsAt,
|
|
7982
8119
|
// The zone the times were shown in, which is the one the visitor chose.
|
|
7983
|
-
timezone: zone
|
|
8120
|
+
timezone: zone,
|
|
8121
|
+
// This dialog can show a booking confirmed in one step; the server
|
|
8122
|
+
// only skips the code for a dialog that says so.
|
|
8123
|
+
instant: true
|
|
7984
8124
|
})
|
|
7985
8125
|
});
|
|
7986
8126
|
const json = await res.json();
|
|
@@ -7988,6 +8128,11 @@ function BookingDialog({
|
|
|
7988
8128
|
setError((_a2 = json.error) != null ? _a2 : "Couldn't hold that slot");
|
|
7989
8129
|
return;
|
|
7990
8130
|
}
|
|
8131
|
+
if (json.data.confirmed) {
|
|
8132
|
+
setMeetUrl((_b2 = json.data.meetUrl) != null ? _b2 : null);
|
|
8133
|
+
setStep("done");
|
|
8134
|
+
return;
|
|
8135
|
+
}
|
|
7991
8136
|
setBookingId(json.data.bookingId);
|
|
7992
8137
|
setStep("code");
|
|
7993
8138
|
} catch (e) {
|
|
@@ -8151,6 +8296,22 @@ function BookingDialog({
|
|
|
8151
8296
|
) : null,
|
|
8152
8297
|
page.hostName && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { fontSize: 14, fontWeight: 500, ...muted }, children: page.hostName })
|
|
8153
8298
|
] }),
|
|
8299
|
+
preview && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
8300
|
+
"div",
|
|
8301
|
+
{
|
|
8302
|
+
style: {
|
|
8303
|
+
alignSelf: "flex-start",
|
|
8304
|
+
padding: "3px 9px",
|
|
8305
|
+
borderRadius: 999,
|
|
8306
|
+
border: `1px dashed ${t.border}`,
|
|
8307
|
+
fontSize: 11.5,
|
|
8308
|
+
fontWeight: 600,
|
|
8309
|
+
letterSpacing: "0.02em",
|
|
8310
|
+
color: t.muted
|
|
8311
|
+
},
|
|
8312
|
+
children: "Preview \u2014 nothing is booked"
|
|
8313
|
+
}
|
|
8314
|
+
),
|
|
8154
8315
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { fontSize: 20, fontWeight: 600, lineHeight: 1.25, paddingRight: 32, overflowWrap: "anywhere" }, children: page.title }),
|
|
8155
8316
|
page.description && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { fontSize: 13, lineHeight: 1.5, overflowWrap: "anywhere", ...muted }, children: page.description }),
|
|
8156
8317
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 10, marginTop: 4, fontSize: 14 }, children: [
|
|
@@ -8588,6 +8749,7 @@ function BookingDialog({
|
|
|
8588
8749
|
},
|
|
8589
8750
|
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { maxWidth: 440, display: "flex", flexDirection: "column", gap: 14 }, children: [
|
|
8590
8751
|
error && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { color: t.danger, fontSize: 13, lineHeight: 1.5 }, children: error }),
|
|
8752
|
+
previewEnded && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { fontSize: 13, lineHeight: 1.5, ...muted }, children: "End of the preview \u2014 a prospect would be booked here. Nothing was booked and no code was sent." }),
|
|
8591
8753
|
step === "details" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
8592
8754
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Field, { t, label: "Your name", value: name, onChange: setName, autoComplete: "name" }),
|
|
8593
8755
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Field, { t, label: "Email", value: email, onChange: setEmail, type: "email", autoComplete: "email" }),
|
|
@@ -8600,7 +8762,7 @@ function BookingDialog({
|
|
|
8600
8762
|
onChange: setPhone,
|
|
8601
8763
|
type: "tel",
|
|
8602
8764
|
autoComplete: "tel",
|
|
8603
|
-
hint: "We send a code here to confirm, then a reminder before the call."
|
|
8765
|
+
hint: requireOtp ? "We send a code here to confirm, then a reminder before the call." : "We send a reminder here before the call."
|
|
8604
8766
|
}
|
|
8605
8767
|
),
|
|
8606
8768
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Field, { t, label: "Anything we should know? (optional)", value: note, onChange: setNote, multiline: true }),
|
|
@@ -8625,7 +8787,7 @@ function BookingDialog({
|
|
|
8625
8787
|
onClick: startBooking,
|
|
8626
8788
|
disabled: !canSubmitDetails || busy,
|
|
8627
8789
|
style: primaryStyle(t, !canSubmitDetails || busy),
|
|
8628
|
-
children: busy ? "Sending code\u2026" : "Send verification code"
|
|
8790
|
+
children: requireOtp ? busy ? "Sending code\u2026" : "Send verification code" : busy ? "Booking\u2026" : "Book demo"
|
|
8629
8791
|
}
|
|
8630
8792
|
)
|
|
8631
8793
|
] })
|
|
@@ -9428,7 +9590,11 @@ function GlitchgrabProviderInner({
|
|
|
9428
9590
|
[token, baseUrl, session]
|
|
9429
9591
|
);
|
|
9430
9592
|
const findSimilar = (0, import_react6.useCallback)(
|
|
9431
|
-
(description) => findSimilarIssues(description, token, baseUrl, identity),
|
|
9593
|
+
(description, files) => findSimilarIssues(description, token, baseUrl, identity, files),
|
|
9594
|
+
[token, baseUrl, identity]
|
|
9595
|
+
);
|
|
9596
|
+
const readFile = (0, import_react6.useCallback)(
|
|
9597
|
+
(file) => readAttachment(file, token, baseUrl, identity),
|
|
9432
9598
|
[token, baseUrl, identity]
|
|
9433
9599
|
);
|
|
9434
9600
|
const transcribe = (0, import_react6.useCallback)(
|
|
@@ -9459,8 +9625,9 @@ function GlitchgrabProviderInner({
|
|
|
9459
9625
|
const [glitchgrabReport, setGlitchgrabReport] = (0, import_react6.useState)(false);
|
|
9460
9626
|
const [signedUsers, setSignedUsers] = (0, import_react6.useState)("OFF");
|
|
9461
9627
|
const aiBlockedUnsigned = signedUsers === "ENFORCE" && !signature;
|
|
9462
|
-
const [
|
|
9463
|
-
const openBookingDialog = (0, import_react6.useCallback)(() =>
|
|
9628
|
+
const [booking, setBooking] = (0, import_react6.useState)("closed");
|
|
9629
|
+
const openBookingDialog = (0, import_react6.useCallback)(() => setBooking("live"), []);
|
|
9630
|
+
const openBookingPreview = (0, import_react6.useCallback)(() => setBooking("preview"), []);
|
|
9464
9631
|
(0, import_react6.useEffect)(() => {
|
|
9465
9632
|
let cancelled = false;
|
|
9466
9633
|
fetch(`${baseUrl}/api/v1/sdk/project`, {
|
|
@@ -9535,6 +9702,7 @@ function GlitchgrabProviderInner({
|
|
|
9535
9702
|
addBreadcrumb: addBreadcrumb2,
|
|
9536
9703
|
openReportDialog,
|
|
9537
9704
|
openBookingDialog,
|
|
9705
|
+
openBookingPreview,
|
|
9538
9706
|
enhanceText: enhance,
|
|
9539
9707
|
shortcutLabel
|
|
9540
9708
|
},
|
|
@@ -9556,8 +9724,9 @@ function GlitchgrabProviderInner({
|
|
|
9556
9724
|
{
|
|
9557
9725
|
token,
|
|
9558
9726
|
baseUrl: baseUrl != null ? baseUrl : DEFAULT_BASE_URL2,
|
|
9559
|
-
open:
|
|
9560
|
-
|
|
9727
|
+
open: booking !== "closed",
|
|
9728
|
+
preview: booking === "preview",
|
|
9729
|
+
onClose: () => setBooking("closed")
|
|
9561
9730
|
}
|
|
9562
9731
|
),
|
|
9563
9732
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
@@ -9568,6 +9737,7 @@ function GlitchgrabProviderInner({
|
|
|
9568
9737
|
enhanceText: aiAssist && !aiBlockedUnsigned ? enhance : void 0,
|
|
9569
9738
|
assist: aiAssist && !aiBlockedUnsigned ? assist : void 0,
|
|
9570
9739
|
findSimilarIssues: aiAssist && !aiBlockedUnsigned ? findSimilar : void 0,
|
|
9740
|
+
readFile: aiAssist && !aiBlockedUnsigned ? readFile : void 0,
|
|
9571
9741
|
reportGlitchgrabProblem: glitchgrabReport ? reportGlitchgrabProblem : void 0,
|
|
9572
9742
|
transcribeAudio: aiBlockedUnsigned ? void 0 : transcribe,
|
|
9573
9743
|
types,
|
|
@@ -9972,6 +10142,7 @@ function useGlitchgrabFeedback(query) {
|
|
|
9972
10142
|
// Annotate the CommonJS export names for ESM import in node:
|
|
9973
10143
|
0 && (module.exports = {
|
|
9974
10144
|
BookDemoButton,
|
|
10145
|
+
BookingDialog,
|
|
9975
10146
|
FeedbackButton,
|
|
9976
10147
|
GLITCHGRAB_SHORTCUT,
|
|
9977
10148
|
GLITCHGRAB_SHORTCUT_MAC,
|