"use client"; import { Images, Loader2 } from "lucide-react"; import { useEffect, useState } from "react"; import Modal from "@/components/Modal"; import { apiMyMedia, type MediaAttachment } from "@/lib/api"; import { isOwnImage, variantURL, widthSrcSet } from "@/lib/responsiveImage"; /** 来源标签映射 */ const SOURCE_LABELS: Record = { library_cover: "书籍封面", library_content: "书籍内容", post: "帖子插图", }; function sourceLabel(source?: string): string { return SOURCE_LABELS[source || "post"] || source || "帖子插图"; } /** 按来源分组(library_cover 优先,其次 library_content,最后 post/其他) */ function groupBySource(items: MediaAttachment[]): [string, MediaAttachment[]][] { const groups = new Map(); for (const item of items) { const key = item.source || "post"; if (!groups.has(key)) groups.set(key, []); groups.get(key)!.push(item); } // 按优先级排序 const order = ["library_cover", "library_content", "post"]; return Array.from(groups.entries()).sort( ([a], [b]) => order.indexOf(a) - order.indexOf(b) ); } /** 书籍封面图库选择弹窗:列出本人媒体库图片,按来源分组 */ export default function LibraryCoverPicker({ open, onClose, onPick, }: { open: boolean; onClose: () => void; onPick: (item: MediaAttachment) => void; }) { const [items, setItems] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(""); useEffect(() => { if (!open) return; let cancelled = false; setLoading(true); setError(""); void apiMyMedia() .then((res) => { if (cancelled) return; if (res.error) { setError(res.error); setItems([]); return; } setItems((res.attachments || []).filter((item) => item.kind === "image")); }) .catch(() => { if (!cancelled) setError("加载媒体库失败"); }) .finally(() => { if (!cancelled) setLoading(false); }); return () => { cancelled = true; }; }, [open]); const groups = groupBySource(items); return ( {loading ? (

加载中

) : error ? (

{error}

) : items.length === 0 ? (

图库还没有图片。上传封面或发帖插图后,会自动出现在这里。

) : (
{groups.map(([source, groupItems]) => (

{sourceLabel(source)} ({groupItems.length})

{groupItems.map((item) => ( ))}
))}
)}
); }