@campfire-interactive/shell-header 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +52 -10
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -604,6 +604,9 @@ function UserMenu({
|
|
|
604
604
|
] });
|
|
605
605
|
}
|
|
606
606
|
|
|
607
|
+
// src/ShellHeader.tsx
|
|
608
|
+
import { useRef as useRef6, useState as useState7 } from "react";
|
|
609
|
+
|
|
607
610
|
// src/AboutModal.tsx
|
|
608
611
|
import { useEffect as useEffect4, useState as useState4 } from "react";
|
|
609
612
|
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
@@ -872,7 +875,7 @@ function normalizeRect(x0, y0, x1, y1) {
|
|
|
872
875
|
h: Math.abs(y1 - y0)
|
|
873
876
|
};
|
|
874
877
|
}
|
|
875
|
-
function BugReportModal({ config, onClose }) {
|
|
878
|
+
function BugReportModal({ config, initialScreenshot, onClose }) {
|
|
876
879
|
const [view, setView] = useState6("form");
|
|
877
880
|
const [title, setTitle] = useState6("");
|
|
878
881
|
const [description, setDescription] = useState6("");
|
|
@@ -886,6 +889,21 @@ function BugReportModal({ config, onClose }) {
|
|
|
886
889
|
const displayCanvasRef = useRef4(null);
|
|
887
890
|
const dragStartRef = useRef4(null);
|
|
888
891
|
const [mode, setMode] = useState6("crop");
|
|
892
|
+
const initialLoadedRef = useRef4(false);
|
|
893
|
+
useEffect6(() => {
|
|
894
|
+
if (!initialScreenshot || initialLoadedRef.current) return;
|
|
895
|
+
initialLoadedRef.current = true;
|
|
896
|
+
let cancelled = false;
|
|
897
|
+
void blobToCanvas(initialScreenshot).then((image) => {
|
|
898
|
+
if (cancelled) return;
|
|
899
|
+
originalRef.current = cloneCanvas(image);
|
|
900
|
+
workCanvasRef.current = image;
|
|
901
|
+
setView("editor");
|
|
902
|
+
});
|
|
903
|
+
return () => {
|
|
904
|
+
cancelled = true;
|
|
905
|
+
};
|
|
906
|
+
}, [initialScreenshot]);
|
|
889
907
|
const closeUnlessBusy = useCallback(() => {
|
|
890
908
|
if (submitState === "submitting" || capturing) return;
|
|
891
909
|
if (screenshot) URL.revokeObjectURL(screenshot.previewUrl);
|
|
@@ -1229,9 +1247,10 @@ function cloneCanvas(source) {
|
|
|
1229
1247
|
}
|
|
1230
1248
|
|
|
1231
1249
|
// src/useBugReportShortcut.ts
|
|
1232
|
-
import { useEffect as useEffect7,
|
|
1233
|
-
function useBugReportShortcut(enabled) {
|
|
1234
|
-
const
|
|
1250
|
+
import { useEffect as useEffect7, useRef as useRef5 } from "react";
|
|
1251
|
+
function useBugReportShortcut(enabled, onShortcut) {
|
|
1252
|
+
const handlerRef = useRef5(onShortcut);
|
|
1253
|
+
handlerRef.current = onShortcut;
|
|
1235
1254
|
useEffect7(() => {
|
|
1236
1255
|
if (!enabled) return;
|
|
1237
1256
|
function handleKeyDown(e) {
|
|
@@ -1244,12 +1263,11 @@ function useBugReportShortcut(enabled) {
|
|
|
1244
1263
|
if (tag === "INPUT" || tag === "TEXTAREA" || target.isContentEditable) return;
|
|
1245
1264
|
}
|
|
1246
1265
|
e.preventDefault();
|
|
1247
|
-
|
|
1266
|
+
handlerRef.current();
|
|
1248
1267
|
}
|
|
1249
1268
|
document.addEventListener("keydown", handleKeyDown);
|
|
1250
1269
|
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
1251
1270
|
}, [enabled]);
|
|
1252
|
-
return [isOpen, setIsOpen];
|
|
1253
1271
|
}
|
|
1254
1272
|
|
|
1255
1273
|
// src/assets/campfire-wordmark.png
|
|
@@ -1287,7 +1305,21 @@ function ShellHeader({
|
|
|
1287
1305
|
}) {
|
|
1288
1306
|
const currentApp = appCatalog.find((a) => a.id === appId);
|
|
1289
1307
|
const [aboutOpen, setAboutOpen] = useAboutShortcut(about !== void 0);
|
|
1290
|
-
const [bugOpen, setBugOpen] =
|
|
1308
|
+
const [bugOpen, setBugOpen] = useState7(false);
|
|
1309
|
+
const [bugShot, setBugShot] = useState7(null);
|
|
1310
|
+
const bugCaptureBusy = useRef6(false);
|
|
1311
|
+
useBugReportShortcut(bugReport !== void 0, () => {
|
|
1312
|
+
if (bugOpen) {
|
|
1313
|
+
setBugOpen(false);
|
|
1314
|
+
return;
|
|
1315
|
+
}
|
|
1316
|
+
if (bugCaptureBusy.current) return;
|
|
1317
|
+
bugCaptureBusy.current = true;
|
|
1318
|
+
captureTabScreenshot().then((shot) => setBugShot(shot)).catch(() => setBugShot(null)).finally(() => {
|
|
1319
|
+
bugCaptureBusy.current = false;
|
|
1320
|
+
setBugOpen(true);
|
|
1321
|
+
});
|
|
1322
|
+
});
|
|
1291
1323
|
const brandStyle = brandWidth ? { width: `${brandWidth}px`, flexShrink: 0, boxSizing: "border-box" } : void 0;
|
|
1292
1324
|
return /* @__PURE__ */ jsxs7(Fragment4, { children: [
|
|
1293
1325
|
/* @__PURE__ */ jsxs7("header", { className: "cfi-sh-header", children: [
|
|
@@ -1332,17 +1364,27 @@ function ShellHeader({
|
|
|
1332
1364
|
] })
|
|
1333
1365
|
] }),
|
|
1334
1366
|
about && aboutOpen && /* @__PURE__ */ jsx7(AboutModal, { about, onClose: () => setAboutOpen(false) }),
|
|
1335
|
-
bugReport && bugOpen && /* @__PURE__ */ jsx7(
|
|
1367
|
+
bugReport && bugOpen && /* @__PURE__ */ jsx7(
|
|
1368
|
+
BugReportModal,
|
|
1369
|
+
{
|
|
1370
|
+
config: bugReport,
|
|
1371
|
+
initialScreenshot: bugShot,
|
|
1372
|
+
onClose: () => {
|
|
1373
|
+
setBugOpen(false);
|
|
1374
|
+
setBugShot(null);
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
)
|
|
1336
1378
|
] });
|
|
1337
1379
|
}
|
|
1338
1380
|
|
|
1339
1381
|
// src/LocaleSwitcher.tsx
|
|
1340
|
-
import { useState as useState8, useRef as
|
|
1382
|
+
import { useState as useState8, useRef as useRef7, useEffect as useEffect8 } from "react";
|
|
1341
1383
|
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1342
1384
|
function LocaleSwitcher({ currentLocale, supportedLocales, onLocaleChange }) {
|
|
1343
1385
|
const [open, setOpen] = useState8(false);
|
|
1344
1386
|
const [updating, setUpdating] = useState8(false);
|
|
1345
|
-
const ref =
|
|
1387
|
+
const ref = useRef7(null);
|
|
1346
1388
|
useEffect8(() => {
|
|
1347
1389
|
function handleClickOutside(e) {
|
|
1348
1390
|
if (ref.current && !ref.current.contains(e.target)) {
|