mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-21 23:05:46 +00:00
feat(sidebar): long-press drag to reorder and hide nav items (#269)
Hold for 1s then drag to reorder configurable library and system links; drop outside the sidebar to hide items (same visibility as Settings). Show a trash hint near the cursor when outside removal applies. Extract shared reorder helpers into src/utils/sidebarNavReorder.ts and reuse them from the Settings sidebar customizer.
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
import { ALL_NAV_ITEMS } from '../config/navItems';
|
||||
import 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 (!ALL_NAV_ITEMS[cfg.id] || ALL_NAV_ITEMS[cfg.id].section !== 'library') return false;
|
||||
if (randomNavMode === 'hub' && (cfg.id === 'randomMix' || cfg.id === 'randomAlbums')) 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]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
Reference in New Issue
Block a user