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 (
-
- );
- } else {
- return <>>;
- }
- };
-
- const MediaList = ({ attachments = [] }: { attachments: Attachment[] }) => {
- const cards = attachments.map((attachment) => (
-
-
-
- ));
-
- return {cards}
;
- };
-
- const OtherList = ({ attachments = [] }: { attachments: Attachment[] }) => {
- if (attachments.length === 0) return <>>;
-
- return (
-
- {otherAttachments.map((attachment) => (
-
- ))}
-
- );
- };
-
- return (
- <>
- {mediaAttachments.length > 0 && }
-
-
- setPreviewImage((prev) => ({ ...prev, open }))}
- imgUrls={previewImage.urls}
- initialIndex={previewImage.index}
- />
- >
- );
-};
-
-export default memo(MemoAttachmentListView);
diff --git a/web/src/components/MemoEditor/AttachmentListView.tsx b/web/src/components/MemoEditor/AttachmentListView.tsx
deleted file mode 100644
index 613294912..000000000
--- a/web/src/components/MemoEditor/AttachmentListView.tsx
+++ /dev/null
@@ -1,71 +0,0 @@
-import { DndContext, closestCenter, MouseSensor, TouchSensor, useSensor, useSensors, DragEndEvent } from "@dnd-kit/core";
-import { arrayMove, SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";
-import { FileIcon, XIcon } from "lucide-react";
-import { Attachment } from "@/types/proto/api/v1/attachment_service";
-import { getAttachmentThumbnailUrl, getAttachmentType } from "@/utils/attachment";
-import SortableItem from "./SortableItem";
-
-interface Props {
- attachmentList: Attachment[];
- setAttachmentList: (attachmentList: Attachment[]) => void;
-}
-
-const AttachmentListView = (props: Props) => {
- const { attachmentList, setAttachmentList } = props;
- const sensors = useSensors(useSensor(MouseSensor), useSensor(TouchSensor));
-
- const handleDeleteAttachment = async (name: string) => {
- setAttachmentList(attachmentList.filter((attachment) => attachment.name !== name));
- };
-
- const handleDragEnd = (event: DragEndEvent) => {
- const { active, over } = event;
-
- if (over && active.id !== over.id) {
- const oldIndex = attachmentList.findIndex((attachment) => attachment.name === active.id);
- const newIndex = attachmentList.findIndex((attachment) => attachment.name === over.id);
-
- setAttachmentList(arrayMove(attachmentList, oldIndex, newIndex));
- }
- };
-
- return (
-
- attachment.name)} strategy={verticalListSortingStrategy}>
- {attachmentList.length > 0 && (
-
- {attachmentList.map((attachment) => {
- return (
-
-
- {getAttachmentType(attachment) === "image/*" ? (
-
- ) : (
-
- )}
- {attachment.filename}
-
-
-
- );
- })}
-
- )}
-
-
- );
-};
-
-export default AttachmentListView;
diff --git a/web/src/components/MemoEditor/LocationView.tsx b/web/src/components/MemoEditor/LocationView.tsx
deleted file mode 100644
index 253130b8a..000000000
--- a/web/src/components/MemoEditor/LocationView.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import { MapPinIcon, XIcon } from "lucide-react";
-import { Location } from "@/types/proto/api/v1/memo_service";
-
-interface Props {
- location?: Location;
- onRemove: () => void;
-}
-
-const LocationView = (props: Props) => {
- if (!props.location) {
- return null;
- }
-
- return (
-
-
-
- {props.location.placeholder}
-
-
-
- );
-};
-
-export default LocationView;
diff --git a/web/src/components/MemoEditor/RelationListView.tsx b/web/src/components/MemoEditor/RelationListView.tsx
deleted file mode 100644
index af2dd69d0..000000000
--- a/web/src/components/MemoEditor/RelationListView.tsx
+++ /dev/null
@@ -1,55 +0,0 @@
-import { LinkIcon, XIcon } from "lucide-react";
-import { observer } from "mobx-react-lite";
-import { useEffect, useState } from "react";
-import { memoStore } from "@/store";
-import { Memo, MemoRelation, MemoRelation_Type } from "@/types/proto/api/v1/memo_service";
-
-interface Props {
- relationList: MemoRelation[];
- setRelationList: (relationList: MemoRelation[]) => void;
-}
-
-const RelationListView = observer((props: Props) => {
- const { relationList, setRelationList } = props;
- const [referencingMemoList, setReferencingMemoList] = useState([]);
-
- useEffect(() => {
- (async () => {
- const requests = relationList
- .filter((relation) => relation.type === MemoRelation_Type.REFERENCE)
- .map(async (relation) => {
- return await memoStore.getOrFetchMemoByName(relation.relatedMemo!.name, { skipStore: true });
- });
- const list = await Promise.all(requests);
- setReferencingMemoList(list);
- })();
- }, [relationList]);
-
- const handleDeleteRelation = async (memo: Memo) => {
- setRelationList(relationList.filter((relation) => relation.relatedMemo?.name !== memo.name));
- };
-
- return (
- <>
- {referencingMemoList.length > 0 && (
-
- {referencingMemoList.map((memo) => {
- return (
-
handleDeleteRelation(memo)}
- >
-
- {memo.snippet}
-
-
- );
- })}
-
- )}
- >
- );
-});
-
-export default RelationListView;
diff --git a/web/src/components/MemoLocationView.tsx b/web/src/components/MemoLocationView.tsx
deleted file mode 100644
index e2f39c037..000000000
--- a/web/src/components/MemoLocationView.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import { LatLng } from "leaflet";
-import { MapPinIcon } from "lucide-react";
-import { useState } from "react";
-import { Location } from "@/types/proto/api/v1/memo_service";
-import LeafletMap from "./LeafletMap";
-import { Popover, PopoverContent, PopoverTrigger } from "./ui/popover";
-
-interface Props {
- location: Location;
-}
-
-const MemoLocationView: React.FC = (props: Props) => {
- const { location } = props;
- const [popoverOpen, setPopoverOpen] = useState(false);
-
- return (
-
-
-
-
-
- {location.placeholder ? location.placeholder : `[${location.latitude}, ${location.longitude}]`}
-
-
-
-
-
-
-
-
-
- );
-};
-
-export default MemoLocationView;
diff --git a/web/src/components/MemoRelationListView.tsx b/web/src/components/MemoRelationListView.tsx
deleted file mode 100644
index 7699a1dbc..000000000
--- a/web/src/components/MemoRelationListView.tsx
+++ /dev/null
@@ -1,110 +0,0 @@
-import { LinkIcon, MilestoneIcon } from "lucide-react";
-import { memo, useState } from "react";
-import { Link } from "react-router-dom";
-import { cn } from "@/lib/utils";
-import { extractMemoIdFromName } from "@/store/common";
-import { Memo, MemoRelation } from "@/types/proto/api/v1/memo_service";
-import { useTranslate } from "@/utils/i18n";
-
-interface Props {
- memo: Memo;
- relations: MemoRelation[];
- parentPage?: string;
-}
-
-const MemoRelationListView = (props: Props) => {
- const t = useTranslate();
- const { memo, relations: relationList, parentPage } = props;
- const referencingMemoList = relationList
- .filter((relation) => relation.memo?.name === memo.name && relation.relatedMemo?.name !== memo.name)
- .map((relation) => relation.relatedMemo!);
- const referencedMemoList = relationList
- .filter((relation) => relation.memo?.name !== memo.name && relation.relatedMemo?.name === memo.name)
- .map((relation) => relation.memo!);
- const [selectedTab, setSelectedTab] = useState<"referencing" | "referenced">(
- referencingMemoList.length === 0 ? "referenced" : "referencing",
- );
-
- if (referencingMemoList.length + referencedMemoList.length === 0) {
- return null;
- }
-
- return (
-
-
- {referencingMemoList.length > 0 && (
-
- )}
- {referencedMemoList.length > 0 && (
-
- )}
-
- {selectedTab === "referencing" && referencingMemoList.length > 0 && (
-
- {referencingMemoList.map((memo) => {
- return (
-
-
- {extractMemoIdFromName(memo.name).slice(0, 6)}
-
- {memo.snippet}
-
- );
- })}
-
- )}
- {selectedTab === "referenced" && referencedMemoList.length > 0 && (
-
- {referencedMemoList.map((memo) => {
- return (
-
-
- {extractMemoIdFromName(memo.name).slice(0, 6)}
-
- {memo.snippet}
-
- );
- })}
-
- )}
-
- );
-};
-
-export default memo(MemoRelationListView);