Files
Psychotoxical-psysonic/src/utils/componentHelpers/sidebarNavReorder.ts
T
cucadmuh a8cfff0b62 feat(library): local lossless index, filters, and conserve dedicated page (#871)
* feat(library): local lossless index, filters, and conserve dedicated page

Add SQLite-backed lossless album browse and advanced-search filtering,
wire All Albums and artist/album lossless drill-down mode, and hide the
standalone /lossless-albums nav entry from sidebar visibility settings
(conserved route, default off).

* docs(release): note lossless local index in CHANGELOG and credits (PR #871)
2026-05-27 00:02:46 +03:00

69 lines
2.4 KiB
TypeScript

import { ALL_NAV_ITEMS } from '../../config/navItems';
import { CONSERVED_SIDEBAR_NAV_IDS, type SidebarItemConfig } from '../../store/sidebarStore';
export type SidebarNavSection = 'library' | 'system';
export type SidebarNavDropTarget = {
idx: number;
before: boolean;
section: SidebarNavSection;
};
export function getLibraryItemsForReorder(
items: SidebarItemConfig[],
randomNavMode: 'hub' | 'separate',
): SidebarItemConfig[] {
return items.filter(cfg => {
if (CONSERVED_SIDEBAR_NAV_IDS.has(cfg.id)) return false;
if (!ALL_NAV_ITEMS[cfg.id] || ALL_NAV_ITEMS[cfg.id].section !== 'library') return false;
if (randomNavMode === 'hub' && (cfg.id === 'randomMix' || cfg.id === 'randomAlbums' || cfg.id === 'luckyMix')) return false;
if (randomNavMode === 'separate' && cfg.id === 'randomPicker') return false;
return true;
});
}
export function getSystemItemsForReorder(items: SidebarItemConfig[]): SidebarItemConfig[] {
return items.filter(cfg => ALL_NAV_ITEMS[cfg.id]?.section === 'system');
}
/** Same entries as in Settings toggles — safe to hide via drag-out. */
export function isSidebarNavItemUserHideable(id: string): boolean {
return Boolean(ALL_NAV_ITEMS[id]) && !CONSERVED_SIDEBAR_NAV_IDS.has(id);
}
/**
* Reorders one sidebar section (library or system) like the Settings customizer.
* Returns a new `items` array, or null if nothing changes.
*/
export function applySidebarDropReorder(
allItems: SidebarItemConfig[],
section: SidebarNavSection,
fromIdx: number,
target: SidebarNavDropTarget | null,
randomNavMode: 'hub' | 'separate',
): SidebarItemConfig[] | null {
if (!target || target.section !== section) return null;
const sectionItems =
section === 'library'
? [...getLibraryItemsForReorder(allItems, randomNavMode)]
: [...getSystemItemsForReorder(allItems)];
const insertBefore = target.before ? target.idx : target.idx + 1;
if (insertBefore === fromIdx || insertBefore === fromIdx + 1) return null;
const [moved] = sectionItems.splice(fromIdx, 1);
sectionItems.splice(insertBefore > fromIdx ? insertBefore - 1 : insertBefore, 0, moved);
const visibleIds = new Set(sectionItems.map(c => c.id));
const next = [...allItems];
const positions = next
.map((cfg, i) => ({ cfg, i }))
.filter(({ cfg }) => visibleIds.has(cfg.id))
.map(({ i }) => i);
positions.forEach((pos, i) => {
next[pos] = sectionItems[i];
});
return next;
}