glitchgrab 1.47.0 → 1.48.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 +271 -59
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +271 -59
- package/dist/index.mjs.map +1 -1
- package/dist/server.js.map +1 -1
- package/dist/server.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -73,6 +73,37 @@ var import_react6 = require("react");
|
|
|
73
73
|
// src/error-boundary.tsx
|
|
74
74
|
var React = __toESM(require("react"));
|
|
75
75
|
|
|
76
|
+
// ../report-ui/dist/assist-response.mjs
|
|
77
|
+
var ASSIST_OFFLINE_MESSAGE = "The assistant is unavailable \u2014 write your report below and send it as normal.";
|
|
78
|
+
function assistOffline() {
|
|
79
|
+
return { conversationId: null, question: null, report: null, degraded: ASSIST_OFFLINE_MESSAGE };
|
|
80
|
+
}
|
|
81
|
+
function toAssistTurnResult(ok, body) {
|
|
82
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
83
|
+
const envelope = body != null ? body : null;
|
|
84
|
+
if (!ok || !(envelope == null ? void 0 : envelope.success)) {
|
|
85
|
+
return {
|
|
86
|
+
...assistOffline(),
|
|
87
|
+
// The server words why (cap, rate limit, switched off). An hourly limit
|
|
88
|
+
// keeps the assistant button for this report.
|
|
89
|
+
degraded: (_a = envelope == null ? void 0 : envelope.error) != null ? _a : ASSIST_OFFLINE_MESSAGE,
|
|
90
|
+
retryable: (envelope == null ? void 0 : envelope.retryable) === true
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const d = (_b = envelope.data) != null ? _b : {};
|
|
94
|
+
return {
|
|
95
|
+
conversationId: (_c = d.conversationId) != null ? _c : null,
|
|
96
|
+
question: (_d = d.question) != null ? _d : null,
|
|
97
|
+
options: Array.isArray(d.options) ? d.options.filter((o) => typeof o === "string") : [],
|
|
98
|
+
report: (_e = d.report) != null ? _e : null,
|
|
99
|
+
duplicate: (_f = d.duplicate) != null ? _f : null,
|
|
100
|
+
related: (_g = d.related) != null ? _g : null,
|
|
101
|
+
solved: (_h = d.solved) != null ? _h : null,
|
|
102
|
+
aboutGlitchgrab: d.aboutGlitchgrab === true,
|
|
103
|
+
degraded: null
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
76
107
|
// src/redact.ts
|
|
77
108
|
var SENSITIVE_KEY_RE = /(pass|pwd|secret|token|auth|session|cookie|credential|apikey|api_key|access_key|private|signature|otp|pin|cvv|card|ssn|aadhaar|pan)/i;
|
|
78
109
|
var EMAIL_RE = /[\w.+-]+@[\w-]+\.[\w.-]+/g;
|
|
@@ -747,13 +778,7 @@ async function findSimilarIssues(description, token, baseUrl, identity) {
|
|
|
747
778
|
}
|
|
748
779
|
}
|
|
749
780
|
async function assistTurn(params, token, baseUrl) {
|
|
750
|
-
|
|
751
|
-
const offline = {
|
|
752
|
-
conversationId: null,
|
|
753
|
-
question: null,
|
|
754
|
-
report: null,
|
|
755
|
-
degraded: "The assistant is unavailable \u2014 write your report below and send it as normal."
|
|
756
|
-
};
|
|
781
|
+
const offline = assistOffline();
|
|
757
782
|
try {
|
|
758
783
|
const url = `${baseUrl != null ? baseUrl : DEFAULT_BASE_URL}/api/v1/ai/report-chat`;
|
|
759
784
|
const response = await fetch(url, {
|
|
@@ -764,28 +789,7 @@ async function assistTurn(params, token, baseUrl) {
|
|
|
764
789
|
},
|
|
765
790
|
body: JSON.stringify(params)
|
|
766
791
|
});
|
|
767
|
-
|
|
768
|
-
if (!response.ok || !(envelope == null ? void 0 : envelope.success)) {
|
|
769
|
-
return {
|
|
770
|
-
conversationId: null,
|
|
771
|
-
question: null,
|
|
772
|
-
report: null,
|
|
773
|
-
degraded: (_a = envelope == null ? void 0 : envelope.error) != null ? _a : offline.degraded,
|
|
774
|
-
// An hourly limit, not a cap: the dialog keeps the assistant button.
|
|
775
|
-
retryable: (envelope == null ? void 0 : envelope.retryable) === true
|
|
776
|
-
};
|
|
777
|
-
}
|
|
778
|
-
return {
|
|
779
|
-
conversationId: (_c = (_b = envelope.data) == null ? void 0 : _b.conversationId) != null ? _c : null,
|
|
780
|
-
question: (_e = (_d = envelope.data) == null ? void 0 : _d.question) != null ? _e : null,
|
|
781
|
-
options: (_g = (_f = envelope.data) == null ? void 0 : _f.options) != null ? _g : [],
|
|
782
|
-
report: (_i = (_h = envelope.data) == null ? void 0 : _h.report) != null ? _i : null,
|
|
783
|
-
duplicate: (_k = (_j = envelope.data) == null ? void 0 : _j.duplicate) != null ? _k : null,
|
|
784
|
-
related: (_m = (_l = envelope.data) == null ? void 0 : _l.related) != null ? _m : null,
|
|
785
|
-
solved: (_o = (_n = envelope.data) == null ? void 0 : _n.solved) != null ? _o : null,
|
|
786
|
-
aboutGlitchgrab: ((_p = envelope.data) == null ? void 0 : _p.aboutGlitchgrab) === true,
|
|
787
|
-
degraded: null
|
|
788
|
-
};
|
|
792
|
+
return toAssistTurnResult(response.ok, await response.json().catch(() => null));
|
|
789
793
|
} catch (e) {
|
|
790
794
|
return offline;
|
|
791
795
|
}
|
|
@@ -1475,6 +1479,17 @@ var STARTERS = [
|
|
|
1475
1479
|
"It did the wrong thing",
|
|
1476
1480
|
"I wish it could\u2026"
|
|
1477
1481
|
];
|
|
1482
|
+
var CONFIRM_OPTION = "Yes, that's it";
|
|
1483
|
+
function isCheckBackQuestion(text) {
|
|
1484
|
+
const t2 = text.trim();
|
|
1485
|
+
return /^so,? you['’]?re saying\b/i.test(t2) || /\b(is that right|is that correct|did i get (that|it) right|have i got (that|it) right)\s*\??\s*$/i.test(t2);
|
|
1486
|
+
}
|
|
1487
|
+
function isAffirmativeReply(text) {
|
|
1488
|
+
return /^(y|ya|yah|yes|yess|yeah|yep|yup|ok|okay|sure|correct|right|exactly|confirm(ed)?|that['’]?s (it|right|correct)|yes,? that['’]?s (it|right)|haan|han|ha|ho|hmm yes|👍)[\s.!👍]*$/i.test(
|
|
1489
|
+
text.trim()
|
|
1490
|
+
);
|
|
1491
|
+
}
|
|
1492
|
+
var AUTO_FILE_SECONDS = 4;
|
|
1478
1493
|
var NARROW_QUERY = "(max-width: 640px)";
|
|
1479
1494
|
function useIsNarrow() {
|
|
1480
1495
|
const [narrow, setNarrow] = (0, import_react3.useState)(false);
|
|
@@ -1589,12 +1604,15 @@ function AssistSheet({
|
|
|
1589
1604
|
const [duplicate, setDuplicate] = (0, import_react3.useState)(null);
|
|
1590
1605
|
const [glitchgrabOffer, setGlitchgrabOffer] = (0, import_react3.useState)(false);
|
|
1591
1606
|
const [solved, setSolved] = (0, import_react3.useState)(null);
|
|
1607
|
+
const needsSeverity = (tile) => showSeverity && tile === "BUG" && !severity;
|
|
1592
1608
|
const [phase, setPhase] = (0, import_react3.useState)(
|
|
1593
|
-
!typePicked ? "type" : currentTile === "RATING" ? "rating" : "chat"
|
|
1609
|
+
() => !typePicked ? "type" : currentTile === "RATING" ? "rating" : needsSeverity(currentTile) ? "severity" : "chat"
|
|
1594
1610
|
);
|
|
1611
|
+
const [autoFileLeft, setAutoFileLeft] = (0, import_react3.useState)(null);
|
|
1595
1612
|
const scrollRef = (0, import_react3.useRef)(null);
|
|
1596
1613
|
const draftRef = (0, import_react3.useRef)(null);
|
|
1597
1614
|
const seededRef = (0, import_react3.useRef)(false);
|
|
1615
|
+
const seedPendingRef = (0, import_react3.useRef)(false);
|
|
1598
1616
|
const eventsRef = (0, import_react3.useRef)([]);
|
|
1599
1617
|
const aiDraftRef = (0, import_react3.useRef)(null);
|
|
1600
1618
|
function logEvent(type, detail) {
|
|
@@ -1634,14 +1652,33 @@ function AssistSheet({
|
|
|
1634
1652
|
var _a;
|
|
1635
1653
|
if (phase === "draft") (_a = draftRef.current) == null ? void 0 : _a.focus();
|
|
1636
1654
|
}, [phase]);
|
|
1655
|
+
(0, import_react3.useEffect)(() => {
|
|
1656
|
+
if (autoFileLeft === null) return;
|
|
1657
|
+
if (isSubmitting || submitted || phase !== "draft") {
|
|
1658
|
+
setAutoFileLeft(null);
|
|
1659
|
+
return;
|
|
1660
|
+
}
|
|
1661
|
+
if (autoFileLeft <= 0) {
|
|
1662
|
+
sendDraft(true);
|
|
1663
|
+
return;
|
|
1664
|
+
}
|
|
1665
|
+
const id = setTimeout(() => setAutoFileLeft((n) => n === null ? null : n - 1), 1e3);
|
|
1666
|
+
return () => clearTimeout(id);
|
|
1667
|
+
}, [autoFileLeft, isSubmitting, submitted, phase]);
|
|
1668
|
+
function stopAutoFile(reason) {
|
|
1669
|
+
if (autoFileLeft === null) return;
|
|
1670
|
+
setAutoFileLeft(null);
|
|
1671
|
+
logEvent("auto_file_stopped", reason);
|
|
1672
|
+
}
|
|
1637
1673
|
function degradeKeepingEvents(events, message, retryable) {
|
|
1638
1674
|
if (events) eventsRef.current = [...events, ...eventsRef.current];
|
|
1639
1675
|
flushEvents();
|
|
1640
1676
|
onDegrade(message, retryable);
|
|
1641
1677
|
}
|
|
1642
|
-
async function runTurn(history2) {
|
|
1678
|
+
async function runTurn(history2, autoFile = false) {
|
|
1643
1679
|
var _a, _b;
|
|
1644
1680
|
setBusy(true);
|
|
1681
|
+
setAutoFileLeft(null);
|
|
1645
1682
|
let result;
|
|
1646
1683
|
const events = takeEvents();
|
|
1647
1684
|
try {
|
|
@@ -1701,6 +1738,9 @@ function AssistSheet({
|
|
|
1701
1738
|
setMessages([...history2, { role: "assistant", content: result.report, kind: "report" }]);
|
|
1702
1739
|
setOptions([]);
|
|
1703
1740
|
setPhase("draft");
|
|
1741
|
+
if (autoFile && !attach && !(severityAsked && !severity)) {
|
|
1742
|
+
setAutoFileLeft(AUTO_FILE_SECONDS);
|
|
1743
|
+
}
|
|
1704
1744
|
return;
|
|
1705
1745
|
}
|
|
1706
1746
|
if (result.question) {
|
|
@@ -1714,13 +1754,34 @@ function AssistSheet({
|
|
|
1714
1754
|
if (seededRef.current) return;
|
|
1715
1755
|
seededRef.current = true;
|
|
1716
1756
|
if (!typePicked || currentTile === "RATING") return;
|
|
1757
|
+
if (phase === "severity") {
|
|
1758
|
+
seedPendingRef.current = true;
|
|
1759
|
+
return;
|
|
1760
|
+
}
|
|
1761
|
+
seedFromDescription();
|
|
1762
|
+
}, []);
|
|
1763
|
+
function seedFromDescription() {
|
|
1717
1764
|
const seed = description.trim();
|
|
1718
1765
|
if (!seed) return;
|
|
1719
1766
|
const history2 = [{ role: "user", content: seed }];
|
|
1720
1767
|
setMessages(history2);
|
|
1721
1768
|
void runTurn(history2);
|
|
1722
|
-
}
|
|
1723
|
-
function
|
|
1769
|
+
}
|
|
1770
|
+
function answerSeverity(value) {
|
|
1771
|
+
onSeverityChange(value);
|
|
1772
|
+
setPhase("chat");
|
|
1773
|
+
if (seedPendingRef.current) {
|
|
1774
|
+
seedPendingRef.current = false;
|
|
1775
|
+
seedFromDescription();
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
function sendTyped(text) {
|
|
1779
|
+
var _a;
|
|
1780
|
+
const lastAssistant = [...messages].reverse().find((m) => m.role === "assistant");
|
|
1781
|
+
const checkingBack = options.includes(CONFIRM_OPTION) || (lastAssistant == null ? void 0 : lastAssistant.kind) !== "report" && isCheckBackQuestion((_a = lastAssistant == null ? void 0 : lastAssistant.content) != null ? _a : "");
|
|
1782
|
+
send(text, checkingBack && isAffirmativeReply(text));
|
|
1783
|
+
}
|
|
1784
|
+
function send(text, autoFile = false) {
|
|
1724
1785
|
const value = text.trim();
|
|
1725
1786
|
if (!value || busy) return;
|
|
1726
1787
|
setOptions([]);
|
|
@@ -1735,11 +1796,11 @@ function AssistSheet({
|
|
|
1735
1796
|
const history2 = [...base, { role: "user", content: value }];
|
|
1736
1797
|
setMessages(history2);
|
|
1737
1798
|
setInput("");
|
|
1738
|
-
void runTurn(history2);
|
|
1799
|
+
void runTurn(history2, autoFile);
|
|
1739
1800
|
}
|
|
1740
1801
|
function pickType(tile) {
|
|
1741
1802
|
onPickType(tile);
|
|
1742
|
-
setPhase(tile === "RATING" ? "rating" : "chat");
|
|
1803
|
+
setPhase(tile === "RATING" ? "rating" : needsSeverity(tile) ? "severity" : "chat");
|
|
1743
1804
|
}
|
|
1744
1805
|
function withCurrentDraft(history2) {
|
|
1745
1806
|
const current = description.trim();
|
|
@@ -1752,9 +1813,10 @@ function AssistSheet({
|
|
|
1752
1813
|
}
|
|
1753
1814
|
return next;
|
|
1754
1815
|
}
|
|
1755
|
-
function sendDraft() {
|
|
1816
|
+
function sendDraft(auto = false) {
|
|
1817
|
+
setAutoFileLeft(null);
|
|
1756
1818
|
const edited = aiDraftRef.current !== null && description.trim() !== aiDraftRef.current.trim();
|
|
1757
|
-
logEvent("draft_sent", edited ? "edited" : "as drafted");
|
|
1819
|
+
logEvent("draft_sent", auto ? "auto-filed" : edited ? "edited" : "as drafted");
|
|
1758
1820
|
flushEvents();
|
|
1759
1821
|
onSend();
|
|
1760
1822
|
}
|
|
@@ -1814,6 +1876,7 @@ function AssistSheet({
|
|
|
1814
1876
|
@keyframes gg-sheet-in{from{transform:translateX(24px);opacity:0}to{transform:translateX(0);opacity:1}}
|
|
1815
1877
|
@keyframes gg-sheet-up{from{transform:translateY(24px);opacity:0}to{transform:translateY(0);opacity:1}}
|
|
1816
1878
|
@keyframes gg-sheet-fade{from{opacity:0}to{opacity:1}}
|
|
1879
|
+
@keyframes gg-autofile{from{transform:scaleX(0)}to{transform:scaleX(1)}}
|
|
1817
1880
|
@keyframes gg-dot{0%,80%,100%{transform:translateY(0);opacity:.4}40%{transform:translateY(-3px);opacity:1}}
|
|
1818
1881
|
[data-gg-sheet-send]:focus-visible,[data-gg-chip]:focus-visible,[data-gg-assist-remove]:focus-visible{outline:2px solid currentColor;outline-offset:2px}
|
|
1819
1882
|
` }),
|
|
@@ -1908,6 +1971,7 @@ function AssistSheet({
|
|
|
1908
1971
|
),
|
|
1909
1972
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { fontSize: "11.5px", color: t2.textMuted, marginTop: "3px" }, children: [
|
|
1910
1973
|
phase === "type" ? null : reportTypeLabel,
|
|
1974
|
+
phase !== "type" && severityAsked && severity ? ` \xB7 ${SEVERITY_LABELS[severity]}` : null,
|
|
1911
1975
|
projectSlot ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { marginLeft: "6px" }, children: projectSlot }) : null
|
|
1912
1976
|
] })
|
|
1913
1977
|
] }),
|
|
@@ -2026,6 +2090,62 @@ function AssistSheet({
|
|
|
2026
2090
|
}
|
|
2027
2091
|
)
|
|
2028
2092
|
] }),
|
|
2093
|
+
phase === "severity" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
|
|
2094
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
2095
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Avatar, { who: "assistant", theme: t2 }),
|
|
2096
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2097
|
+
"div",
|
|
2098
|
+
{
|
|
2099
|
+
style: {
|
|
2100
|
+
padding: "9px 12px",
|
|
2101
|
+
borderRadius: "12px 12px 12px 4px",
|
|
2102
|
+
backgroundColor: t2.bgSecondary,
|
|
2103
|
+
fontSize: "13px",
|
|
2104
|
+
lineHeight: 1.55,
|
|
2105
|
+
maxWidth: "88%"
|
|
2106
|
+
},
|
|
2107
|
+
children: "How bad is it?"
|
|
2108
|
+
}
|
|
2109
|
+
)
|
|
2110
|
+
] }),
|
|
2111
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2112
|
+
"div",
|
|
2113
|
+
{
|
|
2114
|
+
role: "radiogroup",
|
|
2115
|
+
"aria-label": "Severity",
|
|
2116
|
+
style: {
|
|
2117
|
+
display: "flex",
|
|
2118
|
+
flexWrap: "wrap",
|
|
2119
|
+
gap: "6px",
|
|
2120
|
+
paddingLeft: "32px"
|
|
2121
|
+
},
|
|
2122
|
+
children: SEVERITY_LEVELS.map((s) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2123
|
+
"button",
|
|
2124
|
+
{
|
|
2125
|
+
type: "button",
|
|
2126
|
+
role: "radio",
|
|
2127
|
+
"aria-checked": severity === s,
|
|
2128
|
+
"data-gg-chip": "",
|
|
2129
|
+
"data-gg-severity": s,
|
|
2130
|
+
onClick: () => answerSeverity(s),
|
|
2131
|
+
style: {
|
|
2132
|
+
border: `1px solid ${t2.inputBorder}`,
|
|
2133
|
+
background: "transparent",
|
|
2134
|
+
color: t2.textMuted,
|
|
2135
|
+
borderRadius: "999px",
|
|
2136
|
+
// Same as the picker and option chips — one chip size.
|
|
2137
|
+
padding: "8px 12px",
|
|
2138
|
+
fontSize: "12px",
|
|
2139
|
+
fontFamily: "inherit",
|
|
2140
|
+
cursor: "pointer"
|
|
2141
|
+
},
|
|
2142
|
+
children: SEVERITY_LABELS[s]
|
|
2143
|
+
},
|
|
2144
|
+
s
|
|
2145
|
+
))
|
|
2146
|
+
}
|
|
2147
|
+
)
|
|
2148
|
+
] }),
|
|
2029
2149
|
phase === "rating" && !submitted && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
|
|
2030
2150
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
2031
2151
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Avatar, { who: "assistant", theme: t2 }),
|
|
@@ -2214,7 +2334,11 @@ function AssistSheet({
|
|
|
2214
2334
|
color: t2.text,
|
|
2215
2335
|
border: live ? "none" : `1px solid ${t2.accent}66`
|
|
2216
2336
|
},
|
|
2217
|
-
children: live ?
|
|
2337
|
+
children: live ? (
|
|
2338
|
+
// #402: "have a read" beside a countdown reads as a
|
|
2339
|
+
// contradiction. Say what is about to happen instead.
|
|
2340
|
+
autoFileLeft !== null ? "Here's your report \u2014 I'll file it unless you want to change something." : "Here's your report \u2014 have a read."
|
|
2341
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
2218
2342
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2219
2343
|
"span",
|
|
2220
2344
|
{
|
|
@@ -2381,7 +2505,7 @@ function AssistSheet({
|
|
|
2381
2505
|
"data-gg-option": "",
|
|
2382
2506
|
onClick: () => {
|
|
2383
2507
|
logEvent("option_tap", option);
|
|
2384
|
-
send(option);
|
|
2508
|
+
send(option, option === CONFIRM_OPTION);
|
|
2385
2509
|
},
|
|
2386
2510
|
style: {
|
|
2387
2511
|
border: `1px solid ${t2.inputBorder}`,
|
|
@@ -2468,7 +2592,10 @@ function AssistSheet({
|
|
|
2468
2592
|
{
|
|
2469
2593
|
ref: draftRef,
|
|
2470
2594
|
value: description,
|
|
2471
|
-
onChange: (e) =>
|
|
2595
|
+
onChange: (e) => {
|
|
2596
|
+
stopAutoFile("edited the draft");
|
|
2597
|
+
onDescriptionChange(e.target.value);
|
|
2598
|
+
},
|
|
2472
2599
|
rows: 6,
|
|
2473
2600
|
style: {
|
|
2474
2601
|
width: "100%",
|
|
@@ -2487,7 +2614,7 @@ function AssistSheet({
|
|
|
2487
2614
|
}
|
|
2488
2615
|
}
|
|
2489
2616
|
),
|
|
2490
|
-
severityAsked && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
2617
|
+
severityAsked && autoFileLeft === null && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
2491
2618
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
2492
2619
|
"span",
|
|
2493
2620
|
{
|
|
@@ -2609,7 +2736,7 @@ function AssistSheet({
|
|
|
2609
2736
|
)
|
|
2610
2737
|
}
|
|
2611
2738
|
),
|
|
2612
|
-
!submitted && phase !== "type" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
2739
|
+
!submitted && phase !== "type" && phase !== "severity" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
2613
2740
|
"div",
|
|
2614
2741
|
{
|
|
2615
2742
|
style: {
|
|
@@ -2716,6 +2843,7 @@ function AssistSheet({
|
|
|
2716
2843
|
"aria-label": `Remove image ${i + 1}`,
|
|
2717
2844
|
title: "Remove this image",
|
|
2718
2845
|
onClick: () => {
|
|
2846
|
+
stopAutoFile("changed attachments");
|
|
2719
2847
|
logEvent(
|
|
2720
2848
|
"image_removed",
|
|
2721
2849
|
pageShot && shot === pageShot ? "page capture" : "attached"
|
|
@@ -2826,6 +2954,7 @@ function AssistSheet({
|
|
|
2826
2954
|
"aria-label": `Remove file ${file.name}`,
|
|
2827
2955
|
title: "Remove this file",
|
|
2828
2956
|
onClick: () => {
|
|
2957
|
+
stopAutoFile("changed attachments");
|
|
2829
2958
|
logEvent("file_removed", read ? "read" : "not read");
|
|
2830
2959
|
onRemoveFile(i);
|
|
2831
2960
|
},
|
|
@@ -2908,6 +3037,7 @@ function AssistSheet({
|
|
|
2908
3037
|
var _a;
|
|
2909
3038
|
const picked = Array.from((_a = e.target.files) != null ? _a : []);
|
|
2910
3039
|
if (picked.length) {
|
|
3040
|
+
stopAutoFile("changed attachments");
|
|
2911
3041
|
const images = picked.filter((f) => f.type.startsWith("image/")).length;
|
|
2912
3042
|
if (images) logEvent("image_added", String(images));
|
|
2913
3043
|
if (picked.length > images) {
|
|
@@ -2937,11 +3067,14 @@ function AssistSheet({
|
|
|
2937
3067
|
"textarea",
|
|
2938
3068
|
{
|
|
2939
3069
|
value: input,
|
|
2940
|
-
onChange: (e) =>
|
|
3070
|
+
onChange: (e) => {
|
|
3071
|
+
stopAutoFile("typing a change");
|
|
3072
|
+
setInput(e.target.value);
|
|
3073
|
+
},
|
|
2941
3074
|
onKeyDown: (e) => {
|
|
2942
3075
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
2943
3076
|
e.preventDefault();
|
|
2944
|
-
|
|
3077
|
+
sendTyped(input);
|
|
2945
3078
|
}
|
|
2946
3079
|
},
|
|
2947
3080
|
placeholder: phase === "draft" ? "Anything to change? Tell me here\u2026" : "Type your answer\u2026",
|
|
@@ -2971,7 +3104,7 @@ function AssistSheet({
|
|
|
2971
3104
|
{
|
|
2972
3105
|
type: "button",
|
|
2973
3106
|
"data-gg-sheet-send": "",
|
|
2974
|
-
onClick: () =>
|
|
3107
|
+
onClick: () => sendTyped(input),
|
|
2975
3108
|
disabled: busy || !input.trim(),
|
|
2976
3109
|
"aria-label": "Send message",
|
|
2977
3110
|
"data-gg-send-message": "",
|
|
@@ -3010,12 +3143,87 @@ function AssistSheet({
|
|
|
3010
3143
|
children: validationError
|
|
3011
3144
|
}
|
|
3012
3145
|
),
|
|
3013
|
-
|
|
3146
|
+
autoFileLeft !== null ? (
|
|
3147
|
+
// #402: "Yes, that's it" was the confirmation. The draft
|
|
3148
|
+
// files itself unless they stop it — the bar shows how
|
|
3149
|
+
// long is left, the button sends now.
|
|
3150
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "8px", marginTop: "8px" }, children: [
|
|
3151
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
3152
|
+
"button",
|
|
3153
|
+
{
|
|
3154
|
+
type: "button",
|
|
3155
|
+
"data-gg-sheet-send": "",
|
|
3156
|
+
"data-gg-auto-file": "",
|
|
3157
|
+
onClick: () => sendDraft(),
|
|
3158
|
+
style: {
|
|
3159
|
+
flex: 1,
|
|
3160
|
+
minWidth: 0,
|
|
3161
|
+
position: "relative",
|
|
3162
|
+
overflow: "hidden",
|
|
3163
|
+
padding: "12px",
|
|
3164
|
+
borderRadius: "10px",
|
|
3165
|
+
border: "none",
|
|
3166
|
+
backgroundColor: t2.accent,
|
|
3167
|
+
color: t2.accentText,
|
|
3168
|
+
fontSize: "14px",
|
|
3169
|
+
fontWeight: 700,
|
|
3170
|
+
fontFamily: "inherit",
|
|
3171
|
+
cursor: "pointer"
|
|
3172
|
+
},
|
|
3173
|
+
children: [
|
|
3174
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
3175
|
+
"span",
|
|
3176
|
+
{
|
|
3177
|
+
"aria-hidden": "true",
|
|
3178
|
+
style: {
|
|
3179
|
+
position: "absolute",
|
|
3180
|
+
inset: 0,
|
|
3181
|
+
backgroundColor: "rgba(255,255,255,0.22)",
|
|
3182
|
+
transformOrigin: "left",
|
|
3183
|
+
animation: `gg-autofile ${AUTO_FILE_SECONDS}s linear forwards`
|
|
3184
|
+
}
|
|
3185
|
+
}
|
|
3186
|
+
),
|
|
3187
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: { position: "relative" }, children: [
|
|
3188
|
+
"Filing in ",
|
|
3189
|
+
autoFileLeft,
|
|
3190
|
+
"s\u2026"
|
|
3191
|
+
] })
|
|
3192
|
+
]
|
|
3193
|
+
}
|
|
3194
|
+
),
|
|
3195
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
3196
|
+
"button",
|
|
3197
|
+
{
|
|
3198
|
+
type: "button",
|
|
3199
|
+
"data-gg-edit-first": "",
|
|
3200
|
+
onClick: () => {
|
|
3201
|
+
var _a;
|
|
3202
|
+
stopAutoFile("edit first");
|
|
3203
|
+
(_a = draftRef.current) == null ? void 0 : _a.focus();
|
|
3204
|
+
},
|
|
3205
|
+
style: {
|
|
3206
|
+
flexShrink: 0,
|
|
3207
|
+
padding: "12px 14px",
|
|
3208
|
+
borderRadius: "10px",
|
|
3209
|
+
border: `1px solid ${t2.inputBorder}`,
|
|
3210
|
+
background: "transparent",
|
|
3211
|
+
color: t2.text,
|
|
3212
|
+
fontSize: "13px",
|
|
3213
|
+
fontWeight: 600,
|
|
3214
|
+
fontFamily: "inherit",
|
|
3215
|
+
cursor: "pointer"
|
|
3216
|
+
},
|
|
3217
|
+
children: "Edit first"
|
|
3218
|
+
}
|
|
3219
|
+
)
|
|
3220
|
+
] })
|
|
3221
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
3014
3222
|
"button",
|
|
3015
3223
|
{
|
|
3016
3224
|
type: "button",
|
|
3017
3225
|
"data-gg-sheet-send": "",
|
|
3018
|
-
onClick: sendDraft,
|
|
3226
|
+
onClick: () => sendDraft(),
|
|
3019
3227
|
disabled: isSubmitting || !description.trim(),
|
|
3020
3228
|
style: {
|
|
3021
3229
|
width: "100%",
|
|
@@ -3991,9 +4199,11 @@ function ReportDialog({
|
|
|
3991
4199
|
reporter,
|
|
3992
4200
|
onClose,
|
|
3993
4201
|
headerSlot,
|
|
3994
|
-
reportGlitchgrabProblem
|
|
4202
|
+
reportGlitchgrabProblem,
|
|
4203
|
+
layout = "modal"
|
|
3995
4204
|
}) {
|
|
3996
4205
|
var _a;
|
|
4206
|
+
const sheet = layout === "sheet";
|
|
3997
4207
|
const [isEnhancing, setIsEnhancing] = (0, import_react.useState)(false);
|
|
3998
4208
|
const [assistOpen, setAssistOpen] = (0, import_react.useState)(false);
|
|
3999
4209
|
const [assistNotice, setAssistNotice] = (0, import_react.useState)(null);
|
|
@@ -4801,8 +5011,8 @@ function ReportDialog({
|
|
|
4801
5011
|
// dialog's state IS the report, and unmounting would drop the
|
|
4802
5012
|
// screenshots, attachments and step the reporter is on.
|
|
4803
5013
|
display: sheetUp ? "none" : "flex",
|
|
4804
|
-
alignItems: "center",
|
|
4805
|
-
justifyContent: "center",
|
|
5014
|
+
alignItems: sheet ? "stretch" : "center",
|
|
5015
|
+
justifyContent: sheet ? "flex-end" : "center",
|
|
4806
5016
|
backgroundColor: "rgba(0,0,0,0.5)",
|
|
4807
5017
|
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
|
|
4808
5018
|
},
|
|
@@ -4822,14 +5032,15 @@ function ReportDialog({
|
|
|
4822
5032
|
style: {
|
|
4823
5033
|
position: "relative",
|
|
4824
5034
|
zIndex: 2147483647,
|
|
4825
|
-
width: "420px",
|
|
4826
|
-
maxWidth: "calc(100% - 32px)",
|
|
4827
|
-
maxHeight: "calc(100dvh - 32px)",
|
|
5035
|
+
width: sheet ? "440px" : "420px",
|
|
5036
|
+
maxWidth: sheet ? "100%" : "calc(100% - 32px)",
|
|
5037
|
+
maxHeight: sheet ? "100dvh" : "calc(100dvh - 32px)",
|
|
5038
|
+
...sheet ? { height: "100dvh", borderLeft: `1px solid ${t2.inputBorder}` } : {},
|
|
4828
5039
|
display: "flex",
|
|
4829
5040
|
flexDirection: "column",
|
|
4830
5041
|
backgroundColor: t2.bg,
|
|
4831
|
-
borderRadius: "12px",
|
|
4832
|
-
boxShadow: "0 20px 60px rgba(0, 0, 0, 0.2), 0 4px 16px rgba(0, 0, 0, 0.1)",
|
|
5042
|
+
borderRadius: sheet ? 0 : "12px",
|
|
5043
|
+
boxShadow: sheet ? "0 20px 60px rgba(0, 0, 0, 0.35)" : "0 20px 60px rgba(0, 0, 0, 0.2), 0 4px 16px rgba(0, 0, 0, 0.1)",
|
|
4833
5044
|
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
4834
5045
|
overflow: "hidden",
|
|
4835
5046
|
color: t2.text,
|
|
@@ -4863,7 +5074,7 @@ function ReportDialog({
|
|
|
4863
5074
|
gap: "8px"
|
|
4864
5075
|
},
|
|
4865
5076
|
children: [
|
|
4866
|
-
step > 1 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
5077
|
+
step > 1 && availableTypes.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
4867
5078
|
"button",
|
|
4868
5079
|
{
|
|
4869
5080
|
type: "button",
|
|
@@ -4981,7 +5192,7 @@ function ReportDialog({
|
|
|
4981
5192
|
]
|
|
4982
5193
|
}
|
|
4983
5194
|
),
|
|
4984
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
5195
|
+
availableTypes.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
4985
5196
|
"div",
|
|
4986
5197
|
{
|
|
4987
5198
|
style: {
|
|
@@ -5257,6 +5468,7 @@ function ReportDialog({
|
|
|
5257
5468
|
"button",
|
|
5258
5469
|
{
|
|
5259
5470
|
type: "button",
|
|
5471
|
+
disabled: availableTypes.length === 1,
|
|
5260
5472
|
onClick: () => setStep(1),
|
|
5261
5473
|
style: {
|
|
5262
5474
|
display: "inline-flex",
|
|
@@ -5271,12 +5483,12 @@ function ReportDialog({
|
|
|
5271
5483
|
fontSize: "11px",
|
|
5272
5484
|
fontWeight: 600,
|
|
5273
5485
|
fontFamily: "inherit",
|
|
5274
|
-
cursor: "pointer"
|
|
5486
|
+
cursor: availableTypes.length === 1 ? "default" : "pointer"
|
|
5275
5487
|
},
|
|
5276
5488
|
children: [
|
|
5277
5489
|
getTypeIcon(reportType, isRating ? "#f59e0b" : t2.accent, 13),
|
|
5278
5490
|
getTypeLabel(reportType),
|
|
5279
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { color: t2.textMuted, fontWeight: 400 }, children: "\xB7 change" })
|
|
5491
|
+
availableTypes.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { color: t2.textMuted, fontWeight: 400 }, children: "\xB7 change" })
|
|
5280
5492
|
]
|
|
5281
5493
|
}
|
|
5282
5494
|
),
|