glitchgrab 1.35.0 → 1.37.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.js +600 -131
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +600 -131
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -647,7 +647,7 @@ async function enhanceText(text, token, baseUrl, screenshot, context) {
|
|
|
647
647
|
}
|
|
648
648
|
}
|
|
649
649
|
async function assistTurn(params, token, baseUrl) {
|
|
650
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
650
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
651
651
|
const offline = {
|
|
652
652
|
conversationId: null,
|
|
653
653
|
question: null,
|
|
@@ -676,7 +676,10 @@ async function assistTurn(params, token, baseUrl) {
|
|
|
676
676
|
return {
|
|
677
677
|
conversationId: (_c = (_b = envelope.data) == null ? void 0 : _b.conversationId) != null ? _c : null,
|
|
678
678
|
question: (_e = (_d = envelope.data) == null ? void 0 : _d.question) != null ? _e : null,
|
|
679
|
-
|
|
679
|
+
options: (_g = (_f = envelope.data) == null ? void 0 : _f.options) != null ? _g : [],
|
|
680
|
+
report: (_i = (_h = envelope.data) == null ? void 0 : _h.report) != null ? _i : null,
|
|
681
|
+
duplicate: (_k = (_j = envelope.data) == null ? void 0 : _j.duplicate) != null ? _k : null,
|
|
682
|
+
solved: (_m = (_l = envelope.data) == null ? void 0 : _l.solved) != null ? _m : null,
|
|
680
683
|
degraded: null
|
|
681
684
|
};
|
|
682
685
|
} catch (e) {
|
|
@@ -1203,6 +1206,26 @@ function AnnotationCanvas({ imageSrc, onSave, onCancel }) {
|
|
|
1203
1206
|
}
|
|
1204
1207
|
);
|
|
1205
1208
|
}
|
|
1209
|
+
function getTypeLabel(type) {
|
|
1210
|
+
switch (type) {
|
|
1211
|
+
case "RATING":
|
|
1212
|
+
return "Rating";
|
|
1213
|
+
case "BUG":
|
|
1214
|
+
return "Bug Report";
|
|
1215
|
+
case "FEATURE_REQUEST":
|
|
1216
|
+
return "Feature Request";
|
|
1217
|
+
case "UI_IMPROVEMENT":
|
|
1218
|
+
return "UI Improvement";
|
|
1219
|
+
case "PERFORMANCE":
|
|
1220
|
+
return "Performance";
|
|
1221
|
+
case "SECURITY":
|
|
1222
|
+
return "Security";
|
|
1223
|
+
case "QUESTION":
|
|
1224
|
+
return "Question";
|
|
1225
|
+
case "OTHER":
|
|
1226
|
+
return "Other";
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1206
1229
|
var STARTERS = [
|
|
1207
1230
|
"Something on this page is broken",
|
|
1208
1231
|
"It did the wrong thing",
|
|
@@ -1281,6 +1304,12 @@ function AssistSheet({
|
|
|
1281
1304
|
attachmentCount,
|
|
1282
1305
|
context,
|
|
1283
1306
|
reportTypeLabel,
|
|
1307
|
+
typePicked,
|
|
1308
|
+
currentTile,
|
|
1309
|
+
tiles,
|
|
1310
|
+
onPickType,
|
|
1311
|
+
rating,
|
|
1312
|
+
onRatingChange,
|
|
1284
1313
|
projectSlot,
|
|
1285
1314
|
reporterName,
|
|
1286
1315
|
description,
|
|
@@ -1288,18 +1317,27 @@ function AssistSheet({
|
|
|
1288
1317
|
severity,
|
|
1289
1318
|
onSeverityChange,
|
|
1290
1319
|
showSeverity,
|
|
1320
|
+
onDuplicateChange,
|
|
1321
|
+
onConversationChange,
|
|
1291
1322
|
isSubmitting,
|
|
1292
1323
|
submitted,
|
|
1293
1324
|
onSend,
|
|
1294
1325
|
onDegrade,
|
|
1295
|
-
onClose
|
|
1326
|
+
onClose,
|
|
1327
|
+
onFinish
|
|
1296
1328
|
}) {
|
|
1297
1329
|
const narrow = useIsNarrow();
|
|
1298
1330
|
const [messages, setMessages] = (0, import_react3.useState)([]);
|
|
1299
1331
|
const [input, setInput] = (0, import_react3.useState)("");
|
|
1300
1332
|
const [busy, setBusy] = (0, import_react3.useState)(false);
|
|
1301
1333
|
const [conversationId, setConversationId] = (0, import_react3.useState)(null);
|
|
1302
|
-
const [
|
|
1334
|
+
const [hoveredStar, setHoveredStar] = (0, import_react3.useState)(0);
|
|
1335
|
+
const [options, setOptions] = (0, import_react3.useState)([]);
|
|
1336
|
+
const [duplicate, setDuplicate] = (0, import_react3.useState)(null);
|
|
1337
|
+
const [solved, setSolved] = (0, import_react3.useState)(null);
|
|
1338
|
+
const [phase, setPhase] = (0, import_react3.useState)(
|
|
1339
|
+
!typePicked ? "type" : currentTile === "RATING" ? "rating" : "chat"
|
|
1340
|
+
);
|
|
1303
1341
|
const scrollRef = (0, import_react3.useRef)(null);
|
|
1304
1342
|
const inputRef = (0, import_react3.useRef)(null);
|
|
1305
1343
|
const draftRef = (0, import_react3.useRef)(null);
|
|
@@ -1313,6 +1351,7 @@ function AssistSheet({
|
|
|
1313
1351
|
if (phase === "draft") (_a = draftRef.current) == null ? void 0 : _a.focus();
|
|
1314
1352
|
}, [phase]);
|
|
1315
1353
|
async function runTurn(history2) {
|
|
1354
|
+
var _a, _b, _c, _d;
|
|
1316
1355
|
setBusy(true);
|
|
1317
1356
|
let result;
|
|
1318
1357
|
try {
|
|
@@ -1327,15 +1366,28 @@ function AssistSheet({
|
|
|
1327
1366
|
onDegrade(result.degraded);
|
|
1328
1367
|
return;
|
|
1329
1368
|
}
|
|
1330
|
-
if (result.conversationId)
|
|
1369
|
+
if (result.conversationId) {
|
|
1370
|
+
setConversationId(result.conversationId);
|
|
1371
|
+
onConversationChange == null ? void 0 : onConversationChange(result.conversationId);
|
|
1372
|
+
}
|
|
1373
|
+
setDuplicate((_a = result.duplicate) != null ? _a : null);
|
|
1374
|
+
onDuplicateChange == null ? void 0 : onDuplicateChange((_c = (_b = result.duplicate) == null ? void 0 : _b.number) != null ? _c : null);
|
|
1375
|
+
if (result.solved) {
|
|
1376
|
+
setSolved(result.solved);
|
|
1377
|
+
setOptions([]);
|
|
1378
|
+
setPhase("solved");
|
|
1379
|
+
return;
|
|
1380
|
+
}
|
|
1331
1381
|
if (result.report) {
|
|
1332
1382
|
onDescriptionChange(result.report);
|
|
1333
1383
|
setMessages([...history2, { role: "assistant", content: "Here's your report \u2014 have a read." }]);
|
|
1384
|
+
setOptions([]);
|
|
1334
1385
|
setPhase("draft");
|
|
1335
1386
|
return;
|
|
1336
1387
|
}
|
|
1337
1388
|
if (result.question) {
|
|
1338
1389
|
setMessages([...history2, { role: "assistant", content: result.question }]);
|
|
1390
|
+
setOptions((_d = result.options) != null ? _d : []);
|
|
1339
1391
|
return;
|
|
1340
1392
|
}
|
|
1341
1393
|
onDegrade("The assistant had nothing to add \u2014 write your report below and send it as normal.");
|
|
@@ -1343,6 +1395,7 @@ function AssistSheet({
|
|
|
1343
1395
|
(0, import_react3.useEffect)(() => {
|
|
1344
1396
|
if (seededRef.current) return;
|
|
1345
1397
|
seededRef.current = true;
|
|
1398
|
+
if (!typePicked || currentTile === "RATING") return;
|
|
1346
1399
|
const seed = description.trim();
|
|
1347
1400
|
if (!seed) return;
|
|
1348
1401
|
const history2 = [{ role: "user", content: seed }];
|
|
@@ -1352,12 +1405,17 @@ function AssistSheet({
|
|
|
1352
1405
|
function send(text) {
|
|
1353
1406
|
const value = text.trim();
|
|
1354
1407
|
if (!value || busy) return;
|
|
1408
|
+
setOptions([]);
|
|
1355
1409
|
const history2 = [...messages, { role: "user", content: value }];
|
|
1356
1410
|
setMessages(history2);
|
|
1357
1411
|
setInput("");
|
|
1358
1412
|
void runTurn(history2);
|
|
1359
1413
|
}
|
|
1360
|
-
|
|
1414
|
+
function pickType(tile) {
|
|
1415
|
+
onPickType(tile);
|
|
1416
|
+
setPhase(tile === "RATING" ? "rating" : "chat");
|
|
1417
|
+
}
|
|
1418
|
+
const empty = phase === "chat" && messages.length === 0 && !busy;
|
|
1361
1419
|
const initials = (reporterName != null ? reporterName : "").split(/\s+/).filter(Boolean).slice(0, 2).map((w) => {
|
|
1362
1420
|
var _a, _b;
|
|
1363
1421
|
return (_b = (_a = w[0]) == null ? void 0 : _a.toUpperCase()) != null ? _b : "";
|
|
@@ -1473,7 +1531,7 @@ function AssistSheet({
|
|
|
1473
1531
|
}
|
|
1474
1532
|
),
|
|
1475
1533
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { fontSize: "11.5px", color: t2.textMuted, marginTop: "3px" }, children: [
|
|
1476
|
-
reportTypeLabel,
|
|
1534
|
+
phase === "type" ? null : reportTypeLabel,
|
|
1477
1535
|
projectSlot ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { marginLeft: "6px" }, children: projectSlot }) : null
|
|
1478
1536
|
] })
|
|
1479
1537
|
] }),
|
|
@@ -1481,20 +1539,24 @@ function AssistSheet({
|
|
|
1481
1539
|
"button",
|
|
1482
1540
|
{
|
|
1483
1541
|
type: "button",
|
|
1542
|
+
"data-gg-write-myself": "",
|
|
1484
1543
|
onClick: onClose,
|
|
1485
|
-
"aria-label": "
|
|
1544
|
+
"aria-label": "Write it myself instead",
|
|
1486
1545
|
style: {
|
|
1487
1546
|
flexShrink: 0,
|
|
1488
|
-
border:
|
|
1547
|
+
border: `1px solid ${t2.inputBorder}`,
|
|
1548
|
+
borderRadius: "999px",
|
|
1489
1549
|
background: "transparent",
|
|
1490
1550
|
color: t2.textMuted,
|
|
1491
1551
|
cursor: "pointer",
|
|
1492
|
-
fontSize:
|
|
1552
|
+
fontSize: "11.5px",
|
|
1493
1553
|
lineHeight: 1,
|
|
1494
1554
|
fontFamily: "inherit",
|
|
1495
|
-
|
|
1555
|
+
whiteSpace: "nowrap",
|
|
1556
|
+
// ~32px tall either way — this is the escape hatch, not a hint.
|
|
1557
|
+
padding: "9px 11px"
|
|
1496
1558
|
},
|
|
1497
|
-
children:
|
|
1559
|
+
children: "Write it myself"
|
|
1498
1560
|
}
|
|
1499
1561
|
)
|
|
1500
1562
|
]
|
|
@@ -1523,6 +1585,182 @@ function AssistSheet({
|
|
|
1523
1585
|
minWidth: 0
|
|
1524
1586
|
},
|
|
1525
1587
|
children: [
|
|
1588
|
+
phase === "type" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
|
|
1589
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
1590
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Avatar, { who: "assistant", theme: t2 }),
|
|
1591
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1592
|
+
"div",
|
|
1593
|
+
{
|
|
1594
|
+
style: {
|
|
1595
|
+
padding: "9px 12px",
|
|
1596
|
+
borderRadius: "12px 12px 12px 4px",
|
|
1597
|
+
backgroundColor: t2.bgSecondary,
|
|
1598
|
+
fontSize: "13px",
|
|
1599
|
+
lineHeight: 1.55,
|
|
1600
|
+
maxWidth: "88%"
|
|
1601
|
+
},
|
|
1602
|
+
children: [
|
|
1603
|
+
reporterName ? `Hi ${reporterName.split(" ")[0]} \u2014 w` : "W",
|
|
1604
|
+
"hat do you want to do? Pick one and I'll take it from there."
|
|
1605
|
+
]
|
|
1606
|
+
}
|
|
1607
|
+
)
|
|
1608
|
+
] }),
|
|
1609
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1610
|
+
"div",
|
|
1611
|
+
{
|
|
1612
|
+
style: {
|
|
1613
|
+
display: "flex",
|
|
1614
|
+
flexWrap: "wrap",
|
|
1615
|
+
gap: "6px",
|
|
1616
|
+
paddingLeft: "32px"
|
|
1617
|
+
},
|
|
1618
|
+
children: tiles.map((tile) => {
|
|
1619
|
+
const rate = tile === "RATING";
|
|
1620
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1621
|
+
"button",
|
|
1622
|
+
{
|
|
1623
|
+
type: "button",
|
|
1624
|
+
"data-gg-chip": "",
|
|
1625
|
+
"data-gg-tile": tile,
|
|
1626
|
+
onClick: () => pickType(tile),
|
|
1627
|
+
style: {
|
|
1628
|
+
display: "inline-flex",
|
|
1629
|
+
alignItems: "center",
|
|
1630
|
+
gap: "5px",
|
|
1631
|
+
// The rating is the only tile that isn't a report, so
|
|
1632
|
+
// it wears the star colour the dialog's hero row uses
|
|
1633
|
+
// rather than hiding among the report types.
|
|
1634
|
+
border: `1px solid ${rate ? "rgba(245,158,11,0.5)" : t2.inputBorder}`,
|
|
1635
|
+
background: rate ? "rgba(245,158,11,0.08)" : "transparent",
|
|
1636
|
+
color: rate ? "#f59e0b" : t2.textMuted,
|
|
1637
|
+
borderRadius: "999px",
|
|
1638
|
+
// 8px vertical keeps the tap target at ~32px.
|
|
1639
|
+
padding: "8px 12px",
|
|
1640
|
+
fontSize: "12px",
|
|
1641
|
+
fontWeight: rate ? 600 : 400,
|
|
1642
|
+
fontFamily: "inherit",
|
|
1643
|
+
cursor: "pointer"
|
|
1644
|
+
},
|
|
1645
|
+
children: rate ? "\u2605 Rate us" : getTypeLabel(tile)
|
|
1646
|
+
},
|
|
1647
|
+
tile
|
|
1648
|
+
);
|
|
1649
|
+
})
|
|
1650
|
+
}
|
|
1651
|
+
)
|
|
1652
|
+
] }),
|
|
1653
|
+
phase === "rating" && !submitted && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
|
|
1654
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
1655
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Avatar, { who: "assistant", theme: t2 }),
|
|
1656
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1657
|
+
"div",
|
|
1658
|
+
{
|
|
1659
|
+
style: {
|
|
1660
|
+
padding: "9px 12px",
|
|
1661
|
+
borderRadius: "12px 12px 12px 4px",
|
|
1662
|
+
backgroundColor: t2.bgSecondary,
|
|
1663
|
+
fontSize: "13px",
|
|
1664
|
+
lineHeight: 1.55,
|
|
1665
|
+
maxWidth: "88%"
|
|
1666
|
+
},
|
|
1667
|
+
children: "How are we doing? Tap a star \u2014 the words are optional."
|
|
1668
|
+
}
|
|
1669
|
+
)
|
|
1670
|
+
] }),
|
|
1671
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1672
|
+
"div",
|
|
1673
|
+
{
|
|
1674
|
+
style: {
|
|
1675
|
+
display: "flex",
|
|
1676
|
+
flexDirection: "column",
|
|
1677
|
+
gap: "10px",
|
|
1678
|
+
marginLeft: "32px",
|
|
1679
|
+
padding: "12px",
|
|
1680
|
+
borderRadius: "12px",
|
|
1681
|
+
border: "1px solid rgba(245,158,11,0.4)",
|
|
1682
|
+
backgroundColor: "rgba(245,158,11,0.06)"
|
|
1683
|
+
},
|
|
1684
|
+
children: [
|
|
1685
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", gap: "4px" }, role: "group", "aria-label": "Rating", children: [1, 2, 3, 4, 5].map((star) => {
|
|
1686
|
+
const filled = star <= (hoveredStar || rating);
|
|
1687
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1688
|
+
"button",
|
|
1689
|
+
{
|
|
1690
|
+
type: "button",
|
|
1691
|
+
"aria-label": `${star} star${star > 1 ? "s" : ""}`,
|
|
1692
|
+
"aria-pressed": star <= rating,
|
|
1693
|
+
onClick: () => onRatingChange(star),
|
|
1694
|
+
onMouseEnter: () => setHoveredStar(star),
|
|
1695
|
+
onMouseLeave: () => setHoveredStar(0),
|
|
1696
|
+
style: {
|
|
1697
|
+
border: "none",
|
|
1698
|
+
background: "transparent",
|
|
1699
|
+
padding: 0,
|
|
1700
|
+
cursor: "pointer",
|
|
1701
|
+
lineHeight: 0
|
|
1702
|
+
},
|
|
1703
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "30", height: "30", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1704
|
+
"path",
|
|
1705
|
+
{
|
|
1706
|
+
d: "M12 3l2.6 5.3 5.9.9-4.3 4.1 1 5.8L12 16.4 6.8 19.1l1-5.8L3.5 9.2l5.9-.9L12 3z",
|
|
1707
|
+
fill: filled ? "#f59e0b" : "transparent",
|
|
1708
|
+
stroke: filled ? "#f59e0b" : t2.inputBorder,
|
|
1709
|
+
strokeWidth: "1.5",
|
|
1710
|
+
strokeLinejoin: "round"
|
|
1711
|
+
}
|
|
1712
|
+
) })
|
|
1713
|
+
},
|
|
1714
|
+
star
|
|
1715
|
+
);
|
|
1716
|
+
}) }),
|
|
1717
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1718
|
+
"textarea",
|
|
1719
|
+
{
|
|
1720
|
+
value: description,
|
|
1721
|
+
onChange: (e) => onDescriptionChange(e.target.value),
|
|
1722
|
+
rows: 3,
|
|
1723
|
+
placeholder: "What made it good \u2014 or what let you down? (optional)",
|
|
1724
|
+
style: {
|
|
1725
|
+
width: "100%",
|
|
1726
|
+
padding: "10px",
|
|
1727
|
+
borderRadius: "8px",
|
|
1728
|
+
border: `1px solid ${t2.inputBorder}`,
|
|
1729
|
+
backgroundColor: t2.inputBg,
|
|
1730
|
+
color: t2.text,
|
|
1731
|
+
fontSize: "13px",
|
|
1732
|
+
lineHeight: 1.5,
|
|
1733
|
+
fontFamily: "inherit",
|
|
1734
|
+
resize: "vertical",
|
|
1735
|
+
outline: "none",
|
|
1736
|
+
boxSizing: "border-box"
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
),
|
|
1740
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1741
|
+
"button",
|
|
1742
|
+
{
|
|
1743
|
+
type: "button",
|
|
1744
|
+
onClick: () => setPhase("type"),
|
|
1745
|
+
style: {
|
|
1746
|
+
alignSelf: "flex-start",
|
|
1747
|
+
border: "none",
|
|
1748
|
+
background: "transparent",
|
|
1749
|
+
color: t2.textMuted,
|
|
1750
|
+
fontSize: "12px",
|
|
1751
|
+
fontFamily: "inherit",
|
|
1752
|
+
// A bare text link is ~14px tall — half a thumb.
|
|
1753
|
+
padding: "9px 0",
|
|
1754
|
+
cursor: "pointer",
|
|
1755
|
+
textDecoration: "underline"
|
|
1756
|
+
},
|
|
1757
|
+
children: "Report something instead"
|
|
1758
|
+
}
|
|
1759
|
+
)
|
|
1760
|
+
]
|
|
1761
|
+
}
|
|
1762
|
+
)
|
|
1763
|
+
] }),
|
|
1526
1764
|
empty && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
|
|
1527
1765
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
1528
1766
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Avatar, { who: "assistant", theme: t2 }),
|
|
@@ -1611,6 +1849,47 @@ function AssistSheet({
|
|
|
1611
1849
|
i
|
|
1612
1850
|
);
|
|
1613
1851
|
}),
|
|
1852
|
+
options.length > 0 && !busy && phase === "chat" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1853
|
+
"div",
|
|
1854
|
+
{
|
|
1855
|
+
style: {
|
|
1856
|
+
display: "flex",
|
|
1857
|
+
// Long labels wrapped into a ragged row that always stranded
|
|
1858
|
+
// the last chip on a line of its own. Past ~24 characters
|
|
1859
|
+
// these stop being chips and become a choice list, so they
|
|
1860
|
+
// stack full width and read like one.
|
|
1861
|
+
flexDirection: options.some((o) => o.length > 24) ? "column" : "row",
|
|
1862
|
+
alignItems: options.some((o) => o.length > 24) ? "stretch" : "flex-start",
|
|
1863
|
+
flexWrap: "wrap",
|
|
1864
|
+
gap: "6px",
|
|
1865
|
+
paddingLeft: "32px"
|
|
1866
|
+
},
|
|
1867
|
+
children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1868
|
+
"button",
|
|
1869
|
+
{
|
|
1870
|
+
type: "button",
|
|
1871
|
+
"data-gg-chip": "",
|
|
1872
|
+
"data-gg-option": "",
|
|
1873
|
+
onClick: () => send(option),
|
|
1874
|
+
style: {
|
|
1875
|
+
border: `1px solid ${t2.inputBorder}`,
|
|
1876
|
+
background: "transparent",
|
|
1877
|
+
color: t2.textMuted,
|
|
1878
|
+
borderRadius: "999px",
|
|
1879
|
+
// Same 8px as the picker chips — one tap target size in
|
|
1880
|
+
// this sheet, not two.
|
|
1881
|
+
padding: "8px 12px",
|
|
1882
|
+
fontSize: "12px",
|
|
1883
|
+
fontFamily: "inherit",
|
|
1884
|
+
cursor: "pointer",
|
|
1885
|
+
textAlign: "left"
|
|
1886
|
+
},
|
|
1887
|
+
children: option
|
|
1888
|
+
},
|
|
1889
|
+
option
|
|
1890
|
+
))
|
|
1891
|
+
}
|
|
1892
|
+
),
|
|
1614
1893
|
busy && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "8px" }, role: "status", "aria-label": "Thinking", children: [
|
|
1615
1894
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Avatar, { who: "assistant", theme: t2 }),
|
|
1616
1895
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
@@ -1668,6 +1947,32 @@ function AssistSheet({
|
|
|
1668
1947
|
children: "Your report \xB7 edit anything"
|
|
1669
1948
|
}
|
|
1670
1949
|
),
|
|
1950
|
+
duplicate && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1951
|
+
"div",
|
|
1952
|
+
{
|
|
1953
|
+
style: {
|
|
1954
|
+
display: "flex",
|
|
1955
|
+
flexDirection: "column",
|
|
1956
|
+
gap: "3px",
|
|
1957
|
+
padding: "9px 10px",
|
|
1958
|
+
borderRadius: "8px",
|
|
1959
|
+
border: "1px solid rgba(245,158,11,0.4)",
|
|
1960
|
+
backgroundColor: "rgba(245,158,11,0.08)",
|
|
1961
|
+
fontSize: "12px",
|
|
1962
|
+
lineHeight: 1.5
|
|
1963
|
+
},
|
|
1964
|
+
children: [
|
|
1965
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: "#f59e0b", fontWeight: 600 }, children: "Our team is already on this" }),
|
|
1966
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: { color: t2.textMuted, wordBreak: "break-word" }, children: [
|
|
1967
|
+
"#",
|
|
1968
|
+
duplicate.number,
|
|
1969
|
+
" ",
|
|
1970
|
+
duplicate.title
|
|
1971
|
+
] }),
|
|
1972
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: t2.textMuted }, children: "Your details will be added to it instead of opening a new issue." })
|
|
1973
|
+
]
|
|
1974
|
+
}
|
|
1975
|
+
),
|
|
1671
1976
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1672
1977
|
"textarea",
|
|
1673
1978
|
{
|
|
@@ -1751,7 +2056,7 @@ function AssistSheet({
|
|
|
1751
2056
|
color: t2.textMuted,
|
|
1752
2057
|
fontSize: "12px",
|
|
1753
2058
|
fontFamily: "inherit",
|
|
1754
|
-
padding: 0,
|
|
2059
|
+
padding: "9px 0",
|
|
1755
2060
|
cursor: "pointer",
|
|
1756
2061
|
textDecoration: "underline"
|
|
1757
2062
|
},
|
|
@@ -1761,6 +2066,33 @@ function AssistSheet({
|
|
|
1761
2066
|
]
|
|
1762
2067
|
}
|
|
1763
2068
|
),
|
|
2069
|
+
phase === "solved" && solved && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
|
|
2070
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
2071
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Avatar, { who: "assistant", theme: t2 }),
|
|
2072
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2073
|
+
"div",
|
|
2074
|
+
{
|
|
2075
|
+
style: {
|
|
2076
|
+
padding: "9px 12px",
|
|
2077
|
+
borderRadius: "12px 12px 12px 4px",
|
|
2078
|
+
backgroundColor: t2.bgSecondary,
|
|
2079
|
+
fontSize: "13px",
|
|
2080
|
+
lineHeight: 1.55,
|
|
2081
|
+
maxWidth: "88%",
|
|
2082
|
+
whiteSpace: "pre-wrap"
|
|
2083
|
+
},
|
|
2084
|
+
children: solved
|
|
2085
|
+
}
|
|
2086
|
+
)
|
|
2087
|
+
] }),
|
|
2088
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2089
|
+
"span",
|
|
2090
|
+
{
|
|
2091
|
+
style: { fontSize: "11.5px", color: t2.textMuted, paddingLeft: "32px" },
|
|
2092
|
+
children: "Nothing was filed \u2014 you are all set."
|
|
2093
|
+
}
|
|
2094
|
+
)
|
|
2095
|
+
] }),
|
|
1764
2096
|
submitted && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1765
2097
|
"div",
|
|
1766
2098
|
{
|
|
@@ -1782,7 +2114,7 @@ function AssistSheet({
|
|
|
1782
2114
|
)
|
|
1783
2115
|
}
|
|
1784
2116
|
),
|
|
1785
|
-
!submitted && /* @__PURE__ */ (0, import_jsx_runtime2.
|
|
2117
|
+
!submitted && phase !== "type" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1786
2118
|
"div",
|
|
1787
2119
|
{
|
|
1788
2120
|
style: {
|
|
@@ -1792,93 +2124,157 @@ function AssistSheet({
|
|
|
1792
2124
|
paddingBottom: narrow ? "max(12px, env(safe-area-inset-bottom))" : "12px",
|
|
1793
2125
|
backgroundColor: t2.bg
|
|
1794
2126
|
},
|
|
1795
|
-
children:
|
|
1796
|
-
"
|
|
1797
|
-
|
|
1798
|
-
type: "button",
|
|
1799
|
-
"data-gg-sheet-send": "",
|
|
1800
|
-
onClick: onSend,
|
|
1801
|
-
disabled: isSubmitting || !description.trim(),
|
|
1802
|
-
style: {
|
|
1803
|
-
width: "100%",
|
|
1804
|
-
padding: "12px",
|
|
1805
|
-
borderRadius: "10px",
|
|
1806
|
-
border: "none",
|
|
1807
|
-
backgroundColor: isSubmitting || !description.trim() ? t2.bgSecondary : t2.accent,
|
|
1808
|
-
color: isSubmitting || !description.trim() ? t2.textMuted : t2.accentText,
|
|
1809
|
-
fontSize: "14px",
|
|
1810
|
-
fontWeight: 700,
|
|
1811
|
-
fontFamily: "inherit",
|
|
1812
|
-
cursor: isSubmitting || !description.trim() ? "default" : "pointer"
|
|
1813
|
-
},
|
|
1814
|
-
children: isSubmitting ? "Sending\u2026" : "Send Report"
|
|
1815
|
-
}
|
|
1816
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "8px", alignItems: "flex-end" }, children: [
|
|
1817
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1818
|
-
"textarea",
|
|
2127
|
+
children: [
|
|
2128
|
+
phase === "solved" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2129
|
+
"button",
|
|
1819
2130
|
{
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
2131
|
+
type: "button",
|
|
2132
|
+
"data-gg-sheet-send": "",
|
|
2133
|
+
onClick: () => (onFinish != null ? onFinish : onClose)(),
|
|
2134
|
+
style: {
|
|
2135
|
+
width: "100%",
|
|
2136
|
+
padding: "12px",
|
|
2137
|
+
borderRadius: "10px",
|
|
2138
|
+
border: "none",
|
|
2139
|
+
backgroundColor: t2.accent,
|
|
2140
|
+
color: t2.accentText,
|
|
2141
|
+
fontSize: "14px",
|
|
2142
|
+
fontWeight: 700,
|
|
2143
|
+
fontFamily: "inherit",
|
|
2144
|
+
cursor: "pointer"
|
|
1828
2145
|
},
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
2146
|
+
children: "Done"
|
|
2147
|
+
}
|
|
2148
|
+
) : phase === "rating" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2149
|
+
"button",
|
|
2150
|
+
{
|
|
2151
|
+
type: "button",
|
|
2152
|
+
"data-gg-sheet-send": "",
|
|
2153
|
+
onClick: onSend,
|
|
2154
|
+
disabled: isSubmitting || rating < 1,
|
|
1833
2155
|
style: {
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
maxHeight: "120px",
|
|
1837
|
-
padding: "11px 12px",
|
|
2156
|
+
width: "100%",
|
|
2157
|
+
padding: "12px",
|
|
1838
2158
|
borderRadius: "10px",
|
|
1839
|
-
border:
|
|
1840
|
-
backgroundColor: t2.
|
|
1841
|
-
color: t2.
|
|
1842
|
-
fontSize: "
|
|
1843
|
-
|
|
2159
|
+
border: "none",
|
|
2160
|
+
backgroundColor: isSubmitting || rating < 1 ? t2.bgSecondary : "#f59e0b",
|
|
2161
|
+
color: isSubmitting || rating < 1 ? t2.textMuted : "#1a1a1a",
|
|
2162
|
+
fontSize: "14px",
|
|
2163
|
+
fontWeight: 700,
|
|
1844
2164
|
fontFamily: "inherit",
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
}
|
|
2165
|
+
cursor: isSubmitting || rating < 1 ? "default" : "pointer"
|
|
2166
|
+
},
|
|
2167
|
+
children: isSubmitting ? "Sending\u2026" : rating < 1 ? "Pick a star first" : "Send Rating"
|
|
1849
2168
|
}
|
|
1850
|
-
),
|
|
1851
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2169
|
+
) : phase === "draft" ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1852
2170
|
"button",
|
|
1853
2171
|
{
|
|
1854
2172
|
type: "button",
|
|
1855
2173
|
"data-gg-sheet-send": "",
|
|
1856
|
-
onClick:
|
|
1857
|
-
disabled:
|
|
1858
|
-
"aria-label": "Send message",
|
|
2174
|
+
onClick: onSend,
|
|
2175
|
+
disabled: isSubmitting || !description.trim(),
|
|
1859
2176
|
style: {
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
height: "42px",
|
|
2177
|
+
width: "100%",
|
|
2178
|
+
padding: "12px",
|
|
1863
2179
|
borderRadius: "10px",
|
|
1864
2180
|
border: "none",
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
cursor:
|
|
2181
|
+
backgroundColor: isSubmitting || !description.trim() ? t2.bgSecondary : t2.accent,
|
|
2182
|
+
color: isSubmitting || !description.trim() ? t2.textMuted : t2.accentText,
|
|
2183
|
+
fontSize: "14px",
|
|
2184
|
+
fontWeight: 700,
|
|
2185
|
+
fontFamily: "inherit",
|
|
2186
|
+
cursor: isSubmitting || !description.trim() ? "default" : "pointer"
|
|
1871
2187
|
},
|
|
1872
|
-
children:
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
2188
|
+
children: isSubmitting ? "Sending\u2026" : duplicate ? `Add to #${duplicate.number}` : "Send Report"
|
|
2189
|
+
}
|
|
2190
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "8px", alignItems: "flex-end" }, children: [
|
|
2191
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2192
|
+
"textarea",
|
|
2193
|
+
{
|
|
2194
|
+
ref: inputRef,
|
|
2195
|
+
value: input,
|
|
2196
|
+
onChange: (e) => setInput(e.target.value),
|
|
2197
|
+
onKeyDown: (e) => {
|
|
2198
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
2199
|
+
e.preventDefault();
|
|
2200
|
+
send(input);
|
|
2201
|
+
}
|
|
2202
|
+
},
|
|
2203
|
+
placeholder: "Type your answer\u2026",
|
|
2204
|
+
rows: 1,
|
|
2205
|
+
disabled: busy,
|
|
2206
|
+
autoFocus: true,
|
|
2207
|
+
style: {
|
|
2208
|
+
flex: 1,
|
|
2209
|
+
minHeight: "42px",
|
|
2210
|
+
maxHeight: "120px",
|
|
2211
|
+
padding: "11px 12px",
|
|
2212
|
+
borderRadius: "10px",
|
|
2213
|
+
border: `1px solid ${t2.inputBorder}`,
|
|
2214
|
+
backgroundColor: t2.inputBg,
|
|
2215
|
+
color: t2.text,
|
|
2216
|
+
fontSize: "13px",
|
|
2217
|
+
lineHeight: 1.4,
|
|
2218
|
+
fontFamily: "inherit",
|
|
2219
|
+
resize: "none",
|
|
2220
|
+
outline: "none",
|
|
2221
|
+
boxSizing: "border-box"
|
|
1877
2222
|
}
|
|
1878
|
-
|
|
2223
|
+
}
|
|
2224
|
+
),
|
|
2225
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2226
|
+
"button",
|
|
2227
|
+
{
|
|
2228
|
+
type: "button",
|
|
2229
|
+
"data-gg-sheet-send": "",
|
|
2230
|
+
onClick: () => send(input),
|
|
2231
|
+
disabled: busy || !input.trim(),
|
|
2232
|
+
"aria-label": "Send message",
|
|
2233
|
+
"data-gg-send-message": "",
|
|
2234
|
+
style: {
|
|
2235
|
+
flexShrink: 0,
|
|
2236
|
+
width: "42px",
|
|
2237
|
+
height: "42px",
|
|
2238
|
+
borderRadius: "10px",
|
|
2239
|
+
border: "none",
|
|
2240
|
+
display: "inline-flex",
|
|
2241
|
+
alignItems: "center",
|
|
2242
|
+
justifyContent: "center",
|
|
2243
|
+
backgroundColor: busy || !input.trim() ? t2.bgSecondary : t2.accent,
|
|
2244
|
+
color: busy || !input.trim() ? t2.textMuted : t2.accentText,
|
|
2245
|
+
cursor: busy || !input.trim() ? "default" : "pointer"
|
|
2246
|
+
},
|
|
2247
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("svg", { width: "17", height: "17", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2248
|
+
"path",
|
|
2249
|
+
{
|
|
2250
|
+
d: "M3 20.5L21.5 12 3 3.5V10l12 2-12 2v6.5z",
|
|
2251
|
+
fill: "currentColor"
|
|
2252
|
+
}
|
|
2253
|
+
) })
|
|
2254
|
+
}
|
|
2255
|
+
)
|
|
2256
|
+
] }),
|
|
2257
|
+
phase === "chat" && messages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2258
|
+
"button",
|
|
2259
|
+
{
|
|
2260
|
+
type: "button",
|
|
2261
|
+
"data-gg-write-myself": "",
|
|
2262
|
+
onClick: onClose,
|
|
2263
|
+
style: {
|
|
2264
|
+
display: "block",
|
|
2265
|
+
margin: "8px auto 0",
|
|
2266
|
+
border: "none",
|
|
2267
|
+
background: "transparent",
|
|
2268
|
+
color: t2.textMuted,
|
|
2269
|
+
fontSize: "11.5px",
|
|
2270
|
+
fontFamily: "inherit",
|
|
2271
|
+
padding: "6px 8px",
|
|
2272
|
+
cursor: "pointer"
|
|
2273
|
+
},
|
|
2274
|
+
children: "Not getting it? Fill the form yourself \u2192"
|
|
1879
2275
|
}
|
|
1880
2276
|
)
|
|
1881
|
-
]
|
|
2277
|
+
]
|
|
1882
2278
|
}
|
|
1883
2279
|
)
|
|
1884
2280
|
]
|
|
@@ -2248,6 +2644,9 @@ function ReportDialog({
|
|
|
2248
2644
|
const [assistOpen, setAssistOpen] = (0, import_react.useState)(false);
|
|
2249
2645
|
const [assistNotice, setAssistNotice] = (0, import_react.useState)(null);
|
|
2250
2646
|
const [assistUsed, setAssistUsed] = (0, import_react.useState)(false);
|
|
2647
|
+
const [typeChosen, setTypeChosen] = (0, import_react.useState)(false);
|
|
2648
|
+
const [duplicateIssueNumber, setDuplicateIssueNumber] = (0, import_react.useState)(null);
|
|
2649
|
+
const [aiConversationId, setAiConversationId] = (0, import_react.useState)(null);
|
|
2251
2650
|
const [isEnhanced, setIsEnhanced] = (0, import_react.useState)(false);
|
|
2252
2651
|
const [originalDescription, setOriginalDescription] = (0, import_react.useState)(
|
|
2253
2652
|
null
|
|
@@ -2300,6 +2699,10 @@ function ReportDialog({
|
|
|
2300
2699
|
const sarvamChunksRef = (0, import_react.useRef)([]);
|
|
2301
2700
|
const spaceTimerRef = (0, import_react.useRef)(null);
|
|
2302
2701
|
const isPushToTalkRef = (0, import_react.useRef)(false);
|
|
2702
|
+
const spaceEditsRef = (0, import_react.useRef)(0);
|
|
2703
|
+
const descriptionRef = (0, import_react.useRef)("");
|
|
2704
|
+
const lastVoiceTextRef = (0, import_react.useRef)(null);
|
|
2705
|
+
const hadWebSpeechRef = (0, import_react.useRef)(false);
|
|
2303
2706
|
(0, import_react.useEffect)(() => {
|
|
2304
2707
|
if (!isOpen) return;
|
|
2305
2708
|
const HOST_LAYERS = '[role="dialog"],[role="alertdialog"],[role="menu"],[role="listbox"]';
|
|
@@ -2355,6 +2758,7 @@ function ReportDialog({
|
|
|
2355
2758
|
e.preventDefault();
|
|
2356
2759
|
setRating(Number(e.key));
|
|
2357
2760
|
setReportType("RATING");
|
|
2761
|
+
setTypeChosen(true);
|
|
2358
2762
|
setStep(2);
|
|
2359
2763
|
return;
|
|
2360
2764
|
}
|
|
@@ -2366,6 +2770,7 @@ function ReportDialog({
|
|
|
2366
2770
|
if (match) {
|
|
2367
2771
|
e.preventDefault();
|
|
2368
2772
|
setReportType(match);
|
|
2773
|
+
setTypeChosen(true);
|
|
2369
2774
|
setStep(2);
|
|
2370
2775
|
}
|
|
2371
2776
|
};
|
|
@@ -2419,10 +2824,12 @@ function ReportDialog({
|
|
|
2419
2824
|
setAnnotatingIndex(null);
|
|
2420
2825
|
if (availableTypes.length === 1) {
|
|
2421
2826
|
setReportType(availableTypes[0]);
|
|
2827
|
+
setTypeChosen(true);
|
|
2422
2828
|
setStep(2);
|
|
2423
2829
|
}
|
|
2424
2830
|
const shot = await captureScreenshot();
|
|
2425
2831
|
if (shot) setScreenshots([shot]);
|
|
2832
|
+
if (assist && !assistUsed) setAssistOpen(true);
|
|
2426
2833
|
setIsOpen(true);
|
|
2427
2834
|
};
|
|
2428
2835
|
(0, import_react.useEffect)(() => {
|
|
@@ -2432,6 +2839,7 @@ function ReportDialog({
|
|
|
2432
2839
|
if (detail == null ? void 0 : detail.description) setDescription(detail.description);
|
|
2433
2840
|
if (detail == null ? void 0 : detail.type) {
|
|
2434
2841
|
setReportType(detail.type);
|
|
2842
|
+
setTypeChosen(true);
|
|
2435
2843
|
setStep(2);
|
|
2436
2844
|
}
|
|
2437
2845
|
handleOpen();
|
|
@@ -2555,6 +2963,22 @@ function ReportDialog({
|
|
|
2555
2963
|
}, 3e3);
|
|
2556
2964
|
return () => clearInterval(id);
|
|
2557
2965
|
}, [isOpen, transcribeAudio2]);
|
|
2966
|
+
(0, import_react.useEffect)(() => {
|
|
2967
|
+
descriptionRef.current = description;
|
|
2968
|
+
}, [description]);
|
|
2969
|
+
const rebaseVoiceOnUserEdits = () => {
|
|
2970
|
+
var _a2;
|
|
2971
|
+
const live = descriptionRef.current;
|
|
2972
|
+
const baseline = (_a2 = lastVoiceTextRef.current) != null ? _a2 : textBeforeVoiceRef.current;
|
|
2973
|
+
if (live === baseline) return;
|
|
2974
|
+
voiceBaseRef.current = live;
|
|
2975
|
+
textBeforeVoiceRef.current = live;
|
|
2976
|
+
};
|
|
2977
|
+
const setDescriptionFromVoice = (text) => {
|
|
2978
|
+
lastVoiceTextRef.current = text;
|
|
2979
|
+
descriptionRef.current = text;
|
|
2980
|
+
setDescription(text);
|
|
2981
|
+
};
|
|
2558
2982
|
const stopVoice = () => {
|
|
2559
2983
|
var _a2, _b2;
|
|
2560
2984
|
usingWebSpeechRef.current = false;
|
|
@@ -2583,7 +3007,7 @@ function ReportDialog({
|
|
|
2583
3007
|
} catch (e) {
|
|
2584
3008
|
}
|
|
2585
3009
|
};
|
|
2586
|
-
const sheetUp = !!assist && assistOpen
|
|
3010
|
+
const sheetUp = !!assist && assistOpen;
|
|
2587
3011
|
(0, import_react.useEffect)(() => {
|
|
2588
3012
|
const el = modalRef.current;
|
|
2589
3013
|
if (!el) return;
|
|
@@ -2605,6 +3029,8 @@ function ReportDialog({
|
|
|
2605
3029
|
setRating(0);
|
|
2606
3030
|
setHoveredStar(0);
|
|
2607
3031
|
setReportType("BUG");
|
|
3032
|
+
setTypeChosen(false);
|
|
3033
|
+
setDuplicateIssueNumber(null);
|
|
2608
3034
|
setSeverity("medium");
|
|
2609
3035
|
setValidationError(null);
|
|
2610
3036
|
setVoiceError(null);
|
|
@@ -2619,6 +3045,8 @@ function ReportDialog({
|
|
|
2619
3045
|
stopListeningAndTranscribe();
|
|
2620
3046
|
return;
|
|
2621
3047
|
}
|
|
3048
|
+
lastVoiceTextRef.current = null;
|
|
3049
|
+
hadWebSpeechRef.current = false;
|
|
2622
3050
|
const SpeechRec = typeof window !== "undefined" ? window.SpeechRecognition || window.webkitSpeechRecognition : void 0;
|
|
2623
3051
|
let stream = null;
|
|
2624
3052
|
try {
|
|
@@ -2633,13 +3061,14 @@ function ReportDialog({
|
|
|
2633
3061
|
if (stream && transcribeAudio2) {
|
|
2634
3062
|
streamRef.current = stream;
|
|
2635
3063
|
sarvamChunksRef.current = [];
|
|
2636
|
-
textBeforeVoiceRef.current =
|
|
3064
|
+
textBeforeVoiceRef.current = descriptionRef.current;
|
|
2637
3065
|
const rec = new MediaRecorder(stream);
|
|
2638
3066
|
mediaRecorderRef.current = rec;
|
|
2639
3067
|
rec.ondataavailable = (e) => {
|
|
2640
3068
|
if (e.data.size > 0) sarvamChunksRef.current.push(e.data);
|
|
2641
3069
|
};
|
|
2642
3070
|
rec.onstop = async () => {
|
|
3071
|
+
var _a2;
|
|
2643
3072
|
stream.getTracks().forEach((t22) => t22.stop());
|
|
2644
3073
|
if (streamRef.current === stream) streamRef.current = null;
|
|
2645
3074
|
mediaRecorderRef.current = null;
|
|
@@ -2651,11 +3080,18 @@ function ReportDialog({
|
|
|
2651
3080
|
const blob = new Blob(chunks, { type: rec.mimeType || "audio/webm" });
|
|
2652
3081
|
const text = await transcribeAudio2(blob);
|
|
2653
3082
|
if (text.trim()) {
|
|
2654
|
-
const
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
3083
|
+
const live = descriptionRef.current;
|
|
3084
|
+
const baseline = (_a2 = lastVoiceTextRef.current) != null ? _a2 : textBeforeVoiceRef.current;
|
|
3085
|
+
const userEdited = live !== baseline;
|
|
3086
|
+
if (userEdited && hadWebSpeechRef.current) {
|
|
3087
|
+
} else {
|
|
3088
|
+
const base = userEdited ? live : textBeforeVoiceRef.current;
|
|
3089
|
+
const sep = base.trim() ? " " : "";
|
|
3090
|
+
setDescriptionFromVoice(base + sep + text.trim());
|
|
3091
|
+
setValidationError(null);
|
|
3092
|
+
setIsEnhanced(false);
|
|
3093
|
+
setOriginalDescription(null);
|
|
3094
|
+
}
|
|
2659
3095
|
}
|
|
2660
3096
|
} catch (e) {
|
|
2661
3097
|
}
|
|
@@ -2666,8 +3102,9 @@ function ReportDialog({
|
|
|
2666
3102
|
if (SpeechRec) {
|
|
2667
3103
|
setVoiceError(null);
|
|
2668
3104
|
usingWebSpeechRef.current = true;
|
|
2669
|
-
|
|
2670
|
-
|
|
3105
|
+
hadWebSpeechRef.current = true;
|
|
3106
|
+
voiceBaseRef.current = descriptionRef.current;
|
|
3107
|
+
textBeforeVoiceRef.current = descriptionRef.current;
|
|
2671
3108
|
const recognition = new SpeechRec();
|
|
2672
3109
|
recognition.lang = "en-IN";
|
|
2673
3110
|
recognition.interimResults = true;
|
|
@@ -2682,12 +3119,13 @@ function ReportDialog({
|
|
|
2682
3119
|
if (event.results[i].isFinal) finalText += text;
|
|
2683
3120
|
else interimText += text;
|
|
2684
3121
|
}
|
|
3122
|
+
rebaseVoiceOnUserEdits();
|
|
2685
3123
|
if (finalText) {
|
|
2686
3124
|
const sep = voiceBaseRef.current.trim() ? " " : "";
|
|
2687
3125
|
voiceBaseRef.current += sep + finalText.trim();
|
|
2688
3126
|
}
|
|
2689
3127
|
const liveText = interimText ? voiceBaseRef.current + (voiceBaseRef.current.trim() ? " " : "") + interimText : voiceBaseRef.current;
|
|
2690
|
-
|
|
3128
|
+
setDescriptionFromVoice(liveText);
|
|
2691
3129
|
setValidationError(null);
|
|
2692
3130
|
};
|
|
2693
3131
|
recognition.onend = () => {
|
|
@@ -2714,37 +3152,54 @@ function ReportDialog({
|
|
|
2714
3152
|
setIsListening(true);
|
|
2715
3153
|
}
|
|
2716
3154
|
};
|
|
3155
|
+
const cancelPushToTalkArm = () => {
|
|
3156
|
+
if (!spaceTimerRef.current) return;
|
|
3157
|
+
clearTimeout(spaceTimerRef.current);
|
|
3158
|
+
spaceTimerRef.current = null;
|
|
3159
|
+
};
|
|
3160
|
+
const notePushToTalkEdit = () => {
|
|
3161
|
+
if (!spaceTimerRef.current) return;
|
|
3162
|
+
spaceEditsRef.current += 1;
|
|
3163
|
+
if (spaceEditsRef.current > 1) cancelPushToTalkArm();
|
|
3164
|
+
};
|
|
2717
3165
|
const handleSpaceDown = (e) => {
|
|
2718
|
-
|
|
2719
|
-
|
|
3166
|
+
if (e.code !== "Space") {
|
|
3167
|
+
if (!e.metaKey && !e.ctrlKey && !e.altKey) cancelPushToTalkArm();
|
|
3168
|
+
return;
|
|
3169
|
+
}
|
|
2720
3170
|
if (isListening || isPushToTalkRef.current) {
|
|
2721
3171
|
e.preventDefault();
|
|
2722
3172
|
return;
|
|
2723
3173
|
}
|
|
2724
3174
|
if (e.repeat || !transcribeAudio2 || isTranscribing || spaceTimerRef.current)
|
|
2725
3175
|
return;
|
|
2726
|
-
|
|
3176
|
+
if (e.currentTarget.value !== "") return;
|
|
3177
|
+
spaceEditsRef.current = 0;
|
|
2727
3178
|
spaceTimerRef.current = setTimeout(() => {
|
|
3179
|
+
var _a2;
|
|
2728
3180
|
spaceTimerRef.current = null;
|
|
2729
3181
|
isPushToTalkRef.current = true;
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
)
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
3182
|
+
const el = textareaRef.current;
|
|
3183
|
+
const caret = (_a2 = el == null ? void 0 : el.selectionStart) != null ? _a2 : null;
|
|
3184
|
+
if (el && caret !== null && caret === el.selectionEnd && el.value[caret - 1] === " ") {
|
|
3185
|
+
const cut = caret - 1;
|
|
3186
|
+
setDescription(
|
|
3187
|
+
(prev) => prev[cut] === " " ? prev.slice(0, cut) + prev.slice(cut + 1) : prev
|
|
3188
|
+
);
|
|
3189
|
+
descriptionRef.current = descriptionRef.current.slice(0, cut) + descriptionRef.current.slice(cut + 1);
|
|
3190
|
+
requestAnimationFrame(() => {
|
|
3191
|
+
if (textareaRef.current) {
|
|
3192
|
+
textareaRef.current.selectionStart = cut;
|
|
3193
|
+
textareaRef.current.selectionEnd = cut;
|
|
3194
|
+
}
|
|
3195
|
+
});
|
|
3196
|
+
}
|
|
2739
3197
|
void toggleVoice();
|
|
2740
3198
|
}, 400);
|
|
2741
3199
|
};
|
|
2742
3200
|
const handleSpaceUp = (e) => {
|
|
2743
3201
|
if (e.code !== "Space") return;
|
|
2744
|
-
|
|
2745
|
-
clearTimeout(spaceTimerRef.current);
|
|
2746
|
-
spaceTimerRef.current = null;
|
|
2747
|
-
}
|
|
3202
|
+
cancelPushToTalkArm();
|
|
2748
3203
|
if (isPushToTalkRef.current) {
|
|
2749
3204
|
isPushToTalkRef.current = false;
|
|
2750
3205
|
stopListeningAndTranscribe();
|
|
@@ -2789,6 +3244,12 @@ function ReportDialog({
|
|
|
2789
3244
|
if (showSeverity && reportType === "BUG") {
|
|
2790
3245
|
metadata.severity = severity;
|
|
2791
3246
|
}
|
|
3247
|
+
if (duplicateIssueNumber) {
|
|
3248
|
+
metadata.duplicateIssueNumber = String(duplicateIssueNumber);
|
|
3249
|
+
}
|
|
3250
|
+
if (aiConversationId) {
|
|
3251
|
+
metadata.aiConversationId = aiConversationId;
|
|
3252
|
+
}
|
|
2792
3253
|
const result = await report(
|
|
2793
3254
|
// The RATING branch returned above, so anything reaching here is a real
|
|
2794
3255
|
// ReportType — the widened tile union can't leak into the report API.
|
|
@@ -2801,6 +3262,8 @@ function ReportDialog({
|
|
|
2801
3262
|
setDescription("");
|
|
2802
3263
|
setScreenshots([]);
|
|
2803
3264
|
setAttachments([]);
|
|
3265
|
+
setAiConversationId(null);
|
|
3266
|
+
setDuplicateIssueNumber(null);
|
|
2804
3267
|
setTimeout(() => {
|
|
2805
3268
|
setSubmitted(false);
|
|
2806
3269
|
handleClose();
|
|
@@ -3151,6 +3614,7 @@ function ReportDialog({
|
|
|
3151
3614
|
onClick: () => {
|
|
3152
3615
|
setRating(star);
|
|
3153
3616
|
setReportType("RATING");
|
|
3617
|
+
setTypeChosen(true);
|
|
3154
3618
|
setStep(2);
|
|
3155
3619
|
},
|
|
3156
3620
|
style: {
|
|
@@ -3261,6 +3725,7 @@ function ReportDialog({
|
|
|
3261
3725
|
"data-gg-type": type,
|
|
3262
3726
|
onClick: () => {
|
|
3263
3727
|
setReportType(type);
|
|
3728
|
+
setTypeChosen(true);
|
|
3264
3729
|
setStep(2);
|
|
3265
3730
|
},
|
|
3266
3731
|
style: {
|
|
@@ -3380,6 +3845,7 @@ function ReportDialog({
|
|
|
3380
3845
|
type: "button",
|
|
3381
3846
|
onClick: () => {
|
|
3382
3847
|
setAssistNotice(null);
|
|
3848
|
+
setTypeChosen(true);
|
|
3383
3849
|
setAssistOpen(true);
|
|
3384
3850
|
},
|
|
3385
3851
|
style: {
|
|
@@ -3420,6 +3886,7 @@ function ReportDialog({
|
|
|
3420
3886
|
ref: textareaRef,
|
|
3421
3887
|
value: description,
|
|
3422
3888
|
onChange: (e) => {
|
|
3889
|
+
notePushToTalkEdit();
|
|
3423
3890
|
setDescription(e.target.value);
|
|
3424
3891
|
if (validationError) setValidationError(null);
|
|
3425
3892
|
if (isEnhanced) {
|
|
@@ -4528,6 +4995,22 @@ function ReportDialog({
|
|
|
4528
4995
|
attachmentCount: screenshots.length + attachments.length,
|
|
4529
4996
|
context: { ...assistContext != null ? assistContext : {}, reportType },
|
|
4530
4997
|
reportTypeLabel: getTypeLabel(reportType),
|
|
4998
|
+
typePicked: typeChosen,
|
|
4999
|
+
currentTile: reportType,
|
|
5000
|
+
tiles: sendFeedback2 ? [...availableTypes, "RATING"] : availableTypes,
|
|
5001
|
+
onPickType: (tile) => {
|
|
5002
|
+
setReportType(tile);
|
|
5003
|
+
setTypeChosen(true);
|
|
5004
|
+
setStep(2);
|
|
5005
|
+
},
|
|
5006
|
+
onDuplicateChange: setDuplicateIssueNumber,
|
|
5007
|
+
onConversationChange: setAiConversationId,
|
|
5008
|
+
onFinish: handleClose,
|
|
5009
|
+
rating,
|
|
5010
|
+
onRatingChange: (value) => {
|
|
5011
|
+
setRating(value);
|
|
5012
|
+
if (validationError) setValidationError(null);
|
|
5013
|
+
},
|
|
4531
5014
|
projectSlot: headerSlot,
|
|
4532
5015
|
reporterName: (_b = reporter == null ? void 0 : reporter.name) != null ? _b : null,
|
|
4533
5016
|
description,
|
|
@@ -4557,26 +5040,6 @@ function ReportDialog({
|
|
|
4557
5040
|
)
|
|
4558
5041
|
] });
|
|
4559
5042
|
}
|
|
4560
|
-
function getTypeLabel(type) {
|
|
4561
|
-
switch (type) {
|
|
4562
|
-
case "RATING":
|
|
4563
|
-
return "Rating";
|
|
4564
|
-
case "BUG":
|
|
4565
|
-
return "Bug Report";
|
|
4566
|
-
case "FEATURE_REQUEST":
|
|
4567
|
-
return "Feature Request";
|
|
4568
|
-
case "UI_IMPROVEMENT":
|
|
4569
|
-
return "UI Improvement";
|
|
4570
|
-
case "PERFORMANCE":
|
|
4571
|
-
return "Performance";
|
|
4572
|
-
case "SECURITY":
|
|
4573
|
-
return "Security";
|
|
4574
|
-
case "QUESTION":
|
|
4575
|
-
return "Question";
|
|
4576
|
-
case "OTHER":
|
|
4577
|
-
return "Other";
|
|
4578
|
-
}
|
|
4579
|
-
}
|
|
4580
5043
|
function getPlaceholder(type, idx = 0, hasVoice = false) {
|
|
4581
5044
|
if (type === "RATING") return "What made it good \u2014 or what let you down? (optional)";
|
|
4582
5045
|
if (hasVoice && idx === 1) return "Hold Space to speak \u2014 we'll transcribe it";
|
|
@@ -5561,6 +6024,12 @@ function GlitchgrabProviderInner({
|
|
|
5561
6024
|
return assistTurn(
|
|
5562
6025
|
{
|
|
5563
6026
|
...params,
|
|
6027
|
+
// Same identity the report itself carries, from the same prop.
|
|
6028
|
+
reporter: session ? {
|
|
6029
|
+
key: session.userId,
|
|
6030
|
+
name: session.name ? String(session.name) : null,
|
|
6031
|
+
email: session.email ? String(session.email) : null
|
|
6032
|
+
} : void 0,
|
|
5564
6033
|
context: {
|
|
5565
6034
|
...(_a = params.context) != null ? _a : {},
|
|
5566
6035
|
url: ctx.url,
|
|
@@ -5572,7 +6041,7 @@ function GlitchgrabProviderInner({
|
|
|
5572
6041
|
baseUrl
|
|
5573
6042
|
);
|
|
5574
6043
|
},
|
|
5575
|
-
[token, baseUrl]
|
|
6044
|
+
[token, baseUrl, session]
|
|
5576
6045
|
);
|
|
5577
6046
|
const transcribe = (0, import_react5.useCallback)(
|
|
5578
6047
|
async (blob) => {
|