From fc43f8657166798f38e21175815e898364d323b5 Mon Sep 17 00:00:00 2001 From: Johnny Date: Sun, 9 Nov 2025 07:23:31 +0800 Subject: [PATCH] chore(web): unify Location/Attachments/Relations components (#5241) Co-authored-by: Claude --- web/src/components/MemoAttachmentListView.tsx | 113 ------------- .../MemoEditor/AttachmentListView.tsx | 71 -------- .../components/MemoEditor/LocationView.tsx | 34 ---- .../MemoEditor/RelationListView.tsx | 55 ------- web/src/components/MemoEditor/index.tsx | 11 +- web/src/components/MemoLocationView.tsx | 35 ---- web/src/components/MemoRelationListView.tsx | 110 ------------- web/src/components/MemoView.tsx | 10 +- .../memo-metadata/AttachmentCard.tsx | 96 +++++++++++ .../memo-metadata/AttachmentList.tsx | 144 +++++++++++++++++ .../memo-metadata/LocationDisplay.tsx | 62 +++++++ .../memo-metadata/MetadataBadge.tsx | 46 ++++++ .../components/memo-metadata/MetadataCard.tsx | 26 +++ .../components/memo-metadata/RelationCard.tsx | 61 +++++++ .../components/memo-metadata/RelationList.tsx | 153 ++++++++++++++++++ web/src/components/memo-metadata/index.ts | 17 ++ web/src/components/memo-metadata/types.ts | 10 ++ 17 files changed, 624 insertions(+), 430 deletions(-) delete mode 100644 web/src/components/MemoAttachmentListView.tsx delete mode 100644 web/src/components/MemoEditor/AttachmentListView.tsx delete mode 100644 web/src/components/MemoEditor/LocationView.tsx delete mode 100644 web/src/components/MemoEditor/RelationListView.tsx delete mode 100644 web/src/components/MemoLocationView.tsx delete mode 100644 web/src/components/MemoRelationListView.tsx create mode 100644 web/src/components/memo-metadata/AttachmentCard.tsx create mode 100644 web/src/components/memo-metadata/AttachmentList.tsx create mode 100644 web/src/components/memo-metadata/LocationDisplay.tsx create mode 100644 web/src/components/memo-metadata/MetadataBadge.tsx create mode 100644 web/src/components/memo-metadata/MetadataCard.tsx create mode 100644 web/src/components/memo-metadata/RelationCard.tsx create mode 100644 web/src/components/memo-metadata/RelationList.tsx create mode 100644 web/src/components/memo-metadata/index.ts create mode 100644 web/src/components/memo-metadata/types.ts diff --git a/web/src/components/MemoAttachmentListView.tsx b/web/src/components/MemoAttachmentListView.tsx deleted file mode 100644 index 7749fb0e2..000000000 --- a/web/src/components/MemoAttachmentListView.tsx +++ /dev/null @@ -1,113 +0,0 @@ -import { memo, useState } from "react"; -import { cn } from "@/lib/utils"; -import { Attachment } from "@/types/proto/api/v1/attachment_service"; -import { getAttachmentThumbnailUrl, getAttachmentType, getAttachmentUrl } from "@/utils/attachment"; -import MemoAttachment from "./MemoAttachment"; -import PreviewImageDialog from "./PreviewImageDialog"; - -const MemoAttachmentListView = ({ attachments = [] }: { attachments: Attachment[] }) => { - const [previewImage, setPreviewImage] = useState<{ open: boolean; urls: string[]; index: number }>({ - open: false, - urls: [], - index: 0, - }); - const mediaAttachments: Attachment[] = []; - const otherAttachments: Attachment[] = []; - - attachments.forEach((attachment) => { - const type = getAttachmentType(attachment); - if (type === "image/*" || type === "video/*") { - mediaAttachments.push(attachment); - return; - } - - otherAttachments.push(attachment); - }); - - const handleImageClick = (imgUrl: string) => { - const imgUrls = mediaAttachments - .filter((attachment) => getAttachmentType(attachment) === "image/*") - .map((attachment) => getAttachmentUrl(attachment)); - const index = imgUrls.findIndex((url) => url === imgUrl); - setPreviewImage({ open: true, urls: imgUrls, index }); - }; - - const MediaCard = ({ attachment, className }: { attachment: Attachment; className?: string }) => { - const type = getAttachmentType(attachment); - const attachmentUrl = getAttachmentUrl(attachment); - const attachmentThumbnailUrl = getAttachmentThumbnailUrl(attachment); - - if (type === "image/*") { - return ( - { - // Fallback to original image if thumbnail fails - const target = e.target as HTMLImageElement; - if (target.src.includes("?thumbnail=true")) { - console.warn("Thumbnail failed, falling back to original image:", attachmentUrl); - target.src = attachmentUrl; - } - }} - onClick={() => handleImageClick(attachmentUrl)} - decoding="async" - loading="lazy" - /> - ); - } else if (type === "video/*") { - return ( -