Files
UHD_Media_Tool/apps/web/app/components/settings/sections.tsx
T
rootandClaude Opus 5.5 8071ad33f9 feat(web): 设置页按新分类重排,加搜索、缓存分区与旧锚点跳转
- 左栏三组分区 + 当前分区的节;窄屏为搜索框、分组下拉和节的横排胶囊
- 搜索框按分区、节、节别名和字段名定位,选中字段时滚到该字段并聚焦
- 旧 hash(#automation/cache、#api-keys、#library/scrape 等)replace 到新位置
- 下载器分区放下载盘水位与保种缺省值,名字与实例抽屉统一(暂停线 / 恢复线 / 保种天数)
- 新增获取、整理与刮削、系统、缓存分区;API Key 并入账户与安全,快捷键移到界面
- 补上缺的入口:最小视频体积、子会话并发与层数、搜索站点;日志保留天数(已废弃)不再显示
- 缓存分区按区列出条数、占用、最近写入,单区清空二次确认;TMDB 与图片缓存并入
- 保存提示统一为「已保存「节名」」;按入库口径把相关文案改成「整理」

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
2026-10-06 18:01:26 +08:00

74 lines
2.8 KiB
TypeScript

import {
resolveSettingsHash,
SETTINGS_GROUPS,
SETTINGS_SECTIONS,
type SettingsSectionDef,
type SettingsSectionId,
} from "@umt/contracts";
import {
Bot,
Database,
Download,
FolderTree,
Globe,
type LucideIcon,
Monitor,
Search,
Settings2,
Shield,
Tags,
Tv,
Wand2,
} from "lucide-react";
import type { ReactNode } from "react";
import { AccountSection } from "./account.tsx";
import { AcquireSection } from "./acquire.tsx";
import { AgentSection } from "./agent.tsx";
import { CacheSection } from "./cache.tsx";
import { DownloadersSection } from "./downloaders.tsx";
import { MediaServersSection } from "./instances.tsx";
import { InterfaceSection } from "./interface.tsx";
import { LibrarySection } from "./library.tsx";
import { MetadataSection } from "./metadata.tsx";
import { OrganizeSection } from "./organize.tsx";
import { SitesSection } from "./sites.tsx";
import { SystemSection } from "./system.tsx";
// 设置分区:文案、分组与字段归属在 contracts 的 SETTINGS_SECTIONS,这里只挂图标与渲染
const UI: Record<SettingsSectionId, { icon: LucideIcon; render: () => ReactNode }> = {
downloaders: { icon: Download, render: () => <DownloadersSection /> },
"media-servers": { icon: Tv, render: () => <MediaServersSection /> },
sites: { icon: Globe, render: () => <SitesSection /> },
metadata: { icon: Tags, render: () => <MetadataSection /> },
acquire: { icon: Search, render: () => <AcquireSection /> },
library: { icon: FolderTree, render: () => <LibrarySection /> },
organize: { icon: Wand2, render: () => <OrganizeSection /> },
agent: { icon: Bot, render: () => <AgentSection /> },
system: { icon: Settings2, render: () => <SystemSection /> },
cache: { icon: Database, render: () => <CacheSection /> },
account: { icon: Shield, render: () => <AccountSection /> },
interface: { icon: Monitor, render: () => <InterfaceSection /> },
};
export type SectionView = SettingsSectionDef & { icon: LucideIcon; render: () => ReactNode };
export const SECTIONS: SectionView[] = SETTINGS_SECTIONS.map((s) => ({ ...s, ...UI[s.id] }));
/** 左栏分组:接入 / 流程 / 系统 */
export const SECTION_GROUPS = SETTINGS_GROUPS.map((g) => ({
...g,
sections: SECTIONS.filter((s) => s.group === g.id),
}));
/**
* URL hash:`#<分区>` 或 `#<分区>/<节>`;旧 hash 换成新位置(moved = true 时页面用 replace 改地址栏),
* 不认识的落到第一个分区
*/
export function parseSettingsHash(hash: string): { section: SectionView; anchor: string | null; moved: boolean } {
const r = resolveSettingsHash(hash);
const section = SECTIONS.find((s) => s.id === r.section) ?? (SECTIONS[0] as SectionView);
return { section, anchor: r.section ? r.anchor : null, moved: r.moved };
}
export const settingsHash = (section: string, anchor?: string | null) => `#${section}${anchor ? `/${anchor}` : ""}`;