This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
- Keep queue-card titles and content aligned when expanding or collapsing details by reserving scrollbar space.
|
||||||
- Move the queue-card remove button slightly toward the top-right corner while retaining its 32-pixel click target.
|
- Move the queue-card remove button slightly toward the top-right corner while retaining its 32-pixel click target.
|
||||||
- Show a yellow left border on waiting queue cards, matching their status dot.
|
- Show a yellow left border on waiting queue cards, matching their status dot.
|
||||||
- Place the queue-card date on the left beside the details arrow and the download status on the right below the progress bar.
|
- Place the queue-card date on the left beside the details arrow and the download status on the right below the progress bar.
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ Aktueller veröffentlichter Stand: **1.0.20**, Tag `v1.0.20`, veröffentlicht am
|
|||||||
|
|
||||||
## Letzte Änderungen
|
## Letzte Änderungen
|
||||||
|
|
||||||
|
- Titelsprung beim Auf-/Zuklappen der Queue-Cards behoben: `scrollbar-gutter: stable` reserviert den 8-px-Platz der Scrollleiste, damit sich Kartenbreite und Titelumbruch nicht ändern. In Tab- und Split-Ansicht nachgemessen. Neuer Queue-UI-Regressionscheck überschreitet beim Öffnen gezielt die Scrollgrenze und prüft die Titelgeometrie während beider Animationen in Hell/Dunkel und Deutsch/Englisch; Hintergrund-Synchronisierung wird nach dem Fixture-Abgleich für diese deterministische Messung angehalten. Vor dem Fix fehlgeschlagen, danach erfolgreich. Build, 19 gezielte Tests und Lint erfolgreich (15 bestehende Warnungen). Noch nicht veröffentlicht.
|
||||||
- Löschen-Button in Queue-Cards um jeweils 3 px nach oben und rechts verschoben; Klickfläche bleibt 32 × 32 px. Build, fünf Stylesheet-Tests und isolierter Queue-UI-Test erfolgreich; Hell/Dunkel visuell geprüft. Noch nicht veröffentlicht.
|
- Löschen-Button in Queue-Cards um jeweils 3 px nach oben und rechts verschoben; Klickfläche bleibt 32 × 32 px. Build, fünf Stylesheet-Tests und isolierter Queue-UI-Test erfolgreich; Hell/Dunkel visuell geprüft. Noch nicht veröffentlicht.
|
||||||
- Wartende Queue-Cards haben jetzt eine gelbe linke Statuslinie passend zum Wartepunkt. Der Wartet-Text bleibt ohne Umrandung oder gelblichen Hintergrund. Build, fünf Stylesheet-Tests und isolierter Queue-UI-Test erfolgreich; Linie in Hell/Dunkel visuell geprüft. Noch nicht veröffentlicht.
|
- Wartende Queue-Cards haben jetzt eine gelbe linke Statuslinie passend zum Wartepunkt. Der Wartet-Text bleibt ohne Umrandung oder gelblichen Hintergrund. Build, fünf Stylesheet-Tests und isolierter Queue-UI-Test erfolgreich; Linie in Hell/Dunkel visuell geprüft. Noch nicht veröffentlicht.
|
||||||
- Nach Release 1.0.20: Datum und Status in der Queue-Card getauscht. Datum steht jetzt links neben dem Detailpfeil, Status rechts unter dem Fortschrittsbalken. Schriftgrößen, gelber Wartepunkt und Aufklappanimation bleiben erhalten. Build, 19 gezielte Tests, Queue-UI-Test in Deutsch/Englisch und Hell/Dunkel sowie vollständiger Workspace-UI-Test erfolgreich; Lint ohne Fehler bei 15 bestehenden Warnungen. Änderung zunächst nur auf `public-v1`/Hot-Dev, noch nicht veröffentlicht.
|
- Nach Release 1.0.20: Datum und Status in der Queue-Card getauscht. Datum steht jetzt links neben dem Detailpfeil, Status rechts unter dem Fortschrittsbalken. Schriftgrößen, gelber Wartepunkt und Aufklappanimation bleiben erhalten. Build, 19 gezielte Tests, Queue-UI-Test in Deutsch/Englisch und Hell/Dunkel sowie vollständiger Workspace-UI-Test erfolgreich; Lint ohne Fehler bei 15 bestehenden Warnungen. Änderung zunächst nur auf `public-v1`/Hot-Dev, noch nicht veröffentlicht.
|
||||||
|
|||||||
@@ -38,7 +38,11 @@ async function main() {
|
|||||||
ipcMain.removeHandler('get-queue');
|
ipcMain.removeHandler('get-queue');
|
||||||
ipcMain.handle('get-queue', async () => items);
|
ipcMain.handle('get-queue', async () => items);
|
||||||
}, fixtures);
|
}, fixtures);
|
||||||
await win.evaluate(() => syncQueueAndDownloadState());
|
await win.evaluate(async () => {
|
||||||
|
await syncQueueAndDownloadState();
|
||||||
|
clearTimeout(queueSyncTimer);
|
||||||
|
queueSyncTimer = null;
|
||||||
|
});
|
||||||
assert.equal(await win.locator('#queueList .queue-item').count(), fixtures.length, 'Queue fixtures survive background synchronization');
|
assert.equal(await win.locator('#queueList .queue-item').count(), fixtures.length, 'Queue fixtures survive background synchronization');
|
||||||
for (const theme of ['twitch', 'light']) {
|
for (const theme of ['twitch', 'light']) {
|
||||||
for (const language of ['de', 'en']) {
|
for (const language of ['de', 'en']) {
|
||||||
@@ -71,6 +75,48 @@ async function main() {
|
|||||||
assert(card.overflow <= 1, `Card overflow: ${JSON.stringify(card)}`);
|
assert(card.overflow <= 1, `Card overflow: ${JSON.stringify(card)}`);
|
||||||
}
|
}
|
||||||
await win.locator('.queue-section').screenshot({ path: path.join(artifacts, `queue-${theme}-${language}.png`) });
|
await win.locator('.queue-section').screenshot({ path: path.join(artifacts, `queue-${theme}-${language}.png`) });
|
||||||
|
const expansionLayout = await win.locator('#queueList').evaluate(async (list) => {
|
||||||
|
const items = [...list.querySelectorAll('.queue-item')];
|
||||||
|
const originalStyles = [list, ...items].map((element) => element.getAttribute('style'));
|
||||||
|
const item = items[0];
|
||||||
|
const details = item.querySelector('.queue-details');
|
||||||
|
const frame = () => new Promise((resolve) => requestAnimationFrame(resolve));
|
||||||
|
const measure = () => {
|
||||||
|
const title = item.querySelector('.title').getBoundingClientRect();
|
||||||
|
return { left: title.left, width: title.width, height: title.height, overflowing: list.scrollHeight > list.clientHeight };
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
for (const other of items.slice(2)) other.style.display = 'none';
|
||||||
|
list.style.flex = '0 0 auto';
|
||||||
|
list.style.height = `${items.slice(0, 2).reduce((height, card) => height + card.getBoundingClientRect().height + parseFloat(getComputedStyle(card).marginBottom), 0) + 20}px`;
|
||||||
|
const before = measure();
|
||||||
|
const samples = [];
|
||||||
|
const animate = async () => {
|
||||||
|
toggleQueueDetails(item.dataset.id);
|
||||||
|
await frame();
|
||||||
|
await frame();
|
||||||
|
do {
|
||||||
|
samples.push(measure());
|
||||||
|
await frame();
|
||||||
|
} while (details.getAnimations().length);
|
||||||
|
return measure();
|
||||||
|
};
|
||||||
|
const expanded = await animate();
|
||||||
|
const collapsed = await animate();
|
||||||
|
return { before, expanded, collapsed, samples };
|
||||||
|
} finally {
|
||||||
|
[list, ...items].forEach((element, index) => {
|
||||||
|
if (originalStyles[index] === null) element.removeAttribute('style');
|
||||||
|
else element.setAttribute('style', originalStyles[index]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
assert(!expansionLayout.before.overflowing && expansionLayout.expanded.overflowing && !expansionLayout.collapsed.overflowing, `Expansion fixture crosses the scrollbar threshold (${theme}/${language}): ${JSON.stringify({ before: expansionLayout.before, expanded: expansionLayout.expanded, collapsed: expansionLayout.collapsed })}`);
|
||||||
|
for (const sample of [...expansionLayout.samples, expansionLayout.expanded, expansionLayout.collapsed]) {
|
||||||
|
for (const dimension of ['left', 'width', 'height']) {
|
||||||
|
assert(Math.abs(sample[dimension] - expansionLayout.before[dimension]) <= 0.5, `Title ${dimension} shifts during expansion (${theme}/${language})`);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const card = win.locator('.queue-item[data-id="pending"]');
|
const card = win.locator('.queue-item[data-id="pending"]');
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ describe('production style modules', () => {
|
|||||||
.replace(/\r\n/g, '\n'));
|
.replace(/\r\n/g, '\n'));
|
||||||
const digest = createHash('sha256').update(content).digest('hex');
|
const digest = createHash('sha256').update(content).digest('hex');
|
||||||
|
|
||||||
expect(digest).toBe('db798e79ce538bd99fe6a21fa9de545150a2d0efd4a925e6f662a664bdb6ff03');
|
expect(digest).toBe('a2626a94632641b7e6039d5a50165e34224a75a1d286db90ae9e22bdae72064e');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('derives the Windows hot-development executable version from package metadata', () => {
|
test('derives the Windows hot-development executable version from package metadata', () => {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
.queue-list {
|
.queue-list {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
scrollbar-gutter: stable;
|
||||||
min-height: 60px;
|
min-height: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user