glitchgrab 1.58.3 → 1.59.1
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 +55 -0
- package/dist/index.d.mts +84 -4
- package/dist/index.d.ts +84 -4
- package/dist/index.js +328 -34
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +325 -34
- package/dist/index.mjs.map +1 -1
- package/dist/server.d.mts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js.map +1 -1
- package/dist/server.mjs.map +1 -1
- package/dist/{types-BpTLWJ1y.d.mts → types-BlMF6wzX.d.mts} +28 -2
- package/dist/{types-BpTLWJ1y.d.ts → types-BlMF6wzX.d.ts} +28 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -49,12 +49,14 @@ __export(index_exports, {
|
|
|
49
49
|
computeSignature: () => computeSignature,
|
|
50
50
|
enhanceText: () => enhanceText,
|
|
51
51
|
fetchGlitchgrabFeedback: () => fetchGlitchgrabFeedback,
|
|
52
|
+
fetchGlitchgrabReportThread: () => fetchGlitchgrabReportThread,
|
|
52
53
|
fetchGlitchgrabReports: () => fetchGlitchgrabReports,
|
|
53
54
|
getAppContext: () => getAppContext,
|
|
54
55
|
getBreadcrumbs: () => getBreadcrumbs,
|
|
55
56
|
getShortcutLabel: () => getShortcutLabel2,
|
|
56
57
|
initBreadcrumbs: () => initBreadcrumbs,
|
|
57
58
|
matchesShortcut: () => matchesShortcut,
|
|
59
|
+
postGlitchgrabReportComment: () => postGlitchgrabReportComment,
|
|
58
60
|
sanitizeUrl: () => sanitizeUrl,
|
|
59
61
|
sendFeedback: () => sendFeedback,
|
|
60
62
|
sendLead: () => sendLead,
|
|
@@ -65,6 +67,7 @@ __export(index_exports, {
|
|
|
65
67
|
useGlitchgrab: () => useGlitchgrab,
|
|
66
68
|
useGlitchgrabActions: () => useGlitchgrabActions,
|
|
67
69
|
useGlitchgrabFeedback: () => useGlitchgrabFeedback,
|
|
70
|
+
useGlitchgrabReportThread: () => useGlitchgrabReportThread,
|
|
68
71
|
useGlitchgrabReports: () => useGlitchgrabReports
|
|
69
72
|
});
|
|
70
73
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -772,12 +775,21 @@ function signedFields(identity) {
|
|
|
772
775
|
return { userId: identity.userId, signature: identity.signature };
|
|
773
776
|
}
|
|
774
777
|
async function enhanceText(text, token, baseUrl, screenshot, context, identity) {
|
|
778
|
+
try {
|
|
779
|
+
return await enhanceTextOrThrow(text, token, baseUrl, screenshot, context, identity);
|
|
780
|
+
} catch (e) {
|
|
781
|
+
return text;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
async function enhanceTextOrThrow(text, token, baseUrl, screenshot, context, identity) {
|
|
775
785
|
var _a;
|
|
786
|
+
const trimmed = text.trim();
|
|
787
|
+
if (!trimmed) return text;
|
|
788
|
+
const unavailable = "AI enhance isn't available right now \u2014 send your report as written.";
|
|
789
|
+
let response;
|
|
776
790
|
try {
|
|
777
|
-
const trimmed = text.trim();
|
|
778
|
-
if (!trimmed) return text;
|
|
779
791
|
const url = `${baseUrl != null ? baseUrl : DEFAULT_BASE_URL}/api/v1/ai/enhance-text`;
|
|
780
|
-
|
|
792
|
+
response = await fetch(url, {
|
|
781
793
|
method: "POST",
|
|
782
794
|
headers: {
|
|
783
795
|
"Content-Type": "application/json",
|
|
@@ -790,15 +802,20 @@ async function enhanceText(text, token, baseUrl, screenshot, context, identity)
|
|
|
790
802
|
...signedFields(identity)
|
|
791
803
|
})
|
|
792
804
|
});
|
|
793
|
-
if (!response.ok) return text;
|
|
794
|
-
const envelope = await response.json();
|
|
795
|
-
if ((envelope == null ? void 0 : envelope.success) && typeof ((_a = envelope.data) == null ? void 0 : _a.text) === "string") {
|
|
796
|
-
return envelope.data.text;
|
|
797
|
-
}
|
|
798
|
-
return text;
|
|
799
805
|
} catch (e) {
|
|
800
|
-
|
|
806
|
+
throw new Error(unavailable);
|
|
807
|
+
}
|
|
808
|
+
if (response.status === 429) {
|
|
809
|
+
throw new Error("Too many AI enhance tries \u2014 wait a while, or send your report as written.");
|
|
801
810
|
}
|
|
811
|
+
const envelope = await response.json().catch(() => null);
|
|
812
|
+
if (response.ok && (envelope == null ? void 0 : envelope.success) && typeof ((_a = envelope.data) == null ? void 0 : _a.text) === "string") {
|
|
813
|
+
return envelope.data.text;
|
|
814
|
+
}
|
|
815
|
+
if (response.status === 400 && typeof (envelope == null ? void 0 : envelope.error) === "string") {
|
|
816
|
+
throw new Error(envelope.error);
|
|
817
|
+
}
|
|
818
|
+
throw new Error(unavailable);
|
|
802
819
|
}
|
|
803
820
|
async function findSimilarIssues(description, token, baseUrl, identity, files) {
|
|
804
821
|
var _a;
|
|
@@ -5550,6 +5567,7 @@ function ReportDialog({
|
|
|
5550
5567
|
const [aiConversationId, setAiConversationId] = (0, import_react.useState)(null);
|
|
5551
5568
|
const [issueTitle, setIssueTitle] = (0, import_react.useState)("");
|
|
5552
5569
|
const [isEnhanced, setIsEnhanced] = (0, import_react.useState)(false);
|
|
5570
|
+
const [enhanceError, setEnhanceError] = (0, import_react.useState)(null);
|
|
5553
5571
|
const [originalDescription, setOriginalDescription] = (0, import_react.useState)(
|
|
5554
5572
|
null
|
|
5555
5573
|
);
|
|
@@ -6004,6 +6022,7 @@ function ReportDialog({
|
|
|
6004
6022
|
setSelfReportFrom(null);
|
|
6005
6023
|
setVoiceError(null);
|
|
6006
6024
|
setIsEnhanced(false);
|
|
6025
|
+
setEnhanceError(null);
|
|
6007
6026
|
setOriginalDescription(null);
|
|
6008
6027
|
setAssistOpen(false);
|
|
6009
6028
|
setAssistUsed(false);
|
|
@@ -6069,6 +6088,7 @@ function ReportDialog({
|
|
|
6069
6088
|
const sep = base.trim() ? " " : "";
|
|
6070
6089
|
setDescriptionFromVoice(base + sep + text.trim());
|
|
6071
6090
|
setValidationError(null);
|
|
6091
|
+
setEnhanceError(null);
|
|
6072
6092
|
setIsEnhanced(false);
|
|
6073
6093
|
setOriginalDescription(null);
|
|
6074
6094
|
}
|
|
@@ -7164,6 +7184,7 @@ function ReportDialog({
|
|
|
7164
7184
|
notePushToTalkEdit();
|
|
7165
7185
|
setDescription(e.target.value);
|
|
7166
7186
|
if (validationError) setValidationError(null);
|
|
7187
|
+
if (enhanceError) setEnhanceError(null);
|
|
7167
7188
|
if (isEnhanced) {
|
|
7168
7189
|
setIsEnhanced(false);
|
|
7169
7190
|
setOriginalDescription(null);
|
|
@@ -7285,6 +7306,7 @@ function ReportDialog({
|
|
|
7285
7306
|
var _a2;
|
|
7286
7307
|
if (!description.trim() || isEnhancing) return;
|
|
7287
7308
|
setIsEnhancing(true);
|
|
7309
|
+
setEnhanceError(null);
|
|
7288
7310
|
try {
|
|
7289
7311
|
const polished = await enhanceText2(
|
|
7290
7312
|
description,
|
|
@@ -7297,6 +7319,10 @@ function ReportDialog({
|
|
|
7297
7319
|
if (validationError)
|
|
7298
7320
|
setValidationError(null);
|
|
7299
7321
|
}
|
|
7322
|
+
} catch (err) {
|
|
7323
|
+
setEnhanceError(
|
|
7324
|
+
err instanceof Error && err.message ? err.message : "AI enhance isn't available right now \u2014 send your report as written."
|
|
7325
|
+
);
|
|
7300
7326
|
} finally {
|
|
7301
7327
|
setIsEnhancing(false);
|
|
7302
7328
|
}
|
|
@@ -7555,6 +7581,20 @@ function ReportDialog({
|
|
|
7555
7581
|
children: voiceError
|
|
7556
7582
|
}
|
|
7557
7583
|
),
|
|
7584
|
+
enhanceError && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
7585
|
+
"p",
|
|
7586
|
+
{
|
|
7587
|
+
role: "alert",
|
|
7588
|
+
style: {
|
|
7589
|
+
color: "#ef4444",
|
|
7590
|
+
fontSize: "11px",
|
|
7591
|
+
lineHeight: 1.5,
|
|
7592
|
+
marginTop: "4px",
|
|
7593
|
+
marginBottom: 0
|
|
7594
|
+
},
|
|
7595
|
+
children: enhanceError
|
|
7596
|
+
}
|
|
7597
|
+
),
|
|
7558
7598
|
assistNotice && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
7559
7599
|
"p",
|
|
7560
7600
|
{
|
|
@@ -8577,6 +8617,69 @@ function getTypeIcon(type, color, size = 24) {
|
|
|
8577
8617
|
|
|
8578
8618
|
// src/booking-dialog.tsx
|
|
8579
8619
|
var import_react5 = require("react");
|
|
8620
|
+
|
|
8621
|
+
// src/phone.ts
|
|
8622
|
+
var COUNTRIES = [
|
|
8623
|
+
{ iso: "IN", name: "India", dial: "91" },
|
|
8624
|
+
{ iso: "AE", name: "UAE", dial: "971" },
|
|
8625
|
+
{ iso: "US", name: "US / Canada", dial: "1" },
|
|
8626
|
+
{ iso: "GB", name: "UK", dial: "44" },
|
|
8627
|
+
{ iso: "SG", name: "Singapore", dial: "65" },
|
|
8628
|
+
{ iso: "AU", name: "Australia", dial: "61" },
|
|
8629
|
+
{ iso: "SA", name: "Saudi Arabia", dial: "966" },
|
|
8630
|
+
{ iso: "QA", name: "Qatar", dial: "974" },
|
|
8631
|
+
{ iso: "NP", name: "Nepal", dial: "977" },
|
|
8632
|
+
{ iso: "BD", name: "Bangladesh", dial: "880" },
|
|
8633
|
+
{ iso: "LK", name: "Sri Lanka", dial: "94" },
|
|
8634
|
+
{ iso: "DE", name: "Germany", dial: "49" }
|
|
8635
|
+
];
|
|
8636
|
+
var ZONE_COUNTRY = {
|
|
8637
|
+
"Asia/Kolkata": "91",
|
|
8638
|
+
"Asia/Calcutta": "91",
|
|
8639
|
+
"Asia/Dubai": "971",
|
|
8640
|
+
"Europe/London": "44",
|
|
8641
|
+
"Asia/Singapore": "65",
|
|
8642
|
+
"Asia/Riyadh": "966",
|
|
8643
|
+
"Asia/Qatar": "974",
|
|
8644
|
+
"Asia/Kathmandu": "977",
|
|
8645
|
+
"Asia/Katmandu": "977",
|
|
8646
|
+
"Asia/Dhaka": "880",
|
|
8647
|
+
"Asia/Colombo": "94",
|
|
8648
|
+
"Europe/Berlin": "49"
|
|
8649
|
+
};
|
|
8650
|
+
function defaultDialForZone(zone) {
|
|
8651
|
+
if (ZONE_COUNTRY[zone]) return ZONE_COUNTRY[zone];
|
|
8652
|
+
if (zone.startsWith("America/")) return "1";
|
|
8653
|
+
if (zone.startsWith("Australia/")) return "61";
|
|
8654
|
+
return "91";
|
|
8655
|
+
}
|
|
8656
|
+
function splitTypedPhone(typed, dial) {
|
|
8657
|
+
const trimmed = typed.trim();
|
|
8658
|
+
const digits = trimmed.replace(/\D/g, "");
|
|
8659
|
+
if (trimmed.startsWith("+")) {
|
|
8660
|
+
const match = [...COUNTRIES].sort((a, b) => b.dial.length - a.dial.length).find((c) => digits.startsWith(c.dial));
|
|
8661
|
+
if (match) return { dial: match.dial, national: digits.slice(match.dial.length) };
|
|
8662
|
+
}
|
|
8663
|
+
if (dial === "91" && digits.length === 12 && digits.startsWith("91")) return { dial, national: digits.slice(2) };
|
|
8664
|
+
if (dial === "91" && digits.length === 11 && digits.startsWith("0")) return { dial, national: digits.slice(1) };
|
|
8665
|
+
return { dial, national: digits };
|
|
8666
|
+
}
|
|
8667
|
+
function phoneProblem(dial, national) {
|
|
8668
|
+
const digits = national.replace(/\D/g, "");
|
|
8669
|
+
if (!digits) return "Enter your mobile number";
|
|
8670
|
+
if (dial === "91") {
|
|
8671
|
+
if (digits.length !== 10) return `An Indian mobile has 10 digits \u2014 this has ${digits.length}`;
|
|
8672
|
+
if (!/^[6-9]/.test(digits)) return "An Indian mobile starts with 6, 7, 8 or 9";
|
|
8673
|
+
return null;
|
|
8674
|
+
}
|
|
8675
|
+
if (digits.length < 6 || digits.length > 12) return "Check the number \u2014 it looks too short or too long";
|
|
8676
|
+
return null;
|
|
8677
|
+
}
|
|
8678
|
+
function toE164(dial, national) {
|
|
8679
|
+
return `+${dial}${national.replace(/\D/g, "")}`;
|
|
8680
|
+
}
|
|
8681
|
+
|
|
8682
|
+
// src/booking-dialog.tsx
|
|
8580
8683
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
8581
8684
|
function readQuestions(value) {
|
|
8582
8685
|
if (!Array.isArray(value)) return [];
|
|
@@ -8719,7 +8822,9 @@ function BookingDialog({
|
|
|
8719
8822
|
open,
|
|
8720
8823
|
onClose,
|
|
8721
8824
|
preview = false,
|
|
8722
|
-
availabilityUrl
|
|
8825
|
+
availabilityUrl,
|
|
8826
|
+
intro,
|
|
8827
|
+
onBooked
|
|
8723
8828
|
}) {
|
|
8724
8829
|
var _a, _b, _c, _d, _e;
|
|
8725
8830
|
const wide = useMediaQuery(WIDE_QUERY, true);
|
|
@@ -8742,6 +8847,8 @@ function BookingDialog({
|
|
|
8742
8847
|
const [name, setName] = (0, import_react5.useState)("");
|
|
8743
8848
|
const [email, setEmail] = (0, import_react5.useState)("");
|
|
8744
8849
|
const [phone, setPhone] = (0, import_react5.useState)("");
|
|
8850
|
+
const [dial, setDial] = (0, import_react5.useState)(() => defaultDialForZone(localZone()));
|
|
8851
|
+
const [phoneTouched, setPhoneTouched] = (0, import_react5.useState)(false);
|
|
8745
8852
|
const [note, setNote] = (0, import_react5.useState)("");
|
|
8746
8853
|
const [questions, setQuestions] = (0, import_react5.useState)([]);
|
|
8747
8854
|
const [answers, setAnswers] = (0, import_react5.useState)({});
|
|
@@ -8852,8 +8959,12 @@ function BookingDialog({
|
|
|
8852
8959
|
const view = step !== "slots" ? step : !pageLoaded ? "loading" : questions.length > 0 && !asked ? "questions" : "slots";
|
|
8853
8960
|
const roomy = step === "slots";
|
|
8854
8961
|
async function startBooking() {
|
|
8855
|
-
var _a2, _b2;
|
|
8962
|
+
var _a2, _b2, _c2;
|
|
8856
8963
|
if (!selected) return;
|
|
8964
|
+
if (phoneError) {
|
|
8965
|
+
setPhoneTouched(true);
|
|
8966
|
+
return;
|
|
8967
|
+
}
|
|
8857
8968
|
if (preview) {
|
|
8858
8969
|
setPreviewEnded(true);
|
|
8859
8970
|
return;
|
|
@@ -8867,7 +8978,7 @@ function BookingDialog({
|
|
|
8867
8978
|
body: JSON.stringify({
|
|
8868
8979
|
name,
|
|
8869
8980
|
email,
|
|
8870
|
-
phone,
|
|
8981
|
+
phone: toE164(dial, phone),
|
|
8871
8982
|
note,
|
|
8872
8983
|
answers: Object.fromEntries(given.map((q) => [q.id, q.answer])),
|
|
8873
8984
|
startsAt: selected.startsAt,
|
|
@@ -8886,6 +8997,7 @@ function BookingDialog({
|
|
|
8886
8997
|
if (json.data.confirmed) {
|
|
8887
8998
|
setMeetUrl((_b2 = json.data.meetUrl) != null ? _b2 : null);
|
|
8888
8999
|
setStep("done");
|
|
9000
|
+
reportBooked(json.data.bookingId, (_c2 = json.data.meetUrl) != null ? _c2 : null);
|
|
8889
9001
|
return;
|
|
8890
9002
|
}
|
|
8891
9003
|
setBookingId(json.data.bookingId);
|
|
@@ -8896,8 +9008,16 @@ function BookingDialog({
|
|
|
8896
9008
|
setBusy(false);
|
|
8897
9009
|
}
|
|
8898
9010
|
}
|
|
9011
|
+
function reportBooked(id, meet) {
|
|
9012
|
+
if (!onBooked || !id || !selected) return;
|
|
9013
|
+
try {
|
|
9014
|
+
onBooked({ bookingId: id, startsAt: selected.startsAt, name, email, phone: toE164(dial, phone), meetUrl: meet });
|
|
9015
|
+
} catch (e) {
|
|
9016
|
+
console.error("[glitchgrab] onBooked threw", e);
|
|
9017
|
+
}
|
|
9018
|
+
}
|
|
8899
9019
|
async function confirmBooking() {
|
|
8900
|
-
var _a2;
|
|
9020
|
+
var _a2, _b2;
|
|
8901
9021
|
if (!bookingId) return;
|
|
8902
9022
|
setBusy(true);
|
|
8903
9023
|
setError(null);
|
|
@@ -8914,13 +9034,15 @@ function BookingDialog({
|
|
|
8914
9034
|
}
|
|
8915
9035
|
setMeetUrl(json.data.meetUrl);
|
|
8916
9036
|
setStep("done");
|
|
9037
|
+
reportBooked(bookingId, (_b2 = json.data.meetUrl) != null ? _b2 : null);
|
|
8917
9038
|
} catch (e) {
|
|
8918
9039
|
setError("Couldn't reach the booking service");
|
|
8919
9040
|
} finally {
|
|
8920
9041
|
setBusy(false);
|
|
8921
9042
|
}
|
|
8922
9043
|
}
|
|
8923
|
-
const
|
|
9044
|
+
const phoneError = phoneProblem(dial, phone);
|
|
9045
|
+
const canSubmitDetails = Boolean(name.trim() && email.includes("@"));
|
|
8924
9046
|
const selectedEnd = selected ? (_e = selected.endsAt) != null ? _e : new Date(new Date(selected.startsAt).getTime() + page.slotMinutes * 6e4).toISOString() : null;
|
|
8925
9047
|
const monthDate = new Date(keyToUtc(`${month}-01`));
|
|
8926
9048
|
const muted = { color: t.muted };
|
|
@@ -9067,6 +9189,14 @@ function BookingDialog({
|
|
|
9067
9189
|
children: "Preview \u2014 nothing is booked"
|
|
9068
9190
|
}
|
|
9069
9191
|
),
|
|
9192
|
+
intro && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
9193
|
+
"div",
|
|
9194
|
+
{
|
|
9195
|
+
"data-glitchgrab-booking-intro": true,
|
|
9196
|
+
style: { fontSize: 13, fontWeight: 600, lineHeight: 1.45, paddingRight: 32, color: t.ink, overflowWrap: "anywhere" },
|
|
9197
|
+
children: intro
|
|
9198
|
+
}
|
|
9199
|
+
),
|
|
9070
9200
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { fontSize: 20, fontWeight: 600, lineHeight: 1.25, paddingRight: 32, overflowWrap: "anywhere" }, children: page.title }),
|
|
9071
9201
|
page.description && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { fontSize: 13, lineHeight: 1.5, overflowWrap: "anywhere", ...muted }, children: page.description }),
|
|
9072
9202
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: 10, marginTop: 4, fontSize: 14 }, children: [
|
|
@@ -9509,14 +9639,17 @@ function BookingDialog({
|
|
|
9509
9639
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Field, { t, label: "Your name", value: name, onChange: setName, autoComplete: "name" }),
|
|
9510
9640
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Field, { t, label: "Email", value: email, onChange: setEmail, type: "email", autoComplete: "email" }),
|
|
9511
9641
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
9512
|
-
|
|
9642
|
+
PhoneField,
|
|
9513
9643
|
{
|
|
9514
9644
|
t,
|
|
9515
|
-
|
|
9516
|
-
|
|
9517
|
-
onChange:
|
|
9518
|
-
|
|
9519
|
-
|
|
9645
|
+
dial,
|
|
9646
|
+
national: phone,
|
|
9647
|
+
onChange: (nextDial, national) => {
|
|
9648
|
+
setDial(nextDial);
|
|
9649
|
+
setPhone(national);
|
|
9650
|
+
},
|
|
9651
|
+
onBlur: () => setPhoneTouched(true),
|
|
9652
|
+
error: phoneTouched ? phoneError : null,
|
|
9520
9653
|
hint: requireOtp ? "We send a code here to confirm, then a reminder before the call." : "We send a reminder here before the call."
|
|
9521
9654
|
}
|
|
9522
9655
|
),
|
|
@@ -9804,6 +9937,64 @@ function Field({
|
|
|
9804
9937
|
hint && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { marginTop: 6, fontSize: 12, fontWeight: 400, color: t.muted }, children: hint })
|
|
9805
9938
|
] });
|
|
9806
9939
|
}
|
|
9940
|
+
function PhoneField({
|
|
9941
|
+
t,
|
|
9942
|
+
dial,
|
|
9943
|
+
national,
|
|
9944
|
+
onChange,
|
|
9945
|
+
onBlur,
|
|
9946
|
+
error,
|
|
9947
|
+
hint
|
|
9948
|
+
}) {
|
|
9949
|
+
const box = {
|
|
9950
|
+
boxSizing: "border-box",
|
|
9951
|
+
padding: "9px 12px",
|
|
9952
|
+
background: t.input,
|
|
9953
|
+
color: t.text,
|
|
9954
|
+
border: `1px solid ${error ? t.danger : t.border}`,
|
|
9955
|
+
borderRadius: 8,
|
|
9956
|
+
fontFamily: "inherit",
|
|
9957
|
+
fontSize: 14,
|
|
9958
|
+
outline: "none"
|
|
9959
|
+
};
|
|
9960
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { style: { display: "block", fontSize: 13, fontWeight: 500, color: t.text }, children: [
|
|
9961
|
+
"Mobile number",
|
|
9962
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", gap: 8, marginTop: 6 }, children: [
|
|
9963
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
9964
|
+
"select",
|
|
9965
|
+
{
|
|
9966
|
+
"aria-label": "Country code",
|
|
9967
|
+
value: dial,
|
|
9968
|
+
onChange: (e) => onChange(e.target.value, national),
|
|
9969
|
+
style: { ...box, flex: "0 0 auto", paddingRight: 8, cursor: "pointer" },
|
|
9970
|
+
children: COUNTRIES.map((c) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("option", { value: c.dial, children: [
|
|
9971
|
+
c.iso,
|
|
9972
|
+
" +",
|
|
9973
|
+
c.dial
|
|
9974
|
+
] }, c.iso))
|
|
9975
|
+
}
|
|
9976
|
+
),
|
|
9977
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
9978
|
+
"input",
|
|
9979
|
+
{
|
|
9980
|
+
type: "tel",
|
|
9981
|
+
autoComplete: "tel",
|
|
9982
|
+
inputMode: "numeric",
|
|
9983
|
+
placeholder: dial === "91" ? "98765 43210" : "Mobile number",
|
|
9984
|
+
value: national,
|
|
9985
|
+
"aria-invalid": Boolean(error),
|
|
9986
|
+
onChange: (e) => {
|
|
9987
|
+
const next = splitTypedPhone(e.target.value, dial);
|
|
9988
|
+
onChange(next.dial, next.national);
|
|
9989
|
+
},
|
|
9990
|
+
onBlur,
|
|
9991
|
+
style: { ...box, flex: "1 1 auto", minWidth: 0, width: "100%" }
|
|
9992
|
+
}
|
|
9993
|
+
)
|
|
9994
|
+
] }),
|
|
9995
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { role: "alert", style: { marginTop: 6, fontSize: 12, fontWeight: 500, color: t.danger }, children: error }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { marginTop: 6, fontSize: 12, fontWeight: 400, color: t.muted }, children: hint })
|
|
9996
|
+
] });
|
|
9997
|
+
}
|
|
9807
9998
|
|
|
9808
9999
|
// src/rejection.ts
|
|
9809
10000
|
var DETAILS_MAX_LENGTH = 1e3;
|
|
@@ -10308,21 +10499,27 @@ function GlitchgrabProviderInner({
|
|
|
10308
10499
|
() => ({ userId: signedUserId != null ? signedUserId : null, signature }),
|
|
10309
10500
|
[signedUserId, signature]
|
|
10310
10501
|
);
|
|
10502
|
+
const enhanceForDialog = (0, import_react6.useCallback)(
|
|
10503
|
+
async (text, screenshot) => {
|
|
10504
|
+
const ctx = captureContext(visitedPagesRef.current);
|
|
10505
|
+
const context = {
|
|
10506
|
+
url: ctx.url,
|
|
10507
|
+
visitedPages: ctx.visitedPages.slice(-5),
|
|
10508
|
+
breadcrumbs: ctx.breadcrumbs.slice(-10).map((b) => ({ type: b.type, message: b.message }))
|
|
10509
|
+
};
|
|
10510
|
+
return await enhanceTextOrThrow(text, token, baseUrl, screenshot, context, identity);
|
|
10511
|
+
},
|
|
10512
|
+
[token, baseUrl, identity]
|
|
10513
|
+
);
|
|
10311
10514
|
const enhance = (0, import_react6.useCallback)(
|
|
10312
10515
|
async (text, screenshot) => {
|
|
10313
10516
|
try {
|
|
10314
|
-
|
|
10315
|
-
const context = {
|
|
10316
|
-
url: ctx.url,
|
|
10317
|
-
visitedPages: ctx.visitedPages.slice(-5),
|
|
10318
|
-
breadcrumbs: ctx.breadcrumbs.slice(-10).map((b) => ({ type: b.type, message: b.message }))
|
|
10319
|
-
};
|
|
10320
|
-
return await enhanceText(text, token, baseUrl, screenshot, context, identity);
|
|
10517
|
+
return await enhanceForDialog(text, screenshot);
|
|
10321
10518
|
} catch (e) {
|
|
10322
10519
|
return text;
|
|
10323
10520
|
}
|
|
10324
10521
|
},
|
|
10325
|
-
[
|
|
10522
|
+
[enhanceForDialog]
|
|
10326
10523
|
);
|
|
10327
10524
|
const assist = (0, import_react6.useCallback)(
|
|
10328
10525
|
async (params) => {
|
|
@@ -10388,8 +10585,18 @@ function GlitchgrabProviderInner({
|
|
|
10388
10585
|
const [signedUsers, setSignedUsers] = (0, import_react6.useState)("OFF");
|
|
10389
10586
|
const aiBlockedUnsigned = signedUsers === "ENFORCE" && !signature;
|
|
10390
10587
|
const [booking, setBooking] = (0, import_react6.useState)("closed");
|
|
10391
|
-
const
|
|
10392
|
-
const
|
|
10588
|
+
const [bookingOptions, setBookingOptions] = (0, import_react6.useState)({});
|
|
10589
|
+
const openBookingDialog = (0, import_react6.useCallback)((options) => {
|
|
10590
|
+
setBookingOptions({
|
|
10591
|
+
intro: typeof (options == null ? void 0 : options.intro) === "string" ? options.intro : void 0,
|
|
10592
|
+
onBooked: typeof (options == null ? void 0 : options.onBooked) === "function" ? options.onBooked : void 0
|
|
10593
|
+
});
|
|
10594
|
+
setBooking("live");
|
|
10595
|
+
}, []);
|
|
10596
|
+
const openBookingPreview = (0, import_react6.useCallback)(() => {
|
|
10597
|
+
setBookingOptions({});
|
|
10598
|
+
setBooking("preview");
|
|
10599
|
+
}, []);
|
|
10393
10600
|
(0, import_react6.useEffect)(() => {
|
|
10394
10601
|
let cancelled = false;
|
|
10395
10602
|
fetch(`${baseUrl}/api/v1/sdk/project`, {
|
|
@@ -10488,6 +10695,8 @@ function GlitchgrabProviderInner({
|
|
|
10488
10695
|
baseUrl: baseUrl != null ? baseUrl : DEFAULT_BASE_URL2,
|
|
10489
10696
|
open: booking !== "closed",
|
|
10490
10697
|
preview: booking === "preview",
|
|
10698
|
+
intro: bookingOptions.intro,
|
|
10699
|
+
onBooked: bookingOptions.onBooked,
|
|
10491
10700
|
onClose: () => setBooking("closed")
|
|
10492
10701
|
}
|
|
10493
10702
|
),
|
|
@@ -10496,7 +10705,7 @@ function GlitchgrabProviderInner({
|
|
|
10496
10705
|
{
|
|
10497
10706
|
report,
|
|
10498
10707
|
sendFeedback: feedback,
|
|
10499
|
-
enhanceText: aiAssist && !aiBlockedUnsigned ?
|
|
10708
|
+
enhanceText: aiAssist && !aiBlockedUnsigned ? enhanceForDialog : void 0,
|
|
10500
10709
|
assist: aiAssist && !aiBlockedUnsigned ? assist : void 0,
|
|
10501
10710
|
findSimilarIssues: aiAssist && !aiBlockedUnsigned ? findSimilar : void 0,
|
|
10502
10711
|
readFile: aiAssist && !aiBlockedUnsigned ? readFile : void 0,
|
|
@@ -10629,12 +10838,13 @@ function BookDemoButton({
|
|
|
10629
10838
|
children
|
|
10630
10839
|
}) {
|
|
10631
10840
|
const { openBookingDialog } = useGlitchgrab();
|
|
10632
|
-
|
|
10841
|
+
const open = () => openBookingDialog();
|
|
10842
|
+
if (children) return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_jsx_runtime9.Fragment, { children: children({ onClick: open }) });
|
|
10633
10843
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
10634
10844
|
"button",
|
|
10635
10845
|
{
|
|
10636
10846
|
type: "button",
|
|
10637
|
-
onClick:
|
|
10847
|
+
onClick: open,
|
|
10638
10848
|
className,
|
|
10639
10849
|
style: className ? void 0 : {
|
|
10640
10850
|
padding: "10px 18px",
|
|
@@ -10841,6 +11051,87 @@ function useGlitchgrabActions({
|
|
|
10841
11051
|
error
|
|
10842
11052
|
};
|
|
10843
11053
|
}
|
|
11054
|
+
async function fetchGlitchgrabReportThread({
|
|
11055
|
+
token,
|
|
11056
|
+
reportId
|
|
11057
|
+
}) {
|
|
11058
|
+
var _a, _b, _c;
|
|
11059
|
+
const res = await fetch(`${BASE_URL}/api/v1/sdk/reports/${encodeURIComponent(reportId)}`, {
|
|
11060
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
11061
|
+
});
|
|
11062
|
+
const data = await res.json().catch(() => ({}));
|
|
11063
|
+
if (!res.ok || !data.success) throw new Error((_a = data.error) != null ? _a : "Failed to fetch report");
|
|
11064
|
+
return { ...data.data, comments: (_c = (_b = data.data) == null ? void 0 : _b.comments) != null ? _c : [] };
|
|
11065
|
+
}
|
|
11066
|
+
async function postGlitchgrabReportComment({
|
|
11067
|
+
token,
|
|
11068
|
+
reportId,
|
|
11069
|
+
message,
|
|
11070
|
+
reporterName,
|
|
11071
|
+
reporterEmail
|
|
11072
|
+
}) {
|
|
11073
|
+
var _a;
|
|
11074
|
+
const res = await fetch(`${BASE_URL}/api/v1/sdk/reports/${encodeURIComponent(reportId)}/comments`, {
|
|
11075
|
+
method: "POST",
|
|
11076
|
+
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
|
|
11077
|
+
body: JSON.stringify({ message, reporterName, reporterEmail })
|
|
11078
|
+
});
|
|
11079
|
+
const data = await res.json().catch(() => ({}));
|
|
11080
|
+
if (!res.ok || !data.success) throw new Error((_a = data.error) != null ? _a : "Failed to post comment");
|
|
11081
|
+
return data.data;
|
|
11082
|
+
}
|
|
11083
|
+
function useGlitchgrabReportThread({
|
|
11084
|
+
token,
|
|
11085
|
+
reportId,
|
|
11086
|
+
reporterName,
|
|
11087
|
+
reporterEmail
|
|
11088
|
+
}) {
|
|
11089
|
+
var _a;
|
|
11090
|
+
const [report, setReport] = (0, import_react8.useState)(null);
|
|
11091
|
+
const [isLoading, setIsLoading] = (0, import_react8.useState)(!!reportId);
|
|
11092
|
+
const [isFetching, setIsFetching] = (0, import_react8.useState)(false);
|
|
11093
|
+
const [isPosting, setIsPosting] = (0, import_react8.useState)(false);
|
|
11094
|
+
const [error, setError] = (0, import_react8.useState)(null);
|
|
11095
|
+
const refetch = (0, import_react8.useCallback)(async () => {
|
|
11096
|
+
if (!token || !reportId) {
|
|
11097
|
+
setReport(null);
|
|
11098
|
+
setIsLoading(false);
|
|
11099
|
+
return;
|
|
11100
|
+
}
|
|
11101
|
+
setIsFetching(true);
|
|
11102
|
+
setError(null);
|
|
11103
|
+
try {
|
|
11104
|
+
setReport(await fetchGlitchgrabReportThread({ token, reportId }));
|
|
11105
|
+
} catch (e) {
|
|
11106
|
+
setError(e instanceof Error ? e.message : "Network error");
|
|
11107
|
+
} finally {
|
|
11108
|
+
setIsLoading(false);
|
|
11109
|
+
setIsFetching(false);
|
|
11110
|
+
}
|
|
11111
|
+
}, [token, reportId]);
|
|
11112
|
+
(0, import_react8.useEffect)(() => {
|
|
11113
|
+
refetch();
|
|
11114
|
+
}, [refetch]);
|
|
11115
|
+
const addComment = (0, import_react8.useCallback)(
|
|
11116
|
+
async (message) => {
|
|
11117
|
+
if (!token || !reportId || !message.trim()) return false;
|
|
11118
|
+
setIsPosting(true);
|
|
11119
|
+
setError(null);
|
|
11120
|
+
try {
|
|
11121
|
+
await postGlitchgrabReportComment({ token, reportId, message: message.trim(), reporterName, reporterEmail });
|
|
11122
|
+
await refetch();
|
|
11123
|
+
return true;
|
|
11124
|
+
} catch (e) {
|
|
11125
|
+
setError(e instanceof Error ? e.message : "Failed to post comment");
|
|
11126
|
+
return false;
|
|
11127
|
+
} finally {
|
|
11128
|
+
setIsPosting(false);
|
|
11129
|
+
}
|
|
11130
|
+
},
|
|
11131
|
+
[token, reportId, reporterName, reporterEmail, refetch]
|
|
11132
|
+
);
|
|
11133
|
+
return { report, comments: (_a = report == null ? void 0 : report.comments) != null ? _a : [], isLoading, isFetching, isPosting, error, refetch, addComment };
|
|
11134
|
+
}
|
|
10844
11135
|
|
|
10845
11136
|
// src/use-feedback.ts
|
|
10846
11137
|
var import_react9 = require("react");
|
|
@@ -10922,12 +11213,14 @@ function useGlitchgrabFeedback(query) {
|
|
|
10922
11213
|
computeSignature,
|
|
10923
11214
|
enhanceText,
|
|
10924
11215
|
fetchGlitchgrabFeedback,
|
|
11216
|
+
fetchGlitchgrabReportThread,
|
|
10925
11217
|
fetchGlitchgrabReports,
|
|
10926
11218
|
getAppContext,
|
|
10927
11219
|
getBreadcrumbs,
|
|
10928
11220
|
getShortcutLabel,
|
|
10929
11221
|
initBreadcrumbs,
|
|
10930
11222
|
matchesShortcut,
|
|
11223
|
+
postGlitchgrabReportComment,
|
|
10931
11224
|
sanitizeUrl,
|
|
10932
11225
|
sendFeedback,
|
|
10933
11226
|
sendLead,
|
|
@@ -10938,6 +11231,7 @@ function useGlitchgrabFeedback(query) {
|
|
|
10938
11231
|
useGlitchgrab,
|
|
10939
11232
|
useGlitchgrabActions,
|
|
10940
11233
|
useGlitchgrabFeedback,
|
|
11234
|
+
useGlitchgrabReportThread,
|
|
10941
11235
|
useGlitchgrabReports
|
|
10942
11236
|
});
|
|
10943
11237
|
//# sourceMappingURL=index.js.map
|