Retrieve clipboard data from the event instead

This commit is contained in:
Vishnu Nithin Reddy
2023-10-23 00:07:35 +05:30
parent 68503156cb
commit 80a408063a
3 changed files with 88 additions and 63 deletions

View File

@@ -285,7 +285,7 @@ export default function Table({
const { handler: hotKeysHandler } = useHotKeys([
["mod+C", handleCopy],
["mod+X", handleCut],
["mod+V", handlePaste],
["mod+V", (e) => handlePaste], // So the event isn't passed to the handler
]);
// Handle prompt to save local column sizes if user `canEditColumns`
@@ -324,6 +324,14 @@ export default function Table({
fetchMoreOnBottomReached(containerRef.current);
}, [fetchMoreOnBottomReached, tableNextPage.loading, containerRef]);
useEffect(() => {
document.addEventListener("paste", handlePaste);
return () => {
document.removeEventListener("paste", handlePaste);
};
}, [handlePaste]);
// apply user default sort on first render
const [applySort, setApplySort] = useState(true);
useEffect(() => {

View File

@@ -12,7 +12,6 @@ export default function useHotKeys(actions: HotKeysAction[]) {
const event_ = "nativeEvent" in event ? event.nativeEvent : event;
actions.forEach(([hotkey, handler_]) => {
if (getHotkeyMatcher(hotkey)(event_)) {
event.preventDefault();
handler_(event_);
}
});

View File

@@ -161,71 +161,89 @@ export function useMenuAction(
handleClose,
]);
const handlePaste = useCallback(async () => {
try {
if (!selectedCell || !selectedCol) return;
let text;
const handlePaste = useCallback(
async (e?: ClipboardEvent) => {
try {
text = await navigator.clipboard.readText();
} catch (e) {
enqueueSnackbar(`Read clipboard permission denied.`, {
variant: "error",
});
return;
}
const cellDataType = getFieldProp("dataType", getFieldType(selectedCol));
let parsed;
switch (cellDataType) {
case "number":
parsed = Number(text);
if (isNaN(parsed)) throw new Error(`${text} is not a number`);
break;
case "string":
parsed = text;
break;
case "reference":
try {
parsed = doc(firebaseDb, text);
} catch (e: any) {
enqueueSnackbar(`Invalid reference.`, { variant: "error" });
if (!selectedCell || !selectedCol) return;
let text: string;
// Firefox doesn't allow for reading clipboard data, hence the workaround
if (navigator.userAgent.includes("Firefox")) {
if (!e || !e.clipboardData) {
enqueueSnackbar(`Cannot read clipboard data.`, {
variant: "error",
});
return;
}
break;
default:
parsed = JSON.parse(text);
break;
}
text = e.clipboardData.getData("text/plain") || "";
} else {
try {
text = await navigator.clipboard.readText();
} catch (e) {
enqueueSnackbar(`Read clipboard permission denied.`, {
variant: "error",
});
return;
}
}
const cellDataType = getFieldProp(
"dataType",
getFieldType(selectedCol)
);
let parsed;
switch (cellDataType) {
case "number":
parsed = Number(text);
if (isNaN(parsed)) throw new Error(`${text} is not a number`);
break;
case "string":
parsed = text;
break;
case "reference":
try {
parsed = doc(firebaseDb, text);
} catch (e: any) {
enqueueSnackbar(`Invalid reference.`, { variant: "error" });
}
break;
default:
parsed = JSON.parse(text);
break;
}
if (selectedCol.type === FieldType.slider) {
if (parsed < selectedCol.config?.min) parsed = selectedCol.config?.min;
else if (parsed > selectedCol.config?.max)
parsed = selectedCol.config?.max;
}
if (selectedCol.type === FieldType.slider) {
if (parsed < selectedCol.config?.min)
parsed = selectedCol.config?.min;
else if (parsed > selectedCol.config?.max)
parsed = selectedCol.config?.max;
}
if (selectedCol.type === FieldType.rating) {
if (parsed < 0) parsed = 0;
if (parsed > (selectedCol.config?.max || 5))
parsed = selectedCol.config?.max || 5;
}
if (selectedCol.type === FieldType.rating) {
if (parsed < 0) parsed = 0;
if (parsed > (selectedCol.config?.max || 5))
parsed = selectedCol.config?.max || 5;
}
if (selectedCol.type === FieldType.percentage) {
parsed = parsed / 100;
if (selectedCol.type === FieldType.percentage) {
parsed = parsed / 100;
}
updateField({
path: selectedCell.path,
fieldName: selectedCol.fieldName,
value: parsed,
arrayTableData: {
index: selectedCell.arrayIndex,
},
});
} catch (error) {
enqueueSnackbar(
`${selectedCol?.type} field does not support the data type being pasted`,
{ variant: "error" }
);
}
updateField({
path: selectedCell.path,
fieldName: selectedCol.fieldName,
value: parsed,
arrayTableData: {
index: selectedCell.arrayIndex,
},
});
} catch (error) {
enqueueSnackbar(
`${selectedCol?.type} field does not support the data type being pasted`,
{ variant: "error" }
);
}
if (handleClose) handleClose();
}, [selectedCell, selectedCol, updateField, enqueueSnackbar, handleClose]);
if (handleClose) handleClose();
},
[selectedCell, selectedCol, updateField, enqueueSnackbar, handleClose]
);
useEffect(() => {
if (!selectedCell) return setCellValue("");
@@ -276,9 +294,9 @@ export function useMenuAction(
};
}
const fieldType = getFieldType(selectedCol);
return function () {
return function (e?: ClipboardEvent) {
if (SUPPORTED_TYPES_PASTE.has(fieldType)) {
return func();
return func(e);
} else {
enqueueSnackbar(
`${fieldType} field does not support paste functionality`,