@campfire-interactive/shell-header 0.11.0 → 0.12.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/dist/index.js +54 -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);
|
|
@@ -1075,6 +1093,8 @@ function BugReportModal({ config, onClose }) {
|
|
|
1075
1093
|
role: "dialog",
|
|
1076
1094
|
"aria-modal": "true",
|
|
1077
1095
|
"aria-label": "Report an issue",
|
|
1096
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
1097
|
+
onFocus: (e) => e.stopPropagation(),
|
|
1078
1098
|
children: /* @__PURE__ */ jsxs6("div", { className: `cfi-sh-bug-card${view === "editor" ? " cfi-sh-bug-card-wide" : ""}`, children: [
|
|
1079
1099
|
/* @__PURE__ */ jsxs6("div", { className: "cfi-sh-bug-header", children: [
|
|
1080
1100
|
/* @__PURE__ */ jsx6("span", { className: "cfi-sh-bug-title", children: "Report an issue" }),
|
|
@@ -1229,9 +1249,10 @@ function cloneCanvas(source) {
|
|
|
1229
1249
|
}
|
|
1230
1250
|
|
|
1231
1251
|
// src/useBugReportShortcut.ts
|
|
1232
|
-
import { useEffect as useEffect7,
|
|
1233
|
-
function useBugReportShortcut(enabled) {
|
|
1234
|
-
const
|
|
1252
|
+
import { useEffect as useEffect7, useRef as useRef5 } from "react";
|
|
1253
|
+
function useBugReportShortcut(enabled, onShortcut) {
|
|
1254
|
+
const handlerRef = useRef5(onShortcut);
|
|
1255
|
+
handlerRef.current = onShortcut;
|
|
1235
1256
|
useEffect7(() => {
|
|
1236
1257
|
if (!enabled) return;
|
|
1237
1258
|
function handleKeyDown(e) {
|
|
@@ -1244,12 +1265,11 @@ function useBugReportShortcut(enabled) {
|
|
|
1244
1265
|
if (tag === "INPUT" || tag === "TEXTAREA" || target.isContentEditable) return;
|
|
1245
1266
|
}
|
|
1246
1267
|
e.preventDefault();
|
|
1247
|
-
|
|
1268
|
+
handlerRef.current();
|
|
1248
1269
|
}
|
|
1249
1270
|
document.addEventListener("keydown", handleKeyDown);
|
|
1250
1271
|
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
1251
1272
|
}, [enabled]);
|
|
1252
|
-
return [isOpen, setIsOpen];
|
|
1253
1273
|
}
|
|
1254
1274
|
|
|
1255
1275
|
// src/assets/campfire-wordmark.png
|
|
@@ -1287,7 +1307,21 @@ function ShellHeader({
|
|
|
1287
1307
|
}) {
|
|
1288
1308
|
const currentApp = appCatalog.find((a) => a.id === appId);
|
|
1289
1309
|
const [aboutOpen, setAboutOpen] = useAboutShortcut(about !== void 0);
|
|
1290
|
-
const [bugOpen, setBugOpen] =
|
|
1310
|
+
const [bugOpen, setBugOpen] = useState7(false);
|
|
1311
|
+
const [bugShot, setBugShot] = useState7(null);
|
|
1312
|
+
const bugCaptureBusy = useRef6(false);
|
|
1313
|
+
useBugReportShortcut(bugReport !== void 0, () => {
|
|
1314
|
+
if (bugOpen) {
|
|
1315
|
+
setBugOpen(false);
|
|
1316
|
+
return;
|
|
1317
|
+
}
|
|
1318
|
+
if (bugCaptureBusy.current) return;
|
|
1319
|
+
bugCaptureBusy.current = true;
|
|
1320
|
+
captureTabScreenshot().then((shot) => setBugShot(shot)).catch(() => setBugShot(null)).finally(() => {
|
|
1321
|
+
bugCaptureBusy.current = false;
|
|
1322
|
+
setBugOpen(true);
|
|
1323
|
+
});
|
|
1324
|
+
});
|
|
1291
1325
|
const brandStyle = brandWidth ? { width: `${brandWidth}px`, flexShrink: 0, boxSizing: "border-box" } : void 0;
|
|
1292
1326
|
return /* @__PURE__ */ jsxs7(Fragment4, { children: [
|
|
1293
1327
|
/* @__PURE__ */ jsxs7("header", { className: "cfi-sh-header", children: [
|
|
@@ -1332,17 +1366,27 @@ function ShellHeader({
|
|
|
1332
1366
|
] })
|
|
1333
1367
|
] }),
|
|
1334
1368
|
about && aboutOpen && /* @__PURE__ */ jsx7(AboutModal, { about, onClose: () => setAboutOpen(false) }),
|
|
1335
|
-
bugReport && bugOpen && /* @__PURE__ */ jsx7(
|
|
1369
|
+
bugReport && bugOpen && /* @__PURE__ */ jsx7(
|
|
1370
|
+
BugReportModal,
|
|
1371
|
+
{
|
|
1372
|
+
config: bugReport,
|
|
1373
|
+
initialScreenshot: bugShot,
|
|
1374
|
+
onClose: () => {
|
|
1375
|
+
setBugOpen(false);
|
|
1376
|
+
setBugShot(null);
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
)
|
|
1336
1380
|
] });
|
|
1337
1381
|
}
|
|
1338
1382
|
|
|
1339
1383
|
// src/LocaleSwitcher.tsx
|
|
1340
|
-
import { useState as useState8, useRef as
|
|
1384
|
+
import { useState as useState8, useRef as useRef7, useEffect as useEffect8 } from "react";
|
|
1341
1385
|
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1342
1386
|
function LocaleSwitcher({ currentLocale, supportedLocales, onLocaleChange }) {
|
|
1343
1387
|
const [open, setOpen] = useState8(false);
|
|
1344
1388
|
const [updating, setUpdating] = useState8(false);
|
|
1345
|
-
const ref =
|
|
1389
|
+
const ref = useRef7(null);
|
|
1346
1390
|
useEffect8(() => {
|
|
1347
1391
|
function handleClickOutside(e) {
|
|
1348
1392
|
if (ref.current && !ref.current.contains(e.target)) {
|