mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 17:00:15 +01:00
* 🤖 refactor: streamline model selection logic for title model in GoogleClient
* refactor: add options for empty object schemas in convertJsonSchemaToZod
* refactor: add utility function to check for empty object schemas in convertJsonSchemaToZod
* fix: Google MCP Tool errors, and remove Object Unescaping as Google fixed this
* fix: google safetySettings
* feat: add safety settings exclusion via GOOGLE_EXCLUDE_SAFETY_SETTINGS environment variable
* fix: rename environment variable for console JSON string length
* fix: disable portal for dropdown in ExportModal component
* fix: screenshot functionality to use image placeholder for remote images
* feat: add visionMode property to BaseClient and initialize in GoogleClient to fix resendFiles issue
* fix: enhance formatMessages to include image URLs in message content for Vertex AI
* fix: safety settings for titleChatCompletion
* fix: remove deprecated model assignment in GoogleClient and streamline title model retrieval
* fix: remove unused image preloading logic in ScreenshotContext
* chore: update default google models to latest models shared by vertex ai and gen ai
* refactor: enhance Google error messaging
* fix: update token values and model limits for Gemini models
* ci: fix model matching
* chore: bump version of librechat-data-provider to 0.7.699
70 lines
2.2 KiB
TypeScript
70 lines
2.2 KiB
TypeScript
import { createContext, useRef, useContext, RefObject } from 'react';
|
|
import { toCanvas } from 'html-to-image';
|
|
import { ThemeContext } from '~/hooks/ThemeContext';
|
|
|
|
type ScreenshotContextType = {
|
|
ref?: RefObject<HTMLDivElement>;
|
|
};
|
|
|
|
const ScreenshotContext = createContext<ScreenshotContextType>({});
|
|
|
|
export const useScreenshot = () => {
|
|
const { ref } = useContext(ScreenshotContext);
|
|
const { theme } = useContext(ThemeContext);
|
|
|
|
const takeScreenShot = async (node?: HTMLElement) => {
|
|
if (!node) {
|
|
throw new Error('You should provide correct html node.');
|
|
}
|
|
|
|
let isDark = theme === 'dark';
|
|
if (theme === 'system') {
|
|
isDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
}
|
|
const backgroundColor = isDark ? '#171717' : 'white';
|
|
|
|
const canvas = await toCanvas(node, {
|
|
backgroundColor,
|
|
imagePlaceholder:
|
|
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+ip1sAAAAASUVORK5CYII=',
|
|
});
|
|
|
|
const croppedCanvas = document.createElement('canvas');
|
|
const croppedCanvasContext = croppedCanvas.getContext('2d') as CanvasRenderingContext2D;
|
|
// init data
|
|
const cropPositionTop = 0;
|
|
const cropPositionLeft = 0;
|
|
const cropWidth = canvas.width;
|
|
const cropHeight = canvas.height;
|
|
|
|
croppedCanvas.width = cropWidth;
|
|
croppedCanvas.height = cropHeight;
|
|
|
|
croppedCanvasContext.fillStyle = backgroundColor;
|
|
croppedCanvasContext.fillRect(0, 0, cropWidth, 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 <ScreenshotContext.Provider value={{ ref }}>{children}</ScreenshotContext.Provider>;
|
|
};
|