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.mjs
CHANGED
|
@@ -588,7 +588,7 @@ async function enhanceText(text, token, baseUrl, screenshot, context) {
|
|
|
588
588
|
}
|
|
589
589
|
}
|
|
590
590
|
async function assistTurn(params, token, baseUrl) {
|
|
591
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
591
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
592
592
|
const offline = {
|
|
593
593
|
conversationId: null,
|
|
594
594
|
question: null,
|
|
@@ -617,7 +617,10 @@ async function assistTurn(params, token, baseUrl) {
|
|
|
617
617
|
return {
|
|
618
618
|
conversationId: (_c = (_b = envelope.data) == null ? void 0 : _b.conversationId) != null ? _c : null,
|
|
619
619
|
question: (_e = (_d = envelope.data) == null ? void 0 : _d.question) != null ? _e : null,
|
|
620
|
-
|
|
620
|
+
options: (_g = (_f = envelope.data) == null ? void 0 : _f.options) != null ? _g : [],
|
|
621
|
+
report: (_i = (_h = envelope.data) == null ? void 0 : _h.report) != null ? _i : null,
|
|
622
|
+
duplicate: (_k = (_j = envelope.data) == null ? void 0 : _j.duplicate) != null ? _k : null,
|
|
623
|
+
solved: (_m = (_l = envelope.data) == null ? void 0 : _l.solved) != null ? _m : null,
|
|
621
624
|
degraded: null
|
|
622
625
|
};
|
|
623
626
|
} catch (e) {
|
|
@@ -1148,6 +1151,26 @@ function AnnotationCanvas({ imageSrc, onSave, onCancel }) {
|
|
|
1148
1151
|
}
|
|
1149
1152
|
);
|
|
1150
1153
|
}
|
|
1154
|
+
function getTypeLabel(type) {
|
|
1155
|
+
switch (type) {
|
|
1156
|
+
case "RATING":
|
|
1157
|
+
return "Rating";
|
|
1158
|
+
case "BUG":
|
|
1159
|
+
return "Bug Report";
|
|
1160
|
+
case "FEATURE_REQUEST":
|
|
1161
|
+
return "Feature Request";
|
|
1162
|
+
case "UI_IMPROVEMENT":
|
|
1163
|
+
return "UI Improvement";
|
|
1164
|
+
case "PERFORMANCE":
|
|
1165
|
+
return "Performance";
|
|
1166
|
+
case "SECURITY":
|
|
1167
|
+
return "Security";
|
|
1168
|
+
case "QUESTION":
|
|
1169
|
+
return "Question";
|
|
1170
|
+
case "OTHER":
|
|
1171
|
+
return "Other";
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1151
1174
|
var STARTERS = [
|
|
1152
1175
|
"Something on this page is broken",
|
|
1153
1176
|
"It did the wrong thing",
|
|
@@ -1226,6 +1249,12 @@ function AssistSheet({
|
|
|
1226
1249
|
attachmentCount,
|
|
1227
1250
|
context,
|
|
1228
1251
|
reportTypeLabel,
|
|
1252
|
+
typePicked,
|
|
1253
|
+
currentTile,
|
|
1254
|
+
tiles,
|
|
1255
|
+
onPickType,
|
|
1256
|
+
rating,
|
|
1257
|
+
onRatingChange,
|
|
1229
1258
|
projectSlot,
|
|
1230
1259
|
reporterName,
|
|
1231
1260
|
description,
|
|
@@ -1233,18 +1262,27 @@ function AssistSheet({
|
|
|
1233
1262
|
severity,
|
|
1234
1263
|
onSeverityChange,
|
|
1235
1264
|
showSeverity,
|
|
1265
|
+
onDuplicateChange,
|
|
1266
|
+
onConversationChange,
|
|
1236
1267
|
isSubmitting,
|
|
1237
1268
|
submitted,
|
|
1238
1269
|
onSend,
|
|
1239
1270
|
onDegrade,
|
|
1240
|
-
onClose
|
|
1271
|
+
onClose,
|
|
1272
|
+
onFinish
|
|
1241
1273
|
}) {
|
|
1242
1274
|
const narrow = useIsNarrow();
|
|
1243
1275
|
const [messages, setMessages] = useState2([]);
|
|
1244
1276
|
const [input, setInput] = useState2("");
|
|
1245
1277
|
const [busy, setBusy] = useState2(false);
|
|
1246
1278
|
const [conversationId, setConversationId] = useState2(null);
|
|
1247
|
-
const [
|
|
1279
|
+
const [hoveredStar, setHoveredStar] = useState2(0);
|
|
1280
|
+
const [options, setOptions] = useState2([]);
|
|
1281
|
+
const [duplicate, setDuplicate] = useState2(null);
|
|
1282
|
+
const [solved, setSolved] = useState2(null);
|
|
1283
|
+
const [phase, setPhase] = useState2(
|
|
1284
|
+
!typePicked ? "type" : currentTile === "RATING" ? "rating" : "chat"
|
|
1285
|
+
);
|
|
1248
1286
|
const scrollRef = useRef2(null);
|
|
1249
1287
|
const inputRef = useRef2(null);
|
|
1250
1288
|
const draftRef = useRef2(null);
|
|
@@ -1258,6 +1296,7 @@ function AssistSheet({
|
|
|
1258
1296
|
if (phase === "draft") (_a = draftRef.current) == null ? void 0 : _a.focus();
|
|
1259
1297
|
}, [phase]);
|
|
1260
1298
|
async function runTurn(history2) {
|
|
1299
|
+
var _a, _b, _c, _d;
|
|
1261
1300
|
setBusy(true);
|
|
1262
1301
|
let result;
|
|
1263
1302
|
try {
|
|
@@ -1272,15 +1311,28 @@ function AssistSheet({
|
|
|
1272
1311
|
onDegrade(result.degraded);
|
|
1273
1312
|
return;
|
|
1274
1313
|
}
|
|
1275
|
-
if (result.conversationId)
|
|
1314
|
+
if (result.conversationId) {
|
|
1315
|
+
setConversationId(result.conversationId);
|
|
1316
|
+
onConversationChange == null ? void 0 : onConversationChange(result.conversationId);
|
|
1317
|
+
}
|
|
1318
|
+
setDuplicate((_a = result.duplicate) != null ? _a : null);
|
|
1319
|
+
onDuplicateChange == null ? void 0 : onDuplicateChange((_c = (_b = result.duplicate) == null ? void 0 : _b.number) != null ? _c : null);
|
|
1320
|
+
if (result.solved) {
|
|
1321
|
+
setSolved(result.solved);
|
|
1322
|
+
setOptions([]);
|
|
1323
|
+
setPhase("solved");
|
|
1324
|
+
return;
|
|
1325
|
+
}
|
|
1276
1326
|
if (result.report) {
|
|
1277
1327
|
onDescriptionChange(result.report);
|
|
1278
1328
|
setMessages([...history2, { role: "assistant", content: "Here's your report \u2014 have a read." }]);
|
|
1329
|
+
setOptions([]);
|
|
1279
1330
|
setPhase("draft");
|
|
1280
1331
|
return;
|
|
1281
1332
|
}
|
|
1282
1333
|
if (result.question) {
|
|
1283
1334
|
setMessages([...history2, { role: "assistant", content: result.question }]);
|
|
1335
|
+
setOptions((_d = result.options) != null ? _d : []);
|
|
1284
1336
|
return;
|
|
1285
1337
|
}
|
|
1286
1338
|
onDegrade("The assistant had nothing to add \u2014 write your report below and send it as normal.");
|
|
@@ -1288,6 +1340,7 @@ function AssistSheet({
|
|
|
1288
1340
|
useEffect2(() => {
|
|
1289
1341
|
if (seededRef.current) return;
|
|
1290
1342
|
seededRef.current = true;
|
|
1343
|
+
if (!typePicked || currentTile === "RATING") return;
|
|
1291
1344
|
const seed = description.trim();
|
|
1292
1345
|
if (!seed) return;
|
|
1293
1346
|
const history2 = [{ role: "user", content: seed }];
|
|
@@ -1297,12 +1350,17 @@ function AssistSheet({
|
|
|
1297
1350
|
function send(text) {
|
|
1298
1351
|
const value = text.trim();
|
|
1299
1352
|
if (!value || busy) return;
|
|
1353
|
+
setOptions([]);
|
|
1300
1354
|
const history2 = [...messages, { role: "user", content: value }];
|
|
1301
1355
|
setMessages(history2);
|
|
1302
1356
|
setInput("");
|
|
1303
1357
|
void runTurn(history2);
|
|
1304
1358
|
}
|
|
1305
|
-
|
|
1359
|
+
function pickType(tile) {
|
|
1360
|
+
onPickType(tile);
|
|
1361
|
+
setPhase(tile === "RATING" ? "rating" : "chat");
|
|
1362
|
+
}
|
|
1363
|
+
const empty = phase === "chat" && messages.length === 0 && !busy;
|
|
1306
1364
|
const initials = (reporterName != null ? reporterName : "").split(/\s+/).filter(Boolean).slice(0, 2).map((w) => {
|
|
1307
1365
|
var _a, _b;
|
|
1308
1366
|
return (_b = (_a = w[0]) == null ? void 0 : _a.toUpperCase()) != null ? _b : "";
|
|
@@ -1418,7 +1476,7 @@ function AssistSheet({
|
|
|
1418
1476
|
}
|
|
1419
1477
|
),
|
|
1420
1478
|
/* @__PURE__ */ jsxs2("div", { style: { fontSize: "11.5px", color: t2.textMuted, marginTop: "3px" }, children: [
|
|
1421
|
-
reportTypeLabel,
|
|
1479
|
+
phase === "type" ? null : reportTypeLabel,
|
|
1422
1480
|
projectSlot ? /* @__PURE__ */ jsx2("span", { style: { marginLeft: "6px" }, children: projectSlot }) : null
|
|
1423
1481
|
] })
|
|
1424
1482
|
] }),
|
|
@@ -1426,20 +1484,24 @@ function AssistSheet({
|
|
|
1426
1484
|
"button",
|
|
1427
1485
|
{
|
|
1428
1486
|
type: "button",
|
|
1487
|
+
"data-gg-write-myself": "",
|
|
1429
1488
|
onClick: onClose,
|
|
1430
|
-
"aria-label": "
|
|
1489
|
+
"aria-label": "Write it myself instead",
|
|
1431
1490
|
style: {
|
|
1432
1491
|
flexShrink: 0,
|
|
1433
|
-
border:
|
|
1492
|
+
border: `1px solid ${t2.inputBorder}`,
|
|
1493
|
+
borderRadius: "999px",
|
|
1434
1494
|
background: "transparent",
|
|
1435
1495
|
color: t2.textMuted,
|
|
1436
1496
|
cursor: "pointer",
|
|
1437
|
-
fontSize:
|
|
1497
|
+
fontSize: "11.5px",
|
|
1438
1498
|
lineHeight: 1,
|
|
1439
1499
|
fontFamily: "inherit",
|
|
1440
|
-
|
|
1500
|
+
whiteSpace: "nowrap",
|
|
1501
|
+
// ~32px tall either way — this is the escape hatch, not a hint.
|
|
1502
|
+
padding: "9px 11px"
|
|
1441
1503
|
},
|
|
1442
|
-
children:
|
|
1504
|
+
children: "Write it myself"
|
|
1443
1505
|
}
|
|
1444
1506
|
)
|
|
1445
1507
|
]
|
|
@@ -1468,6 +1530,182 @@ function AssistSheet({
|
|
|
1468
1530
|
minWidth: 0
|
|
1469
1531
|
},
|
|
1470
1532
|
children: [
|
|
1533
|
+
phase === "type" && /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
|
|
1534
|
+
/* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
1535
|
+
/* @__PURE__ */ jsx2(Avatar, { who: "assistant", theme: t2 }),
|
|
1536
|
+
/* @__PURE__ */ jsxs2(
|
|
1537
|
+
"div",
|
|
1538
|
+
{
|
|
1539
|
+
style: {
|
|
1540
|
+
padding: "9px 12px",
|
|
1541
|
+
borderRadius: "12px 12px 12px 4px",
|
|
1542
|
+
backgroundColor: t2.bgSecondary,
|
|
1543
|
+
fontSize: "13px",
|
|
1544
|
+
lineHeight: 1.55,
|
|
1545
|
+
maxWidth: "88%"
|
|
1546
|
+
},
|
|
1547
|
+
children: [
|
|
1548
|
+
reporterName ? `Hi ${reporterName.split(" ")[0]} \u2014 w` : "W",
|
|
1549
|
+
"hat do you want to do? Pick one and I'll take it from there."
|
|
1550
|
+
]
|
|
1551
|
+
}
|
|
1552
|
+
)
|
|
1553
|
+
] }),
|
|
1554
|
+
/* @__PURE__ */ jsx2(
|
|
1555
|
+
"div",
|
|
1556
|
+
{
|
|
1557
|
+
style: {
|
|
1558
|
+
display: "flex",
|
|
1559
|
+
flexWrap: "wrap",
|
|
1560
|
+
gap: "6px",
|
|
1561
|
+
paddingLeft: "32px"
|
|
1562
|
+
},
|
|
1563
|
+
children: tiles.map((tile) => {
|
|
1564
|
+
const rate = tile === "RATING";
|
|
1565
|
+
return /* @__PURE__ */ jsx2(
|
|
1566
|
+
"button",
|
|
1567
|
+
{
|
|
1568
|
+
type: "button",
|
|
1569
|
+
"data-gg-chip": "",
|
|
1570
|
+
"data-gg-tile": tile,
|
|
1571
|
+
onClick: () => pickType(tile),
|
|
1572
|
+
style: {
|
|
1573
|
+
display: "inline-flex",
|
|
1574
|
+
alignItems: "center",
|
|
1575
|
+
gap: "5px",
|
|
1576
|
+
// The rating is the only tile that isn't a report, so
|
|
1577
|
+
// it wears the star colour the dialog's hero row uses
|
|
1578
|
+
// rather than hiding among the report types.
|
|
1579
|
+
border: `1px solid ${rate ? "rgba(245,158,11,0.5)" : t2.inputBorder}`,
|
|
1580
|
+
background: rate ? "rgba(245,158,11,0.08)" : "transparent",
|
|
1581
|
+
color: rate ? "#f59e0b" : t2.textMuted,
|
|
1582
|
+
borderRadius: "999px",
|
|
1583
|
+
// 8px vertical keeps the tap target at ~32px.
|
|
1584
|
+
padding: "8px 12px",
|
|
1585
|
+
fontSize: "12px",
|
|
1586
|
+
fontWeight: rate ? 600 : 400,
|
|
1587
|
+
fontFamily: "inherit",
|
|
1588
|
+
cursor: "pointer"
|
|
1589
|
+
},
|
|
1590
|
+
children: rate ? "\u2605 Rate us" : getTypeLabel(tile)
|
|
1591
|
+
},
|
|
1592
|
+
tile
|
|
1593
|
+
);
|
|
1594
|
+
})
|
|
1595
|
+
}
|
|
1596
|
+
)
|
|
1597
|
+
] }),
|
|
1598
|
+
phase === "rating" && !submitted && /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
|
|
1599
|
+
/* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
1600
|
+
/* @__PURE__ */ jsx2(Avatar, { who: "assistant", theme: t2 }),
|
|
1601
|
+
/* @__PURE__ */ jsx2(
|
|
1602
|
+
"div",
|
|
1603
|
+
{
|
|
1604
|
+
style: {
|
|
1605
|
+
padding: "9px 12px",
|
|
1606
|
+
borderRadius: "12px 12px 12px 4px",
|
|
1607
|
+
backgroundColor: t2.bgSecondary,
|
|
1608
|
+
fontSize: "13px",
|
|
1609
|
+
lineHeight: 1.55,
|
|
1610
|
+
maxWidth: "88%"
|
|
1611
|
+
},
|
|
1612
|
+
children: "How are we doing? Tap a star \u2014 the words are optional."
|
|
1613
|
+
}
|
|
1614
|
+
)
|
|
1615
|
+
] }),
|
|
1616
|
+
/* @__PURE__ */ jsxs2(
|
|
1617
|
+
"div",
|
|
1618
|
+
{
|
|
1619
|
+
style: {
|
|
1620
|
+
display: "flex",
|
|
1621
|
+
flexDirection: "column",
|
|
1622
|
+
gap: "10px",
|
|
1623
|
+
marginLeft: "32px",
|
|
1624
|
+
padding: "12px",
|
|
1625
|
+
borderRadius: "12px",
|
|
1626
|
+
border: "1px solid rgba(245,158,11,0.4)",
|
|
1627
|
+
backgroundColor: "rgba(245,158,11,0.06)"
|
|
1628
|
+
},
|
|
1629
|
+
children: [
|
|
1630
|
+
/* @__PURE__ */ jsx2("div", { style: { display: "flex", gap: "4px" }, role: "group", "aria-label": "Rating", children: [1, 2, 3, 4, 5].map((star) => {
|
|
1631
|
+
const filled = star <= (hoveredStar || rating);
|
|
1632
|
+
return /* @__PURE__ */ jsx2(
|
|
1633
|
+
"button",
|
|
1634
|
+
{
|
|
1635
|
+
type: "button",
|
|
1636
|
+
"aria-label": `${star} star${star > 1 ? "s" : ""}`,
|
|
1637
|
+
"aria-pressed": star <= rating,
|
|
1638
|
+
onClick: () => onRatingChange(star),
|
|
1639
|
+
onMouseEnter: () => setHoveredStar(star),
|
|
1640
|
+
onMouseLeave: () => setHoveredStar(0),
|
|
1641
|
+
style: {
|
|
1642
|
+
border: "none",
|
|
1643
|
+
background: "transparent",
|
|
1644
|
+
padding: 0,
|
|
1645
|
+
cursor: "pointer",
|
|
1646
|
+
lineHeight: 0
|
|
1647
|
+
},
|
|
1648
|
+
children: /* @__PURE__ */ jsx2("svg", { width: "30", height: "30", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(
|
|
1649
|
+
"path",
|
|
1650
|
+
{
|
|
1651
|
+
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",
|
|
1652
|
+
fill: filled ? "#f59e0b" : "transparent",
|
|
1653
|
+
stroke: filled ? "#f59e0b" : t2.inputBorder,
|
|
1654
|
+
strokeWidth: "1.5",
|
|
1655
|
+
strokeLinejoin: "round"
|
|
1656
|
+
}
|
|
1657
|
+
) })
|
|
1658
|
+
},
|
|
1659
|
+
star
|
|
1660
|
+
);
|
|
1661
|
+
}) }),
|
|
1662
|
+
/* @__PURE__ */ jsx2(
|
|
1663
|
+
"textarea",
|
|
1664
|
+
{
|
|
1665
|
+
value: description,
|
|
1666
|
+
onChange: (e) => onDescriptionChange(e.target.value),
|
|
1667
|
+
rows: 3,
|
|
1668
|
+
placeholder: "What made it good \u2014 or what let you down? (optional)",
|
|
1669
|
+
style: {
|
|
1670
|
+
width: "100%",
|
|
1671
|
+
padding: "10px",
|
|
1672
|
+
borderRadius: "8px",
|
|
1673
|
+
border: `1px solid ${t2.inputBorder}`,
|
|
1674
|
+
backgroundColor: t2.inputBg,
|
|
1675
|
+
color: t2.text,
|
|
1676
|
+
fontSize: "13px",
|
|
1677
|
+
lineHeight: 1.5,
|
|
1678
|
+
fontFamily: "inherit",
|
|
1679
|
+
resize: "vertical",
|
|
1680
|
+
outline: "none",
|
|
1681
|
+
boxSizing: "border-box"
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1684
|
+
),
|
|
1685
|
+
/* @__PURE__ */ jsx2(
|
|
1686
|
+
"button",
|
|
1687
|
+
{
|
|
1688
|
+
type: "button",
|
|
1689
|
+
onClick: () => setPhase("type"),
|
|
1690
|
+
style: {
|
|
1691
|
+
alignSelf: "flex-start",
|
|
1692
|
+
border: "none",
|
|
1693
|
+
background: "transparent",
|
|
1694
|
+
color: t2.textMuted,
|
|
1695
|
+
fontSize: "12px",
|
|
1696
|
+
fontFamily: "inherit",
|
|
1697
|
+
// A bare text link is ~14px tall — half a thumb.
|
|
1698
|
+
padding: "9px 0",
|
|
1699
|
+
cursor: "pointer",
|
|
1700
|
+
textDecoration: "underline"
|
|
1701
|
+
},
|
|
1702
|
+
children: "Report something instead"
|
|
1703
|
+
}
|
|
1704
|
+
)
|
|
1705
|
+
]
|
|
1706
|
+
}
|
|
1707
|
+
)
|
|
1708
|
+
] }),
|
|
1471
1709
|
empty && /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
|
|
1472
1710
|
/* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
1473
1711
|
/* @__PURE__ */ jsx2(Avatar, { who: "assistant", theme: t2 }),
|
|
@@ -1556,6 +1794,47 @@ function AssistSheet({
|
|
|
1556
1794
|
i
|
|
1557
1795
|
);
|
|
1558
1796
|
}),
|
|
1797
|
+
options.length > 0 && !busy && phase === "chat" && /* @__PURE__ */ jsx2(
|
|
1798
|
+
"div",
|
|
1799
|
+
{
|
|
1800
|
+
style: {
|
|
1801
|
+
display: "flex",
|
|
1802
|
+
// Long labels wrapped into a ragged row that always stranded
|
|
1803
|
+
// the last chip on a line of its own. Past ~24 characters
|
|
1804
|
+
// these stop being chips and become a choice list, so they
|
|
1805
|
+
// stack full width and read like one.
|
|
1806
|
+
flexDirection: options.some((o) => o.length > 24) ? "column" : "row",
|
|
1807
|
+
alignItems: options.some((o) => o.length > 24) ? "stretch" : "flex-start",
|
|
1808
|
+
flexWrap: "wrap",
|
|
1809
|
+
gap: "6px",
|
|
1810
|
+
paddingLeft: "32px"
|
|
1811
|
+
},
|
|
1812
|
+
children: options.map((option) => /* @__PURE__ */ jsx2(
|
|
1813
|
+
"button",
|
|
1814
|
+
{
|
|
1815
|
+
type: "button",
|
|
1816
|
+
"data-gg-chip": "",
|
|
1817
|
+
"data-gg-option": "",
|
|
1818
|
+
onClick: () => send(option),
|
|
1819
|
+
style: {
|
|
1820
|
+
border: `1px solid ${t2.inputBorder}`,
|
|
1821
|
+
background: "transparent",
|
|
1822
|
+
color: t2.textMuted,
|
|
1823
|
+
borderRadius: "999px",
|
|
1824
|
+
// Same 8px as the picker chips — one tap target size in
|
|
1825
|
+
// this sheet, not two.
|
|
1826
|
+
padding: "8px 12px",
|
|
1827
|
+
fontSize: "12px",
|
|
1828
|
+
fontFamily: "inherit",
|
|
1829
|
+
cursor: "pointer",
|
|
1830
|
+
textAlign: "left"
|
|
1831
|
+
},
|
|
1832
|
+
children: option
|
|
1833
|
+
},
|
|
1834
|
+
option
|
|
1835
|
+
))
|
|
1836
|
+
}
|
|
1837
|
+
),
|
|
1559
1838
|
busy && /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "8px" }, role: "status", "aria-label": "Thinking", children: [
|
|
1560
1839
|
/* @__PURE__ */ jsx2(Avatar, { who: "assistant", theme: t2 }),
|
|
1561
1840
|
/* @__PURE__ */ jsx2(
|
|
@@ -1613,6 +1892,32 @@ function AssistSheet({
|
|
|
1613
1892
|
children: "Your report \xB7 edit anything"
|
|
1614
1893
|
}
|
|
1615
1894
|
),
|
|
1895
|
+
duplicate && /* @__PURE__ */ jsxs2(
|
|
1896
|
+
"div",
|
|
1897
|
+
{
|
|
1898
|
+
style: {
|
|
1899
|
+
display: "flex",
|
|
1900
|
+
flexDirection: "column",
|
|
1901
|
+
gap: "3px",
|
|
1902
|
+
padding: "9px 10px",
|
|
1903
|
+
borderRadius: "8px",
|
|
1904
|
+
border: "1px solid rgba(245,158,11,0.4)",
|
|
1905
|
+
backgroundColor: "rgba(245,158,11,0.08)",
|
|
1906
|
+
fontSize: "12px",
|
|
1907
|
+
lineHeight: 1.5
|
|
1908
|
+
},
|
|
1909
|
+
children: [
|
|
1910
|
+
/* @__PURE__ */ jsx2("span", { style: { color: "#f59e0b", fontWeight: 600 }, children: "Our team is already on this" }),
|
|
1911
|
+
/* @__PURE__ */ jsxs2("span", { style: { color: t2.textMuted, wordBreak: "break-word" }, children: [
|
|
1912
|
+
"#",
|
|
1913
|
+
duplicate.number,
|
|
1914
|
+
" ",
|
|
1915
|
+
duplicate.title
|
|
1916
|
+
] }),
|
|
1917
|
+
/* @__PURE__ */ jsx2("span", { style: { color: t2.textMuted }, children: "Your details will be added to it instead of opening a new issue." })
|
|
1918
|
+
]
|
|
1919
|
+
}
|
|
1920
|
+
),
|
|
1616
1921
|
/* @__PURE__ */ jsx2(
|
|
1617
1922
|
"textarea",
|
|
1618
1923
|
{
|
|
@@ -1696,7 +2001,7 @@ function AssistSheet({
|
|
|
1696
2001
|
color: t2.textMuted,
|
|
1697
2002
|
fontSize: "12px",
|
|
1698
2003
|
fontFamily: "inherit",
|
|
1699
|
-
padding: 0,
|
|
2004
|
+
padding: "9px 0",
|
|
1700
2005
|
cursor: "pointer",
|
|
1701
2006
|
textDecoration: "underline"
|
|
1702
2007
|
},
|
|
@@ -1706,6 +2011,33 @@ function AssistSheet({
|
|
|
1706
2011
|
]
|
|
1707
2012
|
}
|
|
1708
2013
|
),
|
|
2014
|
+
phase === "solved" && solved && /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
|
|
2015
|
+
/* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
2016
|
+
/* @__PURE__ */ jsx2(Avatar, { who: "assistant", theme: t2 }),
|
|
2017
|
+
/* @__PURE__ */ jsx2(
|
|
2018
|
+
"div",
|
|
2019
|
+
{
|
|
2020
|
+
style: {
|
|
2021
|
+
padding: "9px 12px",
|
|
2022
|
+
borderRadius: "12px 12px 12px 4px",
|
|
2023
|
+
backgroundColor: t2.bgSecondary,
|
|
2024
|
+
fontSize: "13px",
|
|
2025
|
+
lineHeight: 1.55,
|
|
2026
|
+
maxWidth: "88%",
|
|
2027
|
+
whiteSpace: "pre-wrap"
|
|
2028
|
+
},
|
|
2029
|
+
children: solved
|
|
2030
|
+
}
|
|
2031
|
+
)
|
|
2032
|
+
] }),
|
|
2033
|
+
/* @__PURE__ */ jsx2(
|
|
2034
|
+
"span",
|
|
2035
|
+
{
|
|
2036
|
+
style: { fontSize: "11.5px", color: t2.textMuted, paddingLeft: "32px" },
|
|
2037
|
+
children: "Nothing was filed \u2014 you are all set."
|
|
2038
|
+
}
|
|
2039
|
+
)
|
|
2040
|
+
] }),
|
|
1709
2041
|
submitted && /* @__PURE__ */ jsxs2(
|
|
1710
2042
|
"div",
|
|
1711
2043
|
{
|
|
@@ -1727,7 +2059,7 @@ function AssistSheet({
|
|
|
1727
2059
|
)
|
|
1728
2060
|
}
|
|
1729
2061
|
),
|
|
1730
|
-
!submitted && /* @__PURE__ */
|
|
2062
|
+
!submitted && phase !== "type" && /* @__PURE__ */ jsxs2(
|
|
1731
2063
|
"div",
|
|
1732
2064
|
{
|
|
1733
2065
|
style: {
|
|
@@ -1737,93 +2069,157 @@ function AssistSheet({
|
|
|
1737
2069
|
paddingBottom: narrow ? "max(12px, env(safe-area-inset-bottom))" : "12px",
|
|
1738
2070
|
backgroundColor: t2.bg
|
|
1739
2071
|
},
|
|
1740
|
-
children:
|
|
1741
|
-
"
|
|
1742
|
-
|
|
1743
|
-
type: "button",
|
|
1744
|
-
"data-gg-sheet-send": "",
|
|
1745
|
-
onClick: onSend,
|
|
1746
|
-
disabled: isSubmitting || !description.trim(),
|
|
1747
|
-
style: {
|
|
1748
|
-
width: "100%",
|
|
1749
|
-
padding: "12px",
|
|
1750
|
-
borderRadius: "10px",
|
|
1751
|
-
border: "none",
|
|
1752
|
-
backgroundColor: isSubmitting || !description.trim() ? t2.bgSecondary : t2.accent,
|
|
1753
|
-
color: isSubmitting || !description.trim() ? t2.textMuted : t2.accentText,
|
|
1754
|
-
fontSize: "14px",
|
|
1755
|
-
fontWeight: 700,
|
|
1756
|
-
fontFamily: "inherit",
|
|
1757
|
-
cursor: isSubmitting || !description.trim() ? "default" : "pointer"
|
|
1758
|
-
},
|
|
1759
|
-
children: isSubmitting ? "Sending\u2026" : "Send Report"
|
|
1760
|
-
}
|
|
1761
|
-
) : /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "8px", alignItems: "flex-end" }, children: [
|
|
1762
|
-
/* @__PURE__ */ jsx2(
|
|
1763
|
-
"textarea",
|
|
2072
|
+
children: [
|
|
2073
|
+
phase === "solved" ? /* @__PURE__ */ jsx2(
|
|
2074
|
+
"button",
|
|
1764
2075
|
{
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
2076
|
+
type: "button",
|
|
2077
|
+
"data-gg-sheet-send": "",
|
|
2078
|
+
onClick: () => (onFinish != null ? onFinish : onClose)(),
|
|
2079
|
+
style: {
|
|
2080
|
+
width: "100%",
|
|
2081
|
+
padding: "12px",
|
|
2082
|
+
borderRadius: "10px",
|
|
2083
|
+
border: "none",
|
|
2084
|
+
backgroundColor: t2.accent,
|
|
2085
|
+
color: t2.accentText,
|
|
2086
|
+
fontSize: "14px",
|
|
2087
|
+
fontWeight: 700,
|
|
2088
|
+
fontFamily: "inherit",
|
|
2089
|
+
cursor: "pointer"
|
|
1773
2090
|
},
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
2091
|
+
children: "Done"
|
|
2092
|
+
}
|
|
2093
|
+
) : phase === "rating" ? /* @__PURE__ */ jsx2(
|
|
2094
|
+
"button",
|
|
2095
|
+
{
|
|
2096
|
+
type: "button",
|
|
2097
|
+
"data-gg-sheet-send": "",
|
|
2098
|
+
onClick: onSend,
|
|
2099
|
+
disabled: isSubmitting || rating < 1,
|
|
1778
2100
|
style: {
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
maxHeight: "120px",
|
|
1782
|
-
padding: "11px 12px",
|
|
2101
|
+
width: "100%",
|
|
2102
|
+
padding: "12px",
|
|
1783
2103
|
borderRadius: "10px",
|
|
1784
|
-
border:
|
|
1785
|
-
backgroundColor: t2.
|
|
1786
|
-
color: t2.
|
|
1787
|
-
fontSize: "
|
|
1788
|
-
|
|
2104
|
+
border: "none",
|
|
2105
|
+
backgroundColor: isSubmitting || rating < 1 ? t2.bgSecondary : "#f59e0b",
|
|
2106
|
+
color: isSubmitting || rating < 1 ? t2.textMuted : "#1a1a1a",
|
|
2107
|
+
fontSize: "14px",
|
|
2108
|
+
fontWeight: 700,
|
|
1789
2109
|
fontFamily: "inherit",
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
}
|
|
2110
|
+
cursor: isSubmitting || rating < 1 ? "default" : "pointer"
|
|
2111
|
+
},
|
|
2112
|
+
children: isSubmitting ? "Sending\u2026" : rating < 1 ? "Pick a star first" : "Send Rating"
|
|
1794
2113
|
}
|
|
1795
|
-
)
|
|
1796
|
-
/* @__PURE__ */ jsx2(
|
|
2114
|
+
) : phase === "draft" ? /* @__PURE__ */ jsx2(
|
|
1797
2115
|
"button",
|
|
1798
2116
|
{
|
|
1799
2117
|
type: "button",
|
|
1800
2118
|
"data-gg-sheet-send": "",
|
|
1801
|
-
onClick:
|
|
1802
|
-
disabled:
|
|
1803
|
-
"aria-label": "Send message",
|
|
2119
|
+
onClick: onSend,
|
|
2120
|
+
disabled: isSubmitting || !description.trim(),
|
|
1804
2121
|
style: {
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
height: "42px",
|
|
2122
|
+
width: "100%",
|
|
2123
|
+
padding: "12px",
|
|
1808
2124
|
borderRadius: "10px",
|
|
1809
2125
|
border: "none",
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
cursor:
|
|
2126
|
+
backgroundColor: isSubmitting || !description.trim() ? t2.bgSecondary : t2.accent,
|
|
2127
|
+
color: isSubmitting || !description.trim() ? t2.textMuted : t2.accentText,
|
|
2128
|
+
fontSize: "14px",
|
|
2129
|
+
fontWeight: 700,
|
|
2130
|
+
fontFamily: "inherit",
|
|
2131
|
+
cursor: isSubmitting || !description.trim() ? "default" : "pointer"
|
|
1816
2132
|
},
|
|
1817
|
-
children:
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
2133
|
+
children: isSubmitting ? "Sending\u2026" : duplicate ? `Add to #${duplicate.number}` : "Send Report"
|
|
2134
|
+
}
|
|
2135
|
+
) : /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "8px", alignItems: "flex-end" }, children: [
|
|
2136
|
+
/* @__PURE__ */ jsx2(
|
|
2137
|
+
"textarea",
|
|
2138
|
+
{
|
|
2139
|
+
ref: inputRef,
|
|
2140
|
+
value: input,
|
|
2141
|
+
onChange: (e) => setInput(e.target.value),
|
|
2142
|
+
onKeyDown: (e) => {
|
|
2143
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
2144
|
+
e.preventDefault();
|
|
2145
|
+
send(input);
|
|
2146
|
+
}
|
|
2147
|
+
},
|
|
2148
|
+
placeholder: "Type your answer\u2026",
|
|
2149
|
+
rows: 1,
|
|
2150
|
+
disabled: busy,
|
|
2151
|
+
autoFocus: true,
|
|
2152
|
+
style: {
|
|
2153
|
+
flex: 1,
|
|
2154
|
+
minHeight: "42px",
|
|
2155
|
+
maxHeight: "120px",
|
|
2156
|
+
padding: "11px 12px",
|
|
2157
|
+
borderRadius: "10px",
|
|
2158
|
+
border: `1px solid ${t2.inputBorder}`,
|
|
2159
|
+
backgroundColor: t2.inputBg,
|
|
2160
|
+
color: t2.text,
|
|
2161
|
+
fontSize: "13px",
|
|
2162
|
+
lineHeight: 1.4,
|
|
2163
|
+
fontFamily: "inherit",
|
|
2164
|
+
resize: "none",
|
|
2165
|
+
outline: "none",
|
|
2166
|
+
boxSizing: "border-box"
|
|
1822
2167
|
}
|
|
1823
|
-
|
|
2168
|
+
}
|
|
2169
|
+
),
|
|
2170
|
+
/* @__PURE__ */ jsx2(
|
|
2171
|
+
"button",
|
|
2172
|
+
{
|
|
2173
|
+
type: "button",
|
|
2174
|
+
"data-gg-sheet-send": "",
|
|
2175
|
+
onClick: () => send(input),
|
|
2176
|
+
disabled: busy || !input.trim(),
|
|
2177
|
+
"aria-label": "Send message",
|
|
2178
|
+
"data-gg-send-message": "",
|
|
2179
|
+
style: {
|
|
2180
|
+
flexShrink: 0,
|
|
2181
|
+
width: "42px",
|
|
2182
|
+
height: "42px",
|
|
2183
|
+
borderRadius: "10px",
|
|
2184
|
+
border: "none",
|
|
2185
|
+
display: "inline-flex",
|
|
2186
|
+
alignItems: "center",
|
|
2187
|
+
justifyContent: "center",
|
|
2188
|
+
backgroundColor: busy || !input.trim() ? t2.bgSecondary : t2.accent,
|
|
2189
|
+
color: busy || !input.trim() ? t2.textMuted : t2.accentText,
|
|
2190
|
+
cursor: busy || !input.trim() ? "default" : "pointer"
|
|
2191
|
+
},
|
|
2192
|
+
children: /* @__PURE__ */ jsx2("svg", { width: "17", height: "17", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(
|
|
2193
|
+
"path",
|
|
2194
|
+
{
|
|
2195
|
+
d: "M3 20.5L21.5 12 3 3.5V10l12 2-12 2v6.5z",
|
|
2196
|
+
fill: "currentColor"
|
|
2197
|
+
}
|
|
2198
|
+
) })
|
|
2199
|
+
}
|
|
2200
|
+
)
|
|
2201
|
+
] }),
|
|
2202
|
+
phase === "chat" && messages.length > 0 && /* @__PURE__ */ jsx2(
|
|
2203
|
+
"button",
|
|
2204
|
+
{
|
|
2205
|
+
type: "button",
|
|
2206
|
+
"data-gg-write-myself": "",
|
|
2207
|
+
onClick: onClose,
|
|
2208
|
+
style: {
|
|
2209
|
+
display: "block",
|
|
2210
|
+
margin: "8px auto 0",
|
|
2211
|
+
border: "none",
|
|
2212
|
+
background: "transparent",
|
|
2213
|
+
color: t2.textMuted,
|
|
2214
|
+
fontSize: "11.5px",
|
|
2215
|
+
fontFamily: "inherit",
|
|
2216
|
+
padding: "6px 8px",
|
|
2217
|
+
cursor: "pointer"
|
|
2218
|
+
},
|
|
2219
|
+
children: "Not getting it? Fill the form yourself \u2192"
|
|
1824
2220
|
}
|
|
1825
2221
|
)
|
|
1826
|
-
]
|
|
2222
|
+
]
|
|
1827
2223
|
}
|
|
1828
2224
|
)
|
|
1829
2225
|
]
|
|
@@ -2193,6 +2589,9 @@ function ReportDialog({
|
|
|
2193
2589
|
const [assistOpen, setAssistOpen] = useState3(false);
|
|
2194
2590
|
const [assistNotice, setAssistNotice] = useState3(null);
|
|
2195
2591
|
const [assistUsed, setAssistUsed] = useState3(false);
|
|
2592
|
+
const [typeChosen, setTypeChosen] = useState3(false);
|
|
2593
|
+
const [duplicateIssueNumber, setDuplicateIssueNumber] = useState3(null);
|
|
2594
|
+
const [aiConversationId, setAiConversationId] = useState3(null);
|
|
2196
2595
|
const [isEnhanced, setIsEnhanced] = useState3(false);
|
|
2197
2596
|
const [originalDescription, setOriginalDescription] = useState3(
|
|
2198
2597
|
null
|
|
@@ -2245,6 +2644,10 @@ function ReportDialog({
|
|
|
2245
2644
|
const sarvamChunksRef = useRef3([]);
|
|
2246
2645
|
const spaceTimerRef = useRef3(null);
|
|
2247
2646
|
const isPushToTalkRef = useRef3(false);
|
|
2647
|
+
const spaceEditsRef = useRef3(0);
|
|
2648
|
+
const descriptionRef = useRef3("");
|
|
2649
|
+
const lastVoiceTextRef = useRef3(null);
|
|
2650
|
+
const hadWebSpeechRef = useRef3(false);
|
|
2248
2651
|
useEffect3(() => {
|
|
2249
2652
|
if (!isOpen) return;
|
|
2250
2653
|
const HOST_LAYERS = '[role="dialog"],[role="alertdialog"],[role="menu"],[role="listbox"]';
|
|
@@ -2300,6 +2703,7 @@ function ReportDialog({
|
|
|
2300
2703
|
e.preventDefault();
|
|
2301
2704
|
setRating(Number(e.key));
|
|
2302
2705
|
setReportType("RATING");
|
|
2706
|
+
setTypeChosen(true);
|
|
2303
2707
|
setStep(2);
|
|
2304
2708
|
return;
|
|
2305
2709
|
}
|
|
@@ -2311,6 +2715,7 @@ function ReportDialog({
|
|
|
2311
2715
|
if (match) {
|
|
2312
2716
|
e.preventDefault();
|
|
2313
2717
|
setReportType(match);
|
|
2718
|
+
setTypeChosen(true);
|
|
2314
2719
|
setStep(2);
|
|
2315
2720
|
}
|
|
2316
2721
|
};
|
|
@@ -2364,10 +2769,12 @@ function ReportDialog({
|
|
|
2364
2769
|
setAnnotatingIndex(null);
|
|
2365
2770
|
if (availableTypes.length === 1) {
|
|
2366
2771
|
setReportType(availableTypes[0]);
|
|
2772
|
+
setTypeChosen(true);
|
|
2367
2773
|
setStep(2);
|
|
2368
2774
|
}
|
|
2369
2775
|
const shot = await captureScreenshot();
|
|
2370
2776
|
if (shot) setScreenshots([shot]);
|
|
2777
|
+
if (assist && !assistUsed) setAssistOpen(true);
|
|
2371
2778
|
setIsOpen(true);
|
|
2372
2779
|
};
|
|
2373
2780
|
useEffect3(() => {
|
|
@@ -2377,6 +2784,7 @@ function ReportDialog({
|
|
|
2377
2784
|
if (detail == null ? void 0 : detail.description) setDescription(detail.description);
|
|
2378
2785
|
if (detail == null ? void 0 : detail.type) {
|
|
2379
2786
|
setReportType(detail.type);
|
|
2787
|
+
setTypeChosen(true);
|
|
2380
2788
|
setStep(2);
|
|
2381
2789
|
}
|
|
2382
2790
|
handleOpen();
|
|
@@ -2500,6 +2908,22 @@ function ReportDialog({
|
|
|
2500
2908
|
}, 3e3);
|
|
2501
2909
|
return () => clearInterval(id);
|
|
2502
2910
|
}, [isOpen, transcribeAudio2]);
|
|
2911
|
+
useEffect3(() => {
|
|
2912
|
+
descriptionRef.current = description;
|
|
2913
|
+
}, [description]);
|
|
2914
|
+
const rebaseVoiceOnUserEdits = () => {
|
|
2915
|
+
var _a2;
|
|
2916
|
+
const live = descriptionRef.current;
|
|
2917
|
+
const baseline = (_a2 = lastVoiceTextRef.current) != null ? _a2 : textBeforeVoiceRef.current;
|
|
2918
|
+
if (live === baseline) return;
|
|
2919
|
+
voiceBaseRef.current = live;
|
|
2920
|
+
textBeforeVoiceRef.current = live;
|
|
2921
|
+
};
|
|
2922
|
+
const setDescriptionFromVoice = (text) => {
|
|
2923
|
+
lastVoiceTextRef.current = text;
|
|
2924
|
+
descriptionRef.current = text;
|
|
2925
|
+
setDescription(text);
|
|
2926
|
+
};
|
|
2503
2927
|
const stopVoice = () => {
|
|
2504
2928
|
var _a2, _b2;
|
|
2505
2929
|
usingWebSpeechRef.current = false;
|
|
@@ -2528,7 +2952,7 @@ function ReportDialog({
|
|
|
2528
2952
|
} catch (e) {
|
|
2529
2953
|
}
|
|
2530
2954
|
};
|
|
2531
|
-
const sheetUp = !!assist && assistOpen
|
|
2955
|
+
const sheetUp = !!assist && assistOpen;
|
|
2532
2956
|
useEffect3(() => {
|
|
2533
2957
|
const el = modalRef.current;
|
|
2534
2958
|
if (!el) return;
|
|
@@ -2550,6 +2974,8 @@ function ReportDialog({
|
|
|
2550
2974
|
setRating(0);
|
|
2551
2975
|
setHoveredStar(0);
|
|
2552
2976
|
setReportType("BUG");
|
|
2977
|
+
setTypeChosen(false);
|
|
2978
|
+
setDuplicateIssueNumber(null);
|
|
2553
2979
|
setSeverity("medium");
|
|
2554
2980
|
setValidationError(null);
|
|
2555
2981
|
setVoiceError(null);
|
|
@@ -2564,6 +2990,8 @@ function ReportDialog({
|
|
|
2564
2990
|
stopListeningAndTranscribe();
|
|
2565
2991
|
return;
|
|
2566
2992
|
}
|
|
2993
|
+
lastVoiceTextRef.current = null;
|
|
2994
|
+
hadWebSpeechRef.current = false;
|
|
2567
2995
|
const SpeechRec = typeof window !== "undefined" ? window.SpeechRecognition || window.webkitSpeechRecognition : void 0;
|
|
2568
2996
|
let stream = null;
|
|
2569
2997
|
try {
|
|
@@ -2578,13 +3006,14 @@ function ReportDialog({
|
|
|
2578
3006
|
if (stream && transcribeAudio2) {
|
|
2579
3007
|
streamRef.current = stream;
|
|
2580
3008
|
sarvamChunksRef.current = [];
|
|
2581
|
-
textBeforeVoiceRef.current =
|
|
3009
|
+
textBeforeVoiceRef.current = descriptionRef.current;
|
|
2582
3010
|
const rec = new MediaRecorder(stream);
|
|
2583
3011
|
mediaRecorderRef.current = rec;
|
|
2584
3012
|
rec.ondataavailable = (e) => {
|
|
2585
3013
|
if (e.data.size > 0) sarvamChunksRef.current.push(e.data);
|
|
2586
3014
|
};
|
|
2587
3015
|
rec.onstop = async () => {
|
|
3016
|
+
var _a2;
|
|
2588
3017
|
stream.getTracks().forEach((t22) => t22.stop());
|
|
2589
3018
|
if (streamRef.current === stream) streamRef.current = null;
|
|
2590
3019
|
mediaRecorderRef.current = null;
|
|
@@ -2596,11 +3025,18 @@ function ReportDialog({
|
|
|
2596
3025
|
const blob = new Blob(chunks, { type: rec.mimeType || "audio/webm" });
|
|
2597
3026
|
const text = await transcribeAudio2(blob);
|
|
2598
3027
|
if (text.trim()) {
|
|
2599
|
-
const
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
3028
|
+
const live = descriptionRef.current;
|
|
3029
|
+
const baseline = (_a2 = lastVoiceTextRef.current) != null ? _a2 : textBeforeVoiceRef.current;
|
|
3030
|
+
const userEdited = live !== baseline;
|
|
3031
|
+
if (userEdited && hadWebSpeechRef.current) {
|
|
3032
|
+
} else {
|
|
3033
|
+
const base = userEdited ? live : textBeforeVoiceRef.current;
|
|
3034
|
+
const sep = base.trim() ? " " : "";
|
|
3035
|
+
setDescriptionFromVoice(base + sep + text.trim());
|
|
3036
|
+
setValidationError(null);
|
|
3037
|
+
setIsEnhanced(false);
|
|
3038
|
+
setOriginalDescription(null);
|
|
3039
|
+
}
|
|
2604
3040
|
}
|
|
2605
3041
|
} catch (e) {
|
|
2606
3042
|
}
|
|
@@ -2611,8 +3047,9 @@ function ReportDialog({
|
|
|
2611
3047
|
if (SpeechRec) {
|
|
2612
3048
|
setVoiceError(null);
|
|
2613
3049
|
usingWebSpeechRef.current = true;
|
|
2614
|
-
|
|
2615
|
-
|
|
3050
|
+
hadWebSpeechRef.current = true;
|
|
3051
|
+
voiceBaseRef.current = descriptionRef.current;
|
|
3052
|
+
textBeforeVoiceRef.current = descriptionRef.current;
|
|
2616
3053
|
const recognition = new SpeechRec();
|
|
2617
3054
|
recognition.lang = "en-IN";
|
|
2618
3055
|
recognition.interimResults = true;
|
|
@@ -2627,12 +3064,13 @@ function ReportDialog({
|
|
|
2627
3064
|
if (event.results[i].isFinal) finalText += text;
|
|
2628
3065
|
else interimText += text;
|
|
2629
3066
|
}
|
|
3067
|
+
rebaseVoiceOnUserEdits();
|
|
2630
3068
|
if (finalText) {
|
|
2631
3069
|
const sep = voiceBaseRef.current.trim() ? " " : "";
|
|
2632
3070
|
voiceBaseRef.current += sep + finalText.trim();
|
|
2633
3071
|
}
|
|
2634
3072
|
const liveText = interimText ? voiceBaseRef.current + (voiceBaseRef.current.trim() ? " " : "") + interimText : voiceBaseRef.current;
|
|
2635
|
-
|
|
3073
|
+
setDescriptionFromVoice(liveText);
|
|
2636
3074
|
setValidationError(null);
|
|
2637
3075
|
};
|
|
2638
3076
|
recognition.onend = () => {
|
|
@@ -2659,37 +3097,54 @@ function ReportDialog({
|
|
|
2659
3097
|
setIsListening(true);
|
|
2660
3098
|
}
|
|
2661
3099
|
};
|
|
3100
|
+
const cancelPushToTalkArm = () => {
|
|
3101
|
+
if (!spaceTimerRef.current) return;
|
|
3102
|
+
clearTimeout(spaceTimerRef.current);
|
|
3103
|
+
spaceTimerRef.current = null;
|
|
3104
|
+
};
|
|
3105
|
+
const notePushToTalkEdit = () => {
|
|
3106
|
+
if (!spaceTimerRef.current) return;
|
|
3107
|
+
spaceEditsRef.current += 1;
|
|
3108
|
+
if (spaceEditsRef.current > 1) cancelPushToTalkArm();
|
|
3109
|
+
};
|
|
2662
3110
|
const handleSpaceDown = (e) => {
|
|
2663
|
-
|
|
2664
|
-
|
|
3111
|
+
if (e.code !== "Space") {
|
|
3112
|
+
if (!e.metaKey && !e.ctrlKey && !e.altKey) cancelPushToTalkArm();
|
|
3113
|
+
return;
|
|
3114
|
+
}
|
|
2665
3115
|
if (isListening || isPushToTalkRef.current) {
|
|
2666
3116
|
e.preventDefault();
|
|
2667
3117
|
return;
|
|
2668
3118
|
}
|
|
2669
3119
|
if (e.repeat || !transcribeAudio2 || isTranscribing || spaceTimerRef.current)
|
|
2670
3120
|
return;
|
|
2671
|
-
|
|
3121
|
+
if (e.currentTarget.value !== "") return;
|
|
3122
|
+
spaceEditsRef.current = 0;
|
|
2672
3123
|
spaceTimerRef.current = setTimeout(() => {
|
|
3124
|
+
var _a2;
|
|
2673
3125
|
spaceTimerRef.current = null;
|
|
2674
3126
|
isPushToTalkRef.current = true;
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
)
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
3127
|
+
const el = textareaRef.current;
|
|
3128
|
+
const caret = (_a2 = el == null ? void 0 : el.selectionStart) != null ? _a2 : null;
|
|
3129
|
+
if (el && caret !== null && caret === el.selectionEnd && el.value[caret - 1] === " ") {
|
|
3130
|
+
const cut = caret - 1;
|
|
3131
|
+
setDescription(
|
|
3132
|
+
(prev) => prev[cut] === " " ? prev.slice(0, cut) + prev.slice(cut + 1) : prev
|
|
3133
|
+
);
|
|
3134
|
+
descriptionRef.current = descriptionRef.current.slice(0, cut) + descriptionRef.current.slice(cut + 1);
|
|
3135
|
+
requestAnimationFrame(() => {
|
|
3136
|
+
if (textareaRef.current) {
|
|
3137
|
+
textareaRef.current.selectionStart = cut;
|
|
3138
|
+
textareaRef.current.selectionEnd = cut;
|
|
3139
|
+
}
|
|
3140
|
+
});
|
|
3141
|
+
}
|
|
2684
3142
|
void toggleVoice();
|
|
2685
3143
|
}, 400);
|
|
2686
3144
|
};
|
|
2687
3145
|
const handleSpaceUp = (e) => {
|
|
2688
3146
|
if (e.code !== "Space") return;
|
|
2689
|
-
|
|
2690
|
-
clearTimeout(spaceTimerRef.current);
|
|
2691
|
-
spaceTimerRef.current = null;
|
|
2692
|
-
}
|
|
3147
|
+
cancelPushToTalkArm();
|
|
2693
3148
|
if (isPushToTalkRef.current) {
|
|
2694
3149
|
isPushToTalkRef.current = false;
|
|
2695
3150
|
stopListeningAndTranscribe();
|
|
@@ -2734,6 +3189,12 @@ function ReportDialog({
|
|
|
2734
3189
|
if (showSeverity && reportType === "BUG") {
|
|
2735
3190
|
metadata.severity = severity;
|
|
2736
3191
|
}
|
|
3192
|
+
if (duplicateIssueNumber) {
|
|
3193
|
+
metadata.duplicateIssueNumber = String(duplicateIssueNumber);
|
|
3194
|
+
}
|
|
3195
|
+
if (aiConversationId) {
|
|
3196
|
+
metadata.aiConversationId = aiConversationId;
|
|
3197
|
+
}
|
|
2737
3198
|
const result = await report(
|
|
2738
3199
|
// The RATING branch returned above, so anything reaching here is a real
|
|
2739
3200
|
// ReportType — the widened tile union can't leak into the report API.
|
|
@@ -2746,6 +3207,8 @@ function ReportDialog({
|
|
|
2746
3207
|
setDescription("");
|
|
2747
3208
|
setScreenshots([]);
|
|
2748
3209
|
setAttachments([]);
|
|
3210
|
+
setAiConversationId(null);
|
|
3211
|
+
setDuplicateIssueNumber(null);
|
|
2749
3212
|
setTimeout(() => {
|
|
2750
3213
|
setSubmitted(false);
|
|
2751
3214
|
handleClose();
|
|
@@ -3096,6 +3559,7 @@ function ReportDialog({
|
|
|
3096
3559
|
onClick: () => {
|
|
3097
3560
|
setRating(star);
|
|
3098
3561
|
setReportType("RATING");
|
|
3562
|
+
setTypeChosen(true);
|
|
3099
3563
|
setStep(2);
|
|
3100
3564
|
},
|
|
3101
3565
|
style: {
|
|
@@ -3206,6 +3670,7 @@ function ReportDialog({
|
|
|
3206
3670
|
"data-gg-type": type,
|
|
3207
3671
|
onClick: () => {
|
|
3208
3672
|
setReportType(type);
|
|
3673
|
+
setTypeChosen(true);
|
|
3209
3674
|
setStep(2);
|
|
3210
3675
|
},
|
|
3211
3676
|
style: {
|
|
@@ -3325,6 +3790,7 @@ function ReportDialog({
|
|
|
3325
3790
|
type: "button",
|
|
3326
3791
|
onClick: () => {
|
|
3327
3792
|
setAssistNotice(null);
|
|
3793
|
+
setTypeChosen(true);
|
|
3328
3794
|
setAssistOpen(true);
|
|
3329
3795
|
},
|
|
3330
3796
|
style: {
|
|
@@ -3365,6 +3831,7 @@ function ReportDialog({
|
|
|
3365
3831
|
ref: textareaRef,
|
|
3366
3832
|
value: description,
|
|
3367
3833
|
onChange: (e) => {
|
|
3834
|
+
notePushToTalkEdit();
|
|
3368
3835
|
setDescription(e.target.value);
|
|
3369
3836
|
if (validationError) setValidationError(null);
|
|
3370
3837
|
if (isEnhanced) {
|
|
@@ -4473,6 +4940,22 @@ function ReportDialog({
|
|
|
4473
4940
|
attachmentCount: screenshots.length + attachments.length,
|
|
4474
4941
|
context: { ...assistContext != null ? assistContext : {}, reportType },
|
|
4475
4942
|
reportTypeLabel: getTypeLabel(reportType),
|
|
4943
|
+
typePicked: typeChosen,
|
|
4944
|
+
currentTile: reportType,
|
|
4945
|
+
tiles: sendFeedback2 ? [...availableTypes, "RATING"] : availableTypes,
|
|
4946
|
+
onPickType: (tile) => {
|
|
4947
|
+
setReportType(tile);
|
|
4948
|
+
setTypeChosen(true);
|
|
4949
|
+
setStep(2);
|
|
4950
|
+
},
|
|
4951
|
+
onDuplicateChange: setDuplicateIssueNumber,
|
|
4952
|
+
onConversationChange: setAiConversationId,
|
|
4953
|
+
onFinish: handleClose,
|
|
4954
|
+
rating,
|
|
4955
|
+
onRatingChange: (value) => {
|
|
4956
|
+
setRating(value);
|
|
4957
|
+
if (validationError) setValidationError(null);
|
|
4958
|
+
},
|
|
4476
4959
|
projectSlot: headerSlot,
|
|
4477
4960
|
reporterName: (_b = reporter == null ? void 0 : reporter.name) != null ? _b : null,
|
|
4478
4961
|
description,
|
|
@@ -4502,26 +4985,6 @@ function ReportDialog({
|
|
|
4502
4985
|
)
|
|
4503
4986
|
] });
|
|
4504
4987
|
}
|
|
4505
|
-
function getTypeLabel(type) {
|
|
4506
|
-
switch (type) {
|
|
4507
|
-
case "RATING":
|
|
4508
|
-
return "Rating";
|
|
4509
|
-
case "BUG":
|
|
4510
|
-
return "Bug Report";
|
|
4511
|
-
case "FEATURE_REQUEST":
|
|
4512
|
-
return "Feature Request";
|
|
4513
|
-
case "UI_IMPROVEMENT":
|
|
4514
|
-
return "UI Improvement";
|
|
4515
|
-
case "PERFORMANCE":
|
|
4516
|
-
return "Performance";
|
|
4517
|
-
case "SECURITY":
|
|
4518
|
-
return "Security";
|
|
4519
|
-
case "QUESTION":
|
|
4520
|
-
return "Question";
|
|
4521
|
-
case "OTHER":
|
|
4522
|
-
return "Other";
|
|
4523
|
-
}
|
|
4524
|
-
}
|
|
4525
4988
|
function getPlaceholder(type, idx = 0, hasVoice = false) {
|
|
4526
4989
|
if (type === "RATING") return "What made it good \u2014 or what let you down? (optional)";
|
|
4527
4990
|
if (hasVoice && idx === 1) return "Hold Space to speak \u2014 we'll transcribe it";
|
|
@@ -5506,6 +5969,12 @@ function GlitchgrabProviderInner({
|
|
|
5506
5969
|
return assistTurn(
|
|
5507
5970
|
{
|
|
5508
5971
|
...params,
|
|
5972
|
+
// Same identity the report itself carries, from the same prop.
|
|
5973
|
+
reporter: session ? {
|
|
5974
|
+
key: session.userId,
|
|
5975
|
+
name: session.name ? String(session.name) : null,
|
|
5976
|
+
email: session.email ? String(session.email) : null
|
|
5977
|
+
} : void 0,
|
|
5509
5978
|
context: {
|
|
5510
5979
|
...(_a = params.context) != null ? _a : {},
|
|
5511
5980
|
url: ctx.url,
|
|
@@ -5517,7 +5986,7 @@ function GlitchgrabProviderInner({
|
|
|
5517
5986
|
baseUrl
|
|
5518
5987
|
);
|
|
5519
5988
|
},
|
|
5520
|
-
[token, baseUrl]
|
|
5989
|
+
[token, baseUrl, session]
|
|
5521
5990
|
);
|
|
5522
5991
|
const transcribe = useCallback2(
|
|
5523
5992
|
async (blob) => {
|