release: publish Multi-Debrid Downloader v2.0.14
Add live English and German localization, queue availability and metadata resolution, responsive package controls, polished navigation and drag interactions, clearer history and account states, and a rebuilt public README. Harden Windows packaging with verified icons and version metadata, archive inspection, and expanded release tests.
This commit is contained in:
+47
-11
@@ -14,8 +14,9 @@ import {
|
||||
type HistoryViewEntry
|
||||
} from "../src/renderer/views/history/history-model";
|
||||
import {
|
||||
HistoryContent,
|
||||
HistoryToolbar,
|
||||
HistoryContent,
|
||||
HistorySidebar,
|
||||
HistoryToolbar,
|
||||
HistoryView,
|
||||
type HistoryViewActions
|
||||
} from "../src/renderer/views/history/HistoryView";
|
||||
@@ -203,8 +204,17 @@ describe("history model", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("HistoryView", () => {
|
||||
it("keeps the header and rows inside the same internal horizontal scroll context", () => {
|
||||
describe("HistoryView", () => {
|
||||
it("marks history filters for one measured vertical selection indicator", () => {
|
||||
const model = buildHistoryViewModel(entries, "week", "", [], [], false, "", now);
|
||||
const html = renderToStaticMarkup(<HistorySidebar actions={createActions()} model={model} />);
|
||||
|
||||
expect(html).toContain("ui-sliding-selection ui-sliding-selection-vertical");
|
||||
expect(html.match(/data-sliding-selection-item="true"/g)).toHaveLength(7);
|
||||
expect(html.match(/data-sliding-selection-active="true"/g)).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("keeps the header and rows inside the same internal horizontal scroll context", () => {
|
||||
const html = renderToStaticMarkup(
|
||||
<HistoryView
|
||||
actions={createActions()}
|
||||
@@ -273,11 +283,25 @@ describe("HistoryView", () => {
|
||||
expect(html).toContain("history-status-failed");
|
||||
expect(html).toContain("Abgeschlossen");
|
||||
expect(html).toContain("Gelöscht");
|
||||
expect(html).toContain("Fehlgeschlagen");
|
||||
expect(html).not.toMatch(/>Start<|>Pause<|>Stop<|Priorität/);
|
||||
});
|
||||
|
||||
it("renders each visual marker once, occupied main rows separately from closed detail rows and an honest footer", () => {
|
||||
expect(html).toContain("Fehlgeschlagen");
|
||||
expect(html).not.toMatch(/>Start<|>Pause<|>Stop<|Priorität/);
|
||||
});
|
||||
|
||||
it("matches the download action control and centers every header except package and file", () => {
|
||||
const content = HistoryContent({
|
||||
actions: createActions(),
|
||||
model: buildHistoryViewModel(entries.slice(0, 1), "all", "", [], [], false, "", now)
|
||||
});
|
||||
const actionCell = findElement(content, (element) => element.props.className === "history-row-action");
|
||||
const styles = readFileSync(new URL("../src/renderer/views/history/history.css", import.meta.url), "utf8").replaceAll("\r\n", "\n");
|
||||
|
||||
expect(actionCell.props.children.props.children).toBe("⋮");
|
||||
expect(styles).toMatch(/\.history-row-action button\s*\{[^}]*background:\s*var\(--ui-input\);[^}]*border:\s*1px solid var\(--ui-border\);[^}]*height:\s*30px;[^}]*width:\s*30px;/s);
|
||||
expect(styles).toMatch(/\.history-table-header-row > span\s*\{[^}]*text-align:\s*center;/s);
|
||||
expect(styles).toMatch(/\.history-table-header-row > span:nth-child\(2\)\s*\{[^}]*text-align:\s*left;/s);
|
||||
});
|
||||
|
||||
it("renders each visual marker once, occupied main rows separately from closed detail rows and an honest footer", () => {
|
||||
const html = renderToStaticMarkup(
|
||||
<HistoryView
|
||||
actions={createActions()}
|
||||
@@ -392,8 +416,20 @@ describe("HistoryView", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("visual history states", () => {
|
||||
it("re-arms the real App mounted gate before every StrictMode lifecycle setup can start async work", () => {
|
||||
describe("visual history states", () => {
|
||||
it("keeps the selected category visible immediately while only its geometry glides", () => {
|
||||
const styles = readFileSync(new URL("../src/renderer/styles.css", import.meta.url), "utf8").replaceAll("\r\n", "\n");
|
||||
const selection = readFileSync(new URL("../src/renderer/ui/SlidingSelection.tsx", import.meta.url), "utf8").replaceAll("\r\n", "\n");
|
||||
const selectionStyles = styles.slice(styles.indexOf(".ui-sliding-selection"), styles.indexOf("html,"));
|
||||
|
||||
expect(selectionStyles).toMatch(/\.ui-sliding-selection::before\s*\{[^}]*opacity:\s*1;/s);
|
||||
expect(selectionStyles).not.toContain(".ui-sliding-selection.has-sliding-selection::before");
|
||||
expect(selectionStyles).not.toMatch(/transition(?:-property)?:[^;]*opacity/);
|
||||
expect(selection).not.toContain("classList.add(\"has-sliding-selection\")");
|
||||
expect(selection).not.toContain("classList.remove(\"has-sliding-selection\")");
|
||||
});
|
||||
|
||||
it("re-arms the real App mounted gate before every StrictMode lifecycle setup can start async work", () => {
|
||||
const source = readFileSync(new URL("../src/renderer/App.tsx", import.meta.url), "utf8").replaceAll("\r\n", "\n");
|
||||
const firstRequest = source.indexOf("window.rd.getVersion()");
|
||||
const effectStart = source.lastIndexOf("useEffect(() => {", firstRequest);
|
||||
|
||||
Reference in New Issue
Block a user