glitchgrab 1.29.0 → 1.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -965,6 +965,7 @@ function ReportDialog({
965
965
  const [isSubmitting, setIsSubmitting] = useState2(false);
966
966
  const [submitted, setSubmitted] = useState2(false);
967
967
  const [screenshots, setScreenshots] = useState2([]);
968
+ const [attachments, setAttachments] = useState2([]);
968
969
  const [previewIndex, setPreviewIndex] = useState2(null);
969
970
  const [annotatingIndex, setAnnotatingIndex] = useState2(null);
970
971
  const fileInputRef = useRef2(null);
@@ -1009,14 +1010,26 @@ function ReportDialog({
1009
1010
  const handleFileUpload = (e) => {
1010
1011
  const files = e.target.files;
1011
1012
  if (!files || files.length === 0) return;
1012
- Array.from(files).forEach((file) => {
1013
+ addFiles(Array.from(files));
1014
+ e.target.value = "";
1015
+ };
1016
+ const addFiles = (files) => {
1017
+ files.forEach((file) => {
1013
1018
  const reader = new FileReader();
1014
- reader.onload = () => {
1015
- setScreenshots((prev) => [...prev, reader.result]);
1016
- };
1019
+ if (file.type.startsWith("image/")) {
1020
+ reader.onload = () => {
1021
+ setScreenshots((prev) => [...prev, reader.result]);
1022
+ };
1023
+ } else {
1024
+ reader.onload = () => {
1025
+ setAttachments((prev) => [
1026
+ ...prev,
1027
+ { name: file.name, size: file.size, dataUrl: reader.result }
1028
+ ]);
1029
+ };
1030
+ }
1017
1031
  reader.readAsDataURL(file);
1018
1032
  });
1019
- e.target.value = "";
1020
1033
  };
1021
1034
  const retakeScreenshot = async () => {
1022
1035
  setPreviewIndex(null);
@@ -1322,6 +1335,7 @@ function ReportDialog({
1322
1335
  setIsSubmitting(true);
1323
1336
  const metadata = {};
1324
1337
  if (screenshots.length > 0) metadata.screenshots = JSON.stringify(screenshots);
1338
+ if (attachments.length > 0) metadata.attachments = JSON.stringify(attachments);
1325
1339
  if (showSeverity && reportType === "BUG") {
1326
1340
  metadata.severity = severity;
1327
1341
  }
@@ -1334,6 +1348,7 @@ function ReportDialog({
1334
1348
  setSubmitted(true);
1335
1349
  setDescription("");
1336
1350
  setScreenshots([]);
1351
+ setAttachments([]);
1337
1352
  setTimeout(() => {
1338
1353
  setSubmitted(false);
1339
1354
  handleClose();
@@ -1353,6 +1368,21 @@ function ReportDialog({
1353
1368
  @keyframes gg-b2{0%,100%{height:8px}50%{height:3px}}
1354
1369
  @keyframes gg-b3{0%,100%{height:4px}30%{height:14px}70%{height:5px}}
1355
1370
  @keyframes gg-b4{0%,100%{height:6px}60%{height:13px}}
1371
+ @keyframes gg-bug-crawl{0%,100%{transform:translateX(0) rotate(0deg)}20%{transform:translateX(-1.5px) rotate(-6deg)}40%{transform:translateX(1.5px) rotate(5deg)}60%{transform:translateX(-1px) rotate(-4deg)}80%{transform:translateX(1px) rotate(3deg)}}
1372
+ @keyframes gg-star-spin{0%,100%{transform:scale(1) rotate(0deg)}50%{transform:scale(1.15) rotate(15deg)}}
1373
+ @keyframes gg-ui-grow{0%,100%{transform:scaleY(1)}50%{transform:scaleY(1.12)}}
1374
+ @keyframes gg-perf-sweep{0%,100%{transform:rotate(0deg)}30%{transform:rotate(-12deg)}70%{transform:rotate(10deg)}}
1375
+ @keyframes gg-shield-pulse{0%,100%{transform:scale(1);opacity:1}50%{transform:scale(1.08);opacity:.75}}
1376
+ @keyframes gg-question-shake{0%,100%{transform:rotate(0deg)}25%{transform:rotate(-7deg)}75%{transform:rotate(7deg)}}
1377
+ @keyframes gg-chat-tilt{0%,100%{transform:rotate(0deg) translateY(0)}50%{transform:rotate(-6deg) translateY(-2px)}}
1378
+ button[data-gg-type] > svg{transform-origin:center}
1379
+ button[data-gg-type="BUG"] > svg{animation:gg-bug-crawl 2.2s ease-in-out infinite}
1380
+ button[data-gg-type="FEATURE_REQUEST"] > svg{animation:gg-star-spin 2.6s ease-in-out infinite}
1381
+ button[data-gg-type="UI_IMPROVEMENT"] > svg{animation:gg-ui-grow 1.8s ease-in-out infinite;transform-origin:bottom}
1382
+ button[data-gg-type="PERFORMANCE"] > svg{animation:gg-perf-sweep 2.4s ease-in-out infinite}
1383
+ button[data-gg-type="SECURITY"] > svg{animation:gg-shield-pulse 2.2s ease-in-out infinite;transform-origin:top}
1384
+ button[data-gg-type="QUESTION"] > svg{animation:gg-question-shake 2s ease-in-out infinite}
1385
+ button[data-gg-type="OTHER"] > svg{animation:gg-chat-tilt 2.2s ease-in-out infinite}
1356
1386
  ` }),
1357
1387
  document.body
1358
1388
  ),
@@ -1470,7 +1500,19 @@ function ReportDialog({
1470
1500
  },
1471
1501
  children: step === 1 ? "What's on your mind?" : "Tell us more"
1472
1502
  }
1473
- ),
1503
+ )
1504
+ ]
1505
+ }
1506
+ ),
1507
+ /* @__PURE__ */ jsxs2(
1508
+ "div",
1509
+ {
1510
+ style: {
1511
+ display: "flex",
1512
+ alignItems: "center",
1513
+ gap: "8px"
1514
+ },
1515
+ children: [
1474
1516
  step === 1 && /* @__PURE__ */ jsx2(
1475
1517
  "span",
1476
1518
  {
@@ -1488,45 +1530,45 @@ function ReportDialog({
1488
1530
  },
1489
1531
  children: getShortcutLabel()
1490
1532
  }
1533
+ ),
1534
+ /* @__PURE__ */ jsx2(
1535
+ "button",
1536
+ {
1537
+ type: "button",
1538
+ onClick: handleClose,
1539
+ style: {
1540
+ background: "none",
1541
+ border: "none",
1542
+ cursor: "pointer",
1543
+ padding: "4px",
1544
+ display: "flex",
1545
+ alignItems: "center",
1546
+ justifyContent: "center"
1547
+ },
1548
+ "aria-label": "Close",
1549
+ children: /* @__PURE__ */ jsx2(
1550
+ "svg",
1551
+ {
1552
+ width: "16",
1553
+ height: "16",
1554
+ viewBox: "0 0 16 16",
1555
+ fill: "none",
1556
+ style: { display: "block" },
1557
+ children: /* @__PURE__ */ jsx2(
1558
+ "path",
1559
+ {
1560
+ d: "M4 4L12 12M12 4L4 12",
1561
+ stroke: t.textMuted,
1562
+ strokeWidth: "2",
1563
+ strokeLinecap: "round"
1564
+ }
1565
+ )
1566
+ }
1567
+ )
1568
+ }
1491
1569
  )
1492
1570
  ]
1493
1571
  }
1494
- ),
1495
- /* @__PURE__ */ jsx2(
1496
- "button",
1497
- {
1498
- type: "button",
1499
- onClick: handleClose,
1500
- style: {
1501
- background: "none",
1502
- border: "none",
1503
- cursor: "pointer",
1504
- padding: "4px",
1505
- display: "flex",
1506
- alignItems: "center",
1507
- justifyContent: "center"
1508
- },
1509
- "aria-label": "Close",
1510
- children: /* @__PURE__ */ jsx2(
1511
- "svg",
1512
- {
1513
- width: "16",
1514
- height: "16",
1515
- viewBox: "0 0 16 16",
1516
- fill: "none",
1517
- style: { display: "block" },
1518
- children: /* @__PURE__ */ jsx2(
1519
- "path",
1520
- {
1521
- d: "M4 4L12 12M12 4L4 12",
1522
- stroke: t.textMuted,
1523
- strokeWidth: "2",
1524
- strokeLinecap: "round"
1525
- }
1526
- )
1527
- }
1528
- )
1529
- }
1530
1572
  )
1531
1573
  ]
1532
1574
  }
@@ -1615,6 +1657,7 @@ function ReportDialog({
1615
1657
  "button",
1616
1658
  {
1617
1659
  type: "button",
1660
+ "data-gg-type": type,
1618
1661
  onClick: () => {
1619
1662
  setReportType(type);
1620
1663
  setStep(2);
@@ -2070,8 +2113,8 @@ function ReportDialog({
2070
2113
  fontWeight: 500
2071
2114
  },
2072
2115
  children: [
2073
- "Screenshots",
2074
- screenshots.length > 0 ? ` (${screenshots.length})` : ""
2116
+ "Attachments",
2117
+ screenshots.length + attachments.length > 0 ? ` (${screenshots.length + attachments.length})` : ""
2075
2118
  ]
2076
2119
  }
2077
2120
  ),
@@ -2209,6 +2252,133 @@ function ReportDialog({
2209
2252
  ))
2210
2253
  }
2211
2254
  ),
2255
+ attachments.length > 0 && /* @__PURE__ */ jsx2(
2256
+ "div",
2257
+ {
2258
+ style: {
2259
+ display: "flex",
2260
+ flexDirection: "column",
2261
+ gap: "6px",
2262
+ marginBottom: "8px"
2263
+ },
2264
+ children: attachments.map((a, i) => /* @__PURE__ */ jsxs2(
2265
+ "div",
2266
+ {
2267
+ style: {
2268
+ display: "flex",
2269
+ alignItems: "center",
2270
+ gap: "8px",
2271
+ padding: "6px 8px",
2272
+ borderRadius: "6px",
2273
+ border: `1px solid ${t.border}`
2274
+ },
2275
+ children: [
2276
+ /* @__PURE__ */ jsxs2(
2277
+ "svg",
2278
+ {
2279
+ width: "14",
2280
+ height: "14",
2281
+ viewBox: "0 0 24 24",
2282
+ fill: "none",
2283
+ style: { flexShrink: 0, opacity: 0.6 },
2284
+ children: [
2285
+ /* @__PURE__ */ jsx2(
2286
+ "path",
2287
+ {
2288
+ d: "M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z",
2289
+ stroke: t.textMuted,
2290
+ strokeWidth: "1.5",
2291
+ strokeLinecap: "round",
2292
+ strokeLinejoin: "round"
2293
+ }
2294
+ ),
2295
+ /* @__PURE__ */ jsx2(
2296
+ "path",
2297
+ {
2298
+ d: "M14 2v6h6",
2299
+ stroke: t.textMuted,
2300
+ strokeWidth: "1.5",
2301
+ strokeLinecap: "round",
2302
+ strokeLinejoin: "round"
2303
+ }
2304
+ )
2305
+ ]
2306
+ }
2307
+ ),
2308
+ /* @__PURE__ */ jsx2(
2309
+ "span",
2310
+ {
2311
+ style: {
2312
+ fontSize: "11px",
2313
+ color: t.text,
2314
+ flex: 1,
2315
+ overflow: "hidden",
2316
+ textOverflow: "ellipsis",
2317
+ whiteSpace: "nowrap"
2318
+ },
2319
+ children: a.name
2320
+ }
2321
+ ),
2322
+ /* @__PURE__ */ jsxs2(
2323
+ "span",
2324
+ {
2325
+ style: { fontSize: "10px", color: t.textMuted },
2326
+ children: [
2327
+ (a.size / 1024).toFixed(0),
2328
+ "KB"
2329
+ ]
2330
+ }
2331
+ ),
2332
+ /* @__PURE__ */ jsx2(
2333
+ "button",
2334
+ {
2335
+ type: "button",
2336
+ onClick: () => setAttachments(
2337
+ (prev) => prev.filter((_, idx) => idx !== i)
2338
+ ),
2339
+ "aria-label": `Remove ${a.name}`,
2340
+ style: {
2341
+ width: "16px",
2342
+ height: "16px",
2343
+ borderRadius: "50%",
2344
+ border: "none",
2345
+ background: "#ef4444",
2346
+ color: "#fff",
2347
+ fontSize: "10px",
2348
+ lineHeight: 1,
2349
+ padding: 0,
2350
+ cursor: "pointer",
2351
+ display: "flex",
2352
+ alignItems: "center",
2353
+ justifyContent: "center",
2354
+ flexShrink: 0
2355
+ },
2356
+ children: /* @__PURE__ */ jsx2(
2357
+ "svg",
2358
+ {
2359
+ width: "8",
2360
+ height: "8",
2361
+ viewBox: "0 0 10 10",
2362
+ fill: "none",
2363
+ children: /* @__PURE__ */ jsx2(
2364
+ "path",
2365
+ {
2366
+ d: "M1 1L9 9M9 1L1 9",
2367
+ stroke: "currentColor",
2368
+ strokeWidth: "1.5",
2369
+ strokeLinecap: "round"
2370
+ }
2371
+ )
2372
+ }
2373
+ )
2374
+ }
2375
+ )
2376
+ ]
2377
+ },
2378
+ i
2379
+ ))
2380
+ }
2381
+ ),
2212
2382
  /* @__PURE__ */ jsx2(
2213
2383
  "div",
2214
2384
  {
@@ -2219,17 +2389,7 @@ function ReportDialog({
2219
2389
  onDrop: (e) => {
2220
2390
  e.preventDefault();
2221
2391
  setScreenshotDragOver(false);
2222
- const files = Array.from(
2223
- e.dataTransfer.files
2224
- ).filter((f) => f.type.startsWith("image/"));
2225
- files.forEach((file) => {
2226
- const reader = new FileReader();
2227
- reader.onload = () => setScreenshots((prev) => [
2228
- ...prev,
2229
- reader.result
2230
- ]);
2231
- reader.readAsDataURL(file);
2232
- });
2392
+ addFiles(Array.from(e.dataTransfer.files));
2233
2393
  },
2234
2394
  onDragOver: (e) => {
2235
2395
  e.preventDefault();
@@ -2239,13 +2399,13 @@ function ReportDialog({
2239
2399
  style: {
2240
2400
  border: `1.5px dashed ${screenshotDragOver ? t.accent : t.inputBorder}`,
2241
2401
  borderRadius: "8px",
2242
- padding: screenshots.length > 0 ? "8px 12px" : "18px 12px",
2402
+ padding: screenshots.length + attachments.length > 0 ? "8px 12px" : "18px 12px",
2243
2403
  textAlign: "center",
2244
2404
  cursor: "pointer",
2245
2405
  background: screenshotDragOver ? isDark ? "rgba(34,211,238,0.06)" : "rgba(8,145,178,0.04)" : "transparent",
2246
2406
  transition: "border-color 0.15s ease, background 0.15s ease"
2247
2407
  },
2248
- children: screenshots.length > 0 ? /* @__PURE__ */ jsx2(
2408
+ children: screenshots.length + attachments.length > 0 ? /* @__PURE__ */ jsx2(
2249
2409
  "p",
2250
2410
  {
2251
2411
  style: {
@@ -2314,7 +2474,7 @@ function ReportDialog({
2314
2474
  fontWeight: 600,
2315
2475
  color: t.text
2316
2476
  },
2317
- children: screenshotDragOver ? "Drop to attach" : "Add screenshots"
2477
+ children: screenshotDragOver ? "Drop to attach" : "Add screenshots or files"
2318
2478
  }
2319
2479
  ),
2320
2480
  /* @__PURE__ */ jsx2(
@@ -2325,7 +2485,7 @@ function ReportDialog({
2325
2485
  fontSize: "11px",
2326
2486
  color: t.textMuted
2327
2487
  },
2328
- children: "Drag & drop \xB7 Paste \u2318V / Ctrl+V \xB7 Click to browse"
2488
+ children: "Images, PDF, DOC, XLS \xB7 Drag & drop \xB7 Paste \u2318V / Ctrl+V \xB7 Click to browse"
2329
2489
  }
2330
2490
  )
2331
2491
  ] })
@@ -2430,7 +2590,7 @@ function ReportDialog({
2430
2590
  {
2431
2591
  ref: fileInputRef,
2432
2592
  type: "file",
2433
- accept: "image/*",
2593
+ accept: "image/*,.pdf,.doc,.docx,.xls,.xlsx,.csv",
2434
2594
  multiple: true,
2435
2595
  onChange: handleFileUpload,
2436
2596
  style: { display: "none" }