glitchgrab 1.58.1 → 1.58.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -0
- package/dist/index.d.mts +21 -3
- package/dist/index.d.ts +21 -3
- package/dist/index.js +2205 -1281
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2204 -1281
- package/dist/index.mjs.map +1 -1
- package/dist/server.d.mts +41 -3
- package/dist/server.d.ts +41 -3
- package/dist/server.js +49 -15
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +47 -15
- package/dist/server.mjs.map +1 -1
- package/dist/{types-DfVtKZcp.d.mts → types-BpTLWJ1y.d.mts} +8 -0
- package/dist/{types-DfVtKZcp.d.ts → types-BpTLWJ1y.d.ts} +8 -0
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -178,7 +178,7 @@ function argsToString(args) {
|
|
|
178
178
|
function previewJson(value, max) {
|
|
179
179
|
let out = "";
|
|
180
180
|
const path = /* @__PURE__ */ new WeakSet();
|
|
181
|
-
const
|
|
181
|
+
const write2 = (input, inArray) => {
|
|
182
182
|
if (out.length > max) return;
|
|
183
183
|
let v = input;
|
|
184
184
|
if (v !== null && typeof v === "object" && typeof v.toJSON === "function") {
|
|
@@ -215,7 +215,7 @@ function previewJson(value, max) {
|
|
|
215
215
|
out += "[";
|
|
216
216
|
for (let i = 0; i < obj.length && out.length <= max; i++) {
|
|
217
217
|
if (i > 0) out += ",";
|
|
218
|
-
|
|
218
|
+
write2(obj[i], true);
|
|
219
219
|
}
|
|
220
220
|
out += "]";
|
|
221
221
|
} else {
|
|
@@ -228,13 +228,13 @@ function previewJson(value, max) {
|
|
|
228
228
|
if (child === void 0 || typeof child === "function" || typeof child === "symbol") continue;
|
|
229
229
|
out += `${first ? "" : ","}${JSON.stringify(key)}:`;
|
|
230
230
|
first = false;
|
|
231
|
-
|
|
231
|
+
write2(child, false);
|
|
232
232
|
}
|
|
233
233
|
out += "}";
|
|
234
234
|
}
|
|
235
235
|
path.delete(obj);
|
|
236
236
|
};
|
|
237
|
-
|
|
237
|
+
write2(value, false);
|
|
238
238
|
return out;
|
|
239
239
|
}
|
|
240
240
|
async function readErrorBody(response, url) {
|
|
@@ -587,6 +587,9 @@ function contextMetadata(context) {
|
|
|
587
587
|
var DEFAULT_BASE_URL = "https://glitchgrab.dev";
|
|
588
588
|
var MAX_RETRIES = 3;
|
|
589
589
|
var RETRY_BASE_MS = 500;
|
|
590
|
+
function reportAttemptTimeoutMs(bodyLength) {
|
|
591
|
+
return 1e4 + Math.ceil(bodyLength / 1e5) * 1e3;
|
|
592
|
+
}
|
|
590
593
|
async function sendReport(payload, baseUrl) {
|
|
591
594
|
var _a;
|
|
592
595
|
try {
|
|
@@ -597,13 +600,18 @@ async function sendReport(payload, baseUrl) {
|
|
|
597
600
|
Authorization: `Bearer ${payload.token}`
|
|
598
601
|
};
|
|
599
602
|
const useKeepalive = body.length < 6e4;
|
|
603
|
+
const timeoutMs = reportAttemptTimeoutMs(body.length);
|
|
600
604
|
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
|
|
605
|
+
const isLast = attempt === MAX_RETRIES - 1;
|
|
606
|
+
const controller = !isLast && typeof AbortController === "function" ? new AbortController() : null;
|
|
607
|
+
const timer = controller ? setTimeout(() => controller.abort(), timeoutMs) : null;
|
|
601
608
|
try {
|
|
602
609
|
const response = await fetch(url, {
|
|
603
610
|
method: "POST",
|
|
604
611
|
headers,
|
|
605
612
|
body,
|
|
606
|
-
...useKeepalive ? { keepalive: true } : {}
|
|
613
|
+
...useKeepalive ? { keepalive: true } : {},
|
|
614
|
+
...controller ? { signal: controller.signal } : {}
|
|
607
615
|
});
|
|
608
616
|
if (response.ok) {
|
|
609
617
|
const envelope = await response.json();
|
|
@@ -613,6 +621,8 @@ async function sendReport(payload, baseUrl) {
|
|
|
613
621
|
return null;
|
|
614
622
|
}
|
|
615
623
|
} catch (e) {
|
|
624
|
+
} finally {
|
|
625
|
+
if (timer) clearTimeout(timer);
|
|
616
626
|
}
|
|
617
627
|
if (attempt < MAX_RETRIES - 1) {
|
|
618
628
|
await new Promise(
|
|
@@ -729,7 +739,7 @@ async function enhanceText(text, token, baseUrl, screenshot, context, identity)
|
|
|
729
739
|
return text;
|
|
730
740
|
}
|
|
731
741
|
}
|
|
732
|
-
async function findSimilarIssues(description, token, baseUrl, identity) {
|
|
742
|
+
async function findSimilarIssues(description, token, baseUrl, identity, files) {
|
|
733
743
|
var _a;
|
|
734
744
|
try {
|
|
735
745
|
const url = `${baseUrl != null ? baseUrl : DEFAULT_BASE_URL}/api/v1/reports/similar`;
|
|
@@ -739,7 +749,11 @@ async function findSimilarIssues(description, token, baseUrl, identity) {
|
|
|
739
749
|
"Content-Type": "application/json",
|
|
740
750
|
Authorization: `Bearer ${token}`
|
|
741
751
|
},
|
|
742
|
-
body: JSON.stringify({
|
|
752
|
+
body: JSON.stringify({
|
|
753
|
+
text: description,
|
|
754
|
+
...(files == null ? void 0 : files.length) ? { files } : {},
|
|
755
|
+
...signedFields(identity)
|
|
756
|
+
})
|
|
743
757
|
});
|
|
744
758
|
const envelope = await response.json().catch(() => null);
|
|
745
759
|
if (!response.ok || !(envelope == null ? void 0 : envelope.success)) return null;
|
|
@@ -749,6 +763,25 @@ async function findSimilarIssues(description, token, baseUrl, identity) {
|
|
|
749
763
|
return null;
|
|
750
764
|
}
|
|
751
765
|
}
|
|
766
|
+
async function readAttachment(file, token, baseUrl, identity) {
|
|
767
|
+
var _a;
|
|
768
|
+
try {
|
|
769
|
+
const url = `${baseUrl != null ? baseUrl : DEFAULT_BASE_URL}/api/v1/ai/read-file`;
|
|
770
|
+
const response = await fetch(url, {
|
|
771
|
+
method: "POST",
|
|
772
|
+
headers: {
|
|
773
|
+
"Content-Type": "application/json",
|
|
774
|
+
Authorization: `Bearer ${token}`
|
|
775
|
+
},
|
|
776
|
+
body: JSON.stringify({ name: file.name, data: file.dataUrl, ...signedFields(identity) })
|
|
777
|
+
});
|
|
778
|
+
const envelope = await response.json().catch(() => null);
|
|
779
|
+
if (!response.ok || !(envelope == null ? void 0 : envelope.success) || !((_a = envelope.data) == null ? void 0 : _a.enabled)) return null;
|
|
780
|
+
return typeof envelope.data.text === "string" ? envelope.data.text : null;
|
|
781
|
+
} catch (e) {
|
|
782
|
+
return null;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
752
785
|
async function assistTurn(params, token, baseUrl) {
|
|
753
786
|
const offline = assistOffline();
|
|
754
787
|
try {
|
|
@@ -862,6 +895,292 @@ function clearDedupCache() {
|
|
|
862
895
|
seen.clear();
|
|
863
896
|
}
|
|
864
897
|
|
|
898
|
+
// src/hydration.ts
|
|
899
|
+
var HYDRATION_CODE_RE = /Minified React error #(418|419|422|423|425)\b/;
|
|
900
|
+
var HYDRATION_DEV_RE = /Hydration failed|hydration mismatch|Text content does not match|did not match\. Server|There was an error while hydrating|error occurred during hydration|server rendered HTML didn't match/i;
|
|
901
|
+
var BAILOUT_DIGEST = "BAILOUT_TO_CLIENT_SIDE_RENDERING";
|
|
902
|
+
var DOM_SNIPPET_MAX = 3e3;
|
|
903
|
+
var STACK_FRAMES_MAX = 40;
|
|
904
|
+
function messageOf(error) {
|
|
905
|
+
if (error && typeof error === "object" && typeof error.message === "string") {
|
|
906
|
+
return error.message;
|
|
907
|
+
}
|
|
908
|
+
return typeof error === "string" ? error : "";
|
|
909
|
+
}
|
|
910
|
+
function hydrationCode(message) {
|
|
911
|
+
if (!message) return null;
|
|
912
|
+
const m = HYDRATION_CODE_RE.exec(message);
|
|
913
|
+
if (m) return m[1];
|
|
914
|
+
return HYDRATION_DEV_RE.test(message) ? "dev" : null;
|
|
915
|
+
}
|
|
916
|
+
function isHydrationError(error) {
|
|
917
|
+
if (hydrationCode(messageOf(error))) return true;
|
|
918
|
+
const cause = error && typeof error === "object" ? error.cause : void 0;
|
|
919
|
+
return cause !== void 0 && cause !== error && hydrationCode(messageOf(cause)) !== null;
|
|
920
|
+
}
|
|
921
|
+
function isBailout(error) {
|
|
922
|
+
const e = error;
|
|
923
|
+
if (!e || typeof e !== "object") return false;
|
|
924
|
+
if (e.digest === BAILOUT_DIGEST) return true;
|
|
925
|
+
const c = e.cause;
|
|
926
|
+
return !!c && typeof c === "object" && c.digest === BAILOUT_DIGEST;
|
|
927
|
+
}
|
|
928
|
+
function componentStackNames(stack) {
|
|
929
|
+
if (!stack) return [];
|
|
930
|
+
const names = [];
|
|
931
|
+
for (const raw of stack.split("\n")) {
|
|
932
|
+
const line = raw.trim();
|
|
933
|
+
if (!line) continue;
|
|
934
|
+
let name = "";
|
|
935
|
+
if (line.startsWith("at ")) {
|
|
936
|
+
name = line.slice(3).split(" (")[0].trim();
|
|
937
|
+
} else if (line.includes("@")) {
|
|
938
|
+
name = line.slice(0, line.indexOf("@")).trim();
|
|
939
|
+
} else {
|
|
940
|
+
name = line;
|
|
941
|
+
}
|
|
942
|
+
if (name) names.push(name);
|
|
943
|
+
if (names.length >= STACK_FRAMES_MAX) break;
|
|
944
|
+
}
|
|
945
|
+
return names;
|
|
946
|
+
}
|
|
947
|
+
function componentStackKey(stack) {
|
|
948
|
+
return componentStackNames(stack).join(">");
|
|
949
|
+
}
|
|
950
|
+
var observer = null;
|
|
951
|
+
var observerStarted = false;
|
|
952
|
+
var observerStopAt = 0;
|
|
953
|
+
var OBSERVE_MS = 3e4;
|
|
954
|
+
function startObserver() {
|
|
955
|
+
if (observerStarted || typeof MutationObserver === "undefined" || typeof document === "undefined") {
|
|
956
|
+
return;
|
|
957
|
+
}
|
|
958
|
+
observerStarted = true;
|
|
959
|
+
try {
|
|
960
|
+
observer = new MutationObserver(() => {
|
|
961
|
+
if (Date.now() > observerStopAt) stopObserver();
|
|
962
|
+
});
|
|
963
|
+
observer.observe(document, { childList: true, subtree: true });
|
|
964
|
+
observerStopAt = Date.now() + OBSERVE_MS;
|
|
965
|
+
setTimeout(stopObserver, OBSERVE_MS);
|
|
966
|
+
} catch (e) {
|
|
967
|
+
observer = null;
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
function stopObserver() {
|
|
971
|
+
try {
|
|
972
|
+
observer == null ? void 0 : observer.disconnect();
|
|
973
|
+
} catch (e) {
|
|
974
|
+
}
|
|
975
|
+
observer = null;
|
|
976
|
+
}
|
|
977
|
+
function describeNode(node) {
|
|
978
|
+
if (!node) return "";
|
|
979
|
+
if (node.nodeType === 9) return "#document";
|
|
980
|
+
const el = node;
|
|
981
|
+
if (!el.tagName) return node.nodeName;
|
|
982
|
+
const id = el.id ? `#${el.id}` : "";
|
|
983
|
+
const cls = typeof el.className === "string" && el.className.trim() ? "." + el.className.trim().split(/\s+/).slice(0, 3).join(".") : "";
|
|
984
|
+
return `${el.tagName.toLowerCase()}${id}${cls}`;
|
|
985
|
+
}
|
|
986
|
+
function pathOf(node) {
|
|
987
|
+
const parts = [];
|
|
988
|
+
let cur = node;
|
|
989
|
+
while (cur && parts.length < 6) {
|
|
990
|
+
parts.unshift(describeNode(cur));
|
|
991
|
+
if (cur.nodeType === 9) break;
|
|
992
|
+
cur = cur.parentNode;
|
|
993
|
+
}
|
|
994
|
+
return parts.join(" > ");
|
|
995
|
+
}
|
|
996
|
+
var NON_CONTENT_TAGS = /* @__PURE__ */ new Set(["SCRIPT", "STYLE", "LINK", "META", "NOSCRIPT", "TEMPLATE", "TITLE", "HEAD"]);
|
|
997
|
+
function isInHead(node) {
|
|
998
|
+
for (let cur = node; cur; cur = cur.parentNode) {
|
|
999
|
+
if (cur.nodeName === "HEAD") return true;
|
|
1000
|
+
if (cur.nodeName === "BODY") return false;
|
|
1001
|
+
}
|
|
1002
|
+
return false;
|
|
1003
|
+
}
|
|
1004
|
+
var GSTIN_RE = /\b\d{2}[A-Z]{5}\d{4}[A-Z][A-Z0-9]Z[A-Z0-9]\b/g;
|
|
1005
|
+
var PAN_RE = /\b[A-Z]{5}\d{4}[A-Z]\b/g;
|
|
1006
|
+
function scrubHtml(html) {
|
|
1007
|
+
return redactString(
|
|
1008
|
+
html.replace(/\svalue="[^"]*"/gi, ' value="[REDACTED]"').replace(GSTIN_RE, "[REDACTED_GSTIN]").replace(PAN_RE, "[REDACTED_PAN]").replace(/\d{6,}/g, (m) => "#".repeat(Math.min(m.length, 6)))
|
|
1009
|
+
);
|
|
1010
|
+
}
|
|
1011
|
+
function takeRemovedServerHtml() {
|
|
1012
|
+
var _a, _b;
|
|
1013
|
+
if (!observer) return { html: "", where: "" };
|
|
1014
|
+
try {
|
|
1015
|
+
const records = observer.takeRecords();
|
|
1016
|
+
let html = "";
|
|
1017
|
+
let where = "";
|
|
1018
|
+
for (const rec of records) {
|
|
1019
|
+
if (rec.type !== "childList" || rec.removedNodes.length === 0) continue;
|
|
1020
|
+
if (isInHead(rec.target)) continue;
|
|
1021
|
+
if (!where) where = pathOf(rec.target);
|
|
1022
|
+
for (const node of Array.from(rec.removedNodes)) {
|
|
1023
|
+
if (node.nodeType === 1 && NON_CONTENT_TAGS.has(node.tagName)) continue;
|
|
1024
|
+
if (node.nodeType === 3 && !((_a = node.textContent) != null ? _a : "").trim()) continue;
|
|
1025
|
+
const piece = node.nodeType === 1 ? node.outerHTML : node.nodeType === 3 ? `#text "${(_b = node.textContent) != null ? _b : ""}"` : "";
|
|
1026
|
+
if (!piece) continue;
|
|
1027
|
+
html += (html ? "\n" : "") + piece;
|
|
1028
|
+
if (html.length >= DOM_SNIPPET_MAX) break;
|
|
1029
|
+
}
|
|
1030
|
+
if (html.length >= DOM_SNIPPET_MAX) break;
|
|
1031
|
+
}
|
|
1032
|
+
const scrubbed = scrubHtml(html);
|
|
1033
|
+
return {
|
|
1034
|
+
html: scrubbed.length > DOM_SNIPPET_MAX ? `${scrubbed.slice(0, DOM_SNIPPET_MAX)}\u2026[truncated]` : scrubbed,
|
|
1035
|
+
where
|
|
1036
|
+
};
|
|
1037
|
+
} catch (e) {
|
|
1038
|
+
return { html: "", where: "" };
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
function detectForeignNodes(doc = document) {
|
|
1042
|
+
var _a;
|
|
1043
|
+
const found = [];
|
|
1044
|
+
try {
|
|
1045
|
+
const html = doc.documentElement;
|
|
1046
|
+
if ((html == null ? void 0 : html.classList.contains("translated-ltr")) || (html == null ? void 0 : html.classList.contains("translated-rtl"))) {
|
|
1047
|
+
found.push("Google Translate is active (html.translated-*)");
|
|
1048
|
+
}
|
|
1049
|
+
const fonts = doc.getElementsByTagName("font").length;
|
|
1050
|
+
if (fonts > 0) found.push(`<font> \xD7 ${fonts} (Google Translate or a translation extension)`);
|
|
1051
|
+
const detectors = doc.querySelectorAll("a[x-apple-data-detectors]").length;
|
|
1052
|
+
if (detectors > 0) {
|
|
1053
|
+
found.push(`<a x-apple-data-detectors> \xD7 ${detectors} (iOS format detection turned text into links)`);
|
|
1054
|
+
}
|
|
1055
|
+
if (doc.querySelector("[data-gr-ext-installed],[data-new-gr-c-s-check-loaded],grammarly-desktop-integration")) {
|
|
1056
|
+
found.push("Grammarly extension attributes");
|
|
1057
|
+
}
|
|
1058
|
+
if (doc.querySelector("[data-lt-installed]")) found.push("LanguageTool extension attributes");
|
|
1059
|
+
if ((_a = doc.body) == null ? void 0 : _a.hasAttribute("cz-shortcut-listen")) found.push("ColorZilla extension attribute on <body>");
|
|
1060
|
+
const custom = /* @__PURE__ */ new Set();
|
|
1061
|
+
for (const parent of [html, doc.body]) {
|
|
1062
|
+
if (!parent) continue;
|
|
1063
|
+
for (const child of Array.from(parent.children)) {
|
|
1064
|
+
const tag = child.tagName.toLowerCase();
|
|
1065
|
+
if (tag.includes("-")) custom.add(tag);
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
if (custom.size > 0) {
|
|
1069
|
+
found.push(`custom elements at top level: ${Array.from(custom).slice(0, 5).join(", ")} (often an extension)`);
|
|
1070
|
+
}
|
|
1071
|
+
} catch (e) {
|
|
1072
|
+
}
|
|
1073
|
+
return found;
|
|
1074
|
+
}
|
|
1075
|
+
function hydrationTiming() {
|
|
1076
|
+
var _a, _b, _c, _d;
|
|
1077
|
+
try {
|
|
1078
|
+
if (typeof performance === "undefined") return "";
|
|
1079
|
+
const at2 = Math.round(performance.now());
|
|
1080
|
+
const parts = [`error at ${at2}ms after navigation start`];
|
|
1081
|
+
const nav = (_b = (_a = performance.getEntriesByType) == null ? void 0 : _a.call(performance, "navigation")) == null ? void 0 : _b[0];
|
|
1082
|
+
if (nav == null ? void 0 : nav.domContentLoadedEventEnd) {
|
|
1083
|
+
parts.push(`DOMContentLoaded ${Math.round(nav.domContentLoadedEventEnd)}ms`);
|
|
1084
|
+
}
|
|
1085
|
+
const fetches = ((_d = (_c = performance.getEntriesByType) == null ? void 0 : _c.call(performance, "resource")) != null ? _d : []).filter((e) => {
|
|
1086
|
+
const t = e.initiatorType;
|
|
1087
|
+
return t === "fetch" || t === "xmlhttprequest";
|
|
1088
|
+
}).sort((a, b) => a.responseEnd - b.responseEnd).slice(0, 8).map((e) => {
|
|
1089
|
+
let path = e.name;
|
|
1090
|
+
try {
|
|
1091
|
+
const u = new URL(e.name);
|
|
1092
|
+
path = u.origin === window.location.origin ? u.pathname : `${u.host}${u.pathname}`;
|
|
1093
|
+
} catch (e2) {
|
|
1094
|
+
}
|
|
1095
|
+
return `${path} ${Math.round(e.responseEnd)}ms`;
|
|
1096
|
+
});
|
|
1097
|
+
if (fetches.length > 0) parts.push(`fetches finished before it: ${fetches.join(", ")}`);
|
|
1098
|
+
else parts.push("no fetch had finished yet");
|
|
1099
|
+
return parts.join("; ");
|
|
1100
|
+
} catch (e) {
|
|
1101
|
+
return "";
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
function hydrationMetadata(error, extra) {
|
|
1105
|
+
var _a, _b, _c;
|
|
1106
|
+
const code = (_a = hydrationCode(messageOf(error))) != null ? _a : hydrationCode(messageOf(error == null ? void 0 : error.cause));
|
|
1107
|
+
const meta = { errorKind: "hydration" };
|
|
1108
|
+
if (code) meta.hydrationCode = code;
|
|
1109
|
+
const cause = error == null ? void 0 : error.cause;
|
|
1110
|
+
if (cause && cause !== error && messageOf(cause)) {
|
|
1111
|
+
meta.hydrationCause = messageOf(cause).slice(0, 500);
|
|
1112
|
+
}
|
|
1113
|
+
if ((_b = extra == null ? void 0 : extra.removed) == null ? void 0 : _b.html) meta.hydrationServerHtml = extra.removed.html;
|
|
1114
|
+
if ((_c = extra == null ? void 0 : extra.removed) == null ? void 0 : _c.where) meta.hydrationReplacedIn = extra.removed.where;
|
|
1115
|
+
const foreign = detectForeignNodes();
|
|
1116
|
+
if (foreign.length > 0) meta.hydrationForeignNodes = foreign.join("\n");
|
|
1117
|
+
const timing = hydrationTiming();
|
|
1118
|
+
if (timing) meta.hydrationTiming = timing;
|
|
1119
|
+
return meta;
|
|
1120
|
+
}
|
|
1121
|
+
var handled = /* @__PURE__ */ new WeakSet();
|
|
1122
|
+
function isHandledHydrationError(error) {
|
|
1123
|
+
return !!error && typeof error === "object" && handled.has(error);
|
|
1124
|
+
}
|
|
1125
|
+
function markHandled(error) {
|
|
1126
|
+
if (error && typeof error === "object") {
|
|
1127
|
+
handled.add(error);
|
|
1128
|
+
const cause = error.cause;
|
|
1129
|
+
if (cause && typeof cause === "object") handled.add(cause);
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
var reporter = null;
|
|
1133
|
+
var PATCHED = "__glitchgrabHydrationPatched";
|
|
1134
|
+
function findFiberRoot(container) {
|
|
1135
|
+
if (!container || typeof container !== "object") return null;
|
|
1136
|
+
try {
|
|
1137
|
+
const key = Object.keys(container).find((k) => k.startsWith("__reactContainer$"));
|
|
1138
|
+
if (!key) return null;
|
|
1139
|
+
const hostRoot = container[key];
|
|
1140
|
+
const root = hostRoot == null ? void 0 : hostRoot.stateNode;
|
|
1141
|
+
return root && typeof root === "object" ? root : null;
|
|
1142
|
+
} catch (e) {
|
|
1143
|
+
return null;
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
function patchRoot(root) {
|
|
1147
|
+
if (root[PATCHED]) return true;
|
|
1148
|
+
const original = root.onRecoverableError;
|
|
1149
|
+
if (typeof original !== "function") return false;
|
|
1150
|
+
root.onRecoverableError = function glitchgrabOnRecoverableError(error, info) {
|
|
1151
|
+
var _a;
|
|
1152
|
+
try {
|
|
1153
|
+
if (reporter && isHydrationError(error) && !isBailout(error)) {
|
|
1154
|
+
const removed = takeRemovedServerHtml();
|
|
1155
|
+
markHandled(error);
|
|
1156
|
+
reporter(error, (_a = info == null ? void 0 : info.componentStack) != null ? _a : "", hydrationMetadata(error, { removed }));
|
|
1157
|
+
}
|
|
1158
|
+
} catch (e) {
|
|
1159
|
+
}
|
|
1160
|
+
return original.call(this, error, info);
|
|
1161
|
+
};
|
|
1162
|
+
root[PATCHED] = true;
|
|
1163
|
+
return true;
|
|
1164
|
+
}
|
|
1165
|
+
function patchKnownRoots() {
|
|
1166
|
+
if (typeof document === "undefined") return false;
|
|
1167
|
+
let patched = false;
|
|
1168
|
+
for (const container of [document, document.getElementById("__next"), document.getElementById("root")]) {
|
|
1169
|
+
const root = findFiberRoot(container);
|
|
1170
|
+
if (root && patchRoot(root)) patched = true;
|
|
1171
|
+
}
|
|
1172
|
+
return patched;
|
|
1173
|
+
}
|
|
1174
|
+
function installHydrationCapture(report) {
|
|
1175
|
+
try {
|
|
1176
|
+
if (typeof window === "undefined") return;
|
|
1177
|
+
reporter = report;
|
|
1178
|
+
startObserver();
|
|
1179
|
+
patchKnownRoots();
|
|
1180
|
+
} catch (e) {
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
|
|
865
1184
|
// src/capture.ts
|
|
866
1185
|
var config = null;
|
|
867
1186
|
function registerCaptureConfig(next) {
|
|
@@ -881,7 +1200,7 @@ function sessionMetadata(session) {
|
|
|
881
1200
|
...(session == null ? void 0 : session.phone) ? { sessionUserPhone: String(session.phone) } : {}
|
|
882
1201
|
};
|
|
883
1202
|
}
|
|
884
|
-
function buildCapturedErrorPayload(error, options, cfg, capturedBy = "captureError") {
|
|
1203
|
+
function buildCapturedErrorPayload(error, options, cfg, capturedBy = "captureError", dedupKey) {
|
|
885
1204
|
var _a, _b, _c;
|
|
886
1205
|
const err = error instanceof Error ? error : void 0;
|
|
887
1206
|
const errorMessage = err ? err.message : String(error);
|
|
@@ -893,7 +1212,7 @@ function buildCapturedErrorPayload(error, options, cfg, capturedBy = "captureErr
|
|
|
893
1212
|
const sig = computeSignature({
|
|
894
1213
|
errorMessage,
|
|
895
1214
|
pageUrl: context.url,
|
|
896
|
-
errorStack: err == null ? void 0 : err.stack,
|
|
1215
|
+
errorStack: dedupKey ? `at ${dedupKey}` : err == null ? void 0 : err.stack,
|
|
897
1216
|
digest
|
|
898
1217
|
});
|
|
899
1218
|
if (shouldSkipDuplicate(sig)) return null;
|
|
@@ -933,6 +1252,25 @@ function captureError(error, options) {
|
|
|
933
1252
|
} catch (e) {
|
|
934
1253
|
}
|
|
935
1254
|
}
|
|
1255
|
+
function reportHydrationError(error, componentStack, metadata) {
|
|
1256
|
+
try {
|
|
1257
|
+
const cfg = config;
|
|
1258
|
+
if (!(cfg == null ? void 0 : cfg.token)) return;
|
|
1259
|
+
const payload = buildCapturedErrorPayload(
|
|
1260
|
+
error,
|
|
1261
|
+
{ componentStack: componentStack || void 0, metadata },
|
|
1262
|
+
cfg,
|
|
1263
|
+
"onRecoverableError",
|
|
1264
|
+
componentStackKey(componentStack) || void 0
|
|
1265
|
+
);
|
|
1266
|
+
if (!payload) return;
|
|
1267
|
+
void sendReport(payload, cfg.baseUrl).then((result) => {
|
|
1268
|
+
if (result && cfg.onReportSent) cfg.onReportSent(result);
|
|
1269
|
+
});
|
|
1270
|
+
if (cfg.onError && error instanceof Error) cfg.onError(error);
|
|
1271
|
+
} catch (e) {
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
936
1274
|
|
|
937
1275
|
// src/error-boundary.tsx
|
|
938
1276
|
var GlitchgrabErrorBoundary = class extends React.Component {
|
|
@@ -1355,6 +1693,9 @@ var MAX_ASSIST_IMAGE_CHARS = 35e5;
|
|
|
1355
1693
|
var MAX_ASSIST_FILES = 3;
|
|
1356
1694
|
var MAX_ASSIST_FILE_CHARS = 3e5;
|
|
1357
1695
|
var MAX_ASSIST_FILE_CHARS_EACH = 2e5;
|
|
1696
|
+
var MAX_SIMILAR_FILE_CHARS = 2e4;
|
|
1697
|
+
var MAX_SIMILAR_FILES_TOTAL_CHARS = 4e4;
|
|
1698
|
+
var MAX_READABLE_PDF_BYTES = 3 * 1024 * 1024;
|
|
1358
1699
|
var TEXT_ATTACHMENT_EXTENSIONS = [
|
|
1359
1700
|
".html",
|
|
1360
1701
|
".htm",
|
|
@@ -1385,6 +1726,10 @@ var ATTACHMENT_ACCEPT = [
|
|
|
1385
1726
|
...BINARY_ATTACHMENT_EXTENSIONS
|
|
1386
1727
|
].join(",");
|
|
1387
1728
|
var ASSIST_ATTACHMENT_ACCEPT = ["image/*", ...TEXT_ATTACHMENT_EXTENSIONS].join(",");
|
|
1729
|
+
var ASSIST_ATTACHMENT_ACCEPT_WITH_PDF = [ASSIST_ATTACHMENT_ACCEPT, ".pdf"].join(",");
|
|
1730
|
+
function isPdfFile(name) {
|
|
1731
|
+
return name.toLowerCase().endsWith(".pdf");
|
|
1732
|
+
}
|
|
1388
1733
|
function isAssistReadableFile(name) {
|
|
1389
1734
|
const lower = name.toLowerCase();
|
|
1390
1735
|
return TEXT_ATTACHMENT_EXTENSIONS.some((ext) => lower.endsWith(ext));
|
|
@@ -1405,6 +1750,27 @@ function decodeTextDataUrl(dataUrl) {
|
|
|
1405
1750
|
return null;
|
|
1406
1751
|
}
|
|
1407
1752
|
}
|
|
1753
|
+
function heldFileKey(file) {
|
|
1754
|
+
return `${file.name}:${file.size}`;
|
|
1755
|
+
}
|
|
1756
|
+
function heldFileText(file) {
|
|
1757
|
+
if (isPdfFile(file.name)) return typeof file.text === "string" && file.text.trim() ? file.text : null;
|
|
1758
|
+
if (!isAssistReadableFile(file.name)) return null;
|
|
1759
|
+
const text = decodeTextDataUrl(file.dataUrl);
|
|
1760
|
+
return text && text.trim() ? text : null;
|
|
1761
|
+
}
|
|
1762
|
+
function filesForSimilar(files, each, total) {
|
|
1763
|
+
const picked = [];
|
|
1764
|
+
let used = 0;
|
|
1765
|
+
for (let i = files.length - 1; i >= 0 && used < total; i--) {
|
|
1766
|
+
const text = heldFileText(files[i]);
|
|
1767
|
+
if (!text) continue;
|
|
1768
|
+
const content = text.slice(0, Math.min(each, total - used));
|
|
1769
|
+
picked.unshift({ name: files[i].name, content });
|
|
1770
|
+
used += content.length;
|
|
1771
|
+
}
|
|
1772
|
+
return picked;
|
|
1773
|
+
}
|
|
1408
1774
|
function getTypeLabel(type) {
|
|
1409
1775
|
switch (type) {
|
|
1410
1776
|
case "RATING":
|
|
@@ -1831,6 +2197,79 @@ function renderBlocks(lines, theme, key) {
|
|
|
1831
2197
|
function ChatMarkdown({ text, theme }) {
|
|
1832
2198
|
return /* @__PURE__ */ jsx2("div", { style: STACK, children: renderBlocks(text.replace(/\r\n?/g, "\n").split("\n"), theme, "md") });
|
|
1833
2199
|
}
|
|
2200
|
+
var MAX_SAVED_CHATS = 20;
|
|
2201
|
+
var SAVED_CHAT_MAX_AGE_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
2202
|
+
var TITLE_CHARS = 80;
|
|
2203
|
+
var PREFIX = "glitchgrab:ai-chats:";
|
|
2204
|
+
function chatHistoryKey(...parts) {
|
|
2205
|
+
const input = parts.map((p) => p != null ? p : "").join("\0");
|
|
2206
|
+
let hash = 2166136261;
|
|
2207
|
+
for (let i = 0; i < input.length; i++) {
|
|
2208
|
+
hash ^= input.charCodeAt(i);
|
|
2209
|
+
hash = Math.imul(hash, 16777619);
|
|
2210
|
+
}
|
|
2211
|
+
return (hash >>> 0).toString(36);
|
|
2212
|
+
}
|
|
2213
|
+
function chatTitle(messages) {
|
|
2214
|
+
var _a, _b;
|
|
2215
|
+
const first = (_b = (_a = messages.find((m) => m.role === "user")) == null ? void 0 : _a.content.trim()) != null ? _b : "";
|
|
2216
|
+
const line = first.replace(/\s+/g, " ");
|
|
2217
|
+
return line.length > TITLE_CHARS ? `${line.slice(0, TITLE_CHARS - 1)}\u2026` : line;
|
|
2218
|
+
}
|
|
2219
|
+
function storage() {
|
|
2220
|
+
try {
|
|
2221
|
+
return typeof window !== "undefined" && window.localStorage ? window.localStorage : null;
|
|
2222
|
+
} catch (e) {
|
|
2223
|
+
return null;
|
|
2224
|
+
}
|
|
2225
|
+
}
|
|
2226
|
+
function isSavedChat(value) {
|
|
2227
|
+
if (!value || typeof value !== "object") return false;
|
|
2228
|
+
const c = value;
|
|
2229
|
+
return typeof c.id === "string" && typeof c.title === "string" && typeof c.updatedAt === "number" && (c.status === "open" || c.status === "filed") && Array.isArray(c.messages);
|
|
2230
|
+
}
|
|
2231
|
+
function loadChats(key, now = Date.now()) {
|
|
2232
|
+
const store = storage();
|
|
2233
|
+
if (!store) return [];
|
|
2234
|
+
try {
|
|
2235
|
+
const raw = store.getItem(PREFIX + key);
|
|
2236
|
+
if (!raw) return [];
|
|
2237
|
+
const parsed = JSON.parse(raw);
|
|
2238
|
+
if (!Array.isArray(parsed)) return [];
|
|
2239
|
+
return parsed.filter(isSavedChat).filter((c) => now - c.updatedAt < SAVED_CHAT_MAX_AGE_MS).sort((a, b) => b.updatedAt - a.updatedAt).slice(0, MAX_SAVED_CHATS);
|
|
2240
|
+
} catch (e) {
|
|
2241
|
+
return [];
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
function write(key, chats) {
|
|
2245
|
+
const store = storage();
|
|
2246
|
+
if (!store) return;
|
|
2247
|
+
try {
|
|
2248
|
+
if (chats.length === 0) store.removeItem(PREFIX + key);
|
|
2249
|
+
else store.setItem(PREFIX + key, JSON.stringify(chats));
|
|
2250
|
+
} catch (e) {
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
function saveChat(key, chat, now = Date.now()) {
|
|
2254
|
+
const rest = loadChats(key, now).filter((c) => c.id !== chat.id);
|
|
2255
|
+
const next = [chat, ...rest].slice(0, MAX_SAVED_CHATS);
|
|
2256
|
+
write(key, next);
|
|
2257
|
+
return next;
|
|
2258
|
+
}
|
|
2259
|
+
function markChatFiled(key, conversationId, label, now = Date.now()) {
|
|
2260
|
+
const chats = loadChats(key, now);
|
|
2261
|
+
const hit = chats.find((c) => c.conversationId === conversationId);
|
|
2262
|
+
if (!hit || hit.status === "filed") return;
|
|
2263
|
+
write(
|
|
2264
|
+
key,
|
|
2265
|
+
chats.map((c) => c === hit ? { ...c, status: "filed", filedLabel: label, updatedAt: now } : c)
|
|
2266
|
+
);
|
|
2267
|
+
}
|
|
2268
|
+
function removeChat(key, id, now = Date.now()) {
|
|
2269
|
+
const next = loadChats(key, now).filter((c) => c.id !== id);
|
|
2270
|
+
write(key, next);
|
|
2271
|
+
return next;
|
|
2272
|
+
}
|
|
1834
2273
|
function pickAssistImages(all) {
|
|
1835
2274
|
const picked = [];
|
|
1836
2275
|
let total = 0;
|
|
@@ -1848,9 +2287,8 @@ function pickAssistFiles(files) {
|
|
|
1848
2287
|
let total = 0;
|
|
1849
2288
|
for (let i = files.length - 1; i >= 0 && picked.length < MAX_ASSIST_FILES; i--) {
|
|
1850
2289
|
const attached = files[i];
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
if (!text || !text.trim()) continue;
|
|
2290
|
+
const text = heldFileText(attached);
|
|
2291
|
+
if (!text) continue;
|
|
1854
2292
|
const content = text.slice(0, MAX_ASSIST_FILE_CHARS_EACH);
|
|
1855
2293
|
if (total + content.length > MAX_ASSIST_FILE_CHARS) continue;
|
|
1856
2294
|
picked.unshift({ index: i, file: { name: attached.name, content } });
|
|
@@ -1858,6 +2296,18 @@ function pickAssistFiles(files) {
|
|
|
1858
2296
|
}
|
|
1859
2297
|
return picked;
|
|
1860
2298
|
}
|
|
2299
|
+
function newChatId() {
|
|
2300
|
+
return `local-${Date.now().toString(36)}${Math.random().toString(36).slice(2, 6)}`;
|
|
2301
|
+
}
|
|
2302
|
+
function chatAge(at2, now = Date.now()) {
|
|
2303
|
+
const min = Math.round((now - at2) / 6e4);
|
|
2304
|
+
if (min < 1) return "just now";
|
|
2305
|
+
if (min < 60) return `${min} min ago`;
|
|
2306
|
+
const hours = Math.round(min / 60);
|
|
2307
|
+
if (hours < 24) return `${hours} h ago`;
|
|
2308
|
+
if (hours < 48) return "yesterday";
|
|
2309
|
+
return new Date(at2).toLocaleDateString(void 0, { day: "numeric", month: "short" });
|
|
2310
|
+
}
|
|
1861
2311
|
var STARTERS = [
|
|
1862
2312
|
"Something on this page is broken",
|
|
1863
2313
|
"It did the wrong thing",
|
|
@@ -1940,6 +2390,33 @@ function Avatar({
|
|
|
1940
2390
|
}
|
|
1941
2391
|
);
|
|
1942
2392
|
}
|
|
2393
|
+
var THINKING_SLOW_SECONDS = 20;
|
|
2394
|
+
function ThinkingClock({ color }) {
|
|
2395
|
+
const [seconds, setSeconds] = useState2(0);
|
|
2396
|
+
useEffect2(() => {
|
|
2397
|
+
const started = Date.now();
|
|
2398
|
+
const id = setInterval(() => setSeconds(Math.floor((Date.now() - started) / 1e3)), 1e3);
|
|
2399
|
+
return () => clearInterval(id);
|
|
2400
|
+
}, []);
|
|
2401
|
+
return (
|
|
2402
|
+
// Hidden from screen readers: the bubble already says "Thinking", and a
|
|
2403
|
+
// number changing every second would be read out every second.
|
|
2404
|
+
/* @__PURE__ */ jsxs3(
|
|
2405
|
+
"span",
|
|
2406
|
+
{
|
|
2407
|
+
"data-gg-thinking-clock": "",
|
|
2408
|
+
"aria-hidden": "true",
|
|
2409
|
+
style: { marginLeft: "6px", fontSize: "12px", color, fontVariantNumeric: "tabular-nums" },
|
|
2410
|
+
children: [
|
|
2411
|
+
"Thinking\u2026 ",
|
|
2412
|
+
seconds,
|
|
2413
|
+
"s",
|
|
2414
|
+
seconds >= THINKING_SLOW_SECONDS ? " \xB7 taking longer than usual, still working" : ""
|
|
2415
|
+
]
|
|
2416
|
+
}
|
|
2417
|
+
)
|
|
2418
|
+
);
|
|
2419
|
+
}
|
|
1943
2420
|
function AssistSheet({
|
|
1944
2421
|
assist,
|
|
1945
2422
|
theme: t,
|
|
@@ -1947,6 +2424,7 @@ function AssistSheet({
|
|
|
1947
2424
|
pageShot = null,
|
|
1948
2425
|
onAddFiles,
|
|
1949
2426
|
files = NO_FILES,
|
|
2427
|
+
canReadPdf = false,
|
|
1950
2428
|
onRemoveFile,
|
|
1951
2429
|
onRemoveImage,
|
|
1952
2430
|
attachmentCount,
|
|
@@ -1974,17 +2452,27 @@ function AssistSheet({
|
|
|
1974
2452
|
isSubmitting,
|
|
1975
2453
|
submitted,
|
|
1976
2454
|
onSend,
|
|
2455
|
+
similarSlot,
|
|
2456
|
+
submittedText,
|
|
1977
2457
|
onDegrade,
|
|
1978
2458
|
onClose,
|
|
1979
2459
|
onFinish,
|
|
1980
|
-
onReportGlitchgrabProblem
|
|
2460
|
+
onReportGlitchgrabProblem,
|
|
2461
|
+
historyKey = null
|
|
1981
2462
|
}) {
|
|
2463
|
+
var _a;
|
|
1982
2464
|
const narrow = useIsNarrow();
|
|
1983
2465
|
const severityAsked = showSeverity && currentTile === "BUG";
|
|
1984
2466
|
const [messages, setMessages] = useState2([]);
|
|
1985
2467
|
const [input, setInput] = useState2("");
|
|
1986
2468
|
const [busy, setBusy] = useState2(false);
|
|
1987
2469
|
const [conversationId, setConversationId] = useState2(null);
|
|
2470
|
+
const chatIdRef = useRef2(newChatId());
|
|
2471
|
+
const [savedChats, setSavedChats] = useState2(
|
|
2472
|
+
() => historyKey ? loadChats(historyKey) : []
|
|
2473
|
+
);
|
|
2474
|
+
const [showChats, setShowChats] = useState2(false);
|
|
2475
|
+
const [viewingChat, setViewingChat] = useState2(null);
|
|
1988
2476
|
const [hoveredStar, setHoveredStar] = useState2(0);
|
|
1989
2477
|
const [options, setOptions] = useState2([]);
|
|
1990
2478
|
const [duplicate, setDuplicate] = useState2(null);
|
|
@@ -1997,6 +2485,7 @@ function AssistSheet({
|
|
|
1997
2485
|
const [autoFileLeft, setAutoFileLeft] = useState2(null);
|
|
1998
2486
|
const scrollRef = useRef2(null);
|
|
1999
2487
|
const draftRef = useRef2(null);
|
|
2488
|
+
const composerRef = useRef2(null);
|
|
2000
2489
|
const seededRef = useRef2(false);
|
|
2001
2490
|
const seedPendingRef = useRef2(false);
|
|
2002
2491
|
const eventsRef = useRef2([]);
|
|
@@ -2035,9 +2524,15 @@ function AssistSheet({
|
|
|
2035
2524
|
if (el) el.scrollTop = el.scrollHeight;
|
|
2036
2525
|
}, [messages, busy, phase]);
|
|
2037
2526
|
useEffect2(() => {
|
|
2038
|
-
var
|
|
2039
|
-
if (phase === "draft") (
|
|
2527
|
+
var _a2;
|
|
2528
|
+
if (phase === "draft") (_a2 = draftRef.current) == null ? void 0 : _a2.focus();
|
|
2040
2529
|
}, [phase]);
|
|
2530
|
+
useEffect2(() => {
|
|
2531
|
+
const el = composerRef.current;
|
|
2532
|
+
if (!el) return;
|
|
2533
|
+
el.style.height = "auto";
|
|
2534
|
+
el.style.height = `${el.scrollHeight + 2}px`;
|
|
2535
|
+
}, [input]);
|
|
2041
2536
|
useEffect2(() => {
|
|
2042
2537
|
if (autoFileLeft === null) return;
|
|
2043
2538
|
if (isSubmitting || submitted || phase !== "draft") {
|
|
@@ -2062,7 +2557,8 @@ function AssistSheet({
|
|
|
2062
2557
|
onDegrade(message, retryable);
|
|
2063
2558
|
}
|
|
2064
2559
|
async function runTurn(history2, autoFile = false) {
|
|
2065
|
-
var
|
|
2560
|
+
var _a2, _b, _c;
|
|
2561
|
+
const turnChat = chatIdRef.current;
|
|
2066
2562
|
setBusy(true);
|
|
2067
2563
|
setAutoFileLeft(null);
|
|
2068
2564
|
let result;
|
|
@@ -2099,6 +2595,7 @@ function AssistSheet({
|
|
|
2099
2595
|
} finally {
|
|
2100
2596
|
setBusy(false);
|
|
2101
2597
|
}
|
|
2598
|
+
if (chatIdRef.current !== turnChat) return;
|
|
2102
2599
|
if (result.degraded) {
|
|
2103
2600
|
degradeKeepingEvents(events, result.degraded, result.retryable === true);
|
|
2104
2601
|
return;
|
|
@@ -2109,7 +2606,7 @@ function AssistSheet({
|
|
|
2109
2606
|
}
|
|
2110
2607
|
const attach = result.duplicate ? { ...result.duplicate, kind: "duplicate" } : result.related ? { ...result.related, kind: "related" } : null;
|
|
2111
2608
|
setDuplicate(attach);
|
|
2112
|
-
onDuplicateChange == null ? void 0 : onDuplicateChange((
|
|
2609
|
+
onDuplicateChange == null ? void 0 : onDuplicateChange((_a2 = attach == null ? void 0 : attach.number) != null ? _a2 : null, attach == null ? void 0 : attach.kind);
|
|
2113
2610
|
setGlitchgrabOffer(!!result.aboutGlitchgrab && !!onReportGlitchgrabProblem && !!result.question);
|
|
2114
2611
|
if (result.solved) {
|
|
2115
2612
|
setSolved(result.solved);
|
|
@@ -2163,9 +2660,9 @@ function AssistSheet({
|
|
|
2163
2660
|
}
|
|
2164
2661
|
}
|
|
2165
2662
|
function sendTyped(text) {
|
|
2166
|
-
var
|
|
2663
|
+
var _a2;
|
|
2167
2664
|
const lastAssistant = [...messages].reverse().find((m) => m.role === "assistant");
|
|
2168
|
-
const checkingBack = options.includes(CONFIRM_OPTION) || (lastAssistant == null ? void 0 : lastAssistant.kind) !== "report" && isCheckBackQuestion((
|
|
2665
|
+
const checkingBack = options.includes(CONFIRM_OPTION) || (lastAssistant == null ? void 0 : lastAssistant.kind) !== "report" && isCheckBackQuestion((_a2 = lastAssistant == null ? void 0 : lastAssistant.content) != null ? _a2 : "");
|
|
2169
2666
|
send(text, checkingBack && isAffirmativeReply(text));
|
|
2170
2667
|
}
|
|
2171
2668
|
function send(text, autoFile = false) {
|
|
@@ -2207,7 +2704,215 @@ function AssistSheet({
|
|
|
2207
2704
|
flushEvents();
|
|
2208
2705
|
onSend();
|
|
2209
2706
|
}
|
|
2707
|
+
useEffect2(() => {
|
|
2708
|
+
if (!historyKey || !messages.some((m) => m.role === "user")) return;
|
|
2709
|
+
const done = submitted || phase === "solved";
|
|
2710
|
+
const kept = submitted || phase === "draft" ? withCurrentDraft(messages) : messages;
|
|
2711
|
+
setSavedChats(
|
|
2712
|
+
saveChat(historyKey, {
|
|
2713
|
+
id: chatIdRef.current,
|
|
2714
|
+
conversationId,
|
|
2715
|
+
title: chatTitle(kept),
|
|
2716
|
+
tile: currentTile,
|
|
2717
|
+
messages: kept,
|
|
2718
|
+
...issueTitle ? { issueTitle } : {},
|
|
2719
|
+
status: done ? "filed" : "open",
|
|
2720
|
+
...done ? {
|
|
2721
|
+
filedLabel: submitted ? submittedText != null ? submittedText : `${reportTypeLabel} sent` : "Answered \u2014 nothing was filed"
|
|
2722
|
+
} : {},
|
|
2723
|
+
updatedAt: Date.now()
|
|
2724
|
+
})
|
|
2725
|
+
);
|
|
2726
|
+
}, [
|
|
2727
|
+
historyKey,
|
|
2728
|
+
messages,
|
|
2729
|
+
conversationId,
|
|
2730
|
+
submitted,
|
|
2731
|
+
phase === "solved",
|
|
2732
|
+
issueTitle,
|
|
2733
|
+
phase === "draft" ? description : null
|
|
2734
|
+
]);
|
|
2735
|
+
function resumeChat(chat) {
|
|
2736
|
+
var _a2;
|
|
2737
|
+
flushEvents();
|
|
2738
|
+
chatIdRef.current = chat.id;
|
|
2739
|
+
setMessages(chat.messages);
|
|
2740
|
+
setConversationId(chat.conversationId);
|
|
2741
|
+
onConversationChange == null ? void 0 : onConversationChange(chat.conversationId);
|
|
2742
|
+
setOptions([]);
|
|
2743
|
+
setDuplicate(null);
|
|
2744
|
+
onDuplicateChange == null ? void 0 : onDuplicateChange(null);
|
|
2745
|
+
setGlitchgrabOffer(false);
|
|
2746
|
+
setAutoFileLeft(null);
|
|
2747
|
+
setInput("");
|
|
2748
|
+
if (chat.tile !== currentTile && tiles.includes(chat.tile)) {
|
|
2749
|
+
onPickType(chat.tile);
|
|
2750
|
+
}
|
|
2751
|
+
const last = chat.messages[chat.messages.length - 1];
|
|
2752
|
+
if ((last == null ? void 0 : last.kind) === "report") {
|
|
2753
|
+
onDescriptionChange(last.content);
|
|
2754
|
+
onIssueTitleChange((_a2 = chat.issueTitle) != null ? _a2 : "");
|
|
2755
|
+
aiDraftRef.current = last.content;
|
|
2756
|
+
setPhase("draft");
|
|
2757
|
+
} else {
|
|
2758
|
+
setPhase("chat");
|
|
2759
|
+
}
|
|
2760
|
+
setShowChats(false);
|
|
2761
|
+
setViewingChat(null);
|
|
2762
|
+
}
|
|
2763
|
+
function startNewChat() {
|
|
2764
|
+
flushEvents();
|
|
2765
|
+
chatIdRef.current = newChatId();
|
|
2766
|
+
setMessages([]);
|
|
2767
|
+
setConversationId(null);
|
|
2768
|
+
onConversationChange == null ? void 0 : onConversationChange(null);
|
|
2769
|
+
setOptions([]);
|
|
2770
|
+
setDuplicate(null);
|
|
2771
|
+
onDuplicateChange == null ? void 0 : onDuplicateChange(null);
|
|
2772
|
+
setGlitchgrabOffer(false);
|
|
2773
|
+
setAutoFileLeft(null);
|
|
2774
|
+
setInput("");
|
|
2775
|
+
onDescriptionChange("");
|
|
2776
|
+
onIssueTitleChange("");
|
|
2777
|
+
aiDraftRef.current = null;
|
|
2778
|
+
setPhase("chat");
|
|
2779
|
+
setShowChats(false);
|
|
2780
|
+
setViewingChat(null);
|
|
2781
|
+
}
|
|
2782
|
+
function forgetChat(id) {
|
|
2783
|
+
if (!historyKey) return;
|
|
2784
|
+
setSavedChats(removeChat(historyKey, id));
|
|
2785
|
+
if (viewingChat === id) setViewingChat(null);
|
|
2786
|
+
}
|
|
2787
|
+
const otherChats = savedChats.filter((c) => c.id !== chatIdRef.current);
|
|
2788
|
+
const resumable = (_a = otherChats.find((c) => c.status === "open" && c.messages.length > 0)) != null ? _a : null;
|
|
2210
2789
|
const empty = phase === "chat" && messages.length === 0 && !busy;
|
|
2790
|
+
function renderChatList() {
|
|
2791
|
+
return /* @__PURE__ */ jsxs3("div", { "data-gg-chat-list": "", style: { display: "flex", flexDirection: "column", gap: "8px" }, children: [
|
|
2792
|
+
/* @__PURE__ */ jsxs3("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
2793
|
+
/* @__PURE__ */ jsx3("span", { style: { fontSize: "13px", fontWeight: 600 }, children: "Your chats" }),
|
|
2794
|
+
messages.length > 0 && /* @__PURE__ */ jsx3(
|
|
2795
|
+
"button",
|
|
2796
|
+
{
|
|
2797
|
+
type: "button",
|
|
2798
|
+
"data-gg-new-chat": "",
|
|
2799
|
+
onClick: startNewChat,
|
|
2800
|
+
style: {
|
|
2801
|
+
border: `1px solid ${t.inputBorder}`,
|
|
2802
|
+
borderRadius: "999px",
|
|
2803
|
+
background: "transparent",
|
|
2804
|
+
color: t.text,
|
|
2805
|
+
padding: "7px 12px",
|
|
2806
|
+
fontSize: "12px",
|
|
2807
|
+
fontFamily: "inherit",
|
|
2808
|
+
cursor: "pointer"
|
|
2809
|
+
},
|
|
2810
|
+
children: "+ New chat"
|
|
2811
|
+
}
|
|
2812
|
+
)
|
|
2813
|
+
] }),
|
|
2814
|
+
/* @__PURE__ */ jsx3("span", { style: { fontSize: "11.5px", color: t.textMuted, lineHeight: 1.5 }, children: "Kept in this browser only, for 30 days." }),
|
|
2815
|
+
otherChats.length === 0 && /* @__PURE__ */ jsx3("span", { style: { fontSize: "12.5px", color: t.textMuted, padding: "12px 0" }, children: "No other chats yet." }),
|
|
2816
|
+
otherChats.map((chat) => {
|
|
2817
|
+
var _a2;
|
|
2818
|
+
const filed = chat.status === "filed";
|
|
2819
|
+
const open = viewingChat === chat.id;
|
|
2820
|
+
return /* @__PURE__ */ jsxs3(
|
|
2821
|
+
"div",
|
|
2822
|
+
{
|
|
2823
|
+
"data-gg-saved-chat": chat.status,
|
|
2824
|
+
style: {
|
|
2825
|
+
border: `1px solid ${t.border}`,
|
|
2826
|
+
borderRadius: "10px",
|
|
2827
|
+
padding: "10px 12px",
|
|
2828
|
+
display: "flex",
|
|
2829
|
+
flexDirection: "column",
|
|
2830
|
+
gap: "6px",
|
|
2831
|
+
minWidth: 0
|
|
2832
|
+
},
|
|
2833
|
+
children: [
|
|
2834
|
+
/* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "8px", alignItems: "flex-start", minWidth: 0 }, children: [
|
|
2835
|
+
/* @__PURE__ */ jsxs3(
|
|
2836
|
+
"button",
|
|
2837
|
+
{
|
|
2838
|
+
type: "button",
|
|
2839
|
+
onClick: () => filed ? setViewingChat(open ? null : chat.id) : resumeChat(chat),
|
|
2840
|
+
style: {
|
|
2841
|
+
flex: 1,
|
|
2842
|
+
minWidth: 0,
|
|
2843
|
+
textAlign: "left",
|
|
2844
|
+
border: "none",
|
|
2845
|
+
background: "transparent",
|
|
2846
|
+
color: t.text,
|
|
2847
|
+
padding: 0,
|
|
2848
|
+
fontFamily: "inherit",
|
|
2849
|
+
cursor: "pointer",
|
|
2850
|
+
display: "flex",
|
|
2851
|
+
flexDirection: "column",
|
|
2852
|
+
gap: "4px"
|
|
2853
|
+
},
|
|
2854
|
+
children: [
|
|
2855
|
+
/* @__PURE__ */ jsx3("span", { style: { fontSize: "13px", lineHeight: 1.45, overflowWrap: "anywhere" }, children: chat.title || "Untitled chat" }),
|
|
2856
|
+
/* @__PURE__ */ jsxs3("span", { style: { fontSize: "11.5px", color: t.textMuted }, children: [
|
|
2857
|
+
filed ? (_a2 = chat.filedLabel) != null ? _a2 : "Sent" : "Not sent yet \u2014 tap to continue",
|
|
2858
|
+
" \xB7",
|
|
2859
|
+
" ",
|
|
2860
|
+
chatAge(chat.updatedAt)
|
|
2861
|
+
] })
|
|
2862
|
+
]
|
|
2863
|
+
}
|
|
2864
|
+
),
|
|
2865
|
+
/* @__PURE__ */ jsx3(
|
|
2866
|
+
"button",
|
|
2867
|
+
{
|
|
2868
|
+
type: "button",
|
|
2869
|
+
"aria-label": `Delete chat: ${chat.title}`,
|
|
2870
|
+
onClick: () => forgetChat(chat.id),
|
|
2871
|
+
style: {
|
|
2872
|
+
flexShrink: 0,
|
|
2873
|
+
border: "none",
|
|
2874
|
+
background: "transparent",
|
|
2875
|
+
color: t.textMuted,
|
|
2876
|
+
fontSize: "16px",
|
|
2877
|
+
lineHeight: 1,
|
|
2878
|
+
padding: "4px 6px",
|
|
2879
|
+
cursor: "pointer",
|
|
2880
|
+
fontFamily: "inherit"
|
|
2881
|
+
},
|
|
2882
|
+
children: "\xD7"
|
|
2883
|
+
}
|
|
2884
|
+
)
|
|
2885
|
+
] }),
|
|
2886
|
+
open && /* @__PURE__ */ jsx3(
|
|
2887
|
+
"div",
|
|
2888
|
+
{
|
|
2889
|
+
"data-gg-saved-transcript": "",
|
|
2890
|
+
style: {
|
|
2891
|
+
display: "flex",
|
|
2892
|
+
flexDirection: "column",
|
|
2893
|
+
gap: "6px",
|
|
2894
|
+
borderTop: `1px solid ${t.border}`,
|
|
2895
|
+
paddingTop: "8px",
|
|
2896
|
+
fontSize: "12.5px",
|
|
2897
|
+
lineHeight: 1.5
|
|
2898
|
+
},
|
|
2899
|
+
children: chat.messages.map((m, i) => /* @__PURE__ */ jsxs3("div", { style: { minWidth: 0, overflowWrap: "anywhere" }, children: [
|
|
2900
|
+
/* @__PURE__ */ jsxs3("span", { style: { color: t.textMuted, fontWeight: 600 }, children: [
|
|
2901
|
+
m.role === "user" ? "You" : m.kind === "report" ? "Report" : "Assistant",
|
|
2902
|
+
":",
|
|
2903
|
+
" "
|
|
2904
|
+
] }),
|
|
2905
|
+
/* @__PURE__ */ jsx3("span", { style: { whiteSpace: "pre-wrap" }, children: m.content })
|
|
2906
|
+
] }, i))
|
|
2907
|
+
}
|
|
2908
|
+
)
|
|
2909
|
+
]
|
|
2910
|
+
},
|
|
2911
|
+
chat.id
|
|
2912
|
+
);
|
|
2913
|
+
})
|
|
2914
|
+
] });
|
|
2915
|
+
}
|
|
2211
2916
|
function renderKnownIssue({ title, footer }) {
|
|
2212
2917
|
if (!duplicate) return null;
|
|
2213
2918
|
return /* @__PURE__ */ jsxs3(
|
|
@@ -2241,8 +2946,8 @@ function AssistSheet({
|
|
|
2241
2946
|
);
|
|
2242
2947
|
}
|
|
2243
2948
|
const initials2 = (reporterName != null ? reporterName : "").split(/\s+/).filter(Boolean).slice(0, 2).map((w) => {
|
|
2244
|
-
var
|
|
2245
|
-
return (_b = (
|
|
2949
|
+
var _a2, _b;
|
|
2950
|
+
return (_b = (_a2 = w[0]) == null ? void 0 : _a2.toUpperCase()) != null ? _b : "";
|
|
2246
2951
|
}).join("");
|
|
2247
2952
|
const panelStyle = narrow ? {
|
|
2248
2953
|
width: "100%",
|
|
@@ -2264,6 +2969,7 @@ function AssistSheet({
|
|
|
2264
2969
|
@keyframes gg-sheet-up{from{transform:translateY(24px);opacity:0}to{transform:translateY(0);opacity:1}}
|
|
2265
2970
|
@keyframes gg-sheet-fade{from{opacity:0}to{opacity:1}}
|
|
2266
2971
|
@keyframes gg-autofile{from{transform:scaleX(0)}to{transform:scaleX(1)}}
|
|
2972
|
+
@keyframes gg-spin{to{transform:rotate(360deg)}}
|
|
2267
2973
|
@keyframes gg-dot{0%,80%,100%{transform:translateY(0);opacity:.4}40%{transform:translateY(-3px);opacity:1}}
|
|
2268
2974
|
[data-gg-sheet-send]:focus-visible,[data-gg-chip]:focus-visible,[data-gg-assist-remove]:focus-visible,[data-gg-stop-auto-file]:focus-visible{outline:2px solid currentColor;outline-offset:2px}
|
|
2269
2975
|
` }),
|
|
@@ -2332,7 +3038,9 @@ function AssistSheet({
|
|
|
2332
3038
|
alignItems: "center",
|
|
2333
3039
|
gap: "7px",
|
|
2334
3040
|
fontSize: "14px",
|
|
2335
|
-
fontWeight: 600
|
|
3041
|
+
fontWeight: 600,
|
|
3042
|
+
// One line even with the Chats pill beside it (#567).
|
|
3043
|
+
whiteSpace: "nowrap"
|
|
2336
3044
|
},
|
|
2337
3045
|
children: [
|
|
2338
3046
|
/* @__PURE__ */ jsx3(Sparkle, { color: t.accent }),
|
|
@@ -2362,34 +3070,64 @@ function AssistSheet({
|
|
|
2362
3070
|
projectSlot ? /* @__PURE__ */ jsx3("span", { style: { marginLeft: "6px" }, children: projectSlot }) : null
|
|
2363
3071
|
] })
|
|
2364
3072
|
] }),
|
|
2365
|
-
/* @__PURE__ */
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
3073
|
+
/* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "6px", flexShrink: 0 }, children: [
|
|
3074
|
+
historyKey && (showChats || otherChats.length > 0) && /* @__PURE__ */ jsx3(
|
|
3075
|
+
"button",
|
|
3076
|
+
{
|
|
3077
|
+
type: "button",
|
|
3078
|
+
"data-gg-chats-toggle": "",
|
|
3079
|
+
disabled: busy,
|
|
3080
|
+
"aria-pressed": showChats,
|
|
3081
|
+
onClick: () => {
|
|
3082
|
+
setShowChats((v) => !v);
|
|
3083
|
+
setViewingChat(null);
|
|
3084
|
+
},
|
|
3085
|
+
style: {
|
|
3086
|
+
flexShrink: 0,
|
|
3087
|
+
border: `1px solid ${showChats ? t.accent : t.inputBorder}`,
|
|
3088
|
+
borderRadius: "999px",
|
|
3089
|
+
background: "transparent",
|
|
3090
|
+
color: showChats ? t.accent : t.textMuted,
|
|
3091
|
+
cursor: busy ? "default" : "pointer",
|
|
3092
|
+
opacity: busy ? 0.5 : 1,
|
|
3093
|
+
fontSize: "11.5px",
|
|
3094
|
+
lineHeight: 1,
|
|
3095
|
+
fontFamily: "inherit",
|
|
3096
|
+
whiteSpace: "nowrap",
|
|
3097
|
+
padding: "9px 11px"
|
|
3098
|
+
},
|
|
3099
|
+
children: showChats ? "\u2190 Chat" : `Chats \xB7 ${otherChats.length}`
|
|
3100
|
+
}
|
|
3101
|
+
),
|
|
3102
|
+
/* @__PURE__ */ jsx3(
|
|
3103
|
+
"button",
|
|
3104
|
+
{
|
|
3105
|
+
type: "button",
|
|
3106
|
+
"data-gg-write-myself": "",
|
|
3107
|
+
onClick: () => leave("write_myself", `header, ${phase}`),
|
|
3108
|
+
"aria-label": "Write it myself instead",
|
|
3109
|
+
style: {
|
|
3110
|
+
flexShrink: 0,
|
|
3111
|
+
border: `1px solid ${t.inputBorder}`,
|
|
3112
|
+
borderRadius: "999px",
|
|
3113
|
+
background: "transparent",
|
|
3114
|
+
color: t.textMuted,
|
|
3115
|
+
cursor: "pointer",
|
|
3116
|
+
fontSize: "11.5px",
|
|
3117
|
+
lineHeight: 1,
|
|
3118
|
+
fontFamily: "inherit",
|
|
3119
|
+
whiteSpace: "nowrap",
|
|
3120
|
+
// ~32px tall either way — this is the escape hatch, not a hint.
|
|
3121
|
+
padding: "9px 11px"
|
|
3122
|
+
},
|
|
3123
|
+
children: "Write it myself"
|
|
3124
|
+
}
|
|
3125
|
+
)
|
|
3126
|
+
] })
|
|
2389
3127
|
]
|
|
2390
3128
|
}
|
|
2391
3129
|
),
|
|
2392
|
-
/* @__PURE__ */
|
|
3130
|
+
/* @__PURE__ */ jsxs3(
|
|
2393
3131
|
"div",
|
|
2394
3132
|
{
|
|
2395
3133
|
ref: scrollRef,
|
|
@@ -2401,765 +3139,845 @@ function AssistSheet({
|
|
|
2401
3139
|
display: "flex",
|
|
2402
3140
|
flexDirection: "column"
|
|
2403
3141
|
},
|
|
2404
|
-
children:
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
/* @__PURE__ */ jsxs3(
|
|
3142
|
+
children: [
|
|
3143
|
+
showChats && renderChatList(),
|
|
3144
|
+
/* @__PURE__ */ jsx3(
|
|
3145
|
+
"div",
|
|
3146
|
+
{
|
|
3147
|
+
style: {
|
|
3148
|
+
marginTop: "auto",
|
|
3149
|
+
display: "flex",
|
|
3150
|
+
flexDirection: "column",
|
|
3151
|
+
gap: "12px",
|
|
3152
|
+
minWidth: 0
|
|
3153
|
+
},
|
|
3154
|
+
children: /* @__PURE__ */ jsxs3("div", { style: { display: showChats ? "none" : "contents" }, children: [
|
|
3155
|
+
phase === "type" && /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
|
|
3156
|
+
/* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
3157
|
+
/* @__PURE__ */ jsx3(Avatar, { who: "assistant", theme: t }),
|
|
3158
|
+
/* @__PURE__ */ jsxs3(
|
|
3159
|
+
"div",
|
|
3160
|
+
{
|
|
3161
|
+
style: {
|
|
3162
|
+
padding: "9px 12px",
|
|
3163
|
+
borderRadius: "12px 12px 12px 4px",
|
|
3164
|
+
backgroundColor: t.bgSecondary,
|
|
3165
|
+
fontSize: "13px",
|
|
3166
|
+
lineHeight: 1.55,
|
|
3167
|
+
maxWidth: "88%"
|
|
3168
|
+
},
|
|
3169
|
+
children: [
|
|
3170
|
+
reporterName ? `Hi ${reporterName.split(" ")[0]} \u2014 w` : "W",
|
|
3171
|
+
"hat do you want to do? Pick one and I'll take it from there."
|
|
3172
|
+
]
|
|
3173
|
+
}
|
|
3174
|
+
)
|
|
3175
|
+
] }),
|
|
3176
|
+
/* @__PURE__ */ jsx3(
|
|
2419
3177
|
"div",
|
|
2420
3178
|
{
|
|
2421
3179
|
style: {
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
lineHeight: 1.55,
|
|
2427
|
-
maxWidth: "88%"
|
|
3180
|
+
display: "flex",
|
|
3181
|
+
flexWrap: "wrap",
|
|
3182
|
+
gap: "6px",
|
|
3183
|
+
paddingLeft: "32px"
|
|
2428
3184
|
},
|
|
2429
|
-
children:
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
3185
|
+
children: tiles.map((tile) => {
|
|
3186
|
+
const rate = tile === "RATING";
|
|
3187
|
+
return /* @__PURE__ */ jsx3(
|
|
3188
|
+
"button",
|
|
3189
|
+
{
|
|
3190
|
+
type: "button",
|
|
3191
|
+
"data-gg-chip": "",
|
|
3192
|
+
"data-gg-tile": tile,
|
|
3193
|
+
onClick: () => pickType(tile),
|
|
3194
|
+
style: {
|
|
3195
|
+
display: "inline-flex",
|
|
3196
|
+
alignItems: "center",
|
|
3197
|
+
gap: "5px",
|
|
3198
|
+
// The rating is the only tile that isn't a report, so
|
|
3199
|
+
// it wears the star colour the dialog's hero row uses
|
|
3200
|
+
// rather than hiding among the report types.
|
|
3201
|
+
border: `1px solid ${rate ? "rgba(245,158,11,0.5)" : t.inputBorder}`,
|
|
3202
|
+
background: rate ? "rgba(245,158,11,0.08)" : "transparent",
|
|
3203
|
+
color: rate ? "#f59e0b" : t.textMuted,
|
|
3204
|
+
borderRadius: "999px",
|
|
3205
|
+
// 8px vertical keeps the tap target at ~32px.
|
|
3206
|
+
padding: "8px 12px",
|
|
3207
|
+
fontSize: "12px",
|
|
3208
|
+
fontWeight: rate ? 600 : 400,
|
|
3209
|
+
fontFamily: "inherit",
|
|
3210
|
+
cursor: "pointer"
|
|
3211
|
+
},
|
|
3212
|
+
children: rate ? "\u2605 Rate us" : getTypeLabel(tile)
|
|
3213
|
+
},
|
|
3214
|
+
tile
|
|
3215
|
+
);
|
|
3216
|
+
})
|
|
2433
3217
|
}
|
|
2434
3218
|
)
|
|
2435
3219
|
] }),
|
|
2436
|
-
/* @__PURE__ */
|
|
2437
|
-
"div",
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
3220
|
+
phase === "severity" && /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
|
|
3221
|
+
/* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
3222
|
+
/* @__PURE__ */ jsx3(Avatar, { who: "assistant", theme: t }),
|
|
3223
|
+
/* @__PURE__ */ jsx3(
|
|
3224
|
+
"div",
|
|
3225
|
+
{
|
|
3226
|
+
style: {
|
|
3227
|
+
padding: "9px 12px",
|
|
3228
|
+
borderRadius: "12px 12px 12px 4px",
|
|
3229
|
+
backgroundColor: t.bgSecondary,
|
|
3230
|
+
fontSize: "13px",
|
|
3231
|
+
lineHeight: 1.55,
|
|
3232
|
+
maxWidth: "88%"
|
|
3233
|
+
},
|
|
3234
|
+
children: "How bad is it?"
|
|
3235
|
+
}
|
|
3236
|
+
)
|
|
3237
|
+
] }),
|
|
3238
|
+
/* @__PURE__ */ jsx3(
|
|
3239
|
+
"div",
|
|
3240
|
+
{
|
|
3241
|
+
role: "radiogroup",
|
|
3242
|
+
"aria-label": "Severity",
|
|
3243
|
+
style: {
|
|
3244
|
+
display: "flex",
|
|
3245
|
+
flexWrap: "wrap",
|
|
3246
|
+
gap: "6px",
|
|
3247
|
+
paddingLeft: "32px"
|
|
3248
|
+
},
|
|
3249
|
+
children: SEVERITY_LEVELS.map((s) => /* @__PURE__ */ jsx3(
|
|
2448
3250
|
"button",
|
|
2449
3251
|
{
|
|
2450
3252
|
type: "button",
|
|
3253
|
+
role: "radio",
|
|
3254
|
+
"aria-checked": severity === s,
|
|
2451
3255
|
"data-gg-chip": "",
|
|
2452
|
-
"data-gg-
|
|
2453
|
-
onClick: () =>
|
|
3256
|
+
"data-gg-severity": s,
|
|
3257
|
+
onClick: () => answerSeverity(s),
|
|
2454
3258
|
style: {
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
// The rating is the only tile that isn't a report, so
|
|
2459
|
-
// it wears the star colour the dialog's hero row uses
|
|
2460
|
-
// rather than hiding among the report types.
|
|
2461
|
-
border: `1px solid ${rate ? "rgba(245,158,11,0.5)" : t.inputBorder}`,
|
|
2462
|
-
background: rate ? "rgba(245,158,11,0.08)" : "transparent",
|
|
2463
|
-
color: rate ? "#f59e0b" : t.textMuted,
|
|
3259
|
+
border: `1px solid ${t.inputBorder}`,
|
|
3260
|
+
background: "transparent",
|
|
3261
|
+
color: t.textMuted,
|
|
2464
3262
|
borderRadius: "999px",
|
|
2465
|
-
//
|
|
3263
|
+
// Same as the picker and option chips — one chip size.
|
|
2466
3264
|
padding: "8px 12px",
|
|
2467
3265
|
fontSize: "12px",
|
|
2468
|
-
fontWeight: rate ? 600 : 400,
|
|
2469
3266
|
fontFamily: "inherit",
|
|
2470
3267
|
cursor: "pointer"
|
|
2471
3268
|
},
|
|
2472
|
-
children:
|
|
3269
|
+
children: SEVERITY_LABELS[s]
|
|
2473
3270
|
},
|
|
2474
|
-
|
|
2475
|
-
)
|
|
2476
|
-
})
|
|
2477
|
-
}
|
|
2478
|
-
)
|
|
2479
|
-
] }),
|
|
2480
|
-
phase === "severity" && /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
|
|
2481
|
-
/* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
2482
|
-
/* @__PURE__ */ jsx3(Avatar, { who: "assistant", theme: t }),
|
|
2483
|
-
/* @__PURE__ */ jsx3(
|
|
2484
|
-
"div",
|
|
2485
|
-
{
|
|
2486
|
-
style: {
|
|
2487
|
-
padding: "9px 12px",
|
|
2488
|
-
borderRadius: "12px 12px 12px 4px",
|
|
2489
|
-
backgroundColor: t.bgSecondary,
|
|
2490
|
-
fontSize: "13px",
|
|
2491
|
-
lineHeight: 1.55,
|
|
2492
|
-
maxWidth: "88%"
|
|
2493
|
-
},
|
|
2494
|
-
children: "How bad is it?"
|
|
3271
|
+
s
|
|
3272
|
+
))
|
|
2495
3273
|
}
|
|
2496
3274
|
)
|
|
2497
3275
|
] }),
|
|
2498
|
-
/* @__PURE__ */
|
|
2499
|
-
"div",
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
style: {
|
|
2504
|
-
display: "flex",
|
|
2505
|
-
flexWrap: "wrap",
|
|
2506
|
-
gap: "6px",
|
|
2507
|
-
paddingLeft: "32px"
|
|
2508
|
-
},
|
|
2509
|
-
children: SEVERITY_LEVELS.map((s) => /* @__PURE__ */ jsx3(
|
|
2510
|
-
"button",
|
|
3276
|
+
phase === "rating" && !submitted && /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
|
|
3277
|
+
/* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
3278
|
+
/* @__PURE__ */ jsx3(Avatar, { who: "assistant", theme: t }),
|
|
3279
|
+
/* @__PURE__ */ jsx3(
|
|
3280
|
+
"div",
|
|
2511
3281
|
{
|
|
2512
|
-
type: "button",
|
|
2513
|
-
role: "radio",
|
|
2514
|
-
"aria-checked": severity === s,
|
|
2515
|
-
"data-gg-chip": "",
|
|
2516
|
-
"data-gg-severity": s,
|
|
2517
|
-
onClick: () => answerSeverity(s),
|
|
2518
3282
|
style: {
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
fontSize: "12px",
|
|
2526
|
-
fontFamily: "inherit",
|
|
2527
|
-
cursor: "pointer"
|
|
3283
|
+
padding: "9px 12px",
|
|
3284
|
+
borderRadius: "12px 12px 12px 4px",
|
|
3285
|
+
backgroundColor: t.bgSecondary,
|
|
3286
|
+
fontSize: "13px",
|
|
3287
|
+
lineHeight: 1.55,
|
|
3288
|
+
maxWidth: "88%"
|
|
2528
3289
|
},
|
|
2529
|
-
children:
|
|
2530
|
-
}
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
)
|
|
2535
|
-
] }),
|
|
2536
|
-
phase === "rating" && !submitted && /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
|
|
2537
|
-
/* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
2538
|
-
/* @__PURE__ */ jsx3(Avatar, { who: "assistant", theme: t }),
|
|
2539
|
-
/* @__PURE__ */ jsx3(
|
|
3290
|
+
children: "How are we doing? Tap a star \u2014 the words are optional."
|
|
3291
|
+
}
|
|
3292
|
+
)
|
|
3293
|
+
] }),
|
|
3294
|
+
/* @__PURE__ */ jsxs3(
|
|
2540
3295
|
"div",
|
|
2541
3296
|
{
|
|
2542
3297
|
style: {
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
3298
|
+
display: "flex",
|
|
3299
|
+
flexDirection: "column",
|
|
3300
|
+
gap: "10px",
|
|
3301
|
+
marginLeft: "32px",
|
|
3302
|
+
padding: "12px",
|
|
3303
|
+
borderRadius: "12px",
|
|
3304
|
+
border: "1px solid rgba(245,158,11,0.4)",
|
|
3305
|
+
backgroundColor: "rgba(245,158,11,0.06)"
|
|
2549
3306
|
},
|
|
2550
|
-
children:
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
3307
|
+
children: [
|
|
3308
|
+
/* @__PURE__ */ jsx3("div", { style: { display: "flex", gap: "4px" }, role: "group", "aria-label": "Rating", children: [1, 2, 3, 4, 5].map((star) => {
|
|
3309
|
+
const filled = star <= (hoveredStar || rating);
|
|
3310
|
+
return /* @__PURE__ */ jsx3(
|
|
3311
|
+
"button",
|
|
3312
|
+
{
|
|
3313
|
+
type: "button",
|
|
3314
|
+
"aria-label": `${star} star${star > 1 ? "s" : ""}`,
|
|
3315
|
+
"aria-pressed": star <= rating,
|
|
3316
|
+
onClick: () => onRatingChange(star),
|
|
3317
|
+
onMouseEnter: () => setHoveredStar(star),
|
|
3318
|
+
onMouseLeave: () => setHoveredStar(0),
|
|
3319
|
+
style: {
|
|
3320
|
+
border: "none",
|
|
3321
|
+
background: "transparent",
|
|
3322
|
+
padding: 0,
|
|
3323
|
+
cursor: "pointer",
|
|
3324
|
+
lineHeight: 0
|
|
3325
|
+
},
|
|
3326
|
+
children: /* @__PURE__ */ jsx3("svg", { width: "30", height: "30", viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsx3(
|
|
3327
|
+
"path",
|
|
3328
|
+
{
|
|
3329
|
+
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",
|
|
3330
|
+
fill: filled ? "#f59e0b" : "transparent",
|
|
3331
|
+
stroke: filled ? "#f59e0b" : t.inputBorder,
|
|
3332
|
+
strokeWidth: "1.5",
|
|
3333
|
+
strokeLinejoin: "round"
|
|
3334
|
+
}
|
|
3335
|
+
) })
|
|
3336
|
+
},
|
|
3337
|
+
star
|
|
3338
|
+
);
|
|
3339
|
+
}) }),
|
|
3340
|
+
/* @__PURE__ */ jsx3(
|
|
3341
|
+
"textarea",
|
|
3342
|
+
{
|
|
3343
|
+
value: description,
|
|
3344
|
+
onChange: (e) => onDescriptionChange(e.target.value),
|
|
3345
|
+
rows: 3,
|
|
3346
|
+
placeholder: "What made it good \u2014 or what let you down? (optional)",
|
|
3347
|
+
style: {
|
|
3348
|
+
width: "100%",
|
|
3349
|
+
padding: "10px",
|
|
3350
|
+
borderRadius: "8px",
|
|
3351
|
+
border: `1px solid ${t.inputBorder}`,
|
|
3352
|
+
backgroundColor: t.inputBg,
|
|
3353
|
+
color: t.text,
|
|
3354
|
+
fontSize: "13px",
|
|
3355
|
+
lineHeight: 1.5,
|
|
3356
|
+
fontFamily: "inherit",
|
|
3357
|
+
resize: "vertical",
|
|
3358
|
+
outline: "none",
|
|
3359
|
+
boxSizing: "border-box"
|
|
3360
|
+
}
|
|
3361
|
+
}
|
|
3362
|
+
),
|
|
3363
|
+
/* @__PURE__ */ jsx3(
|
|
2571
3364
|
"button",
|
|
2572
3365
|
{
|
|
2573
3366
|
type: "button",
|
|
2574
|
-
|
|
2575
|
-
"aria-pressed": star <= rating,
|
|
2576
|
-
onClick: () => onRatingChange(star),
|
|
2577
|
-
onMouseEnter: () => setHoveredStar(star),
|
|
2578
|
-
onMouseLeave: () => setHoveredStar(0),
|
|
3367
|
+
onClick: () => setPhase("type"),
|
|
2579
3368
|
style: {
|
|
3369
|
+
alignSelf: "flex-start",
|
|
2580
3370
|
border: "none",
|
|
2581
3371
|
background: "transparent",
|
|
2582
|
-
|
|
3372
|
+
color: t.textMuted,
|
|
3373
|
+
fontSize: "12px",
|
|
3374
|
+
fontFamily: "inherit",
|
|
3375
|
+
// A bare text link is ~14px tall — half a thumb.
|
|
3376
|
+
padding: "9px 0",
|
|
2583
3377
|
cursor: "pointer",
|
|
2584
|
-
|
|
3378
|
+
textDecoration: "underline"
|
|
2585
3379
|
},
|
|
2586
|
-
children:
|
|
2587
|
-
"path",
|
|
2588
|
-
{
|
|
2589
|
-
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",
|
|
2590
|
-
fill: filled ? "#f59e0b" : "transparent",
|
|
2591
|
-
stroke: filled ? "#f59e0b" : t.inputBorder,
|
|
2592
|
-
strokeWidth: "1.5",
|
|
2593
|
-
strokeLinejoin: "round"
|
|
2594
|
-
}
|
|
2595
|
-
) })
|
|
2596
|
-
},
|
|
2597
|
-
star
|
|
2598
|
-
);
|
|
2599
|
-
}) }),
|
|
2600
|
-
/* @__PURE__ */ jsx3(
|
|
2601
|
-
"textarea",
|
|
2602
|
-
{
|
|
2603
|
-
value: description,
|
|
2604
|
-
onChange: (e) => onDescriptionChange(e.target.value),
|
|
2605
|
-
rows: 3,
|
|
2606
|
-
placeholder: "What made it good \u2014 or what let you down? (optional)",
|
|
2607
|
-
style: {
|
|
2608
|
-
width: "100%",
|
|
2609
|
-
padding: "10px",
|
|
2610
|
-
borderRadius: "8px",
|
|
2611
|
-
border: `1px solid ${t.inputBorder}`,
|
|
2612
|
-
backgroundColor: t.inputBg,
|
|
2613
|
-
color: t.text,
|
|
2614
|
-
fontSize: "13px",
|
|
2615
|
-
lineHeight: 1.5,
|
|
2616
|
-
fontFamily: "inherit",
|
|
2617
|
-
resize: "vertical",
|
|
2618
|
-
outline: "none",
|
|
2619
|
-
boxSizing: "border-box"
|
|
3380
|
+
children: "Report something instead"
|
|
2620
3381
|
}
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
style: {
|
|
2629
|
-
alignSelf: "flex-start",
|
|
2630
|
-
border: "none",
|
|
2631
|
-
background: "transparent",
|
|
2632
|
-
color: t.textMuted,
|
|
2633
|
-
fontSize: "12px",
|
|
2634
|
-
fontFamily: "inherit",
|
|
2635
|
-
// A bare text link is ~14px tall — half a thumb.
|
|
2636
|
-
padding: "9px 0",
|
|
2637
|
-
cursor: "pointer",
|
|
2638
|
-
textDecoration: "underline"
|
|
2639
|
-
},
|
|
2640
|
-
children: "Report something instead"
|
|
2641
|
-
}
|
|
2642
|
-
)
|
|
2643
|
-
]
|
|
2644
|
-
}
|
|
2645
|
-
)
|
|
2646
|
-
] }),
|
|
2647
|
-
empty && /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
|
|
2648
|
-
/* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
2649
|
-
/* @__PURE__ */ jsx3(Avatar, { who: "assistant", theme: t }),
|
|
2650
|
-
/* @__PURE__ */ jsxs3(
|
|
3382
|
+
)
|
|
3383
|
+
]
|
|
3384
|
+
}
|
|
3385
|
+
)
|
|
3386
|
+
] }),
|
|
3387
|
+
empty && /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
|
|
3388
|
+
resumable && /* @__PURE__ */ jsxs3(
|
|
2651
3389
|
"div",
|
|
2652
3390
|
{
|
|
3391
|
+
"data-gg-resume-chat": "",
|
|
2653
3392
|
style: {
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
3393
|
+
display: "flex",
|
|
3394
|
+
flexDirection: "column",
|
|
3395
|
+
gap: "8px",
|
|
3396
|
+
padding: "10px 12px",
|
|
3397
|
+
borderRadius: "10px",
|
|
3398
|
+
border: `1px solid ${t.accent}55`,
|
|
3399
|
+
backgroundColor: t.bgSecondary,
|
|
3400
|
+
minWidth: 0
|
|
2660
3401
|
},
|
|
2661
3402
|
children: [
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
"button",
|
|
2679
|
-
{
|
|
2680
|
-
type: "button",
|
|
2681
|
-
"data-gg-chip": "",
|
|
2682
|
-
onClick: () => {
|
|
2683
|
-
logEvent("starter_tap", s);
|
|
2684
|
-
send(s);
|
|
2685
|
-
},
|
|
2686
|
-
style: {
|
|
2687
|
-
border: `1px solid ${t.inputBorder}`,
|
|
2688
|
-
background: "transparent",
|
|
2689
|
-
color: t.textMuted,
|
|
2690
|
-
borderRadius: "999px",
|
|
2691
|
-
padding: "6px 11px",
|
|
2692
|
-
fontSize: "12px",
|
|
2693
|
-
fontFamily: "inherit",
|
|
2694
|
-
cursor: "pointer"
|
|
2695
|
-
},
|
|
2696
|
-
children: s
|
|
2697
|
-
},
|
|
2698
|
-
s
|
|
2699
|
-
))
|
|
2700
|
-
}
|
|
2701
|
-
)
|
|
2702
|
-
] }),
|
|
2703
|
-
messages.map((m, i) => {
|
|
2704
|
-
const mine = m.role === "user";
|
|
2705
|
-
if (m.kind === "report") {
|
|
2706
|
-
const live = phase === "draft" && i === messages.length - 1;
|
|
2707
|
-
return /* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "8px", minWidth: 0 }, children: [
|
|
2708
|
-
/* @__PURE__ */ jsx3(Avatar, { who: "assistant", theme: t }),
|
|
2709
|
-
/* @__PURE__ */ jsx3(
|
|
2710
|
-
"div",
|
|
2711
|
-
{
|
|
2712
|
-
"data-gg-draft-bubble": "",
|
|
2713
|
-
style: {
|
|
2714
|
-
maxWidth: "82%",
|
|
2715
|
-
minWidth: 0,
|
|
2716
|
-
padding: "9px 12px",
|
|
2717
|
-
borderRadius: "12px 12px 12px 4px",
|
|
2718
|
-
fontSize: "13px",
|
|
2719
|
-
lineHeight: 1.55,
|
|
2720
|
-
backgroundColor: t.bgSecondary,
|
|
2721
|
-
color: t.text,
|
|
2722
|
-
border: live ? "none" : `1px solid ${t.accent}66`
|
|
2723
|
-
},
|
|
2724
|
-
children: live ? (
|
|
2725
|
-
// #402: "have a read" beside a countdown reads as a
|
|
2726
|
-
// contradiction. Say what is about to happen instead.
|
|
2727
|
-
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."
|
|
2728
|
-
) : /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
3403
|
+
/* @__PURE__ */ jsxs3("span", { style: { fontSize: "11.5px", color: t.textMuted }, children: [
|
|
3404
|
+
"Pick up where you left off \xB7 ",
|
|
3405
|
+
chatAge(resumable.updatedAt)
|
|
3406
|
+
] }),
|
|
3407
|
+
/* @__PURE__ */ jsx3(
|
|
3408
|
+
"span",
|
|
3409
|
+
{
|
|
3410
|
+
style: {
|
|
3411
|
+
fontSize: "13px",
|
|
3412
|
+
lineHeight: 1.45,
|
|
3413
|
+
overflowWrap: "anywhere"
|
|
3414
|
+
},
|
|
3415
|
+
children: resumable.title
|
|
3416
|
+
}
|
|
3417
|
+
),
|
|
3418
|
+
/* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "8px", flexWrap: "wrap" }, children: [
|
|
2729
3419
|
/* @__PURE__ */ jsx3(
|
|
2730
|
-
"
|
|
3420
|
+
"button",
|
|
2731
3421
|
{
|
|
3422
|
+
type: "button",
|
|
3423
|
+
"data-gg-resume-continue": "",
|
|
3424
|
+
onClick: () => resumeChat(resumable),
|
|
2732
3425
|
style: {
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
3426
|
+
border: "none",
|
|
3427
|
+
borderRadius: "999px",
|
|
3428
|
+
backgroundColor: t.accent,
|
|
3429
|
+
color: t.accentText,
|
|
3430
|
+
padding: "7px 13px",
|
|
3431
|
+
fontSize: "12px",
|
|
3432
|
+
fontWeight: 600,
|
|
3433
|
+
fontFamily: "inherit",
|
|
3434
|
+
cursor: "pointer"
|
|
2740
3435
|
},
|
|
2741
|
-
children: "
|
|
3436
|
+
children: "Continue this chat"
|
|
2742
3437
|
}
|
|
2743
3438
|
),
|
|
2744
3439
|
/* @__PURE__ */ jsx3(
|
|
2745
|
-
"
|
|
3440
|
+
"button",
|
|
2746
3441
|
{
|
|
3442
|
+
type: "button",
|
|
3443
|
+
onClick: () => setShowChats(true),
|
|
2747
3444
|
style: {
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
3445
|
+
border: `1px solid ${t.inputBorder}`,
|
|
3446
|
+
borderRadius: "999px",
|
|
3447
|
+
background: "transparent",
|
|
3448
|
+
color: t.textMuted,
|
|
3449
|
+
padding: "7px 13px",
|
|
3450
|
+
fontSize: "12px",
|
|
3451
|
+
fontFamily: "inherit",
|
|
3452
|
+
cursor: "pointer"
|
|
2754
3453
|
},
|
|
2755
|
-
children:
|
|
3454
|
+
children: "All chats"
|
|
2756
3455
|
}
|
|
2757
3456
|
)
|
|
2758
3457
|
] })
|
|
3458
|
+
]
|
|
3459
|
+
}
|
|
3460
|
+
),
|
|
3461
|
+
/* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
3462
|
+
/* @__PURE__ */ jsx3(Avatar, { who: "assistant", theme: t }),
|
|
3463
|
+
/* @__PURE__ */ jsxs3(
|
|
3464
|
+
"div",
|
|
3465
|
+
{
|
|
3466
|
+
style: {
|
|
3467
|
+
padding: "9px 12px",
|
|
3468
|
+
borderRadius: "12px 12px 12px 4px",
|
|
3469
|
+
backgroundColor: t.bgSecondary,
|
|
3470
|
+
fontSize: "13px",
|
|
3471
|
+
lineHeight: 1.55,
|
|
3472
|
+
maxWidth: "88%"
|
|
3473
|
+
},
|
|
3474
|
+
children: [
|
|
3475
|
+
reporterName ? `Hi ${reporterName.split(" ")[0]} \u2014 t` : "T",
|
|
3476
|
+
"ell me what went wrong in your own words. I can already see your screenshot and what you clicked, so skip the boring parts."
|
|
3477
|
+
]
|
|
2759
3478
|
}
|
|
2760
3479
|
)
|
|
2761
|
-
] },
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
children: [
|
|
2773
|
-
/* @__PURE__ */ jsx3(Avatar, { who: m.role, theme: t, initials: initials2 }),
|
|
2774
|
-
/* @__PURE__ */ jsx3(
|
|
2775
|
-
"div",
|
|
2776
|
-
{
|
|
2777
|
-
style: {
|
|
2778
|
-
maxWidth: "82%",
|
|
2779
|
-
minWidth: 0,
|
|
2780
|
-
padding: "9px 12px",
|
|
2781
|
-
borderRadius: mine ? "12px 12px 4px 12px" : "12px 12px 12px 4px",
|
|
2782
|
-
fontSize: "13px",
|
|
2783
|
-
lineHeight: 1.55,
|
|
2784
|
-
// Markdown owns the assistant's line breaks and lists.
|
|
2785
|
-
whiteSpace: mine ? "pre-wrap" : "normal",
|
|
2786
|
-
wordBreak: "break-word",
|
|
2787
|
-
backgroundColor: mine ? t.accent : t.bgSecondary,
|
|
2788
|
-
color: mine ? t.accentText : t.text
|
|
2789
|
-
},
|
|
2790
|
-
children: mine ? m.content : /* @__PURE__ */ jsx3(ChatMarkdown, { text: m.content, theme: t })
|
|
2791
|
-
}
|
|
2792
|
-
)
|
|
2793
|
-
]
|
|
2794
|
-
},
|
|
2795
|
-
i
|
|
2796
|
-
);
|
|
2797
|
-
}),
|
|
2798
|
-
duplicate && !busy && phase === "chat" && /* @__PURE__ */ jsx3("div", { style: { paddingLeft: "32px", minWidth: 0 }, children: renderKnownIssue({ title: false }) }),
|
|
2799
|
-
glitchgrabOffer && onReportGlitchgrabProblem && !busy && phase === "chat" && /* @__PURE__ */ jsx3("div", { style: { paddingLeft: "32px", minWidth: 0 }, children: /* @__PURE__ */ jsxs3(
|
|
2800
|
-
"div",
|
|
2801
|
-
{
|
|
2802
|
-
"data-gg-glitchgrab-offer": "",
|
|
2803
|
-
style: {
|
|
2804
|
-
display: "flex",
|
|
2805
|
-
flexDirection: "column",
|
|
2806
|
-
gap: "8px",
|
|
2807
|
-
padding: "10px",
|
|
2808
|
-
borderRadius: "8px",
|
|
2809
|
-
border: `1px solid ${t.accent}55`,
|
|
2810
|
-
backgroundColor: `${t.accent}14`,
|
|
2811
|
-
fontSize: "12px",
|
|
2812
|
-
lineHeight: 1.5
|
|
2813
|
-
},
|
|
2814
|
-
children: [
|
|
2815
|
-
/* @__PURE__ */ jsx3("span", { style: { color: t.text, fontWeight: 600 }, children: "This is about Glitchgrab, not this app" }),
|
|
2816
|
-
/* @__PURE__ */ jsx3("span", { style: { color: t.textMuted }, children: "It goes to the team that builds this reporter, with your chat attached." }),
|
|
2817
|
-
/* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexWrap: "wrap", gap: "6px" }, children: [
|
|
2818
|
-
/* @__PURE__ */ jsx3(
|
|
3480
|
+
] }),
|
|
3481
|
+
/* @__PURE__ */ jsx3(
|
|
3482
|
+
"div",
|
|
3483
|
+
{
|
|
3484
|
+
style: {
|
|
3485
|
+
display: "flex",
|
|
3486
|
+
flexWrap: "wrap",
|
|
3487
|
+
gap: "6px",
|
|
3488
|
+
paddingLeft: "32px"
|
|
3489
|
+
},
|
|
3490
|
+
children: STARTERS.map((s) => /* @__PURE__ */ jsx3(
|
|
2819
3491
|
"button",
|
|
2820
3492
|
{
|
|
2821
3493
|
type: "button",
|
|
2822
|
-
"data-gg-
|
|
3494
|
+
"data-gg-chip": "",
|
|
2823
3495
|
onClick: () => {
|
|
2824
|
-
logEvent("
|
|
2825
|
-
|
|
2826
|
-
onReportGlitchgrabProblem(
|
|
2827
|
-
messages.filter((m) => m.role === "user").map((m) => m.content.trim()).filter(Boolean).join("\n\n")
|
|
2828
|
-
);
|
|
3496
|
+
logEvent("starter_tap", s);
|
|
3497
|
+
send(s);
|
|
2829
3498
|
},
|
|
2830
3499
|
style: {
|
|
2831
|
-
|
|
3500
|
+
border: `1px solid ${t.inputBorder}`,
|
|
3501
|
+
background: "transparent",
|
|
3502
|
+
color: t.textMuted,
|
|
2832
3503
|
borderRadius: "999px",
|
|
2833
|
-
|
|
2834
|
-
backgroundColor: t.accent,
|
|
2835
|
-
color: t.accentText,
|
|
3504
|
+
padding: "6px 11px",
|
|
2836
3505
|
fontSize: "12px",
|
|
2837
|
-
fontWeight: 700,
|
|
2838
3506
|
fontFamily: "inherit",
|
|
2839
|
-
cursor: "pointer"
|
|
2840
|
-
// Both stretch, so on a phone each wrapped line reads as
|
|
2841
|
-
// a choice rather than one button left stranded.
|
|
2842
|
-
flex: "1 1 auto"
|
|
3507
|
+
cursor: "pointer"
|
|
2843
3508
|
},
|
|
2844
|
-
children:
|
|
2845
|
-
}
|
|
2846
|
-
|
|
3509
|
+
children: s
|
|
3510
|
+
},
|
|
3511
|
+
s
|
|
3512
|
+
))
|
|
3513
|
+
}
|
|
3514
|
+
)
|
|
3515
|
+
] }),
|
|
3516
|
+
messages.map((m, i) => {
|
|
3517
|
+
const mine = m.role === "user";
|
|
3518
|
+
if (m.kind === "report") {
|
|
3519
|
+
const live = phase === "draft" && i === messages.length - 1;
|
|
3520
|
+
return /* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "8px", minWidth: 0 }, children: [
|
|
3521
|
+
/* @__PURE__ */ jsx3(Avatar, { who: "assistant", theme: t }),
|
|
2847
3522
|
/* @__PURE__ */ jsx3(
|
|
2848
|
-
"
|
|
3523
|
+
"div",
|
|
2849
3524
|
{
|
|
2850
|
-
|
|
2851
|
-
"data-gg-glitchgrab-offer-no": "",
|
|
2852
|
-
onClick: () => {
|
|
2853
|
-
logEvent("glitchgrab_offer_declined");
|
|
2854
|
-
send("No \u2014 it's about this app, not the reporting tool");
|
|
2855
|
-
},
|
|
3525
|
+
"data-gg-draft-bubble": "",
|
|
2856
3526
|
style: {
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
3527
|
+
maxWidth: "82%",
|
|
3528
|
+
minWidth: 0,
|
|
3529
|
+
padding: "9px 12px",
|
|
3530
|
+
borderRadius: "12px 12px 12px 4px",
|
|
3531
|
+
fontSize: "13px",
|
|
3532
|
+
lineHeight: 1.55,
|
|
3533
|
+
backgroundColor: t.bgSecondary,
|
|
3534
|
+
color: t.text,
|
|
3535
|
+
border: live ? "none" : `1px solid ${t.accent}66`
|
|
2866
3536
|
},
|
|
2867
|
-
children:
|
|
3537
|
+
children: live ? (
|
|
3538
|
+
// #402: "have a read" beside a countdown reads as a
|
|
3539
|
+
// contradiction. Say what is about to happen instead.
|
|
3540
|
+
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."
|
|
3541
|
+
) : /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
3542
|
+
/* @__PURE__ */ jsx3(
|
|
3543
|
+
"span",
|
|
3544
|
+
{
|
|
3545
|
+
style: {
|
|
3546
|
+
display: "block",
|
|
3547
|
+
fontSize: "10px",
|
|
3548
|
+
fontWeight: 700,
|
|
3549
|
+
letterSpacing: ".06em",
|
|
3550
|
+
textTransform: "uppercase",
|
|
3551
|
+
color: t.accent,
|
|
3552
|
+
marginBottom: "4px"
|
|
3553
|
+
},
|
|
3554
|
+
children: "Draft so far"
|
|
3555
|
+
}
|
|
3556
|
+
),
|
|
3557
|
+
/* @__PURE__ */ jsx3(
|
|
3558
|
+
"span",
|
|
3559
|
+
{
|
|
3560
|
+
style: {
|
|
3561
|
+
display: "block",
|
|
3562
|
+
whiteSpace: "pre-wrap",
|
|
3563
|
+
wordBreak: "break-word",
|
|
3564
|
+
maxHeight: "160px",
|
|
3565
|
+
overflowY: "auto",
|
|
3566
|
+
color: t.textMuted
|
|
3567
|
+
},
|
|
3568
|
+
children: m.content
|
|
3569
|
+
}
|
|
3570
|
+
)
|
|
3571
|
+
] })
|
|
2868
3572
|
}
|
|
2869
3573
|
)
|
|
2870
|
-
] })
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
options.length > 0 && !busy && phase === "chat" && !glitchgrabOffer && /* @__PURE__ */ jsx3(
|
|
2875
|
-
"div",
|
|
2876
|
-
{
|
|
2877
|
-
style: {
|
|
2878
|
-
display: "flex",
|
|
2879
|
-
// Long labels wrapped into a ragged row that always stranded
|
|
2880
|
-
// the last chip on a line of its own. Past ~24 characters
|
|
2881
|
-
// these stop being chips and become a choice list, so they
|
|
2882
|
-
// stack full width and read like one.
|
|
2883
|
-
flexDirection: options.some((o) => o.length > 24) ? "column" : "row",
|
|
2884
|
-
alignItems: options.some((o) => o.length > 24) ? "stretch" : "flex-start",
|
|
2885
|
-
flexWrap: "wrap",
|
|
2886
|
-
gap: "6px",
|
|
2887
|
-
paddingLeft: "32px"
|
|
2888
|
-
},
|
|
2889
|
-
children: options.map((option) => /* @__PURE__ */ jsx3(
|
|
2890
|
-
"button",
|
|
3574
|
+
] }, i);
|
|
3575
|
+
}
|
|
3576
|
+
return /* @__PURE__ */ jsxs3(
|
|
3577
|
+
"div",
|
|
2891
3578
|
{
|
|
2892
|
-
type: "button",
|
|
2893
|
-
"data-gg-chip": "",
|
|
2894
|
-
"data-gg-option": "",
|
|
2895
|
-
onClick: () => {
|
|
2896
|
-
logEvent("option_tap", option);
|
|
2897
|
-
send(option, option === CONFIRM_OPTION);
|
|
2898
|
-
},
|
|
2899
3579
|
style: {
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
// Same 8px as the picker chips — one tap target size in
|
|
2905
|
-
// this sheet, not two.
|
|
2906
|
-
padding: "8px 12px",
|
|
2907
|
-
fontSize: "12px",
|
|
2908
|
-
fontFamily: "inherit",
|
|
2909
|
-
cursor: "pointer",
|
|
2910
|
-
textAlign: "left"
|
|
3580
|
+
display: "flex",
|
|
3581
|
+
gap: "8px",
|
|
3582
|
+
minWidth: 0,
|
|
3583
|
+
flexDirection: mine ? "row-reverse" : "row"
|
|
2911
3584
|
},
|
|
2912
|
-
children:
|
|
3585
|
+
children: [
|
|
3586
|
+
/* @__PURE__ */ jsx3(Avatar, { who: m.role, theme: t, initials: initials2 }),
|
|
3587
|
+
/* @__PURE__ */ jsx3(
|
|
3588
|
+
"div",
|
|
3589
|
+
{
|
|
3590
|
+
style: {
|
|
3591
|
+
maxWidth: "82%",
|
|
3592
|
+
minWidth: 0,
|
|
3593
|
+
padding: "9px 12px",
|
|
3594
|
+
borderRadius: mine ? "12px 12px 4px 12px" : "12px 12px 12px 4px",
|
|
3595
|
+
fontSize: "13px",
|
|
3596
|
+
lineHeight: 1.55,
|
|
3597
|
+
// Markdown owns the assistant's line breaks and lists.
|
|
3598
|
+
whiteSpace: mine ? "pre-wrap" : "normal",
|
|
3599
|
+
wordBreak: "break-word",
|
|
3600
|
+
backgroundColor: mine ? t.accent : t.bgSecondary,
|
|
3601
|
+
color: mine ? t.accentText : t.text
|
|
3602
|
+
},
|
|
3603
|
+
children: mine ? m.content : /* @__PURE__ */ jsx3(ChatMarkdown, { text: m.content, theme: t })
|
|
3604
|
+
}
|
|
3605
|
+
)
|
|
3606
|
+
]
|
|
2913
3607
|
},
|
|
2914
|
-
|
|
2915
|
-
)
|
|
2916
|
-
}
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
/* @__PURE__ */ jsx3(
|
|
2921
|
-
"span",
|
|
3608
|
+
i
|
|
3609
|
+
);
|
|
3610
|
+
}),
|
|
3611
|
+
duplicate && !busy && phase === "chat" && /* @__PURE__ */ jsx3("div", { style: { paddingLeft: "32px", minWidth: 0 }, children: renderKnownIssue({ title: false }) }),
|
|
3612
|
+
glitchgrabOffer && onReportGlitchgrabProblem && !busy && phase === "chat" && /* @__PURE__ */ jsx3("div", { style: { paddingLeft: "32px", minWidth: 0 }, children: /* @__PURE__ */ jsxs3(
|
|
3613
|
+
"div",
|
|
2922
3614
|
{
|
|
3615
|
+
"data-gg-glitchgrab-offer": "",
|
|
2923
3616
|
style: {
|
|
2924
|
-
display: "
|
|
2925
|
-
|
|
2926
|
-
gap: "
|
|
2927
|
-
padding: "
|
|
2928
|
-
borderRadius: "
|
|
2929
|
-
|
|
3617
|
+
display: "flex",
|
|
3618
|
+
flexDirection: "column",
|
|
3619
|
+
gap: "8px",
|
|
3620
|
+
padding: "10px",
|
|
3621
|
+
borderRadius: "8px",
|
|
3622
|
+
border: `1px solid ${t.accent}55`,
|
|
3623
|
+
backgroundColor: `${t.accent}14`,
|
|
3624
|
+
fontSize: "12px",
|
|
3625
|
+
lineHeight: 1.5
|
|
2930
3626
|
},
|
|
2931
|
-
children: [
|
|
2932
|
-
"span",
|
|
2933
|
-
{
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
3627
|
+
children: [
|
|
3628
|
+
/* @__PURE__ */ jsx3("span", { style: { color: t.text, fontWeight: 600 }, children: "This is about Glitchgrab, not this app" }),
|
|
3629
|
+
/* @__PURE__ */ jsx3("span", { style: { color: t.textMuted }, children: "It goes to the team that builds this reporter, with your chat attached." }),
|
|
3630
|
+
/* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexWrap: "wrap", gap: "6px" }, children: [
|
|
3631
|
+
/* @__PURE__ */ jsx3(
|
|
3632
|
+
"button",
|
|
3633
|
+
{
|
|
3634
|
+
type: "button",
|
|
3635
|
+
"data-gg-glitchgrab-offer-send": "",
|
|
3636
|
+
onClick: () => {
|
|
3637
|
+
logEvent("glitchgrab_offer_tap");
|
|
3638
|
+
setGlitchgrabOffer(false);
|
|
3639
|
+
onReportGlitchgrabProblem(
|
|
3640
|
+
messages.filter((m) => m.role === "user").map((m) => m.content.trim()).filter(Boolean).join("\n\n")
|
|
3641
|
+
);
|
|
3642
|
+
},
|
|
3643
|
+
style: {
|
|
3644
|
+
padding: "8px 12px",
|
|
3645
|
+
borderRadius: "999px",
|
|
3646
|
+
border: "none",
|
|
3647
|
+
backgroundColor: t.accent,
|
|
3648
|
+
color: t.accentText,
|
|
3649
|
+
fontSize: "12px",
|
|
3650
|
+
fontWeight: 700,
|
|
3651
|
+
fontFamily: "inherit",
|
|
3652
|
+
cursor: "pointer",
|
|
3653
|
+
// Both stretch, so on a phone each wrapped line reads as
|
|
3654
|
+
// a choice rather than one button left stranded.
|
|
3655
|
+
flex: "1 1 auto"
|
|
3656
|
+
},
|
|
3657
|
+
children: "Send to the Glitchgrab team"
|
|
3658
|
+
}
|
|
3659
|
+
),
|
|
3660
|
+
/* @__PURE__ */ jsx3(
|
|
3661
|
+
"button",
|
|
3662
|
+
{
|
|
3663
|
+
type: "button",
|
|
3664
|
+
"data-gg-glitchgrab-offer-no": "",
|
|
3665
|
+
onClick: () => {
|
|
3666
|
+
logEvent("glitchgrab_offer_declined");
|
|
3667
|
+
send("No \u2014 it's about this app, not the reporting tool");
|
|
3668
|
+
},
|
|
3669
|
+
style: {
|
|
3670
|
+
padding: "8px 12px",
|
|
3671
|
+
borderRadius: "999px",
|
|
3672
|
+
border: `1px solid ${t.inputBorder}`,
|
|
3673
|
+
background: "transparent",
|
|
3674
|
+
color: t.textMuted,
|
|
3675
|
+
fontSize: "12px",
|
|
3676
|
+
fontFamily: "inherit",
|
|
3677
|
+
cursor: "pointer",
|
|
3678
|
+
flex: "1 1 auto"
|
|
3679
|
+
},
|
|
3680
|
+
children: "No, it's about this app"
|
|
3681
|
+
}
|
|
3682
|
+
)
|
|
3683
|
+
] })
|
|
3684
|
+
]
|
|
2944
3685
|
}
|
|
2945
|
-
)
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
"span",
|
|
2964
|
-
{
|
|
2965
|
-
style: {
|
|
2966
|
-
fontSize: "10px",
|
|
2967
|
-
fontWeight: 700,
|
|
2968
|
-
letterSpacing: ".06em",
|
|
2969
|
-
textTransform: "uppercase",
|
|
2970
|
-
color: t.accent
|
|
2971
|
-
},
|
|
2972
|
-
children: duplicate ? `What we'll add to #${duplicate.number}${duplicate.kind === "related" ? " as a related request" : ""} \xB7 edit anything` : "Your report \xB7 edit anything"
|
|
2973
|
-
}
|
|
2974
|
-
),
|
|
2975
|
-
renderKnownIssue({
|
|
2976
|
-
title: true,
|
|
2977
|
-
footer: "Your details will be added to it instead of opening a new issue."
|
|
2978
|
-
}),
|
|
2979
|
-
!duplicate && issueTitle && // Wraps rather than scrolls sideways: a title cut off at the
|
|
2980
|
-
// box edge is the very thing #543 is about. One line of text,
|
|
2981
|
-
// so Enter is swallowed.
|
|
2982
|
-
/* @__PURE__ */ jsx3(
|
|
2983
|
-
"textarea",
|
|
3686
|
+
) }),
|
|
3687
|
+
options.length > 0 && !busy && phase === "chat" && !glitchgrabOffer && /* @__PURE__ */ jsx3(
|
|
3688
|
+
"div",
|
|
3689
|
+
{
|
|
3690
|
+
style: {
|
|
3691
|
+
display: "flex",
|
|
3692
|
+
// Long labels wrapped into a ragged row that always stranded
|
|
3693
|
+
// the last chip on a line of its own. Past ~24 characters
|
|
3694
|
+
// these stop being chips and become a choice list, so they
|
|
3695
|
+
// stack full width and read like one.
|
|
3696
|
+
flexDirection: options.some((o) => o.length > 24) ? "column" : "row",
|
|
3697
|
+
alignItems: options.some((o) => o.length > 24) ? "stretch" : "flex-start",
|
|
3698
|
+
flexWrap: "wrap",
|
|
3699
|
+
gap: "6px",
|
|
3700
|
+
paddingLeft: "32px"
|
|
3701
|
+
},
|
|
3702
|
+
children: options.map((option) => /* @__PURE__ */ jsx3(
|
|
3703
|
+
"button",
|
|
2984
3704
|
{
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
},
|
|
2992
|
-
onChange: (e) => {
|
|
2993
|
-
stopAutoFile("edited the title");
|
|
2994
|
-
onIssueTitleChange(e.target.value.replace(/[\r\n]+/g, " "));
|
|
3705
|
+
type: "button",
|
|
3706
|
+
"data-gg-chip": "",
|
|
3707
|
+
"data-gg-option": "",
|
|
3708
|
+
onClick: () => {
|
|
3709
|
+
logEvent("option_tap", option);
|
|
3710
|
+
send(option, option === CONFIRM_OPTION);
|
|
2995
3711
|
},
|
|
2996
3712
|
style: {
|
|
2997
|
-
width: "100%",
|
|
2998
|
-
padding: "8px 10px",
|
|
2999
|
-
lineHeight: 1.45,
|
|
3000
|
-
resize: "none",
|
|
3001
|
-
borderRadius: "8px",
|
|
3002
3713
|
border: `1px solid ${t.inputBorder}`,
|
|
3003
|
-
|
|
3004
|
-
color: t.
|
|
3005
|
-
|
|
3006
|
-
|
|
3714
|
+
background: "transparent",
|
|
3715
|
+
color: t.textMuted,
|
|
3716
|
+
borderRadius: "999px",
|
|
3717
|
+
// Same 8px as the picker chips — one tap target size in
|
|
3718
|
+
// this sheet, not two.
|
|
3719
|
+
padding: "8px 12px",
|
|
3720
|
+
fontSize: "12px",
|
|
3007
3721
|
fontFamily: "inherit",
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
}
|
|
3011
|
-
}
|
|
3012
|
-
),
|
|
3013
|
-
/* @__PURE__ */ jsx3(
|
|
3014
|
-
"textarea",
|
|
3015
|
-
{
|
|
3016
|
-
ref: draftRef,
|
|
3017
|
-
value: description,
|
|
3018
|
-
onChange: (e) => {
|
|
3019
|
-
stopAutoFile("edited the draft");
|
|
3020
|
-
onDescriptionChange(e.target.value);
|
|
3722
|
+
cursor: "pointer",
|
|
3723
|
+
textAlign: "left"
|
|
3021
3724
|
},
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3725
|
+
children: option
|
|
3726
|
+
},
|
|
3727
|
+
option
|
|
3728
|
+
))
|
|
3729
|
+
}
|
|
3730
|
+
),
|
|
3731
|
+
busy && /* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "8px", minWidth: 0 }, role: "status", "aria-label": "Thinking", children: [
|
|
3732
|
+
/* @__PURE__ */ jsx3(Avatar, { who: "assistant", theme: t }),
|
|
3733
|
+
/* @__PURE__ */ jsxs3(
|
|
3734
|
+
"span",
|
|
3735
|
+
{
|
|
3736
|
+
style: {
|
|
3737
|
+
display: "inline-flex",
|
|
3738
|
+
alignItems: "center",
|
|
3739
|
+
// The "still working" line must wrap on a phone, not push
|
|
3740
|
+
// the bubble past the sheet's edge.
|
|
3741
|
+
flexWrap: "wrap",
|
|
3742
|
+
minWidth: 0,
|
|
3743
|
+
gap: "4px",
|
|
3744
|
+
padding: "12px",
|
|
3745
|
+
borderRadius: "12px 12px 12px 4px",
|
|
3746
|
+
backgroundColor: t.bgSecondary
|
|
3747
|
+
},
|
|
3748
|
+
children: [
|
|
3749
|
+
[0, 1, 2].map((i) => /* @__PURE__ */ jsx3(
|
|
3750
|
+
"span",
|
|
3751
|
+
{
|
|
3752
|
+
style: {
|
|
3753
|
+
width: "5px",
|
|
3754
|
+
height: "5px",
|
|
3755
|
+
borderRadius: "50%",
|
|
3756
|
+
backgroundColor: t.textMuted,
|
|
3757
|
+
animation: `gg-dot 1.1s ease-in-out ${i * 0.15}s infinite`
|
|
3758
|
+
}
|
|
3759
|
+
},
|
|
3760
|
+
i
|
|
3761
|
+
)),
|
|
3762
|
+
/* @__PURE__ */ jsx3(ThinkingClock, { color: t.textMuted })
|
|
3763
|
+
]
|
|
3764
|
+
}
|
|
3765
|
+
)
|
|
3766
|
+
] }),
|
|
3767
|
+
phase === "draft" && !submitted && /* @__PURE__ */ jsxs3(
|
|
3768
|
+
"div",
|
|
3769
|
+
{
|
|
3770
|
+
style: {
|
|
3771
|
+
border: `1px solid ${t.accent}`,
|
|
3772
|
+
borderRadius: "12px",
|
|
3773
|
+
backgroundColor: t.bgSecondary,
|
|
3774
|
+
padding: "12px",
|
|
3775
|
+
display: "flex",
|
|
3776
|
+
flexDirection: "column",
|
|
3777
|
+
gap: "10px",
|
|
3778
|
+
minWidth: 0,
|
|
3779
|
+
boxSizing: "border-box"
|
|
3780
|
+
},
|
|
3781
|
+
children: [
|
|
3782
|
+
/* @__PURE__ */ jsx3(
|
|
3042
3783
|
"span",
|
|
3043
3784
|
{
|
|
3044
|
-
style: {
|
|
3045
|
-
fontSize: "
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3785
|
+
style: {
|
|
3786
|
+
fontSize: "10px",
|
|
3787
|
+
fontWeight: 700,
|
|
3788
|
+
letterSpacing: ".06em",
|
|
3789
|
+
textTransform: "uppercase",
|
|
3790
|
+
color: t.accent
|
|
3791
|
+
},
|
|
3792
|
+
children: duplicate ? `What we'll add to #${duplicate.number}${duplicate.kind === "related" ? " as a related request" : ""} \xB7 edit anything` : "Your report \xB7 edit anything"
|
|
3793
|
+
}
|
|
3794
|
+
),
|
|
3795
|
+
renderKnownIssue({
|
|
3796
|
+
title: true,
|
|
3797
|
+
footer: "Your details will be added to it instead of opening a new issue."
|
|
3798
|
+
}),
|
|
3799
|
+
!duplicate && issueTitle && // Wraps rather than scrolls sideways: a title cut off at the
|
|
3800
|
+
// box edge is the very thing #543 is about. One line of text,
|
|
3801
|
+
// so Enter is swallowed.
|
|
3802
|
+
/* @__PURE__ */ jsx3(
|
|
3803
|
+
"textarea",
|
|
3804
|
+
{
|
|
3805
|
+
"aria-label": "Title",
|
|
3806
|
+
value: issueTitle,
|
|
3807
|
+
maxLength: 120,
|
|
3808
|
+
rows: 2,
|
|
3809
|
+
onKeyDown: (e) => {
|
|
3810
|
+
if (e.key === "Enter") e.preventDefault();
|
|
3049
3811
|
},
|
|
3050
|
-
|
|
3051
|
-
"
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3812
|
+
onChange: (e) => {
|
|
3813
|
+
stopAutoFile("edited the title");
|
|
3814
|
+
onIssueTitleChange(e.target.value.replace(/[\r\n]+/g, " "));
|
|
3815
|
+
},
|
|
3816
|
+
style: {
|
|
3817
|
+
width: "100%",
|
|
3818
|
+
padding: "8px 10px",
|
|
3819
|
+
lineHeight: 1.45,
|
|
3820
|
+
resize: "none",
|
|
3821
|
+
borderRadius: "8px",
|
|
3822
|
+
border: `1px solid ${t.inputBorder}`,
|
|
3823
|
+
backgroundColor: t.inputBg,
|
|
3824
|
+
color: t.text,
|
|
3825
|
+
fontSize: "13px",
|
|
3826
|
+
fontWeight: 600,
|
|
3827
|
+
fontFamily: "inherit",
|
|
3828
|
+
outline: "none",
|
|
3829
|
+
boxSizing: "border-box"
|
|
3830
|
+
}
|
|
3064
3831
|
}
|
|
3065
3832
|
),
|
|
3066
3833
|
/* @__PURE__ */ jsx3(
|
|
3067
|
-
"
|
|
3834
|
+
"textarea",
|
|
3068
3835
|
{
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
fontFamily: "inherit",
|
|
3092
|
-
whiteSpace: "nowrap",
|
|
3093
|
-
overflow: "hidden",
|
|
3094
|
-
textOverflow: "ellipsis",
|
|
3095
|
-
cursor: "pointer"
|
|
3096
|
-
},
|
|
3097
|
-
children: SEVERITY_LABELS[s]
|
|
3098
|
-
},
|
|
3099
|
-
s
|
|
3100
|
-
);
|
|
3101
|
-
})
|
|
3836
|
+
ref: draftRef,
|
|
3837
|
+
value: description,
|
|
3838
|
+
onChange: (e) => {
|
|
3839
|
+
stopAutoFile("edited the draft");
|
|
3840
|
+
onDescriptionChange(e.target.value);
|
|
3841
|
+
},
|
|
3842
|
+
rows: 6,
|
|
3843
|
+
style: {
|
|
3844
|
+
width: "100%",
|
|
3845
|
+
minHeight: "120px",
|
|
3846
|
+
padding: "10px",
|
|
3847
|
+
borderRadius: "8px",
|
|
3848
|
+
border: `1px solid ${t.inputBorder}`,
|
|
3849
|
+
backgroundColor: t.inputBg,
|
|
3850
|
+
color: t.text,
|
|
3851
|
+
fontSize: "13px",
|
|
3852
|
+
lineHeight: 1.55,
|
|
3853
|
+
fontFamily: "inherit",
|
|
3854
|
+
resize: "vertical",
|
|
3855
|
+
outline: "none",
|
|
3856
|
+
boxSizing: "border-box"
|
|
3857
|
+
}
|
|
3102
3858
|
}
|
|
3103
|
-
)
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3859
|
+
),
|
|
3860
|
+
severityAsked && autoFileLeft === null && /* @__PURE__ */ jsxs3("div", { children: [
|
|
3861
|
+
/* @__PURE__ */ jsxs3(
|
|
3862
|
+
"span",
|
|
3863
|
+
{
|
|
3864
|
+
style: {
|
|
3865
|
+
fontSize: "11.5px",
|
|
3866
|
+
color: t.textMuted,
|
|
3867
|
+
display: "block",
|
|
3868
|
+
marginBottom: "6px"
|
|
3869
|
+
},
|
|
3870
|
+
children: [
|
|
3871
|
+
"How bad is it?",
|
|
3872
|
+
!severity && /* @__PURE__ */ jsx3(
|
|
3873
|
+
"span",
|
|
3874
|
+
{
|
|
3875
|
+
style: {
|
|
3876
|
+
marginLeft: "6px",
|
|
3877
|
+
fontSize: "11px",
|
|
3878
|
+
color: severityRefused ? "#ef4444" : t.textMuted
|
|
3879
|
+
},
|
|
3880
|
+
children: "\xB7 required"
|
|
3881
|
+
}
|
|
3882
|
+
)
|
|
3883
|
+
]
|
|
3884
|
+
}
|
|
3885
|
+
),
|
|
3886
|
+
/* @__PURE__ */ jsx3(
|
|
3887
|
+
"div",
|
|
3888
|
+
{
|
|
3889
|
+
role: "radiogroup",
|
|
3890
|
+
"aria-label": "Severity",
|
|
3891
|
+
style: { display: "flex", gap: "6px" },
|
|
3892
|
+
children: SEVERITY_LEVELS.map((s) => {
|
|
3893
|
+
const on = severity === s;
|
|
3894
|
+
return /* @__PURE__ */ jsx3(
|
|
3895
|
+
"button",
|
|
3896
|
+
{
|
|
3897
|
+
type: "button",
|
|
3898
|
+
onClick: () => onSeverityChange(s),
|
|
3899
|
+
role: "radio",
|
|
3900
|
+
"aria-checked": on,
|
|
3901
|
+
style: {
|
|
3902
|
+
flex: 1,
|
|
3903
|
+
minWidth: 0,
|
|
3904
|
+
padding: "8px 2px",
|
|
3905
|
+
borderRadius: "8px",
|
|
3906
|
+
border: `1px solid ${on ? t.accent : severityRefused ? "#ef4444" : t.inputBorder}`,
|
|
3907
|
+
backgroundColor: on ? t.accent : "transparent",
|
|
3908
|
+
color: on ? t.accentText : t.textMuted,
|
|
3909
|
+
fontSize: "12px",
|
|
3910
|
+
fontWeight: 600,
|
|
3911
|
+
fontFamily: "inherit",
|
|
3912
|
+
whiteSpace: "nowrap",
|
|
3913
|
+
overflow: "hidden",
|
|
3914
|
+
textOverflow: "ellipsis",
|
|
3915
|
+
cursor: "pointer"
|
|
3916
|
+
},
|
|
3917
|
+
children: SEVERITY_LABELS[s]
|
|
3918
|
+
},
|
|
3919
|
+
s
|
|
3920
|
+
);
|
|
3921
|
+
})
|
|
3922
|
+
}
|
|
3923
|
+
)
|
|
3924
|
+
] }),
|
|
3925
|
+
attachmentCount > 0 && /* @__PURE__ */ jsxs3("span", { style: { fontSize: "11.5px", color: t.textMuted }, children: [
|
|
3926
|
+
attachmentCount,
|
|
3927
|
+
" ",
|
|
3928
|
+
attachmentCount === 1 ? "attachment" : "attachments",
|
|
3929
|
+
" will be sent with this."
|
|
3930
|
+
] })
|
|
3931
|
+
]
|
|
3932
|
+
}
|
|
3933
|
+
),
|
|
3934
|
+
phase === "solved" && solved && /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
|
|
3935
|
+
/* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
3936
|
+
/* @__PURE__ */ jsx3(Avatar, { who: "assistant", theme: t }),
|
|
3937
|
+
/* @__PURE__ */ jsx3(
|
|
3938
|
+
"div",
|
|
3939
|
+
{
|
|
3940
|
+
style: {
|
|
3941
|
+
padding: "9px 12px",
|
|
3942
|
+
borderRadius: "12px 12px 12px 4px",
|
|
3943
|
+
backgroundColor: t.bgSecondary,
|
|
3944
|
+
fontSize: "13px",
|
|
3945
|
+
lineHeight: 1.55,
|
|
3946
|
+
maxWidth: "88%",
|
|
3947
|
+
whiteSpace: "pre-wrap"
|
|
3948
|
+
},
|
|
3949
|
+
children: solved
|
|
3950
|
+
}
|
|
3951
|
+
)
|
|
3952
|
+
] }),
|
|
3117
3953
|
/* @__PURE__ */ jsx3(
|
|
3118
|
-
"
|
|
3954
|
+
"span",
|
|
3119
3955
|
{
|
|
3120
|
-
style: {
|
|
3121
|
-
|
|
3122
|
-
borderRadius: "12px 12px 12px 4px",
|
|
3123
|
-
backgroundColor: t.bgSecondary,
|
|
3124
|
-
fontSize: "13px",
|
|
3125
|
-
lineHeight: 1.55,
|
|
3126
|
-
maxWidth: "88%",
|
|
3127
|
-
whiteSpace: "pre-wrap"
|
|
3128
|
-
},
|
|
3129
|
-
children: solved
|
|
3956
|
+
style: { fontSize: "11.5px", color: t.textMuted, paddingLeft: "32px" },
|
|
3957
|
+
children: "Nothing was filed \u2014 you are all set."
|
|
3130
3958
|
}
|
|
3131
3959
|
)
|
|
3132
3960
|
] }),
|
|
3133
|
-
/* @__PURE__ */ jsx3(
|
|
3134
|
-
"
|
|
3961
|
+
submitted && /* @__PURE__ */ jsx3(
|
|
3962
|
+
"div",
|
|
3135
3963
|
{
|
|
3136
|
-
style: {
|
|
3137
|
-
|
|
3964
|
+
style: {
|
|
3965
|
+
textAlign: "center",
|
|
3966
|
+
padding: "24px 0",
|
|
3967
|
+
color: t.accent,
|
|
3968
|
+
fontSize: "14px",
|
|
3969
|
+
fontWeight: 600
|
|
3970
|
+
},
|
|
3971
|
+
children: submittedText != null ? submittedText : `${reportTypeLabel} sent. Thank you!`
|
|
3138
3972
|
}
|
|
3139
3973
|
)
|
|
3140
|
-
] })
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
style: {
|
|
3145
|
-
textAlign: "center",
|
|
3146
|
-
padding: "24px 0",
|
|
3147
|
-
color: t.accent,
|
|
3148
|
-
fontSize: "14px",
|
|
3149
|
-
fontWeight: 600
|
|
3150
|
-
},
|
|
3151
|
-
children: [
|
|
3152
|
-
reportTypeLabel,
|
|
3153
|
-
" sent. Thank you!"
|
|
3154
|
-
]
|
|
3155
|
-
}
|
|
3156
|
-
)
|
|
3157
|
-
]
|
|
3158
|
-
}
|
|
3159
|
-
)
|
|
3974
|
+
] })
|
|
3975
|
+
}
|
|
3976
|
+
)
|
|
3977
|
+
]
|
|
3160
3978
|
}
|
|
3161
3979
|
),
|
|
3162
|
-
!submitted && phase !== "type" && phase !== "severity" && /* @__PURE__ */ jsxs3(
|
|
3980
|
+
!submitted && !showChats && phase !== "type" && phase !== "severity" && /* @__PURE__ */ jsxs3(
|
|
3163
3981
|
"div",
|
|
3164
3982
|
{
|
|
3165
3983
|
style: {
|
|
@@ -3217,342 +4035,363 @@ function AssistSheet({
|
|
|
3217
4035
|
// instead of remounting, and a draft is something you can
|
|
3218
4036
|
// still reply to (#360), not a form that replaced the chat.
|
|
3219
4037
|
/* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
3220
|
-
(
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
4038
|
+
/* @__PURE__ */ jsxs3("div", { style: { display: similarSlot ? "none" : "contents" }, children: [
|
|
4039
|
+
(screenshots.length > 0 || files.length > 0 || onAddFiles) && /* @__PURE__ */ jsxs3(
|
|
4040
|
+
"div",
|
|
4041
|
+
{
|
|
4042
|
+
style: {
|
|
4043
|
+
display: "flex",
|
|
4044
|
+
gap: "8px",
|
|
4045
|
+
alignItems: "center",
|
|
4046
|
+
flexWrap: "wrap",
|
|
4047
|
+
marginBottom: "8px"
|
|
4048
|
+
},
|
|
4049
|
+
children: [
|
|
4050
|
+
screenshots.map((shot, i) => {
|
|
4051
|
+
const read = readShots.has(shot);
|
|
4052
|
+
return /* @__PURE__ */ jsxs3(
|
|
4053
|
+
"div",
|
|
4054
|
+
{
|
|
4055
|
+
style: {
|
|
4056
|
+
position: "relative",
|
|
4057
|
+
width: "40px",
|
|
4058
|
+
height: "40px",
|
|
4059
|
+
flexShrink: 0
|
|
4060
|
+
},
|
|
4061
|
+
children: [
|
|
4062
|
+
/* @__PURE__ */ jsx3(
|
|
4063
|
+
"img",
|
|
4064
|
+
{
|
|
4065
|
+
src: shot,
|
|
4066
|
+
alt: read ? "Attached image the assistant reads" : "Attached image",
|
|
4067
|
+
"data-gg-assist-thumb": "",
|
|
4068
|
+
style: {
|
|
4069
|
+
display: "block",
|
|
4070
|
+
width: "100%",
|
|
4071
|
+
height: "100%",
|
|
4072
|
+
objectFit: "cover",
|
|
4073
|
+
borderRadius: "8px",
|
|
4074
|
+
border: `1px solid ${read ? t.accent : t.inputBorder}`,
|
|
4075
|
+
opacity: read ? 1 : 0.45,
|
|
4076
|
+
boxSizing: "border-box"
|
|
4077
|
+
}
|
|
3258
4078
|
}
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
}
|
|
3315
|
-
|
|
4079
|
+
),
|
|
4080
|
+
onRemoveImage && /* @__PURE__ */ jsx3(
|
|
4081
|
+
"button",
|
|
4082
|
+
{
|
|
4083
|
+
type: "button",
|
|
4084
|
+
"data-gg-assist-remove": "",
|
|
4085
|
+
"aria-label": `Remove image ${i + 1}`,
|
|
4086
|
+
title: "Remove this image",
|
|
4087
|
+
onClick: () => {
|
|
4088
|
+
stopAutoFile("changed attachments");
|
|
4089
|
+
logEvent(
|
|
4090
|
+
"image_removed",
|
|
4091
|
+
pageShot && shot === pageShot ? "page capture" : "attached"
|
|
4092
|
+
);
|
|
4093
|
+
onRemoveImage(i);
|
|
4094
|
+
},
|
|
4095
|
+
style: {
|
|
4096
|
+
position: "absolute",
|
|
4097
|
+
top: "-13px",
|
|
4098
|
+
right: "-13px",
|
|
4099
|
+
width: "32px",
|
|
4100
|
+
height: "32px",
|
|
4101
|
+
border: "none",
|
|
4102
|
+
background: "transparent",
|
|
4103
|
+
padding: 0,
|
|
4104
|
+
cursor: "pointer",
|
|
4105
|
+
display: "flex",
|
|
4106
|
+
alignItems: "center",
|
|
4107
|
+
justifyContent: "center",
|
|
4108
|
+
borderRadius: "50%"
|
|
4109
|
+
},
|
|
4110
|
+
children: /* @__PURE__ */ jsx3(
|
|
4111
|
+
"span",
|
|
4112
|
+
{
|
|
4113
|
+
"aria-hidden": "true",
|
|
4114
|
+
style: {
|
|
4115
|
+
width: "20px",
|
|
4116
|
+
height: "20px",
|
|
4117
|
+
boxSizing: "border-box",
|
|
4118
|
+
borderRadius: "50%",
|
|
4119
|
+
border: `2px solid ${t.bg}`,
|
|
4120
|
+
background: "#ef4444",
|
|
4121
|
+
color: "#fff",
|
|
4122
|
+
display: "flex",
|
|
4123
|
+
alignItems: "center",
|
|
4124
|
+
justifyContent: "center"
|
|
4125
|
+
},
|
|
4126
|
+
children: /* @__PURE__ */ jsx3("svg", { width: "8", height: "8", viewBox: "0 0 10 10", fill: "none", children: /* @__PURE__ */ jsx3(
|
|
4127
|
+
"path",
|
|
4128
|
+
{
|
|
4129
|
+
d: "M1 1L9 9M9 1L1 9",
|
|
4130
|
+
stroke: "currentColor",
|
|
4131
|
+
strokeWidth: "1.6",
|
|
4132
|
+
strokeLinecap: "round"
|
|
4133
|
+
}
|
|
4134
|
+
) })
|
|
4135
|
+
}
|
|
4136
|
+
)
|
|
4137
|
+
}
|
|
4138
|
+
)
|
|
4139
|
+
]
|
|
4140
|
+
},
|
|
4141
|
+
`${i}-${shot.slice(-16)}`
|
|
4142
|
+
);
|
|
4143
|
+
}),
|
|
4144
|
+
files.map((file, i) => {
|
|
4145
|
+
const read = readFiles.has(i);
|
|
4146
|
+
const pdf = isPdfFile(file.name);
|
|
4147
|
+
const why = read ? "the assistant reads this file" : pdf && file.reading ? "reading the text in this PDF\u2026" : pdf && file.text !== void 0 ? file.text === null ? file.tooLarge ? "attached to the report \u2014 too large for the assistant to read (over 3 MB)" : "attached to the report \u2014 couldn't read this PDF" : file.text.trim() ? "attached, but more than one message can carry, so the assistant is not reading it" : "attached to the report \u2014 this PDF has no text to read (a scan?)" : isAssistReadableFile(file.name) ? "attached, but more than one message can carry, so the assistant is not reading it" : "attached to the report \u2014 the assistant can't read this kind of file";
|
|
4148
|
+
return /* @__PURE__ */ jsxs3(
|
|
4149
|
+
"div",
|
|
4150
|
+
{
|
|
4151
|
+
"data-gg-assist-file": "",
|
|
4152
|
+
"data-gg-assist-file-read": read ? "" : void 0,
|
|
4153
|
+
"data-gg-assist-file-reading": pdf && file.reading ? "" : void 0,
|
|
4154
|
+
title: `${file.name} \u2014 ${why}`,
|
|
4155
|
+
style: {
|
|
4156
|
+
position: "relative",
|
|
4157
|
+
height: "40px",
|
|
4158
|
+
maxWidth: "170px",
|
|
4159
|
+
display: "flex",
|
|
4160
|
+
alignItems: "center",
|
|
4161
|
+
gap: "6px",
|
|
4162
|
+
padding: "0 10px",
|
|
4163
|
+
borderRadius: "8px",
|
|
4164
|
+
border: `1px solid ${read ? t.accent : t.inputBorder}`,
|
|
4165
|
+
opacity: read || pdf && file.reading ? 1 : 0.55,
|
|
4166
|
+
boxSizing: "border-box",
|
|
4167
|
+
flexShrink: 0
|
|
4168
|
+
},
|
|
4169
|
+
children: [
|
|
4170
|
+
pdf && file.reading ? /* @__PURE__ */ jsx3(
|
|
4171
|
+
"span",
|
|
4172
|
+
{
|
|
4173
|
+
role: "status",
|
|
4174
|
+
"aria-label": "Reading this PDF",
|
|
4175
|
+
style: {
|
|
4176
|
+
width: "12px",
|
|
4177
|
+
height: "12px",
|
|
4178
|
+
flexShrink: 0,
|
|
4179
|
+
borderRadius: "50%",
|
|
4180
|
+
border: `1.5px solid ${t.inputBorder}`,
|
|
4181
|
+
borderTopColor: t.accent,
|
|
4182
|
+
boxSizing: "border-box",
|
|
4183
|
+
animation: "gg-spin .8s linear infinite"
|
|
3316
4184
|
}
|
|
3317
|
-
|
|
3318
|
-
}
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
4185
|
+
}
|
|
4186
|
+
) : /* @__PURE__ */ jsx3("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", style: { flexShrink: 0 }, children: /* @__PURE__ */ jsx3(
|
|
4187
|
+
"path",
|
|
4188
|
+
{
|
|
4189
|
+
d: "M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z M14 2v6h6",
|
|
4190
|
+
stroke: t.textMuted,
|
|
4191
|
+
strokeWidth: "1.5",
|
|
4192
|
+
strokeLinecap: "round",
|
|
4193
|
+
strokeLinejoin: "round"
|
|
4194
|
+
}
|
|
4195
|
+
) }),
|
|
4196
|
+
/* @__PURE__ */ jsx3(
|
|
4197
|
+
"span",
|
|
4198
|
+
{
|
|
4199
|
+
style: {
|
|
4200
|
+
fontSize: "11.5px",
|
|
4201
|
+
color: t.text,
|
|
4202
|
+
overflow: "hidden",
|
|
4203
|
+
textOverflow: "ellipsis",
|
|
4204
|
+
whiteSpace: "nowrap"
|
|
4205
|
+
},
|
|
4206
|
+
children: file.name
|
|
4207
|
+
}
|
|
4208
|
+
),
|
|
4209
|
+
onRemoveFile && /* @__PURE__ */ jsx3(
|
|
4210
|
+
"button",
|
|
4211
|
+
{
|
|
4212
|
+
type: "button",
|
|
4213
|
+
"data-gg-assist-remove-file": "",
|
|
4214
|
+
"aria-label": `Remove file ${file.name}`,
|
|
4215
|
+
title: "Remove this file",
|
|
4216
|
+
onClick: () => {
|
|
4217
|
+
stopAutoFile("changed attachments");
|
|
4218
|
+
logEvent("file_removed", read ? "read" : "not read");
|
|
4219
|
+
onRemoveFile(i);
|
|
4220
|
+
},
|
|
4221
|
+
style: {
|
|
4222
|
+
position: "absolute",
|
|
4223
|
+
top: "-13px",
|
|
4224
|
+
right: "-13px",
|
|
4225
|
+
width: "32px",
|
|
4226
|
+
height: "32px",
|
|
4227
|
+
border: "none",
|
|
4228
|
+
background: "transparent",
|
|
4229
|
+
padding: 0,
|
|
4230
|
+
cursor: "pointer",
|
|
4231
|
+
display: "flex",
|
|
4232
|
+
alignItems: "center",
|
|
4233
|
+
justifyContent: "center",
|
|
4234
|
+
borderRadius: "50%"
|
|
4235
|
+
},
|
|
4236
|
+
children: /* @__PURE__ */ jsx3(
|
|
4237
|
+
"span",
|
|
4238
|
+
{
|
|
4239
|
+
"aria-hidden": "true",
|
|
4240
|
+
style: {
|
|
4241
|
+
width: "20px",
|
|
4242
|
+
height: "20px",
|
|
4243
|
+
boxSizing: "border-box",
|
|
4244
|
+
borderRadius: "50%",
|
|
4245
|
+
border: `2px solid ${t.bg}`,
|
|
4246
|
+
background: "#ef4444",
|
|
4247
|
+
color: "#fff",
|
|
4248
|
+
display: "flex",
|
|
4249
|
+
alignItems: "center",
|
|
4250
|
+
justifyContent: "center"
|
|
4251
|
+
},
|
|
4252
|
+
children: /* @__PURE__ */ jsx3("svg", { width: "8", height: "8", viewBox: "0 0 10 10", fill: "none", children: /* @__PURE__ */ jsx3(
|
|
4253
|
+
"path",
|
|
4254
|
+
{
|
|
4255
|
+
d: "M1 1L9 9M9 1L1 9",
|
|
4256
|
+
stroke: "currentColor",
|
|
4257
|
+
strokeWidth: "1.6",
|
|
4258
|
+
strokeLinecap: "round"
|
|
4259
|
+
}
|
|
4260
|
+
) })
|
|
4261
|
+
}
|
|
4262
|
+
)
|
|
4263
|
+
}
|
|
4264
|
+
)
|
|
4265
|
+
]
|
|
4266
|
+
},
|
|
4267
|
+
`file-${i}-${file.name}`
|
|
4268
|
+
);
|
|
4269
|
+
}),
|
|
4270
|
+
onAddFiles && /* @__PURE__ */ jsxs3(
|
|
4271
|
+
"label",
|
|
3330
4272
|
{
|
|
3331
|
-
"data-gg-assist-
|
|
3332
|
-
"
|
|
3333
|
-
title: `${file.name} \u2014 ${why}`,
|
|
4273
|
+
"data-gg-assist-attach": "",
|
|
4274
|
+
title: "Attach an image or a file (html, json, log\u2026) \u2014 or paste one",
|
|
3334
4275
|
style: {
|
|
3335
|
-
|
|
4276
|
+
width: "40px",
|
|
3336
4277
|
height: "40px",
|
|
3337
|
-
maxWidth: "170px",
|
|
3338
|
-
display: "flex",
|
|
3339
|
-
alignItems: "center",
|
|
3340
|
-
gap: "6px",
|
|
3341
|
-
padding: "0 10px",
|
|
3342
4278
|
borderRadius: "8px",
|
|
3343
|
-
border: `1px
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
),
|
|
3372
|
-
onRemoveFile && /* @__PURE__ */ jsx3(
|
|
3373
|
-
"button",
|
|
3374
|
-
{
|
|
3375
|
-
type: "button",
|
|
3376
|
-
"data-gg-assist-remove-file": "",
|
|
3377
|
-
"aria-label": `Remove file ${file.name}`,
|
|
3378
|
-
title: "Remove this file",
|
|
3379
|
-
onClick: () => {
|
|
3380
|
-
stopAutoFile("changed attachments");
|
|
3381
|
-
logEvent("file_removed", read ? "read" : "not read");
|
|
3382
|
-
onRemoveFile(i);
|
|
3383
|
-
},
|
|
3384
|
-
style: {
|
|
3385
|
-
position: "absolute",
|
|
3386
|
-
top: "-13px",
|
|
3387
|
-
right: "-13px",
|
|
3388
|
-
width: "32px",
|
|
3389
|
-
height: "32px",
|
|
3390
|
-
border: "none",
|
|
3391
|
-
background: "transparent",
|
|
3392
|
-
padding: 0,
|
|
3393
|
-
cursor: "pointer",
|
|
3394
|
-
display: "flex",
|
|
3395
|
-
alignItems: "center",
|
|
3396
|
-
justifyContent: "center",
|
|
3397
|
-
borderRadius: "50%"
|
|
3398
|
-
},
|
|
3399
|
-
children: /* @__PURE__ */ jsx3(
|
|
3400
|
-
"span",
|
|
3401
|
-
{
|
|
3402
|
-
"aria-hidden": "true",
|
|
3403
|
-
style: {
|
|
3404
|
-
width: "20px",
|
|
3405
|
-
height: "20px",
|
|
3406
|
-
boxSizing: "border-box",
|
|
3407
|
-
borderRadius: "50%",
|
|
3408
|
-
border: `2px solid ${t.bg}`,
|
|
3409
|
-
background: "#ef4444",
|
|
3410
|
-
color: "#fff",
|
|
3411
|
-
display: "flex",
|
|
3412
|
-
alignItems: "center",
|
|
3413
|
-
justifyContent: "center"
|
|
3414
|
-
},
|
|
3415
|
-
children: /* @__PURE__ */ jsx3("svg", { width: "8", height: "8", viewBox: "0 0 10 10", fill: "none", children: /* @__PURE__ */ jsx3(
|
|
3416
|
-
"path",
|
|
3417
|
-
{
|
|
3418
|
-
d: "M1 1L9 9M9 1L1 9",
|
|
3419
|
-
stroke: "currentColor",
|
|
3420
|
-
strokeWidth: "1.6",
|
|
3421
|
-
strokeLinecap: "round"
|
|
3422
|
-
}
|
|
3423
|
-
) })
|
|
3424
|
-
}
|
|
3425
|
-
)
|
|
3426
|
-
}
|
|
3427
|
-
)
|
|
3428
|
-
]
|
|
3429
|
-
},
|
|
3430
|
-
`file-${i}-${file.name}`
|
|
3431
|
-
);
|
|
3432
|
-
}),
|
|
3433
|
-
onAddFiles && /* @__PURE__ */ jsxs3(
|
|
3434
|
-
"label",
|
|
3435
|
-
{
|
|
3436
|
-
"data-gg-assist-attach": "",
|
|
3437
|
-
title: "Attach an image or a file (html, json, log\u2026) \u2014 or paste one",
|
|
3438
|
-
style: {
|
|
3439
|
-
width: "40px",
|
|
3440
|
-
height: "40px",
|
|
3441
|
-
borderRadius: "8px",
|
|
3442
|
-
border: `1px dashed ${t.inputBorder}`,
|
|
3443
|
-
display: "inline-flex",
|
|
3444
|
-
alignItems: "center",
|
|
3445
|
-
justifyContent: "center",
|
|
3446
|
-
color: t.textMuted,
|
|
3447
|
-
fontSize: "18px",
|
|
3448
|
-
cursor: "pointer",
|
|
3449
|
-
flexShrink: 0
|
|
3450
|
-
},
|
|
3451
|
-
children: [
|
|
3452
|
-
"+",
|
|
3453
|
-
/* @__PURE__ */ jsx3(
|
|
3454
|
-
"input",
|
|
3455
|
-
{
|
|
3456
|
-
type: "file",
|
|
3457
|
-
accept: ASSIST_ATTACHMENT_ACCEPT,
|
|
3458
|
-
multiple: true,
|
|
3459
|
-
onChange: (e) => {
|
|
3460
|
-
var _a;
|
|
3461
|
-
const picked = Array.from((_a = e.target.files) != null ? _a : []);
|
|
3462
|
-
if (picked.length) {
|
|
3463
|
-
stopAutoFile("changed attachments");
|
|
3464
|
-
const images = picked.filter((f) => f.type.startsWith("image/")).length;
|
|
3465
|
-
if (images) logEvent("image_added", String(images));
|
|
3466
|
-
if (picked.length > images) {
|
|
3467
|
-
logEvent("file_added", String(picked.length - images));
|
|
4279
|
+
border: `1px dashed ${t.inputBorder}`,
|
|
4280
|
+
display: "inline-flex",
|
|
4281
|
+
alignItems: "center",
|
|
4282
|
+
justifyContent: "center",
|
|
4283
|
+
color: t.textMuted,
|
|
4284
|
+
fontSize: "18px",
|
|
4285
|
+
cursor: "pointer",
|
|
4286
|
+
flexShrink: 0
|
|
4287
|
+
},
|
|
4288
|
+
children: [
|
|
4289
|
+
"+",
|
|
4290
|
+
/* @__PURE__ */ jsx3(
|
|
4291
|
+
"input",
|
|
4292
|
+
{
|
|
4293
|
+
type: "file",
|
|
4294
|
+
accept: canReadPdf ? ASSIST_ATTACHMENT_ACCEPT_WITH_PDF : ASSIST_ATTACHMENT_ACCEPT,
|
|
4295
|
+
multiple: true,
|
|
4296
|
+
onChange: (e) => {
|
|
4297
|
+
var _a2;
|
|
4298
|
+
const picked = Array.from((_a2 = e.target.files) != null ? _a2 : []);
|
|
4299
|
+
if (picked.length) {
|
|
4300
|
+
stopAutoFile("changed attachments");
|
|
4301
|
+
const images = picked.filter((f) => f.type.startsWith("image/")).length;
|
|
4302
|
+
if (images) logEvent("image_added", String(images));
|
|
4303
|
+
if (picked.length > images) {
|
|
4304
|
+
logEvent("file_added", String(picked.length - images));
|
|
4305
|
+
}
|
|
4306
|
+
onAddFiles(picked);
|
|
3468
4307
|
}
|
|
3469
|
-
|
|
3470
|
-
}
|
|
3471
|
-
|
|
3472
|
-
}
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
}
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
] })
|
|
3485
|
-
]
|
|
3486
|
-
}
|
|
3487
|
-
),
|
|
3488
|
-
/* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "8px", alignItems: "flex-end" }, children: [
|
|
3489
|
-
/* @__PURE__ */ jsx3(
|
|
3490
|
-
"textarea",
|
|
3491
|
-
{
|
|
3492
|
-
value: input,
|
|
3493
|
-
onChange: (e) => {
|
|
3494
|
-
stopAutoFile("typing a change");
|
|
3495
|
-
setInput(e.target.value);
|
|
3496
|
-
},
|
|
3497
|
-
onKeyDown: (e) => {
|
|
3498
|
-
if (e.key === "Enter" && !e.shiftKey) {
|
|
3499
|
-
e.preventDefault();
|
|
3500
|
-
sendTyped(input);
|
|
3501
|
-
}
|
|
3502
|
-
},
|
|
3503
|
-
placeholder: phase === "draft" ? "Anything to change? Tell me here\u2026" : "Type your answer\u2026",
|
|
3504
|
-
rows: 1,
|
|
3505
|
-
disabled: busy,
|
|
3506
|
-
autoFocus: true,
|
|
3507
|
-
style: {
|
|
3508
|
-
flex: 1,
|
|
3509
|
-
minHeight: "42px",
|
|
3510
|
-
maxHeight: "120px",
|
|
3511
|
-
padding: "11px 12px",
|
|
3512
|
-
borderRadius: "10px",
|
|
3513
|
-
border: `1px solid ${t.inputBorder}`,
|
|
3514
|
-
backgroundColor: t.inputBg,
|
|
3515
|
-
color: t.text,
|
|
3516
|
-
fontSize: "13px",
|
|
3517
|
-
lineHeight: 1.4,
|
|
3518
|
-
fontFamily: "inherit",
|
|
3519
|
-
resize: "none",
|
|
3520
|
-
outline: "none",
|
|
3521
|
-
boxSizing: "border-box"
|
|
3522
|
-
}
|
|
4308
|
+
e.target.value = "";
|
|
4309
|
+
},
|
|
4310
|
+
style: { display: "none" }
|
|
4311
|
+
}
|
|
4312
|
+
)
|
|
4313
|
+
]
|
|
4314
|
+
}
|
|
4315
|
+
),
|
|
4316
|
+
readShots.size < screenshots.length && /* @__PURE__ */ jsxs3("span", { style: { color: t.textMuted, fontSize: "11px" }, children: [
|
|
4317
|
+
readShots.size,
|
|
4318
|
+
" of ",
|
|
4319
|
+
screenshots.length,
|
|
4320
|
+
" read"
|
|
4321
|
+
] })
|
|
4322
|
+
]
|
|
3523
4323
|
}
|
|
3524
4324
|
),
|
|
3525
|
-
/* @__PURE__ */
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
4325
|
+
/* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "8px", alignItems: "flex-end" }, children: [
|
|
4326
|
+
/* @__PURE__ */ jsx3(
|
|
4327
|
+
"textarea",
|
|
4328
|
+
{
|
|
4329
|
+
ref: composerRef,
|
|
4330
|
+
value: input,
|
|
4331
|
+
onChange: (e) => {
|
|
4332
|
+
stopAutoFile("typing a change");
|
|
4333
|
+
setInput(e.target.value);
|
|
4334
|
+
},
|
|
4335
|
+
onKeyDown: (e) => {
|
|
4336
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
4337
|
+
e.preventDefault();
|
|
4338
|
+
sendTyped(input);
|
|
4339
|
+
}
|
|
4340
|
+
},
|
|
4341
|
+
placeholder: phase === "draft" ? "Anything to change? Tell me here\u2026" : "Type your answer\u2026",
|
|
4342
|
+
rows: 3,
|
|
4343
|
+
disabled: busy,
|
|
4344
|
+
autoFocus: true,
|
|
4345
|
+
style: {
|
|
4346
|
+
flex: 1,
|
|
4347
|
+
minHeight: "72px",
|
|
4348
|
+
maxHeight: "220px",
|
|
4349
|
+
padding: "11px 12px",
|
|
4350
|
+
borderRadius: "10px",
|
|
4351
|
+
border: `1px solid ${t.inputBorder}`,
|
|
4352
|
+
backgroundColor: t.inputBg,
|
|
4353
|
+
color: t.text,
|
|
4354
|
+
fontSize: "13px",
|
|
4355
|
+
lineHeight: 1.4,
|
|
4356
|
+
fontFamily: "inherit",
|
|
4357
|
+
resize: "none",
|
|
4358
|
+
outline: "none",
|
|
4359
|
+
boxSizing: "border-box"
|
|
3552
4360
|
}
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
4361
|
+
}
|
|
4362
|
+
),
|
|
4363
|
+
/* @__PURE__ */ jsx3(
|
|
4364
|
+
"button",
|
|
4365
|
+
{
|
|
4366
|
+
type: "button",
|
|
4367
|
+
"data-gg-sheet-send": "",
|
|
4368
|
+
onClick: () => sendTyped(input),
|
|
4369
|
+
disabled: busy || !input.trim(),
|
|
4370
|
+
"aria-label": "Send message",
|
|
4371
|
+
"data-gg-send-message": "",
|
|
4372
|
+
style: {
|
|
4373
|
+
flexShrink: 0,
|
|
4374
|
+
width: "42px",
|
|
4375
|
+
height: "42px",
|
|
4376
|
+
borderRadius: "10px",
|
|
4377
|
+
border: "none",
|
|
4378
|
+
display: "inline-flex",
|
|
4379
|
+
alignItems: "center",
|
|
4380
|
+
justifyContent: "center",
|
|
4381
|
+
backgroundColor: busy || !input.trim() ? t.bgSecondary : t.accent,
|
|
4382
|
+
color: busy || !input.trim() ? t.textMuted : t.accentText,
|
|
4383
|
+
cursor: busy || !input.trim() ? "default" : "pointer"
|
|
4384
|
+
},
|
|
4385
|
+
children: /* @__PURE__ */ jsx3("svg", { width: "17", height: "17", viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx3(
|
|
4386
|
+
"path",
|
|
4387
|
+
{
|
|
4388
|
+
d: "M3 20.5L21.5 12 3 3.5V10l12 2-12 2v6.5z",
|
|
4389
|
+
fill: "currentColor"
|
|
4390
|
+
}
|
|
4391
|
+
) })
|
|
4392
|
+
}
|
|
4393
|
+
)
|
|
4394
|
+
] })
|
|
3556
4395
|
] }),
|
|
3557
4396
|
phase === "draft" && /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
3558
4397
|
validationError && /* @__PURE__ */ jsx3(
|
|
@@ -3566,7 +4405,7 @@ function AssistSheet({
|
|
|
3566
4405
|
children: validationError
|
|
3567
4406
|
}
|
|
3568
4407
|
),
|
|
3569
|
-
autoFileLeft !== null ? (
|
|
4408
|
+
similarSlot ? similarSlot : autoFileLeft !== null ? (
|
|
3570
4409
|
// #402: "Yes, that's it" was the confirmation. The draft
|
|
3571
4410
|
// files itself unless they stop it — the bar shows how
|
|
3572
4411
|
// long is left, the button sends now, the × on its right
|
|
@@ -4434,20 +5273,20 @@ function initialsOf(name) {
|
|
|
4434
5273
|
}).join("");
|
|
4435
5274
|
}
|
|
4436
5275
|
function ReporterChip({
|
|
4437
|
-
reporter,
|
|
5276
|
+
reporter: reporter2,
|
|
4438
5277
|
t
|
|
4439
5278
|
}) {
|
|
4440
5279
|
var _a;
|
|
4441
5280
|
const [avatarFailed, setAvatarFailed] = useState4(false);
|
|
4442
|
-
const avatarUrl = (
|
|
5281
|
+
const avatarUrl = (reporter2 == null ? void 0 : reporter2.avatarUrl) || "";
|
|
4443
5282
|
useEffect4(() => {
|
|
4444
5283
|
setAvatarFailed(false);
|
|
4445
5284
|
}, [avatarUrl]);
|
|
4446
|
-
const name = ((_a =
|
|
5285
|
+
const name = ((_a = reporter2 == null ? void 0 : reporter2.name) == null ? void 0 : _a.trim()) || "";
|
|
4447
5286
|
const isAnonymous = !name;
|
|
4448
5287
|
const initials2 = isAnonymous ? "" : initialsOf(name);
|
|
4449
5288
|
const label = isAnonymous ? "Anonymous" : name;
|
|
4450
|
-
const title = isAnonymous ? "No reporter identity was passed to Glitchgrab \u2014 this report won't be attributed to anyone" : [name,
|
|
5289
|
+
const title = isAnonymous ? "No reporter identity was passed to Glitchgrab \u2014 this report won't be attributed to anyone" : [name, reporter2 == null ? void 0 : reporter2.email, reporter2 == null ? void 0 : reporter2.role].filter(Boolean).join(" \xB7 ");
|
|
4451
5290
|
const showAvatarImage = !!avatarUrl && !avatarFailed;
|
|
4452
5291
|
return /* @__PURE__ */ jsxs5(
|
|
4453
5292
|
"span",
|
|
@@ -4511,7 +5350,7 @@ function ReporterChip({
|
|
|
4511
5350
|
},
|
|
4512
5351
|
children: [
|
|
4513
5352
|
label,
|
|
4514
|
-
(
|
|
5353
|
+
(reporter2 == null ? void 0 : reporter2.role) ? ` \xB7 ${reporter2.role}` : ""
|
|
4515
5354
|
]
|
|
4516
5355
|
}
|
|
4517
5356
|
)
|
|
@@ -4622,16 +5461,18 @@ function ReportDialog({
|
|
|
4622
5461
|
enhanceText: enhanceText2,
|
|
4623
5462
|
assist,
|
|
4624
5463
|
findSimilarIssues: findSimilarIssues2,
|
|
5464
|
+
readFile,
|
|
4625
5465
|
assistContext = null,
|
|
4626
5466
|
transcribeAudio: transcribeAudio2,
|
|
4627
5467
|
types,
|
|
4628
5468
|
showSeverity = true,
|
|
4629
5469
|
captureScreenshot = captureDefaultScreenshot,
|
|
4630
|
-
reporter,
|
|
5470
|
+
reporter: reporter2,
|
|
4631
5471
|
onClose,
|
|
4632
5472
|
headerSlot,
|
|
4633
5473
|
reportGlitchgrabProblem,
|
|
4634
|
-
layout = "modal"
|
|
5474
|
+
layout = "modal",
|
|
5475
|
+
chatHistoryKey: chatHistoryKey2 = null
|
|
4635
5476
|
}) {
|
|
4636
5477
|
var _a;
|
|
4637
5478
|
const sheet = layout === "sheet";
|
|
@@ -4675,6 +5516,15 @@ function ReportDialog({
|
|
|
4675
5516
|
const pendingShotRef = useRef4(null);
|
|
4676
5517
|
const openGenRef = useRef4(0);
|
|
4677
5518
|
const [attachments, setAttachments] = useState4([]);
|
|
5519
|
+
const [pdfTexts, setPdfTexts] = useState4({});
|
|
5520
|
+
const heldFiles = useMemo2(
|
|
5521
|
+
() => attachments.map((a) => {
|
|
5522
|
+
const read = pdfTexts[heldFileKey(a)];
|
|
5523
|
+
if (!read) return a;
|
|
5524
|
+
return "reading" in read ? { ...a, reading: true } : { ...a, text: read.text, ...read.tooLarge ? { tooLarge: true } : {} };
|
|
5525
|
+
}),
|
|
5526
|
+
[attachments, pdfTexts]
|
|
5527
|
+
);
|
|
4678
5528
|
const [previewIndex, setPreviewIndex] = useState4(null);
|
|
4679
5529
|
const [annotatingIndex, setAnnotatingIndex] = useState4(null);
|
|
4680
5530
|
const [previewZoomed, setPreviewZoomed] = useState4(false);
|
|
@@ -4727,15 +5577,15 @@ function ReportDialog({
|
|
|
4727
5577
|
});
|
|
4728
5578
|
};
|
|
4729
5579
|
applyInert();
|
|
4730
|
-
const
|
|
5580
|
+
const observer2 = new MutationObserver((mutations) => {
|
|
4731
5581
|
const structural = mutations.some(
|
|
4732
5582
|
(m) => m.addedNodes.length > 0 || m.removedNodes.length > 0
|
|
4733
5583
|
);
|
|
4734
5584
|
if (structural) applyInert();
|
|
4735
5585
|
});
|
|
4736
|
-
|
|
5586
|
+
observer2.observe(document.body, { childList: true, subtree: true });
|
|
4737
5587
|
return () => {
|
|
4738
|
-
|
|
5588
|
+
observer2.disconnect();
|
|
4739
5589
|
inerted.forEach((el) => el.removeAttribute("inert"));
|
|
4740
5590
|
};
|
|
4741
5591
|
}, [isOpen]);
|
|
@@ -4835,10 +5685,16 @@ function ReportDialog({
|
|
|
4835
5685
|
files.filter((file) => !file.type.startsWith("image/")).forEach((file) => {
|
|
4836
5686
|
const reader = new FileReader();
|
|
4837
5687
|
reader.onload = () => {
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
]);
|
|
5688
|
+
const dataUrl = reader.result;
|
|
5689
|
+
setAttachments((prev) => [...prev, { name: file.name, size: file.size, dataUrl }]);
|
|
5690
|
+
const key = heldFileKey(file);
|
|
5691
|
+
if (!readFile || !isPdfFile(file.name) || pdfTexts[key]) return;
|
|
5692
|
+
if (file.size > MAX_READABLE_PDF_BYTES) {
|
|
5693
|
+
setPdfTexts((prev) => ({ ...prev, [key]: { text: null, tooLarge: true } }));
|
|
5694
|
+
return;
|
|
5695
|
+
}
|
|
5696
|
+
setPdfTexts((prev) => ({ ...prev, [key]: { reading: true } }));
|
|
5697
|
+
void Promise.resolve().then(() => readFile({ name: file.name, dataUrl })).catch(() => null).then((text) => setPdfTexts((prev) => ({ ...prev, [key]: { text } })));
|
|
4842
5698
|
};
|
|
4843
5699
|
reader.readAsDataURL(file);
|
|
4844
5700
|
});
|
|
@@ -5274,6 +6130,10 @@ function ReportDialog({
|
|
|
5274
6130
|
stopListeningAndTranscribe();
|
|
5275
6131
|
}
|
|
5276
6132
|
};
|
|
6133
|
+
useEffect4(() => {
|
|
6134
|
+
setSimilarIssues(null);
|
|
6135
|
+
setPickedSimilar(null);
|
|
6136
|
+
}, [description]);
|
|
5277
6137
|
const handleSubmit = async (opts) => {
|
|
5278
6138
|
var _a2, _b, _c;
|
|
5279
6139
|
try {
|
|
@@ -5314,11 +6174,17 @@ function ReportDialog({
|
|
|
5314
6174
|
}
|
|
5315
6175
|
const duplicateOf = (_a2 = opts == null ? void 0 : opts.duplicateOf) != null ? _a2 : duplicateIssueNumber;
|
|
5316
6176
|
const attachKind = (opts == null ? void 0 : opts.duplicateOf) ? (_b = opts.kind) != null ? _b : "duplicate" : duplicateKind;
|
|
5317
|
-
if (findSimilarIssues2 && !(opts == null ? void 0 : opts.skipSimilar) && !duplicateOf
|
|
6177
|
+
if (findSimilarIssues2 && !(opts == null ? void 0 : opts.skipSimilar) && !duplicateOf) {
|
|
6178
|
+
const similarFiles = filesForSimilar(
|
|
6179
|
+
heldFiles,
|
|
6180
|
+
MAX_SIMILAR_FILE_CHARS,
|
|
6181
|
+
MAX_SIMILAR_FILES_TOTAL_CHARS
|
|
6182
|
+
);
|
|
5318
6183
|
setIsSubmitting(true);
|
|
5319
6184
|
setCheckingSimilar(true);
|
|
5320
6185
|
const matches = await Promise.race([
|
|
5321
|
-
|
|
6186
|
+
// A PDF still being read is left out rather than waited for.
|
|
6187
|
+
(similarFiles.length ? findSimilarIssues2(description.trim(), similarFiles) : findSimilarIssues2(description.trim())).catch(() => null),
|
|
5322
6188
|
new Promise((resolve) => setTimeout(() => resolve(null), SIMILAR_WAIT_MS))
|
|
5323
6189
|
]);
|
|
5324
6190
|
setCheckingSimilar(false);
|
|
@@ -5350,6 +6216,8 @@ function ReportDialog({
|
|
|
5350
6216
|
if (duplicateOf) {
|
|
5351
6217
|
metadata.duplicateIssueNumber = String(duplicateOf);
|
|
5352
6218
|
if (attachKind === "related") metadata.duplicateKind = "related";
|
|
6219
|
+
} else if (opts == null ? void 0 : opts.possiblyRelated) {
|
|
6220
|
+
metadata.possiblyRelatedIssue = String(opts.possiblyRelated);
|
|
5353
6221
|
}
|
|
5354
6222
|
if (aiConversationId) {
|
|
5355
6223
|
metadata.aiConversationId = aiConversationId;
|
|
@@ -5363,14 +6231,20 @@ function ReportDialog({
|
|
|
5363
6231
|
Object.keys(metadata).length > 0 ? metadata : void 0
|
|
5364
6232
|
);
|
|
5365
6233
|
if (result) {
|
|
5366
|
-
setAddedToIssue(
|
|
6234
|
+
setAddedToIssue(
|
|
6235
|
+
duplicateOf && result.issueNumber === duplicateOf ? duplicateOf : result.status === "DUPLICATE" && result.issueNumber ? result.issueNumber : null
|
|
6236
|
+
);
|
|
5367
6237
|
setAddedAsRelated(!!duplicateOf && result.issueNumber === duplicateOf && attachKind === "related");
|
|
5368
6238
|
const queued = result.status === "QUEUED" && !!result.message;
|
|
5369
6239
|
setQueuedMessage(queued ? (_c = result.message) != null ? _c : null : null);
|
|
6240
|
+
if (chatHistoryKey2 && aiConversationId) {
|
|
6241
|
+
markChatFiled(chatHistoryKey2, aiConversationId, `${getTypeLabel(reportType)} sent`);
|
|
6242
|
+
}
|
|
5370
6243
|
setSubmitted(true);
|
|
5371
6244
|
setDescription("");
|
|
5372
6245
|
setScreenshots([]);
|
|
5373
6246
|
setAttachments([]);
|
|
6247
|
+
setPdfTexts({});
|
|
5374
6248
|
setAiConversationId(null);
|
|
5375
6249
|
setIssueTitle("");
|
|
5376
6250
|
setDuplicateIssueNumber(null);
|
|
@@ -5391,6 +6265,220 @@ function ReportDialog({
|
|
|
5391
6265
|
setAttachingTo(null);
|
|
5392
6266
|
}
|
|
5393
6267
|
};
|
|
6268
|
+
const similarCard = similarIssues ? /* @__PURE__ */ jsxs5(
|
|
6269
|
+
"div",
|
|
6270
|
+
{
|
|
6271
|
+
"data-gg-similar": "",
|
|
6272
|
+
style: {
|
|
6273
|
+
marginTop: "12px",
|
|
6274
|
+
display: "flex",
|
|
6275
|
+
flexDirection: "column",
|
|
6276
|
+
gap: "10px",
|
|
6277
|
+
padding: "12px",
|
|
6278
|
+
borderRadius: "10px",
|
|
6279
|
+
border: "1px solid rgba(245,158,11,0.4)",
|
|
6280
|
+
backgroundColor: "rgba(245,158,11,0.08)"
|
|
6281
|
+
},
|
|
6282
|
+
children: [
|
|
6283
|
+
/* @__PURE__ */ jsxs5("div", { style: { display: "flex", flexDirection: "column", gap: "2px" }, children: [
|
|
6284
|
+
/* @__PURE__ */ jsx5("span", { style: { color: t.text, fontWeight: 600, fontSize: "13px" }, children: "Our team may already have this, or something close" }),
|
|
6285
|
+
/* @__PURE__ */ jsx5("span", { style: { color: t.textMuted, fontSize: "12px", lineHeight: 1.5 }, children: similarIssues.length > 1 ? "Pick the one that matches. Same problem, or a different request for the same feature \u2014 it's added to that issue, so the team has it in one place." : "Same problem, or a different request for the same feature? Pick it \u2014 it's added to that issue, so the team has it in one place." })
|
|
6286
|
+
] }),
|
|
6287
|
+
/* @__PURE__ */ jsx5(
|
|
6288
|
+
"div",
|
|
6289
|
+
{
|
|
6290
|
+
role: "radiogroup",
|
|
6291
|
+
"aria-label": "Existing issues",
|
|
6292
|
+
style: { display: "flex", flexDirection: "column", gap: "6px" },
|
|
6293
|
+
children: similarIssues.map((issue) => {
|
|
6294
|
+
const picked = pickedSimilar === issue.number;
|
|
6295
|
+
return /* @__PURE__ */ jsxs5(
|
|
6296
|
+
"button",
|
|
6297
|
+
{
|
|
6298
|
+
type: "button",
|
|
6299
|
+
role: "radio",
|
|
6300
|
+
"aria-checked": picked,
|
|
6301
|
+
disabled: isSubmitting,
|
|
6302
|
+
onClick: () => setPickedSimilar(issue.number),
|
|
6303
|
+
style: {
|
|
6304
|
+
display: "flex",
|
|
6305
|
+
alignItems: "flex-start",
|
|
6306
|
+
gap: "10px",
|
|
6307
|
+
width: "100%",
|
|
6308
|
+
minHeight: "44px",
|
|
6309
|
+
padding: "9px 10px",
|
|
6310
|
+
borderRadius: "8px",
|
|
6311
|
+
border: `1px solid ${picked ? t.accent : t.border}`,
|
|
6312
|
+
boxShadow: picked ? `0 0 0 1px ${t.accent}` : "none",
|
|
6313
|
+
backgroundColor: t.bg,
|
|
6314
|
+
color: t.text,
|
|
6315
|
+
textAlign: "left",
|
|
6316
|
+
cursor: isSubmitting ? "not-allowed" : "pointer",
|
|
6317
|
+
fontFamily: "inherit"
|
|
6318
|
+
},
|
|
6319
|
+
children: [
|
|
6320
|
+
/* @__PURE__ */ jsx5(
|
|
6321
|
+
"span",
|
|
6322
|
+
{
|
|
6323
|
+
"aria-hidden": "true",
|
|
6324
|
+
style: {
|
|
6325
|
+
flexShrink: 0,
|
|
6326
|
+
marginTop: "2px",
|
|
6327
|
+
width: "14px",
|
|
6328
|
+
height: "14px",
|
|
6329
|
+
boxSizing: "border-box",
|
|
6330
|
+
borderRadius: "50%",
|
|
6331
|
+
border: `2px solid ${picked ? t.accent : t.textMuted}`,
|
|
6332
|
+
backgroundColor: picked ? t.accent : "transparent",
|
|
6333
|
+
boxShadow: picked ? `inset 0 0 0 2px ${t.bg}` : "none"
|
|
6334
|
+
}
|
|
6335
|
+
}
|
|
6336
|
+
),
|
|
6337
|
+
/* @__PURE__ */ jsxs5(
|
|
6338
|
+
"span",
|
|
6339
|
+
{
|
|
6340
|
+
style: {
|
|
6341
|
+
display: "flex",
|
|
6342
|
+
flexDirection: "column",
|
|
6343
|
+
gap: "3px",
|
|
6344
|
+
minWidth: 0
|
|
6345
|
+
},
|
|
6346
|
+
children: [
|
|
6347
|
+
/* @__PURE__ */ jsxs5(
|
|
6348
|
+
"span",
|
|
6349
|
+
{
|
|
6350
|
+
title: issue.title,
|
|
6351
|
+
style: {
|
|
6352
|
+
fontSize: "12.5px",
|
|
6353
|
+
lineHeight: 1.45,
|
|
6354
|
+
wordBreak: "break-word",
|
|
6355
|
+
overflow: "hidden",
|
|
6356
|
+
display: "-webkit-box",
|
|
6357
|
+
WebkitLineClamp: 3,
|
|
6358
|
+
WebkitBoxOrient: "vertical"
|
|
6359
|
+
},
|
|
6360
|
+
children: [
|
|
6361
|
+
/* @__PURE__ */ jsxs5("span", { style: { color: t.textMuted, fontWeight: 600 }, children: [
|
|
6362
|
+
"#",
|
|
6363
|
+
issue.number
|
|
6364
|
+
] }),
|
|
6365
|
+
" ",
|
|
6366
|
+
issue.title
|
|
6367
|
+
]
|
|
6368
|
+
}
|
|
6369
|
+
),
|
|
6370
|
+
issue.status && /* @__PURE__ */ jsx5("span", { style: { fontSize: "11.5px", color: t.textMuted }, children: issue.status })
|
|
6371
|
+
]
|
|
6372
|
+
}
|
|
6373
|
+
)
|
|
6374
|
+
]
|
|
6375
|
+
},
|
|
6376
|
+
issue.number
|
|
6377
|
+
);
|
|
6378
|
+
})
|
|
6379
|
+
}
|
|
6380
|
+
),
|
|
6381
|
+
/* @__PURE__ */ jsx5(
|
|
6382
|
+
"button",
|
|
6383
|
+
{
|
|
6384
|
+
type: "button",
|
|
6385
|
+
disabled: isSubmitting || !pickedSimilar,
|
|
6386
|
+
onClick: () => {
|
|
6387
|
+
if (!pickedSimilar) return;
|
|
6388
|
+
setAttachingTo(pickedSimilar);
|
|
6389
|
+
setDuplicateIssueNumber(pickedSimilar);
|
|
6390
|
+
setDuplicateKind("duplicate");
|
|
6391
|
+
void handleSubmit({ duplicateOf: pickedSimilar, kind: "duplicate" });
|
|
6392
|
+
},
|
|
6393
|
+
style: {
|
|
6394
|
+
width: "100%",
|
|
6395
|
+
minHeight: "40px",
|
|
6396
|
+
padding: "10px",
|
|
6397
|
+
borderRadius: "8px",
|
|
6398
|
+
border: "none",
|
|
6399
|
+
backgroundColor: isSubmitting || !pickedSimilar ? t.bgSecondary : t.accent,
|
|
6400
|
+
color: isSubmitting || !pickedSimilar ? t.textMuted : t.accentText,
|
|
6401
|
+
fontSize: "14px",
|
|
6402
|
+
fontWeight: 600,
|
|
6403
|
+
cursor: isSubmitting || !pickedSimilar ? "not-allowed" : "pointer",
|
|
6404
|
+
fontFamily: "inherit"
|
|
6405
|
+
},
|
|
6406
|
+
children: typeof attachingTo === "number" && duplicateKind !== "related" ? /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
6407
|
+
/* @__PURE__ */ jsx5(ButtonSpinner, {}),
|
|
6408
|
+
"Adding to #",
|
|
6409
|
+
attachingTo,
|
|
6410
|
+
"\u2026"
|
|
6411
|
+
] }) : pickedSimilar ? `Add to #${pickedSimilar}` : "Pick the matching issue"
|
|
6412
|
+
}
|
|
6413
|
+
),
|
|
6414
|
+
pickedSimilar && /* @__PURE__ */ jsx5(
|
|
6415
|
+
"button",
|
|
6416
|
+
{
|
|
6417
|
+
type: "button",
|
|
6418
|
+
disabled: isSubmitting,
|
|
6419
|
+
onClick: () => {
|
|
6420
|
+
setAttachingTo(pickedSimilar);
|
|
6421
|
+
setDuplicateIssueNumber(pickedSimilar);
|
|
6422
|
+
setDuplicateKind("related");
|
|
6423
|
+
void handleSubmit({ duplicateOf: pickedSimilar, kind: "related" });
|
|
6424
|
+
},
|
|
6425
|
+
style: {
|
|
6426
|
+
width: "100%",
|
|
6427
|
+
minHeight: "40px",
|
|
6428
|
+
marginTop: "-4px",
|
|
6429
|
+
padding: "9px 10px",
|
|
6430
|
+
borderRadius: "8px",
|
|
6431
|
+
border: "1px solid rgba(245,158,11,0.4)",
|
|
6432
|
+
backgroundColor: "transparent",
|
|
6433
|
+
color: isSubmitting ? t.textMuted : t.text,
|
|
6434
|
+
fontSize: "13px",
|
|
6435
|
+
fontWeight: 600,
|
|
6436
|
+
cursor: isSubmitting ? "not-allowed" : "pointer",
|
|
6437
|
+
fontFamily: "inherit"
|
|
6438
|
+
},
|
|
6439
|
+
children: typeof attachingTo === "number" && duplicateKind === "related" ? /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
6440
|
+
/* @__PURE__ */ jsx5(ButtonSpinner, {}),
|
|
6441
|
+
"Adding to #",
|
|
6442
|
+
attachingTo,
|
|
6443
|
+
"\u2026"
|
|
6444
|
+
] }) : `Related request \u2014 add to #${pickedSimilar}`
|
|
6445
|
+
}
|
|
6446
|
+
),
|
|
6447
|
+
/* @__PURE__ */ jsx5(
|
|
6448
|
+
"button",
|
|
6449
|
+
{
|
|
6450
|
+
type: "button",
|
|
6451
|
+
disabled: isSubmitting,
|
|
6452
|
+
onClick: () => {
|
|
6453
|
+
var _a2;
|
|
6454
|
+
setAttachingTo("new");
|
|
6455
|
+
void handleSubmit({ skipSimilar: true, possiblyRelated: (_a2 = similarIssues[0]) == null ? void 0 : _a2.number });
|
|
6456
|
+
},
|
|
6457
|
+
style: {
|
|
6458
|
+
width: "100%",
|
|
6459
|
+
minHeight: "40px",
|
|
6460
|
+
marginTop: "-4px",
|
|
6461
|
+
padding: "8px",
|
|
6462
|
+
borderRadius: "8px",
|
|
6463
|
+
border: "none",
|
|
6464
|
+
backgroundColor: "transparent",
|
|
6465
|
+
color: isSubmitting ? t.textMuted : t.text,
|
|
6466
|
+
fontSize: "13px",
|
|
6467
|
+
fontWeight: 500,
|
|
6468
|
+
textDecoration: "underline",
|
|
6469
|
+
textUnderlineOffset: "3px",
|
|
6470
|
+
cursor: isSubmitting ? "not-allowed" : "pointer",
|
|
6471
|
+
fontFamily: "inherit"
|
|
6472
|
+
},
|
|
6473
|
+
children: attachingTo === "new" ? /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
6474
|
+
/* @__PURE__ */ jsx5(ButtonSpinner, {}),
|
|
6475
|
+
"Sending as new\u2026"
|
|
6476
|
+
] }) : "No, mine is different \u2014 send as new"
|
|
6477
|
+
}
|
|
6478
|
+
)
|
|
6479
|
+
]
|
|
6480
|
+
}
|
|
6481
|
+
) : null;
|
|
5394
6482
|
if (!mounted) return null;
|
|
5395
6483
|
return /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
5396
6484
|
isOpen && createPortal3(
|
|
@@ -6929,224 +8017,7 @@ function ReportDialog({
|
|
|
6929
8017
|
children: validationError
|
|
6930
8018
|
}
|
|
6931
8019
|
),
|
|
6932
|
-
|
|
6933
|
-
// Same visual language as the assistant's "Our team is
|
|
6934
|
-
// already on this" card, so both routes to a duplicate
|
|
6935
|
-
// read as one feature.
|
|
6936
|
-
/* @__PURE__ */ jsxs5(
|
|
6937
|
-
"div",
|
|
6938
|
-
{
|
|
6939
|
-
"data-gg-similar": "",
|
|
6940
|
-
style: {
|
|
6941
|
-
marginTop: "12px",
|
|
6942
|
-
display: "flex",
|
|
6943
|
-
flexDirection: "column",
|
|
6944
|
-
gap: "10px",
|
|
6945
|
-
padding: "12px",
|
|
6946
|
-
borderRadius: "10px",
|
|
6947
|
-
border: "1px solid rgba(245,158,11,0.4)",
|
|
6948
|
-
backgroundColor: "rgba(245,158,11,0.08)"
|
|
6949
|
-
},
|
|
6950
|
-
children: [
|
|
6951
|
-
/* @__PURE__ */ jsxs5("div", { style: { display: "flex", flexDirection: "column", gap: "2px" }, children: [
|
|
6952
|
-
/* @__PURE__ */ jsx5("span", { style: { color: t.text, fontWeight: 600, fontSize: "13px" }, children: "Our team may already have this, or something close" }),
|
|
6953
|
-
/* @__PURE__ */ jsx5("span", { style: { color: t.textMuted, fontSize: "12px", lineHeight: 1.5 }, children: similarIssues.length > 1 ? "Pick the one that matches. Same problem, or a different request for the same feature \u2014 it's added to that issue, so the team has it in one place." : "Same problem, or a different request for the same feature? Pick it \u2014 it's added to that issue, so the team has it in one place." })
|
|
6954
|
-
] }),
|
|
6955
|
-
/* @__PURE__ */ jsx5(
|
|
6956
|
-
"div",
|
|
6957
|
-
{
|
|
6958
|
-
role: "radiogroup",
|
|
6959
|
-
"aria-label": "Existing issues",
|
|
6960
|
-
style: { display: "flex", flexDirection: "column", gap: "6px" },
|
|
6961
|
-
children: similarIssues.map((issue) => {
|
|
6962
|
-
const picked = pickedSimilar === issue.number;
|
|
6963
|
-
return /* @__PURE__ */ jsxs5(
|
|
6964
|
-
"button",
|
|
6965
|
-
{
|
|
6966
|
-
type: "button",
|
|
6967
|
-
role: "radio",
|
|
6968
|
-
"aria-checked": picked,
|
|
6969
|
-
disabled: isSubmitting,
|
|
6970
|
-
onClick: () => setPickedSimilar(issue.number),
|
|
6971
|
-
style: {
|
|
6972
|
-
display: "flex",
|
|
6973
|
-
alignItems: "flex-start",
|
|
6974
|
-
gap: "10px",
|
|
6975
|
-
width: "100%",
|
|
6976
|
-
minHeight: "44px",
|
|
6977
|
-
padding: "9px 10px",
|
|
6978
|
-
borderRadius: "8px",
|
|
6979
|
-
border: `1px solid ${picked ? t.accent : t.border}`,
|
|
6980
|
-
boxShadow: picked ? `0 0 0 1px ${t.accent}` : "none",
|
|
6981
|
-
backgroundColor: t.bg,
|
|
6982
|
-
color: t.text,
|
|
6983
|
-
textAlign: "left",
|
|
6984
|
-
cursor: isSubmitting ? "not-allowed" : "pointer",
|
|
6985
|
-
fontFamily: "inherit"
|
|
6986
|
-
},
|
|
6987
|
-
children: [
|
|
6988
|
-
/* @__PURE__ */ jsx5(
|
|
6989
|
-
"span",
|
|
6990
|
-
{
|
|
6991
|
-
"aria-hidden": "true",
|
|
6992
|
-
style: {
|
|
6993
|
-
flexShrink: 0,
|
|
6994
|
-
marginTop: "2px",
|
|
6995
|
-
width: "14px",
|
|
6996
|
-
height: "14px",
|
|
6997
|
-
boxSizing: "border-box",
|
|
6998
|
-
borderRadius: "50%",
|
|
6999
|
-
border: `2px solid ${picked ? t.accent : t.textMuted}`,
|
|
7000
|
-
backgroundColor: picked ? t.accent : "transparent",
|
|
7001
|
-
boxShadow: picked ? `inset 0 0 0 2px ${t.bg}` : "none"
|
|
7002
|
-
}
|
|
7003
|
-
}
|
|
7004
|
-
),
|
|
7005
|
-
/* @__PURE__ */ jsxs5(
|
|
7006
|
-
"span",
|
|
7007
|
-
{
|
|
7008
|
-
style: {
|
|
7009
|
-
display: "flex",
|
|
7010
|
-
flexDirection: "column",
|
|
7011
|
-
gap: "3px",
|
|
7012
|
-
minWidth: 0
|
|
7013
|
-
},
|
|
7014
|
-
children: [
|
|
7015
|
-
/* @__PURE__ */ jsxs5(
|
|
7016
|
-
"span",
|
|
7017
|
-
{
|
|
7018
|
-
title: issue.title,
|
|
7019
|
-
style: {
|
|
7020
|
-
fontSize: "12.5px",
|
|
7021
|
-
lineHeight: 1.45,
|
|
7022
|
-
wordBreak: "break-word",
|
|
7023
|
-
overflow: "hidden",
|
|
7024
|
-
display: "-webkit-box",
|
|
7025
|
-
WebkitLineClamp: 3,
|
|
7026
|
-
WebkitBoxOrient: "vertical"
|
|
7027
|
-
},
|
|
7028
|
-
children: [
|
|
7029
|
-
/* @__PURE__ */ jsxs5("span", { style: { color: t.textMuted, fontWeight: 600 }, children: [
|
|
7030
|
-
"#",
|
|
7031
|
-
issue.number
|
|
7032
|
-
] }),
|
|
7033
|
-
" ",
|
|
7034
|
-
issue.title
|
|
7035
|
-
]
|
|
7036
|
-
}
|
|
7037
|
-
),
|
|
7038
|
-
issue.status && /* @__PURE__ */ jsx5("span", { style: { fontSize: "11.5px", color: t.textMuted }, children: issue.status })
|
|
7039
|
-
]
|
|
7040
|
-
}
|
|
7041
|
-
)
|
|
7042
|
-
]
|
|
7043
|
-
},
|
|
7044
|
-
issue.number
|
|
7045
|
-
);
|
|
7046
|
-
})
|
|
7047
|
-
}
|
|
7048
|
-
),
|
|
7049
|
-
/* @__PURE__ */ jsx5(
|
|
7050
|
-
"button",
|
|
7051
|
-
{
|
|
7052
|
-
type: "button",
|
|
7053
|
-
disabled: isSubmitting || !pickedSimilar,
|
|
7054
|
-
onClick: () => {
|
|
7055
|
-
if (!pickedSimilar) return;
|
|
7056
|
-
setAttachingTo(pickedSimilar);
|
|
7057
|
-
setDuplicateIssueNumber(pickedSimilar);
|
|
7058
|
-
setDuplicateKind("duplicate");
|
|
7059
|
-
void handleSubmit({ duplicateOf: pickedSimilar, kind: "duplicate" });
|
|
7060
|
-
},
|
|
7061
|
-
style: {
|
|
7062
|
-
width: "100%",
|
|
7063
|
-
minHeight: "40px",
|
|
7064
|
-
padding: "10px",
|
|
7065
|
-
borderRadius: "8px",
|
|
7066
|
-
border: "none",
|
|
7067
|
-
backgroundColor: isSubmitting || !pickedSimilar ? t.bgSecondary : t.accent,
|
|
7068
|
-
color: isSubmitting || !pickedSimilar ? t.textMuted : t.accentText,
|
|
7069
|
-
fontSize: "14px",
|
|
7070
|
-
fontWeight: 600,
|
|
7071
|
-
cursor: isSubmitting || !pickedSimilar ? "not-allowed" : "pointer",
|
|
7072
|
-
fontFamily: "inherit"
|
|
7073
|
-
},
|
|
7074
|
-
children: typeof attachingTo === "number" && duplicateKind !== "related" ? /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
7075
|
-
/* @__PURE__ */ jsx5(ButtonSpinner, {}),
|
|
7076
|
-
"Adding to #",
|
|
7077
|
-
attachingTo,
|
|
7078
|
-
"\u2026"
|
|
7079
|
-
] }) : pickedSimilar ? `Add to #${pickedSimilar}` : "Pick the matching issue"
|
|
7080
|
-
}
|
|
7081
|
-
),
|
|
7082
|
-
pickedSimilar && /* @__PURE__ */ jsx5(
|
|
7083
|
-
"button",
|
|
7084
|
-
{
|
|
7085
|
-
type: "button",
|
|
7086
|
-
disabled: isSubmitting,
|
|
7087
|
-
onClick: () => {
|
|
7088
|
-
setAttachingTo(pickedSimilar);
|
|
7089
|
-
setDuplicateIssueNumber(pickedSimilar);
|
|
7090
|
-
setDuplicateKind("related");
|
|
7091
|
-
void handleSubmit({ duplicateOf: pickedSimilar, kind: "related" });
|
|
7092
|
-
},
|
|
7093
|
-
style: {
|
|
7094
|
-
width: "100%",
|
|
7095
|
-
minHeight: "40px",
|
|
7096
|
-
marginTop: "-4px",
|
|
7097
|
-
padding: "9px 10px",
|
|
7098
|
-
borderRadius: "8px",
|
|
7099
|
-
border: "1px solid rgba(245,158,11,0.4)",
|
|
7100
|
-
backgroundColor: "transparent",
|
|
7101
|
-
color: isSubmitting ? t.textMuted : t.text,
|
|
7102
|
-
fontSize: "13px",
|
|
7103
|
-
fontWeight: 600,
|
|
7104
|
-
cursor: isSubmitting ? "not-allowed" : "pointer",
|
|
7105
|
-
fontFamily: "inherit"
|
|
7106
|
-
},
|
|
7107
|
-
children: typeof attachingTo === "number" && duplicateKind === "related" ? /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
7108
|
-
/* @__PURE__ */ jsx5(ButtonSpinner, {}),
|
|
7109
|
-
"Adding to #",
|
|
7110
|
-
attachingTo,
|
|
7111
|
-
"\u2026"
|
|
7112
|
-
] }) : `Related request \u2014 add to #${pickedSimilar}`
|
|
7113
|
-
}
|
|
7114
|
-
),
|
|
7115
|
-
/* @__PURE__ */ jsx5(
|
|
7116
|
-
"button",
|
|
7117
|
-
{
|
|
7118
|
-
type: "button",
|
|
7119
|
-
disabled: isSubmitting,
|
|
7120
|
-
onClick: () => {
|
|
7121
|
-
setAttachingTo("new");
|
|
7122
|
-
void handleSubmit({ skipSimilar: true });
|
|
7123
|
-
},
|
|
7124
|
-
style: {
|
|
7125
|
-
width: "100%",
|
|
7126
|
-
minHeight: "40px",
|
|
7127
|
-
marginTop: "-4px",
|
|
7128
|
-
padding: "8px",
|
|
7129
|
-
borderRadius: "8px",
|
|
7130
|
-
border: "none",
|
|
7131
|
-
backgroundColor: "transparent",
|
|
7132
|
-
color: isSubmitting ? t.textMuted : t.text,
|
|
7133
|
-
fontSize: "13px",
|
|
7134
|
-
fontWeight: 500,
|
|
7135
|
-
textDecoration: "underline",
|
|
7136
|
-
textUnderlineOffset: "3px",
|
|
7137
|
-
cursor: isSubmitting ? "not-allowed" : "pointer",
|
|
7138
|
-
fontFamily: "inherit"
|
|
7139
|
-
},
|
|
7140
|
-
children: attachingTo === "new" ? /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
7141
|
-
/* @__PURE__ */ jsx5(ButtonSpinner, {}),
|
|
7142
|
-
"Sending as new\u2026"
|
|
7143
|
-
] }) : "No, mine is different \u2014 send as new"
|
|
7144
|
-
}
|
|
7145
|
-
)
|
|
7146
|
-
]
|
|
7147
|
-
}
|
|
7148
|
-
)
|
|
7149
|
-
) : /* @__PURE__ */ jsx5(
|
|
8020
|
+
similarCard != null ? similarCard : /* @__PURE__ */ jsx5(
|
|
7150
8021
|
"button",
|
|
7151
8022
|
{
|
|
7152
8023
|
type: "button",
|
|
@@ -7188,7 +8059,7 @@ function ReportDialog({
|
|
|
7188
8059
|
gap: "12px"
|
|
7189
8060
|
},
|
|
7190
8061
|
children: [
|
|
7191
|
-
/* @__PURE__ */ jsx5(ReporterChip, { reporter, t }),
|
|
8062
|
+
/* @__PURE__ */ jsx5(ReporterChip, { reporter: reporter2, t }),
|
|
7192
8063
|
reportGlitchgrabProblem ? /* @__PURE__ */ jsx5(
|
|
7193
8064
|
"button",
|
|
7194
8065
|
{
|
|
@@ -7445,7 +8316,8 @@ function ReportDialog({
|
|
|
7445
8316
|
pageShot,
|
|
7446
8317
|
onAddFiles: addFiles,
|
|
7447
8318
|
onRemoveImage: (index) => setScreenshots((prev) => prev.filter((_, i) => i !== index)),
|
|
7448
|
-
files:
|
|
8319
|
+
files: heldFiles,
|
|
8320
|
+
canReadPdf: !!readFile,
|
|
7449
8321
|
onRemoveFile: (index) => setAttachments((prev) => prev.filter((_, i) => i !== index)),
|
|
7450
8322
|
attachmentCount: screenshots.length + attachments.length,
|
|
7451
8323
|
context: { ...assistContext != null ? assistContext : {}, reportType },
|
|
@@ -7459,10 +8331,15 @@ function ReportDialog({
|
|
|
7459
8331
|
setStep(2);
|
|
7460
8332
|
},
|
|
7461
8333
|
onDuplicateChange: (issueNumber, kind) => {
|
|
8334
|
+
if (issueNumber) {
|
|
8335
|
+
setSimilarIssues(null);
|
|
8336
|
+
setPickedSimilar(null);
|
|
8337
|
+
}
|
|
7462
8338
|
setDuplicateIssueNumber(issueNumber);
|
|
7463
8339
|
setDuplicateKind(issueNumber && kind === "related" ? "related" : "duplicate");
|
|
7464
8340
|
},
|
|
7465
8341
|
onConversationChange: setAiConversationId,
|
|
8342
|
+
historyKey: chatHistoryKey2,
|
|
7466
8343
|
onFinish: handleClose,
|
|
7467
8344
|
rating,
|
|
7468
8345
|
onRatingChange: (value) => {
|
|
@@ -7470,7 +8347,7 @@ function ReportDialog({
|
|
|
7470
8347
|
if (validationError) setValidationError(null);
|
|
7471
8348
|
},
|
|
7472
8349
|
projectSlot: headerSlot,
|
|
7473
|
-
reporterName: (_a =
|
|
8350
|
+
reporterName: (_a = reporter2 == null ? void 0 : reporter2.name) != null ? _a : null,
|
|
7474
8351
|
description,
|
|
7475
8352
|
onDescriptionChange: (value) => {
|
|
7476
8353
|
setDescription(value);
|
|
@@ -7488,7 +8365,9 @@ function ReportDialog({
|
|
|
7488
8365
|
severityRefused: needsSeverity,
|
|
7489
8366
|
isSubmitting,
|
|
7490
8367
|
submitted,
|
|
7491
|
-
onSend: () => void handleSubmit(
|
|
8368
|
+
onSend: () => void handleSubmit(),
|
|
8369
|
+
similarSlot: similarCard,
|
|
8370
|
+
submittedText: addedToIssue ? `Added to #${addedToIssue}${addedAsRelated ? " as a related request" : ""}. Thank you!` : null,
|
|
7492
8371
|
onReportGlitchgrabProblem: reportGlitchgrabProblem ? (prefill) => {
|
|
7493
8372
|
setSelfReportPrefill(prefill != null ? prefill : "");
|
|
7494
8373
|
setSelfReportFrom("assist");
|
|
@@ -7782,7 +8661,9 @@ function BookingDialog({
|
|
|
7782
8661
|
token,
|
|
7783
8662
|
baseUrl,
|
|
7784
8663
|
open,
|
|
7785
|
-
onClose
|
|
8664
|
+
onClose,
|
|
8665
|
+
preview = false,
|
|
8666
|
+
availabilityUrl
|
|
7786
8667
|
}) {
|
|
7787
8668
|
var _a, _b, _c, _d, _e;
|
|
7788
8669
|
const wide = useMediaQuery(WIDE_QUERY, true);
|
|
@@ -7816,10 +8697,12 @@ function BookingDialog({
|
|
|
7816
8697
|
const [meetUrl, setMeetUrl] = useState5(null);
|
|
7817
8698
|
const [busy, setBusy] = useState5(false);
|
|
7818
8699
|
const [error, setError] = useState5(null);
|
|
7819
|
-
const
|
|
7820
|
-
|
|
7821
|
-
|
|
7822
|
-
|
|
8700
|
+
const [previewEnded, setPreviewEnded] = useState5(false);
|
|
8701
|
+
const headers = useMemo3(() => {
|
|
8702
|
+
const out = { "Content-Type": "application/json" };
|
|
8703
|
+
if (token) out.Authorization = `Bearer ${token}`;
|
|
8704
|
+
return out;
|
|
8705
|
+
}, [token]);
|
|
7823
8706
|
const loadMonth = useCallback2(
|
|
7824
8707
|
async (target) => {
|
|
7825
8708
|
var _a2, _b2, _c2;
|
|
@@ -7831,8 +8714,9 @@ function BookingDialog({
|
|
|
7831
8714
|
return;
|
|
7832
8715
|
}
|
|
7833
8716
|
try {
|
|
8717
|
+
const source = availabilityUrl != null ? availabilityUrl : `${baseUrl}/api/v1/sdk/booking/availability`;
|
|
7834
8718
|
const res = await fetch(
|
|
7835
|
-
`${
|
|
8719
|
+
`${source}${source.includes("?") ? "&" : "?"}from=${encodeURIComponent(new Date(from).toISOString())}&to=${encodeURIComponent(new Date(to).toISOString())}${preview ? "&preview=1" : ""}`,
|
|
7836
8720
|
{ headers }
|
|
7837
8721
|
);
|
|
7838
8722
|
const json = await res.json();
|
|
@@ -7861,7 +8745,7 @@ function BookingDialog({
|
|
|
7861
8745
|
setPageLoaded(true);
|
|
7862
8746
|
}
|
|
7863
8747
|
},
|
|
7864
|
-
[baseUrl, headers]
|
|
8748
|
+
[baseUrl, headers, availabilityUrl, preview]
|
|
7865
8749
|
);
|
|
7866
8750
|
useEffect5(() => {
|
|
7867
8751
|
if (!open) return;
|
|
@@ -7875,6 +8759,7 @@ function BookingDialog({
|
|
|
7875
8759
|
setCode("");
|
|
7876
8760
|
setBookingId(null);
|
|
7877
8761
|
setError(null);
|
|
8762
|
+
setPreviewEnded(false);
|
|
7878
8763
|
setAvatarFailed(false);
|
|
7879
8764
|
setPageLoaded(false);
|
|
7880
8765
|
setAsked(false);
|
|
@@ -7913,6 +8798,10 @@ function BookingDialog({
|
|
|
7913
8798
|
async function startBooking() {
|
|
7914
8799
|
var _a2, _b2;
|
|
7915
8800
|
if (!selected) return;
|
|
8801
|
+
if (preview) {
|
|
8802
|
+
setPreviewEnded(true);
|
|
8803
|
+
return;
|
|
8804
|
+
}
|
|
7916
8805
|
setBusy(true);
|
|
7917
8806
|
setError(null);
|
|
7918
8807
|
try {
|
|
@@ -8106,6 +8995,22 @@ function BookingDialog({
|
|
|
8106
8995
|
) : null,
|
|
8107
8996
|
page.hostName && /* @__PURE__ */ jsx6("div", { style: { fontSize: 14, fontWeight: 500, ...muted }, children: page.hostName })
|
|
8108
8997
|
] }),
|
|
8998
|
+
preview && /* @__PURE__ */ jsx6(
|
|
8999
|
+
"div",
|
|
9000
|
+
{
|
|
9001
|
+
style: {
|
|
9002
|
+
alignSelf: "flex-start",
|
|
9003
|
+
padding: "3px 9px",
|
|
9004
|
+
borderRadius: 999,
|
|
9005
|
+
border: `1px dashed ${t.border}`,
|
|
9006
|
+
fontSize: 11.5,
|
|
9007
|
+
fontWeight: 600,
|
|
9008
|
+
letterSpacing: "0.02em",
|
|
9009
|
+
color: t.muted
|
|
9010
|
+
},
|
|
9011
|
+
children: "Preview \u2014 nothing is booked"
|
|
9012
|
+
}
|
|
9013
|
+
),
|
|
8109
9014
|
/* @__PURE__ */ jsx6("div", { style: { fontSize: 20, fontWeight: 600, lineHeight: 1.25, paddingRight: 32, overflowWrap: "anywhere" }, children: page.title }),
|
|
8110
9015
|
page.description && /* @__PURE__ */ jsx6("div", { style: { fontSize: 13, lineHeight: 1.5, overflowWrap: "anywhere", ...muted }, children: page.description }),
|
|
8111
9016
|
/* @__PURE__ */ jsxs6("div", { style: { display: "flex", flexDirection: "column", gap: 10, marginTop: 4, fontSize: 14 }, children: [
|
|
@@ -8543,6 +9448,7 @@ function BookingDialog({
|
|
|
8543
9448
|
},
|
|
8544
9449
|
children: /* @__PURE__ */ jsxs6("div", { style: { maxWidth: 440, display: "flex", flexDirection: "column", gap: 14 }, children: [
|
|
8545
9450
|
error && /* @__PURE__ */ jsx6("div", { style: { color: t.danger, fontSize: 13, lineHeight: 1.5 }, children: error }),
|
|
9451
|
+
previewEnded && /* @__PURE__ */ jsx6("div", { style: { fontSize: 13, lineHeight: 1.5, ...muted }, children: "End of the preview \u2014 a prospect would be booked here. Nothing was booked and no code was sent." }),
|
|
8546
9452
|
step === "details" && /* @__PURE__ */ jsxs6(Fragment5, { children: [
|
|
8547
9453
|
/* @__PURE__ */ jsx6(Field, { t, label: "Your name", value: name, onChange: setName, autoComplete: "name" }),
|
|
8548
9454
|
/* @__PURE__ */ jsx6(Field, { t, label: "Email", value: email, onChange: setEmail, type: "email", autoComplete: "email" }),
|
|
@@ -9028,6 +9934,9 @@ function GlitchgrabProviderInner({
|
|
|
9028
9934
|
onError,
|
|
9029
9935
|
onReportSent
|
|
9030
9936
|
});
|
|
9937
|
+
if (process.env.NODE_ENV !== "development") {
|
|
9938
|
+
installHydrationCapture(reportHydrationError);
|
|
9939
|
+
}
|
|
9031
9940
|
useEffect6(() => {
|
|
9032
9941
|
if (enableBreadcrumbs) {
|
|
9033
9942
|
initBreadcrumbs(maxBreadcrumbs2, { responseBodyOrigins: responseBodyOrigins2 });
|
|
@@ -9083,7 +9992,7 @@ function GlitchgrabProviderInner({
|
|
|
9083
9992
|
return matchesIgnorePatterns(message, ignoreErrors);
|
|
9084
9993
|
};
|
|
9085
9994
|
const handleError = (event) => {
|
|
9086
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
9995
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
9087
9996
|
try {
|
|
9088
9997
|
const isOpaqueCrossOrigin = event.message === "Script error." || event.message === "Script error" || !event.error && !event.filename;
|
|
9089
9998
|
if (isOpaqueCrossOrigin) {
|
|
@@ -9098,6 +10007,7 @@ function GlitchgrabProviderInner({
|
|
|
9098
10007
|
if (event.filename && EXTENSION_ORIGIN_RE.test(event.filename) || ((_a = event.error) == null ? void 0 : _a.stack) && EXTENSION_ORIGIN_RE.test(event.error.stack)) {
|
|
9099
10008
|
return;
|
|
9100
10009
|
}
|
|
10010
|
+
if (isHandledHydrationError(event.error)) return;
|
|
9101
10011
|
incrementErrorCount();
|
|
9102
10012
|
const context = captureContext(visitedPagesRef.current);
|
|
9103
10013
|
const sig = computeSignature({
|
|
@@ -9123,6 +10033,9 @@ function GlitchgrabProviderInner({
|
|
|
9123
10033
|
filename: (_e = event.filename) != null ? _e : "",
|
|
9124
10034
|
lineno: String((_f = event.lineno) != null ? _f : ""),
|
|
9125
10035
|
colno: String((_g = event.colno) != null ? _g : ""),
|
|
10036
|
+
// The root patch could not attach (React internals moved, or a
|
|
10037
|
+
// root it does not know): still label it and send the DOM context.
|
|
10038
|
+
...isHydrationError((_h = event.error) != null ? _h : event.message) ? hydrationMetadata((_i = event.error) != null ? _i : event.message) : {},
|
|
9126
10039
|
...(session == null ? void 0 : session.userId) ? { sessionUserId: session.userId } : {},
|
|
9127
10040
|
...(session == null ? void 0 : session.name) ? { sessionUserName: String(session.name) } : {},
|
|
9128
10041
|
...(session == null ? void 0 : session.email) ? { sessionUserEmail: String(session.email) } : {},
|
|
@@ -9383,7 +10296,11 @@ function GlitchgrabProviderInner({
|
|
|
9383
10296
|
[token, baseUrl, session]
|
|
9384
10297
|
);
|
|
9385
10298
|
const findSimilar = useCallback3(
|
|
9386
|
-
(description) => findSimilarIssues(description, token, baseUrl, identity),
|
|
10299
|
+
(description, files) => findSimilarIssues(description, token, baseUrl, identity, files),
|
|
10300
|
+
[token, baseUrl, identity]
|
|
10301
|
+
);
|
|
10302
|
+
const readFile = useCallback3(
|
|
10303
|
+
(file) => readAttachment(file, token, baseUrl, identity),
|
|
9387
10304
|
[token, baseUrl, identity]
|
|
9388
10305
|
);
|
|
9389
10306
|
const transcribe = useCallback3(
|
|
@@ -9414,8 +10331,9 @@ function GlitchgrabProviderInner({
|
|
|
9414
10331
|
const [glitchgrabReport, setGlitchgrabReport] = useState6(false);
|
|
9415
10332
|
const [signedUsers, setSignedUsers] = useState6("OFF");
|
|
9416
10333
|
const aiBlockedUnsigned = signedUsers === "ENFORCE" && !signature;
|
|
9417
|
-
const [
|
|
9418
|
-
const openBookingDialog = useCallback3(() =>
|
|
10334
|
+
const [booking, setBooking] = useState6("closed");
|
|
10335
|
+
const openBookingDialog = useCallback3(() => setBooking("live"), []);
|
|
10336
|
+
const openBookingPreview = useCallback3(() => setBooking("preview"), []);
|
|
9419
10337
|
useEffect6(() => {
|
|
9420
10338
|
let cancelled = false;
|
|
9421
10339
|
fetch(`${baseUrl}/api/v1/sdk/project`, {
|
|
@@ -9459,7 +10377,7 @@ function GlitchgrabProviderInner({
|
|
|
9459
10377
|
} catch (e) {
|
|
9460
10378
|
}
|
|
9461
10379
|
}, [openReportDialog]);
|
|
9462
|
-
const
|
|
10380
|
+
const reporter2 = useMemo4(() => {
|
|
9463
10381
|
var _a;
|
|
9464
10382
|
if (!session) return null;
|
|
9465
10383
|
const avatar = (_a = session.avatarUrl) != null ? _a : session.image;
|
|
@@ -9490,6 +10408,7 @@ function GlitchgrabProviderInner({
|
|
|
9490
10408
|
addBreadcrumb: addBreadcrumb2,
|
|
9491
10409
|
openReportDialog,
|
|
9492
10410
|
openBookingDialog,
|
|
10411
|
+
openBookingPreview,
|
|
9493
10412
|
enhanceText: enhance,
|
|
9494
10413
|
shortcutLabel
|
|
9495
10414
|
},
|
|
@@ -9511,8 +10430,9 @@ function GlitchgrabProviderInner({
|
|
|
9511
10430
|
{
|
|
9512
10431
|
token,
|
|
9513
10432
|
baseUrl: baseUrl != null ? baseUrl : DEFAULT_BASE_URL2,
|
|
9514
|
-
open:
|
|
9515
|
-
|
|
10433
|
+
open: booking !== "closed",
|
|
10434
|
+
preview: booking === "preview",
|
|
10435
|
+
onClose: () => setBooking("closed")
|
|
9516
10436
|
}
|
|
9517
10437
|
),
|
|
9518
10438
|
/* @__PURE__ */ jsx7(
|
|
@@ -9523,11 +10443,13 @@ function GlitchgrabProviderInner({
|
|
|
9523
10443
|
enhanceText: aiAssist && !aiBlockedUnsigned ? enhance : void 0,
|
|
9524
10444
|
assist: aiAssist && !aiBlockedUnsigned ? assist : void 0,
|
|
9525
10445
|
findSimilarIssues: aiAssist && !aiBlockedUnsigned ? findSimilar : void 0,
|
|
10446
|
+
readFile: aiAssist && !aiBlockedUnsigned ? readFile : void 0,
|
|
9526
10447
|
reportGlitchgrabProblem: glitchgrabReport ? reportGlitchgrabProblem : void 0,
|
|
9527
10448
|
transcribeAudio: aiBlockedUnsigned ? void 0 : transcribe,
|
|
9528
10449
|
types,
|
|
9529
10450
|
showSeverity,
|
|
9530
|
-
reporter,
|
|
10451
|
+
reporter: reporter2,
|
|
10452
|
+
chatHistoryKey: chatHistoryKey("sdk", token, session == null ? void 0 : session.userId),
|
|
9531
10453
|
headerSlot: projectName ? /* @__PURE__ */ jsxs7("div", { style: { fontSize: 11, color: "#9aa0a6" }, children: [
|
|
9532
10454
|
"Reporting to ",
|
|
9533
10455
|
/* @__PURE__ */ jsx7("strong", { style: { color: "#e5e5e5" }, children: projectName })
|
|
@@ -9926,6 +10848,7 @@ function useGlitchgrabFeedback(query) {
|
|
|
9926
10848
|
}
|
|
9927
10849
|
export {
|
|
9928
10850
|
BookDemoButton,
|
|
10851
|
+
BookingDialog,
|
|
9929
10852
|
FeedbackButton,
|
|
9930
10853
|
GLITCHGRAB_SHORTCUT2 as GLITCHGRAB_SHORTCUT,
|
|
9931
10854
|
GLITCHGRAB_SHORTCUT_MAC2 as GLITCHGRAB_SHORTCUT_MAC,
|