feat(web): merge search filters into one row and tidy episode versions (POLISH-1)
- H&R becomes a quick-filter facet (yes/no/unknown, with counts) on search results and the site resources tab; drop the old free/H&R selects, keep size range and sort on the same row (mobile: drawer), single clear button - legacy free/hr URL params migrate into quick filters; stored selections keep the same localStorage key - search timing and query terms move into TechInfo - library episode versions: click the whole row to expand, versions listed as sibling rows, details only under the selected version, raw values in TechInfo - slot comparison gaps get reason codes (matchGapText in contracts reasons.ts): "可换成 2160p", "缺 HDR 版本" Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
12bc4664b6
commit
71b129d85a
19 files changed
+668
-290
No files matched your search
@@ -145,6 +145,7 @@ describe("与版本目标比对", () => {
|
||||
state: "missing",
|
||||
assetId: null,
|
||||
reasons: [],
|
||||
codes: [],
|
||||
});
|
||||
});
|
||||
|
||||
@@ -158,12 +159,29 @@ describe("与版本目标比对", () => {
|
||||
expect(m.state).toBe("upgradeable");
|
||||
expect(m.assetId).toBe("bd");
|
||||
expect(m.reasons.join(" ")).toMatch(/1080p/);
|
||||
expect(m.codes).toEqual(["version_resolution:2160p"]);
|
||||
});
|
||||
|
||||
it("差距原因码:HDR / 字幕 / 来源带目标参数", () => {
|
||||
const hdr: SlotSpec = { id: "h", name: "h", hard: { hdr: { anyOf: ["DV", "HDR10"] } } };
|
||||
expect(matchVersions(hdr, [v("bd", BD_FILE)], { isEpisode: true }).codes).toEqual(["version_hdr"]);
|
||||
const dvOnly: SlotSpec = { id: "d", name: "d", hard: { hdr: { anyOf: ["DV"] } } };
|
||||
expect(matchVersions(dvOnly, [v("bd", BD_FILE)], { isEpisode: true }).codes).toEqual(["version_hdr:DV"]);
|
||||
const remux: SlotSpec = { id: "r", name: "r", hard: { sources: ["REMUX", "BluRay-Disc"] } };
|
||||
expect(matchVersions(remux, [v("dv", DV_FILE, PROBE_DV)], { isEpisode: true }).codes).toEqual([
|
||||
"version_source:REMUX",
|
||||
]);
|
||||
});
|
||||
|
||||
it("达标但升级策略还有余量 = upgradeable;到顶 = satisfied", () => {
|
||||
const up: SlotSpec = { id: "s", name: "x", hard: {}, upgrade: { enabled: true } };
|
||||
const web = matchVersions(up, [v("dv", DV_FILE, PROBE_DV)], { isEpisode: true });
|
||||
expect(web).toMatchObject({ state: "upgradeable", assetId: "dv", reasons: ["来源还能升级"] });
|
||||
expect(web).toMatchObject({
|
||||
state: "upgradeable",
|
||||
assetId: "dv",
|
||||
reasons: ["来源还能升级"],
|
||||
codes: ["version_source_upgrade"],
|
||||
});
|
||||
const capped: SlotSpec = { ...up, upgrade: { enabled: true, ceilingTier: 2 } };
|
||||
expect(matchVersions(capped, [v("dv", DV_FILE, PROBE_DV)], { isEpisode: true }).state).toBe("satisfied");
|
||||
const onlyWeb: SlotSpec = { ...up, hard: { sources: ["WEB-DL"] } };
|
||||
|
||||
Reference in new issue
Block a user