fix: 文件与作品页的低优先级问题(FIX-7)

- 文件列表「主文件」只认视频扩展名(字幕自成资产时位置 is_primary 也为真)
- 行内悬浮操作只在鼠标悬浮时出现,选中行不再常驻遮挡大小/时间
- 种子详情按识别状态说人话,解析结果 JSON 跟随技术信息默认收起
- 作品页空收录版本写「没设收录要求」,版本行写「库里有 N 个版本」

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-09-30 00:00:03 +08:00
1 parent 23bd8cfe45
commit 3c17fa3356
6 files changed
+48 -14

No files matched your search

+5 -8
View File
@@ -515,9 +515,7 @@ export function FileList({
<Cell className="truncate text-right text-caption tabular-nums">{sizeCell(e)}</Cell>
<Cell className="hidden truncate text-caption text-muted-foreground lg:block">{relTime(e.mtime)}</Cell>
<Cell className="relative grid place-items-center">
{onAction && !e.escape ? (
<HoverOps e={e} focused={focused} onAction={onAction} opState={opState} />
) : null}
{onAction && !e.escape ? <HoverOps e={e} onAction={onAction} opState={opState} /> : null}
{menuBtn}
</Cell>
</div>
@@ -561,15 +559,13 @@ export const DRAG_MIME = "application/x-umt-files";
const DESKTOP_COLS =
"grid-cols-[28px_minmax(0,1fr)_120px_5.5rem_32px] lg:grid-cols-[28px_minmax(0,1fr)_120px_5.5rem_6.5rem_32px]";
/** 行内 hover / 聚焦时浮出的 2 个主操作(§5.1),盖在大小/时间列上方 */
/** 行内 hover 时浮出的 2 个主操作(§5.1),盖在大小/时间列上方 */
function HoverOps({
e,
focused,
onAction,
opState,
}: {
e: FileEntry;
focused: boolean;
onAction: (e: FileEntry, op: MenuKey) => void;
opState?: (e: FileEntry, op: MenuKey) => string | null;
}) {
@@ -577,9 +573,10 @@ function HoverOps({
return (
<span
className={cn(
"pointer-events-none absolute top-1/2 right-9 flex -translate-y-1/2 items-center gap-1 rounded-full bg-background/95 py-0.5 pl-1 opacity-0 shadow-sm ring-1 ring-border backdrop-blur transition-opacity duration-micro",
// 只在鼠标悬浮时盖在大小/时间列上;选中/键盘聚焦的行不常驻(否则大小和时间一直被挡),
// 键盘操作走右键菜单与快捷键。
"pointer-events-none absolute top-1/2 right-9 flex -translate-y-1/2 items-center gap-1 rounded-full bg-background/95 py-0.5 pl-1 opacity-0 backdrop-blur shadow-sm ring-1 ring-border transition-opacity duration-micro",
"group-hover/row:pointer-events-auto group-hover/row:opacity-100",
focused && "pointer-events-auto opacity-100",
)}
>
{ops.map((op) => {
+3 -1
View File
@@ -254,7 +254,9 @@ export function EpisodeVersionList({
v={lead}
aside={
versions.length > 1 ? (
<span className="text-meta whitespace-nowrap text-muted-foreground">{versions.length} 个版本</span>
<span className="text-meta whitespace-nowrap text-muted-foreground">
库里有 {versions.length} 个版本
</span>
) : null
}
/>
@@ -13,6 +13,7 @@ import { KvList } from "~/components/console/kv-list.tsx";
import { StatusBadge } from "~/components/console/status-badge.tsx";
import { Button } from "~/components/ui/button.tsx";
import { errorMessage } from "~/lib/api.ts";
import { useUiPrefs } from "~/lib/ui-prefs.ts";
import { formatBytes, formatDateTime } from "~/lib/utils.ts";
import { DownloadDialog } from "./download-dialog.tsx";
import { absTime, categoryLabel, countText, ORIGIN_LABEL, relTime, snatchedOf } from "./release-fields.ts";
@@ -28,13 +29,21 @@ const DECISION_LABEL = {
deferred: { label: "延后:已有计划在途", tone: "warning" },
} as const;
/** 没关联作品时按识别状态说一句(原码不上屏) */
const UNLINKED_TEXT: Record<string, string> = {
unresolved: "还没识别作品。",
ambiguous: "有多个可能的作品,没有自动关联。",
unidentifiable: "没识别出作品。",
rejected: "识别结果已被排除。",
};
/** 本地库存 + 候选理由(来自作品详情:Slot / CandidateEvaluation),不从标题猜 */
function LocalInventory({ release, entry }: { release: WorkbenchRelease; entry: InventoryEntry | undefined }) {
const detail = useEntityDetail(release.entity?.id);
if (!release.entity) {
return (
<p className="text-caption text-muted-foreground">
未关联本地作品({release.resolutionStatus})。
{UNLINKED_TEXT[release.resolutionStatus] ?? "未关联本地作品。"}
<Link to="/console/identity" className="ml-1 underline underline-offset-4">
去指定作品
</Link>
@@ -123,6 +132,7 @@ export function ReleaseDetailSheet({
const refresh = useRefreshReleaseDetail();
const entity = useEntityDetail(release?.entity?.id);
const [dl, setDl] = useState(false);
const techOpen = useUiPrefs().techInfoExpanded;
const r = detail.data?.release ?? release;
// 按需抓详情页:打开抽屉时没有缓存的详情页扩展内容就抓一次(服务端缓存 24 小时,同一资源本次会话只自动抓一次)
@@ -296,7 +306,8 @@ export function ReleaseDetailSheet({
</DetailSection>
) : null}
<JsonView label="解析结果" value={r.parsed} />
{/* 原始解析 JSON 属于技术信息:默认收起,跟随设置 → 界面「技术信息默认展开」 */}
<JsonView label="解析结果" value={r.parsed} defaultOpen={techOpen} />
</>
)}
{r ? <DownloadDialog release={r} slots={entity.data?.slots ?? []} open={dl} onOpenChange={setDl} /> : null}