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.mjs
CHANGED
|
@@ -711,12 +711,21 @@ function signedFields(identity) {
|
|
|
711
711
|
return { userId: identity.userId, signature: identity.signature };
|
|
712
712
|
}
|
|
713
713
|
async function enhanceText(text, token, baseUrl, screenshot, context, identity) {
|
|
714
|
+
try {
|
|
715
|
+
return await enhanceTextOrThrow(text, token, baseUrl, screenshot, context, identity);
|
|
716
|
+
} catch (e) {
|
|
717
|
+
return text;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
async function enhanceTextOrThrow(text, token, baseUrl, screenshot, context, identity) {
|
|
714
721
|
var _a;
|
|
722
|
+
const trimmed = text.trim();
|
|
723
|
+
if (!trimmed) return text;
|
|
724
|
+
const unavailable = "AI enhance isn't available right now \u2014 send your report as written.";
|
|
725
|
+
let response;
|
|
715
726
|
try {
|
|
716
|
-
const trimmed = text.trim();
|
|
717
|
-
if (!trimmed) return text;
|
|
718
727
|
const url = `${baseUrl != null ? baseUrl : DEFAULT_BASE_URL}/api/v1/ai/enhance-text`;
|
|
719
|
-
|
|
728
|
+
response = await fetch(url, {
|
|
720
729
|
method: "POST",
|
|
721
730
|
headers: {
|
|
722
731
|
"Content-Type": "application/json",
|
|
@@ -729,15 +738,20 @@ async function enhanceText(text, token, baseUrl, screenshot, context, identity)
|
|
|
729
738
|
...signedFields(identity)
|
|
730
739
|
})
|
|
731
740
|
});
|
|
732
|
-
if (!response.ok) return text;
|
|
733
|
-
const envelope = await response.json();
|
|
734
|
-
if ((envelope == null ? void 0 : envelope.success) && typeof ((_a = envelope.data) == null ? void 0 : _a.text) === "string") {
|
|
735
|
-
return envelope.data.text;
|
|
736
|
-
}
|
|
737
|
-
return text;
|
|
738
741
|
} catch (e) {
|
|
739
|
-
|
|
742
|
+
throw new Error(unavailable);
|
|
743
|
+
}
|
|
744
|
+
if (response.status === 429) {
|
|
745
|
+
throw new Error("Too many AI enhance tries \u2014 wait a while, or send your report as written.");
|
|
740
746
|
}
|
|
747
|
+
const envelope = await response.json().catch(() => null);
|
|
748
|
+
if (response.ok && (envelope == null ? void 0 : envelope.success) && typeof ((_a = envelope.data) == null ? void 0 : _a.text) === "string") {
|
|
749
|
+
return envelope.data.text;
|
|
750
|
+
}
|
|
751
|
+
if (response.status === 400 && typeof (envelope == null ? void 0 : envelope.error) === "string") {
|
|
752
|
+
throw new Error(envelope.error);
|
|
753
|
+
}
|
|
754
|
+
throw new Error(unavailable);
|
|
741
755
|
}
|
|
742
756
|
async function findSimilarIssues(description, token, baseUrl, identity, files) {
|
|
743
757
|
var _a;
|
|
@@ -5494,6 +5508,7 @@ function ReportDialog({
|
|
|
5494
5508
|
const [aiConversationId, setAiConversationId] = useState4(null);
|
|
5495
5509
|
const [issueTitle, setIssueTitle] = useState4("");
|
|
5496
5510
|
const [isEnhanced, setIsEnhanced] = useState4(false);
|
|
5511
|
+
const [enhanceError, setEnhanceError] = useState4(null);
|
|
5497
5512
|
const [originalDescription, setOriginalDescription] = useState4(
|
|
5498
5513
|
null
|
|
5499
5514
|
);
|
|
@@ -5948,6 +5963,7 @@ function ReportDialog({
|
|
|
5948
5963
|
setSelfReportFrom(null);
|
|
5949
5964
|
setVoiceError(null);
|
|
5950
5965
|
setIsEnhanced(false);
|
|
5966
|
+
setEnhanceError(null);
|
|
5951
5967
|
setOriginalDescription(null);
|
|
5952
5968
|
setAssistOpen(false);
|
|
5953
5969
|
setAssistUsed(false);
|
|
@@ -6013,6 +6029,7 @@ function ReportDialog({
|
|
|
6013
6029
|
const sep = base.trim() ? " " : "";
|
|
6014
6030
|
setDescriptionFromVoice(base + sep + text.trim());
|
|
6015
6031
|
setValidationError(null);
|
|
6032
|
+
setEnhanceError(null);
|
|
6016
6033
|
setIsEnhanced(false);
|
|
6017
6034
|
setOriginalDescription(null);
|
|
6018
6035
|
}
|
|
@@ -7108,6 +7125,7 @@ function ReportDialog({
|
|
|
7108
7125
|
notePushToTalkEdit();
|
|
7109
7126
|
setDescription(e.target.value);
|
|
7110
7127
|
if (validationError) setValidationError(null);
|
|
7128
|
+
if (enhanceError) setEnhanceError(null);
|
|
7111
7129
|
if (isEnhanced) {
|
|
7112
7130
|
setIsEnhanced(false);
|
|
7113
7131
|
setOriginalDescription(null);
|
|
@@ -7229,6 +7247,7 @@ function ReportDialog({
|
|
|
7229
7247
|
var _a2;
|
|
7230
7248
|
if (!description.trim() || isEnhancing) return;
|
|
7231
7249
|
setIsEnhancing(true);
|
|
7250
|
+
setEnhanceError(null);
|
|
7232
7251
|
try {
|
|
7233
7252
|
const polished = await enhanceText2(
|
|
7234
7253
|
description,
|
|
@@ -7241,6 +7260,10 @@ function ReportDialog({
|
|
|
7241
7260
|
if (validationError)
|
|
7242
7261
|
setValidationError(null);
|
|
7243
7262
|
}
|
|
7263
|
+
} catch (err) {
|
|
7264
|
+
setEnhanceError(
|
|
7265
|
+
err instanceof Error && err.message ? err.message : "AI enhance isn't available right now \u2014 send your report as written."
|
|
7266
|
+
);
|
|
7244
7267
|
} finally {
|
|
7245
7268
|
setIsEnhancing(false);
|
|
7246
7269
|
}
|
|
@@ -7499,6 +7522,20 @@ function ReportDialog({
|
|
|
7499
7522
|
children: voiceError
|
|
7500
7523
|
}
|
|
7501
7524
|
),
|
|
7525
|
+
enhanceError && /* @__PURE__ */ jsx5(
|
|
7526
|
+
"p",
|
|
7527
|
+
{
|
|
7528
|
+
role: "alert",
|
|
7529
|
+
style: {
|
|
7530
|
+
color: "#ef4444",
|
|
7531
|
+
fontSize: "11px",
|
|
7532
|
+
lineHeight: 1.5,
|
|
7533
|
+
marginTop: "4px",
|
|
7534
|
+
marginBottom: 0
|
|
7535
|
+
},
|
|
7536
|
+
children: enhanceError
|
|
7537
|
+
}
|
|
7538
|
+
),
|
|
7502
7539
|
assistNotice && /* @__PURE__ */ jsx5(
|
|
7503
7540
|
"p",
|
|
7504
7541
|
{
|
|
@@ -8521,6 +8558,69 @@ function getTypeIcon(type, color, size = 24) {
|
|
|
8521
8558
|
|
|
8522
8559
|
// src/booking-dialog.tsx
|
|
8523
8560
|
import { useCallback as useCallback2, useEffect as useEffect5, useMemo as useMemo3, useState as useState5 } from "react";
|
|
8561
|
+
|
|
8562
|
+
// src/phone.ts
|
|
8563
|
+
var COUNTRIES = [
|
|
8564
|
+
{ iso: "IN", name: "India", dial: "91" },
|
|
8565
|
+
{ iso: "AE", name: "UAE", dial: "971" },
|
|
8566
|
+
{ iso: "US", name: "US / Canada", dial: "1" },
|
|
8567
|
+
{ iso: "GB", name: "UK", dial: "44" },
|
|
8568
|
+
{ iso: "SG", name: "Singapore", dial: "65" },
|
|
8569
|
+
{ iso: "AU", name: "Australia", dial: "61" },
|
|
8570
|
+
{ iso: "SA", name: "Saudi Arabia", dial: "966" },
|
|
8571
|
+
{ iso: "QA", name: "Qatar", dial: "974" },
|
|
8572
|
+
{ iso: "NP", name: "Nepal", dial: "977" },
|
|
8573
|
+
{ iso: "BD", name: "Bangladesh", dial: "880" },
|
|
8574
|
+
{ iso: "LK", name: "Sri Lanka", dial: "94" },
|
|
8575
|
+
{ iso: "DE", name: "Germany", dial: "49" }
|
|
8576
|
+
];
|
|
8577
|
+
var ZONE_COUNTRY = {
|
|
8578
|
+
"Asia/Kolkata": "91",
|
|
8579
|
+
"Asia/Calcutta": "91",
|
|
8580
|
+
"Asia/Dubai": "971",
|
|
8581
|
+
"Europe/London": "44",
|
|
8582
|
+
"Asia/Singapore": "65",
|
|
8583
|
+
"Asia/Riyadh": "966",
|
|
8584
|
+
"Asia/Qatar": "974",
|
|
8585
|
+
"Asia/Kathmandu": "977",
|
|
8586
|
+
"Asia/Katmandu": "977",
|
|
8587
|
+
"Asia/Dhaka": "880",
|
|
8588
|
+
"Asia/Colombo": "94",
|
|
8589
|
+
"Europe/Berlin": "49"
|
|
8590
|
+
};
|
|
8591
|
+
function defaultDialForZone(zone) {
|
|
8592
|
+
if (ZONE_COUNTRY[zone]) return ZONE_COUNTRY[zone];
|
|
8593
|
+
if (zone.startsWith("America/")) return "1";
|
|
8594
|
+
if (zone.startsWith("Australia/")) return "61";
|
|
8595
|
+
return "91";
|
|
8596
|
+
}
|
|
8597
|
+
function splitTypedPhone(typed, dial) {
|
|
8598
|
+
const trimmed = typed.trim();
|
|
8599
|
+
const digits = trimmed.replace(/\D/g, "");
|
|
8600
|
+
if (trimmed.startsWith("+")) {
|
|
8601
|
+
const match = [...COUNTRIES].sort((a, b) => b.dial.length - a.dial.length).find((c) => digits.startsWith(c.dial));
|
|
8602
|
+
if (match) return { dial: match.dial, national: digits.slice(match.dial.length) };
|
|
8603
|
+
}
|
|
8604
|
+
if (dial === "91" && digits.length === 12 && digits.startsWith("91")) return { dial, national: digits.slice(2) };
|
|
8605
|
+
if (dial === "91" && digits.length === 11 && digits.startsWith("0")) return { dial, national: digits.slice(1) };
|
|
8606
|
+
return { dial, national: digits };
|
|
8607
|
+
}
|
|
8608
|
+
function phoneProblem(dial, national) {
|
|
8609
|
+
const digits = national.replace(/\D/g, "");
|
|
8610
|
+
if (!digits) return "Enter your mobile number";
|
|
8611
|
+
if (dial === "91") {
|
|
8612
|
+
if (digits.length !== 10) return `An Indian mobile has 10 digits \u2014 this has ${digits.length}`;
|
|
8613
|
+
if (!/^[6-9]/.test(digits)) return "An Indian mobile starts with 6, 7, 8 or 9";
|
|
8614
|
+
return null;
|
|
8615
|
+
}
|
|
8616
|
+
if (digits.length < 6 || digits.length > 12) return "Check the number \u2014 it looks too short or too long";
|
|
8617
|
+
return null;
|
|
8618
|
+
}
|
|
8619
|
+
function toE164(dial, national) {
|
|
8620
|
+
return `+${dial}${national.replace(/\D/g, "")}`;
|
|
8621
|
+
}
|
|
8622
|
+
|
|
8623
|
+
// src/booking-dialog.tsx
|
|
8524
8624
|
import { Fragment as Fragment5, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
8525
8625
|
function readQuestions(value) {
|
|
8526
8626
|
if (!Array.isArray(value)) return [];
|
|
@@ -8663,7 +8763,9 @@ function BookingDialog({
|
|
|
8663
8763
|
open,
|
|
8664
8764
|
onClose,
|
|
8665
8765
|
preview = false,
|
|
8666
|
-
availabilityUrl
|
|
8766
|
+
availabilityUrl,
|
|
8767
|
+
intro,
|
|
8768
|
+
onBooked
|
|
8667
8769
|
}) {
|
|
8668
8770
|
var _a, _b, _c, _d, _e;
|
|
8669
8771
|
const wide = useMediaQuery(WIDE_QUERY, true);
|
|
@@ -8686,6 +8788,8 @@ function BookingDialog({
|
|
|
8686
8788
|
const [name, setName] = useState5("");
|
|
8687
8789
|
const [email, setEmail] = useState5("");
|
|
8688
8790
|
const [phone, setPhone] = useState5("");
|
|
8791
|
+
const [dial, setDial] = useState5(() => defaultDialForZone(localZone()));
|
|
8792
|
+
const [phoneTouched, setPhoneTouched] = useState5(false);
|
|
8689
8793
|
const [note, setNote] = useState5("");
|
|
8690
8794
|
const [questions, setQuestions] = useState5([]);
|
|
8691
8795
|
const [answers, setAnswers] = useState5({});
|
|
@@ -8796,8 +8900,12 @@ function BookingDialog({
|
|
|
8796
8900
|
const view = step !== "slots" ? step : !pageLoaded ? "loading" : questions.length > 0 && !asked ? "questions" : "slots";
|
|
8797
8901
|
const roomy = step === "slots";
|
|
8798
8902
|
async function startBooking() {
|
|
8799
|
-
var _a2, _b2;
|
|
8903
|
+
var _a2, _b2, _c2;
|
|
8800
8904
|
if (!selected) return;
|
|
8905
|
+
if (phoneError) {
|
|
8906
|
+
setPhoneTouched(true);
|
|
8907
|
+
return;
|
|
8908
|
+
}
|
|
8801
8909
|
if (preview) {
|
|
8802
8910
|
setPreviewEnded(true);
|
|
8803
8911
|
return;
|
|
@@ -8811,7 +8919,7 @@ function BookingDialog({
|
|
|
8811
8919
|
body: JSON.stringify({
|
|
8812
8920
|
name,
|
|
8813
8921
|
email,
|
|
8814
|
-
phone,
|
|
8922
|
+
phone: toE164(dial, phone),
|
|
8815
8923
|
note,
|
|
8816
8924
|
answers: Object.fromEntries(given.map((q) => [q.id, q.answer])),
|
|
8817
8925
|
startsAt: selected.startsAt,
|
|
@@ -8830,6 +8938,7 @@ function BookingDialog({
|
|
|
8830
8938
|
if (json.data.confirmed) {
|
|
8831
8939
|
setMeetUrl((_b2 = json.data.meetUrl) != null ? _b2 : null);
|
|
8832
8940
|
setStep("done");
|
|
8941
|
+
reportBooked(json.data.bookingId, (_c2 = json.data.meetUrl) != null ? _c2 : null);
|
|
8833
8942
|
return;
|
|
8834
8943
|
}
|
|
8835
8944
|
setBookingId(json.data.bookingId);
|
|
@@ -8840,8 +8949,16 @@ function BookingDialog({
|
|
|
8840
8949
|
setBusy(false);
|
|
8841
8950
|
}
|
|
8842
8951
|
}
|
|
8952
|
+
function reportBooked(id, meet) {
|
|
8953
|
+
if (!onBooked || !id || !selected) return;
|
|
8954
|
+
try {
|
|
8955
|
+
onBooked({ bookingId: id, startsAt: selected.startsAt, name, email, phone: toE164(dial, phone), meetUrl: meet });
|
|
8956
|
+
} catch (e) {
|
|
8957
|
+
console.error("[glitchgrab] onBooked threw", e);
|
|
8958
|
+
}
|
|
8959
|
+
}
|
|
8843
8960
|
async function confirmBooking() {
|
|
8844
|
-
var _a2;
|
|
8961
|
+
var _a2, _b2;
|
|
8845
8962
|
if (!bookingId) return;
|
|
8846
8963
|
setBusy(true);
|
|
8847
8964
|
setError(null);
|
|
@@ -8858,13 +8975,15 @@ function BookingDialog({
|
|
|
8858
8975
|
}
|
|
8859
8976
|
setMeetUrl(json.data.meetUrl);
|
|
8860
8977
|
setStep("done");
|
|
8978
|
+
reportBooked(bookingId, (_b2 = json.data.meetUrl) != null ? _b2 : null);
|
|
8861
8979
|
} catch (e) {
|
|
8862
8980
|
setError("Couldn't reach the booking service");
|
|
8863
8981
|
} finally {
|
|
8864
8982
|
setBusy(false);
|
|
8865
8983
|
}
|
|
8866
8984
|
}
|
|
8867
|
-
const
|
|
8985
|
+
const phoneError = phoneProblem(dial, phone);
|
|
8986
|
+
const canSubmitDetails = Boolean(name.trim() && email.includes("@"));
|
|
8868
8987
|
const selectedEnd = selected ? (_e = selected.endsAt) != null ? _e : new Date(new Date(selected.startsAt).getTime() + page.slotMinutes * 6e4).toISOString() : null;
|
|
8869
8988
|
const monthDate = new Date(keyToUtc(`${month}-01`));
|
|
8870
8989
|
const muted = { color: t.muted };
|
|
@@ -9011,6 +9130,14 @@ function BookingDialog({
|
|
|
9011
9130
|
children: "Preview \u2014 nothing is booked"
|
|
9012
9131
|
}
|
|
9013
9132
|
),
|
|
9133
|
+
intro && /* @__PURE__ */ jsx6(
|
|
9134
|
+
"div",
|
|
9135
|
+
{
|
|
9136
|
+
"data-glitchgrab-booking-intro": true,
|
|
9137
|
+
style: { fontSize: 13, fontWeight: 600, lineHeight: 1.45, paddingRight: 32, color: t.ink, overflowWrap: "anywhere" },
|
|
9138
|
+
children: intro
|
|
9139
|
+
}
|
|
9140
|
+
),
|
|
9014
9141
|
/* @__PURE__ */ jsx6("div", { style: { fontSize: 20, fontWeight: 600, lineHeight: 1.25, paddingRight: 32, overflowWrap: "anywhere" }, children: page.title }),
|
|
9015
9142
|
page.description && /* @__PURE__ */ jsx6("div", { style: { fontSize: 13, lineHeight: 1.5, overflowWrap: "anywhere", ...muted }, children: page.description }),
|
|
9016
9143
|
/* @__PURE__ */ jsxs6("div", { style: { display: "flex", flexDirection: "column", gap: 10, marginTop: 4, fontSize: 14 }, children: [
|
|
@@ -9453,14 +9580,17 @@ function BookingDialog({
|
|
|
9453
9580
|
/* @__PURE__ */ jsx6(Field, { t, label: "Your name", value: name, onChange: setName, autoComplete: "name" }),
|
|
9454
9581
|
/* @__PURE__ */ jsx6(Field, { t, label: "Email", value: email, onChange: setEmail, type: "email", autoComplete: "email" }),
|
|
9455
9582
|
/* @__PURE__ */ jsx6(
|
|
9456
|
-
|
|
9583
|
+
PhoneField,
|
|
9457
9584
|
{
|
|
9458
9585
|
t,
|
|
9459
|
-
|
|
9460
|
-
|
|
9461
|
-
onChange:
|
|
9462
|
-
|
|
9463
|
-
|
|
9586
|
+
dial,
|
|
9587
|
+
national: phone,
|
|
9588
|
+
onChange: (nextDial, national) => {
|
|
9589
|
+
setDial(nextDial);
|
|
9590
|
+
setPhone(national);
|
|
9591
|
+
},
|
|
9592
|
+
onBlur: () => setPhoneTouched(true),
|
|
9593
|
+
error: phoneTouched ? phoneError : null,
|
|
9464
9594
|
hint: requireOtp ? "We send a code here to confirm, then a reminder before the call." : "We send a reminder here before the call."
|
|
9465
9595
|
}
|
|
9466
9596
|
),
|
|
@@ -9748,6 +9878,64 @@ function Field({
|
|
|
9748
9878
|
hint && /* @__PURE__ */ jsx6("div", { style: { marginTop: 6, fontSize: 12, fontWeight: 400, color: t.muted }, children: hint })
|
|
9749
9879
|
] });
|
|
9750
9880
|
}
|
|
9881
|
+
function PhoneField({
|
|
9882
|
+
t,
|
|
9883
|
+
dial,
|
|
9884
|
+
national,
|
|
9885
|
+
onChange,
|
|
9886
|
+
onBlur,
|
|
9887
|
+
error,
|
|
9888
|
+
hint
|
|
9889
|
+
}) {
|
|
9890
|
+
const box = {
|
|
9891
|
+
boxSizing: "border-box",
|
|
9892
|
+
padding: "9px 12px",
|
|
9893
|
+
background: t.input,
|
|
9894
|
+
color: t.text,
|
|
9895
|
+
border: `1px solid ${error ? t.danger : t.border}`,
|
|
9896
|
+
borderRadius: 8,
|
|
9897
|
+
fontFamily: "inherit",
|
|
9898
|
+
fontSize: 14,
|
|
9899
|
+
outline: "none"
|
|
9900
|
+
};
|
|
9901
|
+
return /* @__PURE__ */ jsxs6("label", { style: { display: "block", fontSize: 13, fontWeight: 500, color: t.text }, children: [
|
|
9902
|
+
"Mobile number",
|
|
9903
|
+
/* @__PURE__ */ jsxs6("div", { style: { display: "flex", gap: 8, marginTop: 6 }, children: [
|
|
9904
|
+
/* @__PURE__ */ jsx6(
|
|
9905
|
+
"select",
|
|
9906
|
+
{
|
|
9907
|
+
"aria-label": "Country code",
|
|
9908
|
+
value: dial,
|
|
9909
|
+
onChange: (e) => onChange(e.target.value, national),
|
|
9910
|
+
style: { ...box, flex: "0 0 auto", paddingRight: 8, cursor: "pointer" },
|
|
9911
|
+
children: COUNTRIES.map((c) => /* @__PURE__ */ jsxs6("option", { value: c.dial, children: [
|
|
9912
|
+
c.iso,
|
|
9913
|
+
" +",
|
|
9914
|
+
c.dial
|
|
9915
|
+
] }, c.iso))
|
|
9916
|
+
}
|
|
9917
|
+
),
|
|
9918
|
+
/* @__PURE__ */ jsx6(
|
|
9919
|
+
"input",
|
|
9920
|
+
{
|
|
9921
|
+
type: "tel",
|
|
9922
|
+
autoComplete: "tel",
|
|
9923
|
+
inputMode: "numeric",
|
|
9924
|
+
placeholder: dial === "91" ? "98765 43210" : "Mobile number",
|
|
9925
|
+
value: national,
|
|
9926
|
+
"aria-invalid": Boolean(error),
|
|
9927
|
+
onChange: (e) => {
|
|
9928
|
+
const next = splitTypedPhone(e.target.value, dial);
|
|
9929
|
+
onChange(next.dial, next.national);
|
|
9930
|
+
},
|
|
9931
|
+
onBlur,
|
|
9932
|
+
style: { ...box, flex: "1 1 auto", minWidth: 0, width: "100%" }
|
|
9933
|
+
}
|
|
9934
|
+
)
|
|
9935
|
+
] }),
|
|
9936
|
+
error ? /* @__PURE__ */ jsx6("div", { role: "alert", style: { marginTop: 6, fontSize: 12, fontWeight: 500, color: t.danger }, children: error }) : /* @__PURE__ */ jsx6("div", { style: { marginTop: 6, fontSize: 12, fontWeight: 400, color: t.muted }, children: hint })
|
|
9937
|
+
] });
|
|
9938
|
+
}
|
|
9751
9939
|
|
|
9752
9940
|
// src/rejection.ts
|
|
9753
9941
|
var DETAILS_MAX_LENGTH = 1e3;
|
|
@@ -10252,21 +10440,27 @@ function GlitchgrabProviderInner({
|
|
|
10252
10440
|
() => ({ userId: signedUserId != null ? signedUserId : null, signature }),
|
|
10253
10441
|
[signedUserId, signature]
|
|
10254
10442
|
);
|
|
10443
|
+
const enhanceForDialog = useCallback3(
|
|
10444
|
+
async (text, screenshot) => {
|
|
10445
|
+
const ctx = captureContext(visitedPagesRef.current);
|
|
10446
|
+
const context = {
|
|
10447
|
+
url: ctx.url,
|
|
10448
|
+
visitedPages: ctx.visitedPages.slice(-5),
|
|
10449
|
+
breadcrumbs: ctx.breadcrumbs.slice(-10).map((b) => ({ type: b.type, message: b.message }))
|
|
10450
|
+
};
|
|
10451
|
+
return await enhanceTextOrThrow(text, token, baseUrl, screenshot, context, identity);
|
|
10452
|
+
},
|
|
10453
|
+
[token, baseUrl, identity]
|
|
10454
|
+
);
|
|
10255
10455
|
const enhance = useCallback3(
|
|
10256
10456
|
async (text, screenshot) => {
|
|
10257
10457
|
try {
|
|
10258
|
-
|
|
10259
|
-
const context = {
|
|
10260
|
-
url: ctx.url,
|
|
10261
|
-
visitedPages: ctx.visitedPages.slice(-5),
|
|
10262
|
-
breadcrumbs: ctx.breadcrumbs.slice(-10).map((b) => ({ type: b.type, message: b.message }))
|
|
10263
|
-
};
|
|
10264
|
-
return await enhanceText(text, token, baseUrl, screenshot, context, identity);
|
|
10458
|
+
return await enhanceForDialog(text, screenshot);
|
|
10265
10459
|
} catch (e) {
|
|
10266
10460
|
return text;
|
|
10267
10461
|
}
|
|
10268
10462
|
},
|
|
10269
|
-
[
|
|
10463
|
+
[enhanceForDialog]
|
|
10270
10464
|
);
|
|
10271
10465
|
const assist = useCallback3(
|
|
10272
10466
|
async (params) => {
|
|
@@ -10332,8 +10526,18 @@ function GlitchgrabProviderInner({
|
|
|
10332
10526
|
const [signedUsers, setSignedUsers] = useState6("OFF");
|
|
10333
10527
|
const aiBlockedUnsigned = signedUsers === "ENFORCE" && !signature;
|
|
10334
10528
|
const [booking, setBooking] = useState6("closed");
|
|
10335
|
-
const
|
|
10336
|
-
const
|
|
10529
|
+
const [bookingOptions, setBookingOptions] = useState6({});
|
|
10530
|
+
const openBookingDialog = useCallback3((options) => {
|
|
10531
|
+
setBookingOptions({
|
|
10532
|
+
intro: typeof (options == null ? void 0 : options.intro) === "string" ? options.intro : void 0,
|
|
10533
|
+
onBooked: typeof (options == null ? void 0 : options.onBooked) === "function" ? options.onBooked : void 0
|
|
10534
|
+
});
|
|
10535
|
+
setBooking("live");
|
|
10536
|
+
}, []);
|
|
10537
|
+
const openBookingPreview = useCallback3(() => {
|
|
10538
|
+
setBookingOptions({});
|
|
10539
|
+
setBooking("preview");
|
|
10540
|
+
}, []);
|
|
10337
10541
|
useEffect6(() => {
|
|
10338
10542
|
let cancelled = false;
|
|
10339
10543
|
fetch(`${baseUrl}/api/v1/sdk/project`, {
|
|
@@ -10432,6 +10636,8 @@ function GlitchgrabProviderInner({
|
|
|
10432
10636
|
baseUrl: baseUrl != null ? baseUrl : DEFAULT_BASE_URL2,
|
|
10433
10637
|
open: booking !== "closed",
|
|
10434
10638
|
preview: booking === "preview",
|
|
10639
|
+
intro: bookingOptions.intro,
|
|
10640
|
+
onBooked: bookingOptions.onBooked,
|
|
10435
10641
|
onClose: () => setBooking("closed")
|
|
10436
10642
|
}
|
|
10437
10643
|
),
|
|
@@ -10440,7 +10646,7 @@ function GlitchgrabProviderInner({
|
|
|
10440
10646
|
{
|
|
10441
10647
|
report,
|
|
10442
10648
|
sendFeedback: feedback,
|
|
10443
|
-
enhanceText: aiAssist && !aiBlockedUnsigned ?
|
|
10649
|
+
enhanceText: aiAssist && !aiBlockedUnsigned ? enhanceForDialog : void 0,
|
|
10444
10650
|
assist: aiAssist && !aiBlockedUnsigned ? assist : void 0,
|
|
10445
10651
|
findSimilarIssues: aiAssist && !aiBlockedUnsigned ? findSimilar : void 0,
|
|
10446
10652
|
readFile: aiAssist && !aiBlockedUnsigned ? readFile : void 0,
|
|
@@ -10573,12 +10779,13 @@ function BookDemoButton({
|
|
|
10573
10779
|
children
|
|
10574
10780
|
}) {
|
|
10575
10781
|
const { openBookingDialog } = useGlitchgrab();
|
|
10576
|
-
|
|
10782
|
+
const open = () => openBookingDialog();
|
|
10783
|
+
if (children) return /* @__PURE__ */ jsx9(Fragment8, { children: children({ onClick: open }) });
|
|
10577
10784
|
return /* @__PURE__ */ jsx9(
|
|
10578
10785
|
"button",
|
|
10579
10786
|
{
|
|
10580
10787
|
type: "button",
|
|
10581
|
-
onClick:
|
|
10788
|
+
onClick: open,
|
|
10582
10789
|
className,
|
|
10583
10790
|
style: className ? void 0 : {
|
|
10584
10791
|
padding: "10px 18px",
|
|
@@ -10785,6 +10992,87 @@ function useGlitchgrabActions({
|
|
|
10785
10992
|
error
|
|
10786
10993
|
};
|
|
10787
10994
|
}
|
|
10995
|
+
async function fetchGlitchgrabReportThread({
|
|
10996
|
+
token,
|
|
10997
|
+
reportId
|
|
10998
|
+
}) {
|
|
10999
|
+
var _a, _b, _c;
|
|
11000
|
+
const res = await fetch(`${BASE_URL}/api/v1/sdk/reports/${encodeURIComponent(reportId)}`, {
|
|
11001
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
11002
|
+
});
|
|
11003
|
+
const data = await res.json().catch(() => ({}));
|
|
11004
|
+
if (!res.ok || !data.success) throw new Error((_a = data.error) != null ? _a : "Failed to fetch report");
|
|
11005
|
+
return { ...data.data, comments: (_c = (_b = data.data) == null ? void 0 : _b.comments) != null ? _c : [] };
|
|
11006
|
+
}
|
|
11007
|
+
async function postGlitchgrabReportComment({
|
|
11008
|
+
token,
|
|
11009
|
+
reportId,
|
|
11010
|
+
message,
|
|
11011
|
+
reporterName,
|
|
11012
|
+
reporterEmail
|
|
11013
|
+
}) {
|
|
11014
|
+
var _a;
|
|
11015
|
+
const res = await fetch(`${BASE_URL}/api/v1/sdk/reports/${encodeURIComponent(reportId)}/comments`, {
|
|
11016
|
+
method: "POST",
|
|
11017
|
+
headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" },
|
|
11018
|
+
body: JSON.stringify({ message, reporterName, reporterEmail })
|
|
11019
|
+
});
|
|
11020
|
+
const data = await res.json().catch(() => ({}));
|
|
11021
|
+
if (!res.ok || !data.success) throw new Error((_a = data.error) != null ? _a : "Failed to post comment");
|
|
11022
|
+
return data.data;
|
|
11023
|
+
}
|
|
11024
|
+
function useGlitchgrabReportThread({
|
|
11025
|
+
token,
|
|
11026
|
+
reportId,
|
|
11027
|
+
reporterName,
|
|
11028
|
+
reporterEmail
|
|
11029
|
+
}) {
|
|
11030
|
+
var _a;
|
|
11031
|
+
const [report, setReport] = useState8(null);
|
|
11032
|
+
const [isLoading, setIsLoading] = useState8(!!reportId);
|
|
11033
|
+
const [isFetching, setIsFetching] = useState8(false);
|
|
11034
|
+
const [isPosting, setIsPosting] = useState8(false);
|
|
11035
|
+
const [error, setError] = useState8(null);
|
|
11036
|
+
const refetch = useCallback4(async () => {
|
|
11037
|
+
if (!token || !reportId) {
|
|
11038
|
+
setReport(null);
|
|
11039
|
+
setIsLoading(false);
|
|
11040
|
+
return;
|
|
11041
|
+
}
|
|
11042
|
+
setIsFetching(true);
|
|
11043
|
+
setError(null);
|
|
11044
|
+
try {
|
|
11045
|
+
setReport(await fetchGlitchgrabReportThread({ token, reportId }));
|
|
11046
|
+
} catch (e) {
|
|
11047
|
+
setError(e instanceof Error ? e.message : "Network error");
|
|
11048
|
+
} finally {
|
|
11049
|
+
setIsLoading(false);
|
|
11050
|
+
setIsFetching(false);
|
|
11051
|
+
}
|
|
11052
|
+
}, [token, reportId]);
|
|
11053
|
+
useEffect7(() => {
|
|
11054
|
+
refetch();
|
|
11055
|
+
}, [refetch]);
|
|
11056
|
+
const addComment = useCallback4(
|
|
11057
|
+
async (message) => {
|
|
11058
|
+
if (!token || !reportId || !message.trim()) return false;
|
|
11059
|
+
setIsPosting(true);
|
|
11060
|
+
setError(null);
|
|
11061
|
+
try {
|
|
11062
|
+
await postGlitchgrabReportComment({ token, reportId, message: message.trim(), reporterName, reporterEmail });
|
|
11063
|
+
await refetch();
|
|
11064
|
+
return true;
|
|
11065
|
+
} catch (e) {
|
|
11066
|
+
setError(e instanceof Error ? e.message : "Failed to post comment");
|
|
11067
|
+
return false;
|
|
11068
|
+
} finally {
|
|
11069
|
+
setIsPosting(false);
|
|
11070
|
+
}
|
|
11071
|
+
},
|
|
11072
|
+
[token, reportId, reporterName, reporterEmail, refetch]
|
|
11073
|
+
);
|
|
11074
|
+
return { report, comments: (_a = report == null ? void 0 : report.comments) != null ? _a : [], isLoading, isFetching, isPosting, error, refetch, addComment };
|
|
11075
|
+
}
|
|
10788
11076
|
|
|
10789
11077
|
// src/use-feedback.ts
|
|
10790
11078
|
import { useState as useState9, useEffect as useEffect8, useCallback as useCallback5 } from "react";
|
|
@@ -10865,12 +11153,14 @@ export {
|
|
|
10865
11153
|
computeSignature,
|
|
10866
11154
|
enhanceText,
|
|
10867
11155
|
fetchGlitchgrabFeedback,
|
|
11156
|
+
fetchGlitchgrabReportThread,
|
|
10868
11157
|
fetchGlitchgrabReports,
|
|
10869
11158
|
getAppContext,
|
|
10870
11159
|
getBreadcrumbs,
|
|
10871
11160
|
getShortcutLabel2 as getShortcutLabel,
|
|
10872
11161
|
initBreadcrumbs,
|
|
10873
11162
|
matchesShortcut,
|
|
11163
|
+
postGlitchgrabReportComment,
|
|
10874
11164
|
sanitizeUrl,
|
|
10875
11165
|
sendFeedback,
|
|
10876
11166
|
sendLead,
|
|
@@ -10881,6 +11171,7 @@ export {
|
|
|
10881
11171
|
useGlitchgrab,
|
|
10882
11172
|
useGlitchgrabActions,
|
|
10883
11173
|
useGlitchgrabFeedback,
|
|
11174
|
+
useGlitchgrabReportThread,
|
|
10884
11175
|
useGlitchgrabReports
|
|
10885
11176
|
};
|
|
10886
11177
|
//# sourceMappingURL=index.mjs.map
|