@solhun/feedback-kit-web 0.6.0 → 0.6.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.cjs +57 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +57 -9
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -1009,7 +1009,7 @@ var import_feedback_kit_core3 = require("@solhun/feedback-kit-core");
|
|
|
1009
1009
|
var import_react = require("react");
|
|
1010
1010
|
|
|
1011
1011
|
// src/version.ts
|
|
1012
|
-
var VERSION = true ? "0.6.
|
|
1012
|
+
var VERSION = true ? "0.6.1" : "dev";
|
|
1013
1013
|
|
|
1014
1014
|
// src/feedback-kit.tsx
|
|
1015
1015
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -1072,26 +1072,41 @@ async function transcodeToJpeg(dataUrl) {
|
|
|
1072
1072
|
return null;
|
|
1073
1073
|
}
|
|
1074
1074
|
}
|
|
1075
|
+
function looksLikeImageName(name) {
|
|
1076
|
+
return /\.(png|jpe?g|gif|webp|bmp|avif|heic|heif)$/i.test(name);
|
|
1077
|
+
}
|
|
1078
|
+
function isImageFile(file) {
|
|
1079
|
+
if (file.type.startsWith("image/")) return true;
|
|
1080
|
+
return (file.type === "" || file.type === "application/octet-stream") && looksLikeImageName(file.name);
|
|
1081
|
+
}
|
|
1082
|
+
function contentTypeOf(file) {
|
|
1083
|
+
if (file.type !== "") return file.type;
|
|
1084
|
+
const name = file instanceof File ? file.name : "";
|
|
1085
|
+
if (/\.png$/i.test(name)) return "image/png";
|
|
1086
|
+
if (/\.jpe?g$/i.test(name)) return "image/jpeg";
|
|
1087
|
+
return "";
|
|
1088
|
+
}
|
|
1075
1089
|
async function readImageFile(file) {
|
|
1076
|
-
|
|
1090
|
+
const named = file instanceof File ? file : null;
|
|
1091
|
+
if (!file.type.startsWith("image/") && !(named !== null && isImageFile(named))) return null;
|
|
1077
1092
|
const dataUrl = await readDataUrl(file);
|
|
1078
1093
|
if (!dataUrl) return null;
|
|
1079
|
-
|
|
1094
|
+
const type = contentTypeOf(file);
|
|
1095
|
+
if (type === "image/png" || type === "image/jpeg") {
|
|
1080
1096
|
const base64 = base64Of(dataUrl);
|
|
1081
|
-
return base64 ? { base64, contentType:
|
|
1097
|
+
return base64 ? { base64, contentType: type } : null;
|
|
1082
1098
|
}
|
|
1083
1099
|
return transcodeToJpeg(dataUrl);
|
|
1084
1100
|
}
|
|
1085
1101
|
function firstImageOf(transfer) {
|
|
1086
1102
|
if (!transfer) return null;
|
|
1087
1103
|
for (const item of Array.from(transfer.items ?? [])) {
|
|
1088
|
-
if (item.kind
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
}
|
|
1104
|
+
if (item.kind !== "file") continue;
|
|
1105
|
+
const file = item.getAsFile();
|
|
1106
|
+
if (file && isImageFile(file)) return file;
|
|
1092
1107
|
}
|
|
1093
1108
|
for (const file of Array.from(transfer.files ?? [])) {
|
|
1094
|
-
if (file
|
|
1109
|
+
if (isImageFile(file)) return file;
|
|
1095
1110
|
}
|
|
1096
1111
|
return null;
|
|
1097
1112
|
}
|
|
@@ -1433,6 +1448,23 @@ function FeedbackKit(props) {
|
|
|
1433
1448
|
document.addEventListener("keydown", onKeyDownCapture, true);
|
|
1434
1449
|
return () => document.removeEventListener("keydown", onKeyDownCapture, true);
|
|
1435
1450
|
}, [kit, widgetState, pickingState.popup]);
|
|
1451
|
+
(0, import_react.useEffect)(() => {
|
|
1452
|
+
if (!kit || !widgetState?.modal.open) return;
|
|
1453
|
+
if (pickingState.popup) return;
|
|
1454
|
+
const locked = widgetState.modal.submitStatus === "sending" || widgetState.modal.submitStatus === "pending";
|
|
1455
|
+
if (locked) return;
|
|
1456
|
+
const controller = kit;
|
|
1457
|
+
async function onPaste(event) {
|
|
1458
|
+
const file = firstImageOf(event.clipboardData);
|
|
1459
|
+
if (!file) return;
|
|
1460
|
+
event.preventDefault();
|
|
1461
|
+
const shot = await readImageFile(file);
|
|
1462
|
+
if (shot) await controller.widget.modal.attachFile(shot);
|
|
1463
|
+
}
|
|
1464
|
+
const handler = (event) => void onPaste(event);
|
|
1465
|
+
document.addEventListener("paste", handler);
|
|
1466
|
+
return () => document.removeEventListener("paste", handler);
|
|
1467
|
+
}, [kit, widgetState, pickingState.popup]);
|
|
1436
1468
|
if (!kit || !widgetState) {
|
|
1437
1469
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { ...OWN_UI_PROPS, "data-feedback-kit-loading": "true" });
|
|
1438
1470
|
}
|
|
@@ -1470,6 +1502,14 @@ function FeedbackKit(props) {
|
|
|
1470
1502
|
}
|
|
1471
1503
|
input.value = "";
|
|
1472
1504
|
}
|
|
1505
|
+
async function attachToModal(transfer) {
|
|
1506
|
+
const file = firstImageOf(transfer);
|
|
1507
|
+
if (!file) return false;
|
|
1508
|
+
const screenshot = await readImageFile(file);
|
|
1509
|
+
if (!screenshot) return false;
|
|
1510
|
+
await activeKit.widget.modal.attachFile(screenshot);
|
|
1511
|
+
return true;
|
|
1512
|
+
}
|
|
1473
1513
|
async function attachToPopup(transfer) {
|
|
1474
1514
|
const file = firstImageOf(transfer);
|
|
1475
1515
|
if (!file) return false;
|
|
@@ -1570,6 +1610,14 @@ function FeedbackKit(props) {
|
|
|
1570
1610
|
"aria-modal": "true",
|
|
1571
1611
|
"aria-labelledby": "feedback-kit-dialog-title",
|
|
1572
1612
|
onKeyDown: handleModalKeyDown,
|
|
1613
|
+
onDragOver: (event) => {
|
|
1614
|
+
if (!draftLocked && firstImageOf(event.dataTransfer)) event.preventDefault();
|
|
1615
|
+
},
|
|
1616
|
+
onDrop: (event) => {
|
|
1617
|
+
if (draftLocked || !firstImageOf(event.dataTransfer)) return;
|
|
1618
|
+
event.preventDefault();
|
|
1619
|
+
void attachToModal(event.dataTransfer);
|
|
1620
|
+
},
|
|
1573
1621
|
style: {
|
|
1574
1622
|
width: "min(520px, 100%)",
|
|
1575
1623
|
maxHeight: "min(760px, calc(100vh - 40px))",
|