feat(web): top-bar centered nav + Library tab page (replace sidebar)
test-web / test (push) Successful in 32s
test-web / test (push) Successful in 32s
Operator 2026-06-01: "navigation layout and library sections are
what I'd like to have implemented as it seems better than our
current navbar solution. I think I'd like to have these nav options
moved into the top bar centered."
Top-bar restructure:
- Centered nav (replaces the 192dp left sidebar): Home / Library /
Discover, with icons + labels. Labels collapse below sm breakpoint
so the bar stays icon-only on small viewports.
- Right side (search input + user dropdown) unchanged.
- Hamburger button + MobileNavDrawer + the mobileNav store all
removed - the centered nav lives at all viewport sizes.
Library page restructure (mirrors Android LibraryScreen):
- New routes/library/+layout.svelte renders a tab bar across the
five Library sub-pages: Artists / Albums / Liked / History /
Playlists. Active tab gets an accent underline + onSurface text.
- routes/library/+page.server.ts redirects bare /library to
/library/artists (Android default tab).
- /playlists (list) moved to /library/playlists; old URL gets a 308
redirect (routes/playlists/+page.server.ts) so existing bookmarks
land on the new location. /playlists/[id] (detail) is unchanged -
matches the server API URL shape.
Deleted: Shell's sidebar markup, MobileNavDrawer.{svelte,test.ts},
the mobileNav store, the old routes/playlists/+page.svelte. Shell
test rewritten to assert the new 3-item centered nav; playlists
test moved next to its new +page.svelte and its test-utils import
path updated.
This commit is contained in:
@@ -39,30 +39,35 @@ describe('Shell', () => {
|
||||
expect(screen.getByText('alice')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('main nav renders the six primary surfaces in order', () => {
|
||||
test('main nav renders the three primary surfaces in order', () => {
|
||||
render(Shell);
|
||||
const labels = ['Home', 'Artists', 'Albums', 'Liked', 'Discover', 'Playlists'];
|
||||
// Library is a parent for Artists / Albums / Liked / History /
|
||||
// Playlists (tabs under /library); only the parent appears here.
|
||||
const labels = ['Home', 'Library', 'Discover'];
|
||||
for (const label of labels) {
|
||||
expect(screen.getByRole('link', { name: label })).toBeInTheDocument();
|
||||
}
|
||||
expect(screen.getByRole('link', { name: 'Home' })).toHaveAttribute('href', '/');
|
||||
expect(screen.getByRole('link', { name: 'Artists' })).toHaveAttribute('href', '/library/artists');
|
||||
expect(screen.getByRole('link', { name: 'Albums' })).toHaveAttribute('href', '/library/albums');
|
||||
expect(screen.getByRole('link', { name: 'Library' })).toHaveAttribute('href', '/library');
|
||||
expect(screen.getByRole('link', { name: 'Discover' })).toHaveAttribute('href', '/discover');
|
||||
expect(screen.getByRole('link', { name: 'Playlists' })).toHaveAttribute('href', '/playlists');
|
||||
});
|
||||
|
||||
test('main nav omits Search, Requests, Hidden, Settings, and Admin', () => {
|
||||
test('main nav omits Artists/Albums/Liked/History/Playlists/Search/Settings/Admin', () => {
|
||||
userState.current = { id: '1', username: 'alice', is_admin: true };
|
||||
render(Shell);
|
||||
// Search reaches /search via the global SearchInput, Requests is a
|
||||
// tab inside Discover, Hidden lives under Settings, Settings + Admin
|
||||
// live in the username dropdown — none belong on the main nav.
|
||||
// Library sub-pages reach their content via the /library tab bar
|
||||
// (in routes/library/+layout.svelte), not via the global Shell nav.
|
||||
// Search reaches /search via the global SearchInput on the right.
|
||||
// Settings + Admin live in the username dropdown — they're per-
|
||||
// operator chrome, not primary surfaces.
|
||||
const navLinks = screen
|
||||
.getAllByRole('link')
|
||||
.filter((el) => el.closest('nav') !== null)
|
||||
.filter((el) => el.closest('nav[aria-label="Primary"]') !== null)
|
||||
.map((el) => el.textContent?.trim());
|
||||
for (const label of ['Search', 'Requests', 'Hidden', 'Settings', 'Admin']) {
|
||||
for (const label of [
|
||||
'Artists', 'Albums', 'Liked', 'History', 'Playlists',
|
||||
'Search', 'Requests', 'Hidden', 'Settings', 'Admin'
|
||||
]) {
|
||||
expect(navLinks).not.toContain(label);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user