fix: 修复灯箱问题 (#291)

* fix: 修复灯箱问题

- Modified `getDefaultSize` function to accept optional width and height properties.
- Enhanced `ImagePreview` component to allow custom container element and refined click handling for images in chat and markdown contexts.
- Updated `ImageMessage` properties to include optional fields for better flexibility.

* chore: bump version to v0.9.46
This commit is contained in:
haorwen
2025-12-31 08:37:30 +08:00
committed by GitHub
parent 5897f3304a
commit 970f7b11e0
4 changed files with 17 additions and 8 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "vocechat-web",
"version": "0.9.45",
"version": "0.9.46",
"homepage": "https://voce.chat",
"dependencies": {
"@metamask/onboarding": "^1.0.1",
+1 -1
View File
@@ -10,7 +10,7 @@ type Props = {
thumbnail: string;
download: string;
content: string;
properties: { width: number; height: number };
properties: { width?: number; height?: number; name?: string; content_type?: string; size?: number };
};
const ImageMessage: FC<Props> = ({
+14 -5
View File
@@ -4,20 +4,25 @@ import ImagePreviewModal, { PreviewImageData } from "./ImagePreviewModal";
type Props = {
context?: "chat" | "markdown";
container?: HTMLElement | null;
};
const ImagePreview = ({ context = "chat" }: Props) => {
const ImagePreview = ({ context = "chat", container: containerProp }: Props) => {
const [previewImage, setPreviewImage] = useState<PreviewImageData | null>(null);
const closePreviewModal = () => {
setPreviewImage(null);
};
useEffect(() => {
const container = document.querySelector("#CHAT_WRAPPER") as HTMLDivElement;
const container = containerProp || (document.querySelector("#CHAT_WRAPPER") as HTMLDivElement);
if (!container) return;
const chatHandler = (evt: MouseEvent) => {
const target = evt.target as HTMLImageElement;
// 检查灯箱是否已经打开,如果是则忽略所有点击
if (document.querySelector(".yarl__root")) return;
const isMsg = !!target.closest(".vc-msg");
if (isMsg && target && target.nodeName == "IMG" && target.classList.contains("preview")) {
// 排除 markdown 容器内的图片,避免重复处理
const isInMarkdown = !!target.closest("#MARKDOWN_CONTAINER");
if (isMsg && target && target.nodeName == "IMG" && target.classList.contains("preview") && !isInMarkdown) {
// console.log("click chat", target);
evt.stopPropagation();
const thumbnail = target.src;
@@ -29,9 +34,13 @@ const ImagePreview = ({ context = "chat" }: Props) => {
};
const markdownHandler = (evt: MouseEvent) => {
const target = evt.target as HTMLImageElement;
// 检查灯箱是否已经打开,如果是则忽略所有点击
if (document.querySelector(".yarl__root")) return;
const isMsg = !!target.closest(".vc-msg");
// 只处理 markdown 容器内的图片
const isInMarkdown = !!target.closest("#MARKDOWN_CONTAINER");
// 图片 并且没被 a 标签包裹
if (isMsg && target && target.nodeName == "IMG" && target.parentElement?.tagName !== "A") {
if (isMsg && target && target.nodeName == "IMG" && target.parentElement?.tagName !== "A" && isInMarkdown) {
// console.log("click markdown", target);
evt.stopPropagation();
const urlObj = new URL(target.src);
@@ -55,7 +64,7 @@ const ImagePreview = ({ context = "chat" }: Props) => {
return () => {
container.removeEventListener("click", handler, true);
};
}, [context]);
}, [context, containerProp]);
return previewImage ? (
<ImagePreviewModal download={true} data={previewImage} closeModal={closePreviewModal} />
) : null;
+1 -1
View File
@@ -101,7 +101,7 @@ export const isElementVisible = (el: Element | null) => {
);
};
export function getDefaultSize(
size?: { width: number; height: number },
size?: { width?: number; height?: number },
limit?: { min: number; max: number }
) {
if (!size) return { width: 0, height: 0 };