diff --git a/client/package.json b/client/package.json index 0c44f38a1..b41876c85 100644 --- a/client/package.json +++ b/client/package.json @@ -52,7 +52,7 @@ "esbuild": "0.17.19", "export-from-json": "^1.7.2", "filenamify": "^6.0.0", - "html2canvas": "^1.4.1", + "html-to-image": "^1.11.11", "librechat-data-provider": "*", "lodash": "^4.17.21", "lucide-react": "^0.220.0", diff --git a/client/src/hooks/ScreenshotContext.jsx b/client/src/hooks/ScreenshotContext.jsx deleted file mode 100644 index 72e08fb54..000000000 --- a/client/src/hooks/ScreenshotContext.jsx +++ /dev/null @@ -1,44 +0,0 @@ -import { createContext, useRef, useContext } from 'react'; -import html2canvas from 'html2canvas'; - -const ScreenshotContext = createContext({}); - -export const useScreenshot = () => { - const { ref } = useContext(ScreenshotContext); - - const takeScreenShot = (node) => { - if (!node) { - throw new Error('You should provide correct html node.'); - } - return html2canvas(node).then((canvas) => { - const croppedCanvas = document.createElement('canvas'); - const croppedCanvasContext = croppedCanvas.getContext('2d'); - // init data - const cropPositionTop = 0; - const cropPositionLeft = 0; - const cropWidth = canvas.width; - const cropHeight = canvas.height; - - croppedCanvas.width = cropWidth; - croppedCanvas.height = cropHeight; - - croppedCanvasContext.drawImage(canvas, cropPositionLeft, cropPositionTop); - - const base64Image = croppedCanvas.toDataURL('image/png', 1); - - return base64Image; - }); - }; - - const captureScreenshot = () => { - return takeScreenShot(ref.current); - }; - - return { screenshotTargetRef: ref, captureScreenshot }; -}; - -export const ScreenshotProvider = ({ children }) => { - const ref = useRef(null); - - return {children}; -}; diff --git a/client/src/hooks/ScreenshotContext.tsx b/client/src/hooks/ScreenshotContext.tsx new file mode 100644 index 000000000..581e3ad1c --- /dev/null +++ b/client/src/hooks/ScreenshotContext.tsx @@ -0,0 +1,53 @@ +import { createContext, useRef, useContext, Ref } from 'react'; +import { toCanvas } from 'html-to-image'; + +type ScreenshotContextType = { + ref?: Ref; +}; + +const ScreenshotContext = createContext({}); + +export const useScreenshot = () => { + const { ref } = useContext(ScreenshotContext); + + const takeScreenShot = async (node: HTMLElement) => { + if (!node) { + throw new Error('You should provide correct html node.'); + } + const canvas = await toCanvas(node); + const croppedCanvas = document.createElement('canvas'); + const croppedCanvasContext = croppedCanvas.getContext('2d'); + // init data + const cropPositionTop = 0; + const cropPositionLeft = 0; + const cropWidth = canvas.width; + const cropHeight = canvas.height; + + croppedCanvas.width = cropWidth; + croppedCanvas.height = cropHeight; + + croppedCanvasContext?.drawImage(canvas, cropPositionLeft, cropPositionTop); + + const base64Image = croppedCanvas.toDataURL('image/png', 1); + + return base64Image; + }; + + const captureScreenshot = async () => { + if (ref instanceof Function) { + throw new Error('Ref callback is not supported.'); + } + if (ref?.current) { + return takeScreenShot(ref.current); + } + throw new Error('Ref is not attached to any element.'); + }; + + return { screenshotTargetRef: ref, captureScreenshot }; +}; + +export const ScreenshotProvider = ({ children }) => { + const ref = useRef(null); + + return {children}; +};