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* `<app-sidebar>`, 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.
55 lines
1.6 KiB
TypeScript
55 lines
1.6 KiB
TypeScript
import type {
|
|
ReactiveController,
|
|
ReactiveControllerHost,
|
|
} from 'lit';
|
|
import { viewVisibilityStore } from '../view-visibility-store';
|
|
|
|
/**
|
|
* ViewVisibilityController connects a Lit component to the
|
|
* ViewVisibilityStore.
|
|
*
|
|
* It reads through to the store rather than copying the map into a
|
|
* `@state()` field, for the reason `ActiveViewController` does: there
|
|
* are two live `<app-sidebar>` instances the moment `bottom-nav`'s
|
|
* "More" drawer opens, and two components holding their own idea of
|
|
* which destinations exist is how they come to disagree.
|
|
*/
|
|
export class ViewVisibilityController implements ReactiveController {
|
|
private host: ReactiveControllerHost;
|
|
private unsubscribe?: () => void;
|
|
|
|
constructor(host: ReactiveControllerHost) {
|
|
this.host = host;
|
|
host.addController(this);
|
|
}
|
|
|
|
hostConnected(): void {
|
|
this.unsubscribe = viewVisibilityStore.subscribe(() => {
|
|
this.host.requestUpdate();
|
|
});
|
|
|
|
void viewVisibilityStore.init();
|
|
}
|
|
|
|
hostDisconnected(): void {
|
|
this.unsubscribe?.();
|
|
}
|
|
|
|
/** Whether the navigation should offer this destination. */
|
|
visible(view: string): boolean {
|
|
return viewVisibilityStore.visible(view);
|
|
}
|
|
|
|
/**
|
|
* What the config says, ignoring the download-client gate — the
|
|
* state Settings' own checkbox shows.
|
|
*/
|
|
enabled(view: string): boolean {
|
|
return viewVisibilityStore.enabled(view);
|
|
}
|
|
|
|
setVisible(view: string, visible: boolean): Promise<void> {
|
|
return viewVisibilityStore.setVisible(view, visible);
|
|
}
|
|
}
|