"use client"; import { useEffect, useState } from "react"; import { Images, Link2, Loader2, Upload } from "lucide-react"; import Modal from "@/components/Modal"; import { apiMyMedia, type MediaAttachment } from "@/lib/api"; import { isOwnImage, variantURL, widthSrcSet } from "@/lib/responsiveImage"; type InsertTab = "upload" | "url" | "media"; /** * 编辑器插图统一弹窗:上传本地文件 / 图片链接 / 从本人媒体库选择。 * 上传与插入逻辑由父组件处理(需要拿到正文光标),这里只负责选择与展示。 */ export default function ImageInsertModal({ open, onClose, uploading, uploadError, onChooseFile, onDropFile, onInsertUrl, onPickMedia, }: { open: boolean; onClose: () => void; /** 图片上传进行中(来自编辑器,禁用操作并展示进度) */ uploading: boolean; /** 上传失败的提示(也可重试),来自编辑器底部横幅同一状态 */ uploadError: string; /** 打开系统文件选择框(选择后走编辑器上传流程) */ onChooseFile: () => void; /** 拖拽图片到上传区 */ onDropFile: (file: File) => void; /** 链接 tab 提交;校验失败由父组件 toast 并保持弹窗 */ onInsertUrl: (url: string, alt: string) => void; /** 媒体库选中一张图片 */ onPickMedia: (item: MediaAttachment) => void; }) { const [tab, setTab] = useState("upload"); const [url, setUrl] = useState("https://"); const [alt, setAlt] = useState("图片"); const [dragOver, setDragOver] = useState(false); const [media, setMedia] = useState([]); const [mediaLoading, setMediaLoading] = useState(false); const [mediaError, setMediaError] = useState(""); useEffect(() => { if (!open) return; setTab("upload"); setUrl("https://"); setAlt("图片"); setDragOver(false); }, [open]); // 切到「我的图片」时拉取本人媒体库(每次进入都刷新,与上传后可见最新一致) useEffect(() => { if (!open || tab !== "media") return; let cancelled = false; setMediaLoading(true); setMediaError(""); void apiMyMedia() .then((res) => { if (cancelled) return; if (res.error) { setMediaError(res.error); setMedia([]); return; } setMedia((res.attachments || []).filter((item) => item.kind === "image")); }) .catch(() => { if (!cancelled) setMediaError("加载媒体库失败"); }) .finally(() => { if (!cancelled) setMediaLoading(false); }); return () => { cancelled = true; }; }, [open, tab]); const tabs: { key: InsertTab; label: string; icon: React.ReactNode }[] = [ { key: "upload", label: "上传", icon: }, { key: "url", label: "链接", icon: }, { key: "media", label: "我的图片", icon: }, ]; return (
{tabs.map((t) => ( ))}
{tab === "upload" && (
{uploadError && !uploading ? (

{uploadError}

) : null}
)} {tab === "url" && (
)} {tab === "media" && (
{mediaLoading ? (

加载中

) : mediaError ? (

{mediaError}

) : media.length === 0 ? (

媒体库还没有图片。发帖时上传或粘贴图片后,会自动出现在这里。

) : (
{media.map((item) => ( ))}
)}
)}
); }