import { LibraryRootsTable } from "./instances.tsx"; import { NamingSection } from "./naming.tsx"; import { ClassificationSection, OrganizeSourcesSection } from "./organize-sources.tsx"; import { str } from "./resource-section.tsx"; import { SettingsBlock } from "./settings-block.tsx"; import { type CardSpec, SettingsCard, SettingsGate } from "./settings-card.tsx"; // 媒体库与目录:库根(含哨兵状态)+ 默认整理方式 + 刮削 + 命名模板 const ORGANIZE_CARD: CardSpec = { anchor: "organize", title: "整理方式", description: "复制入库时源文件留在缓存继续做种,保留天数在自动化分区设置。", fields: [ { name: "organize.defaultMode", label: "默认整理方式", kind: "select", options: [ { value: "copy", label: "复制(源文件继续做种)" }, { value: "move", label: "移动(移走源文件)" }, ], }, { name: "organize.allowCrossVolumeMove", label: "允许跨卷移动", kind: "switch", hint: "跨卷时按复制 → 核验 → 删源执行", }, ], fromSettings: (s) => ({ "organize.defaultMode": s.organize.defaultMode, "organize.allowCrossVolumeMove": s.organize.allowCrossVolumeMove, }), toPatch: (v) => ({ organize: { defaultMode: str(v["organize.defaultMode"]) as "copy" | "move", allowCrossVolumeMove: v["organize.allowCrossVolumeMove"] === true, }, }), }; // SCR-1 刮削:入库后写 NFO 与图片到媒体库目录(Emby / Jellyfin / Kodi 读取) const SCRAPE_CARD: CardSpec = { anchor: "scrape", title: "刮削", description: "把作品信息写成 NFO,连同海报、背景图放进媒体库目录,Emby、Jellyfin、Kodi 直接读取。", fields: [ { name: "organize.scrapeAfterImport", label: "入库后自动刮削", kind: "switch", hint: "关闭时可在作品详情或文件管理里手动刮削", }, { name: "organize.scrapeMode", label: "已有文件", kind: "select", options: [ { value: "missing", label: "只补缺失" }, { value: "overwrite", label: "全部覆盖" }, ], hint: "全部覆盖会替换目录里已有的 NFO 和图片,包括其他工具写的", }, { name: "organize.scrapeImages", label: "下载图片", kind: "switch", hint: "海报、背景图、季海报", }, { name: "organize.scrapeEpisodeThumbs", label: "下载剧照", kind: "switch", hint: "每集一张,存为「视频名-thumb.jpg」;关闭下载图片时不生效", }, ], fromSettings: (s) => ({ "organize.scrapeAfterImport": s.organize.scrapeAfterImport, "organize.scrapeMode": s.organize.scrapeMode, "organize.scrapeImages": s.organize.scrapeImages, "organize.scrapeEpisodeThumbs": s.organize.scrapeEpisodeThumbs, }), toPatch: (v) => ({ organize: { scrapeAfterImport: v["organize.scrapeAfterImport"] === true, scrapeMode: str(v["organize.scrapeMode"]) === "overwrite" ? "overwrite" : "missing", scrapeImages: v["organize.scrapeImages"] === true, scrapeEpisodeThumbs: v["organize.scrapeEpisodeThumbs"] === true, }, }), }; export function LibrarySection() { return (
{(s) => } {(s) => }
); }