From 43d78a731a349bf125118e8ccb63ab7a4abe7e26 Mon Sep 17 00:00:00 2001 From: Logan Date: Wed, 19 Aug 2026 19:33:44 -0400 Subject: [PATCH] feat(shell): draw only the destinations the user kept The navigation reads the resolved map from the backend rather than holding a copy of the defaults, which would be the copy that shipped in the binary rather than the one being edited. Hiding takes away the nav item and nothing else: `navigate` still resolves a hidden view, which detail views and the launch page depend on. No special case was needed for the highlight, because #72 moved that onto `active-view-store` -- the sidebar asks `isActive(id)` per *rendered* item, so a hidden view lights nothing exactly as a detail view does. Downloads is gated at the nav on `downloadStore.available` rather than in the config, so switching it on in Settings still means what it says once a client exists, and the tab appears without a restart. `available` is false until the providers have loaded, which makes the item appear on a fresh launch rather than appearing and then vanishing. The tab bar honours the toggles too, and the reason is local rather than a general rule about phones: "More" opens the *same* ``, which filters, so an unfiltered bar would contradict its own drawer one tap away. Which four tabs is still plan 016's subset; this only removes from it, and "More" is never filtered. `services/view-meta.ts` is the destination list, on `shortcut-meta.ts`'s pattern, because Settings is now a second reader of the same labels in the same order. Two existing sidebar tests had to say which world they describe: eleven destinations now assumes a configured download client. --- .../src/components/bottom-nav/bottom-nav.ts | 21 +- .../src/components/config-page/config-page.ts | 105 ++++++++++ .../src/components/sidebar/app-sidebar.ts | 42 ++-- frontend/src/services/view-meta.ts | 66 ++++++ .../controllers/view-visibility-controller.ts | 54 +++++ frontend/src/store/download-store.ts | 21 ++ frontend/src/store/view-visibility-store.ts | 119 +++++++++++ frontend/test/components/chrome.test.ts | 19 ++ .../test/components/keyboard-reach.test.ts | 13 +- .../test/components/view-visibility.test.ts | 191 ++++++++++++++++++ 10 files changed, 622 insertions(+), 29 deletions(-) create mode 100644 frontend/src/services/view-meta.ts create mode 100644 frontend/src/store/controllers/view-visibility-controller.ts create mode 100644 frontend/src/store/view-visibility-store.ts create mode 100644 frontend/test/components/view-visibility.test.ts diff --git a/frontend/src/components/bottom-nav/bottom-nav.ts b/frontend/src/components/bottom-nav/bottom-nav.ts index 24f6d7c..c029664 100644 --- a/frontend/src/components/bottom-nav/bottom-nav.ts +++ b/frontend/src/components/bottom-nav/bottom-nav.ts @@ -8,6 +8,7 @@ import '../sidebar/app-sidebar.js'; import { nameDialog } from '@utils/name-dialog'; import { ICON_PLAYLIST } from '@utils/icon-language'; import { ActiveViewController } from '@store/controllers/active-view-controller'; +import { ViewVisibilityController } from '@store/controllers/view-visibility-controller'; type View = 'home' | 'albums' | 'tracks' | 'playlists'; @@ -129,6 +130,22 @@ export class BottomNav extends LitElement { */ private activeCtrl = new ActiveViewController(this); + /** + * The tab bar honours the sidebar's toggles (#25), and the reason is + * inside this component rather than a general rule about phones. + * `PHONE_COLUMN_IDS` is the precedent for "what a phone shows is a + * different question", and it would apply here too -- except that + * "More" opens the *same* ``, which filters. An + * unfiltered bar would therefore contradict its own drawer, one tap + * apart, and a destination the user switched off is off wherever it + * is offered. + * + * Which four tabs remains plan 016's committed subset; this only + * removes from it. Hiding all four leaves "More", which is always + * present and reaches everything. + */ + private visibilityCtrl = new ViewVisibilityController(this); + /** * Whether the drawer has been asked for. * @@ -211,7 +228,9 @@ export class BottomNav extends LitElement { return html`