feat(queue): add Timeline display mode (#1004)

* feat(queue): add Timeline display mode

A third queue display mode alongside Queue and Playlist. Timeline shows
the full queue anchored on the current track — played history above
(dimmed), upcoming below — with 'History' and 'Up next' dividers and the
current row auto-centered. It already follows shuffle order since the
queue is stored in play order. The header mode button now cycles
queue → timeline → playlist; Settings gains a third option.

* i18n(queue): Timeline mode strings (9 locales)

* docs(changelog): note Timeline queue mode (#1004)
This commit is contained in:
Frank Stellmacher
2026-06-05 16:19:20 +02:00
committed by GitHub
parent 41157ccaca
commit 1c23305887
25 changed files with 113 additions and 19 deletions
+5 -5
View File
@@ -156,16 +156,16 @@ describe('QueuePanel — display mode', () => {
expect(container.textContent).toContain('No upcoming tracks');
});
it('header mode-toggle button flips queueDisplayMode (default queue → playlist)', () => {
it('header mode-toggle button advances queueDisplayMode (default queue → timeline)', () => {
seedQueue(makeTracks(3), { index: 0, currentTrack: makeTrack() });
const { container } = renderWithProviders(<QueuePanel />);
// The mode toggle is the first .queue-action-btn in the header (the
// collapse chevron is the second). The default mode is 'queue', so the
// toggle's label names its target ("Playlist").
// collapse chevron is the second). The toggle's label names its target;
// from the default 'queue' that is the next mode in the cycle, "Timeline".
const toggle = container.querySelector<HTMLButtonElement>('.queue-header .queue-action-btn');
expect(toggle?.getAttribute('aria-label')).toBe('Playlist');
expect(toggle?.getAttribute('aria-label')).toBe('Timeline');
toggle!.click();
expect(useAuthStore.getState().queueDisplayMode).toBe('playlist');
expect(useAuthStore.getState().queueDisplayMode).toBe('timeline');
});
});