feat(playlists): track custom order in separate 'order' array; reading API honors 'order' while preserving 'tracks'
This commit is contained in:
parent
5a396d774e
commit
61d4ca16de
@ -9,6 +9,8 @@ const playlistSchema = new mongoose.Schema({
|
|||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
tracks: [String],
|
tracks: [String],
|
||||||
|
// Optional custom order of track IDs (display-only, not exported)
|
||||||
|
order: [String],
|
||||||
children: [{
|
children: [{
|
||||||
type: mongoose.Schema.Types.Mixed
|
type: mongoose.Schema.Types.Mixed
|
||||||
}]
|
}]
|
||||||
|
|||||||
@ -80,7 +80,7 @@ router.post('/batch', async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Reorder tracks inside a playlist (by name)
|
// Reorder tracks inside a playlist (by name). Stores order separately in `order` to avoid interfering with original `tracks`.
|
||||||
router.post('/reorder', async (req: Request, res: Response) => {
|
router.post('/reorder', async (req: Request, res: Response) => {
|
||||||
try {
|
try {
|
||||||
const { playlistName, orderedIds } = req.body as { playlistName: string; orderedIds: string[] };
|
const { playlistName, orderedIds } = req.body as { playlistName: string; orderedIds: string[] };
|
||||||
@ -94,13 +94,9 @@ router.post('/reorder', async (req: Request, res: Response) => {
|
|||||||
const reorderNode = (node: any): any => {
|
const reorderNode = (node: any): any => {
|
||||||
if (!node) return node;
|
if (!node) return node;
|
||||||
if (node.type === 'playlist' && node.name === playlistName) {
|
if (node.type === 'playlist' && node.name === playlistName) {
|
||||||
// Ensure unique order and only include known IDs
|
// Store order separately; do not mutate tracks
|
||||||
const unique = Array.from(new Set(orderedIds));
|
const unique = Array.from(new Set(orderedIds));
|
||||||
// If tracks exist, keep only ids present in unique, and append any tracks not included to preserve membership
|
node.order = unique;
|
||||||
const current: string[] = Array.isArray(node.tracks) ? node.tracks : [];
|
|
||||||
const orderedKnown = unique.filter(id => current.includes(id));
|
|
||||||
const missing = current.filter(id => !unique.includes(id));
|
|
||||||
node.tracks = [...orderedKnown, ...missing];
|
|
||||||
updated = true;
|
updated = true;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -110,8 +110,14 @@ router.get('/playlist/*', async (req: Request, res: Response) => {
|
|||||||
|
|
||||||
// Get all track IDs from the playlist (including nested playlists)
|
// Get all track IDs from the playlist (including nested playlists)
|
||||||
const getAllTrackIds = (node: any): string[] => {
|
const getAllTrackIds = (node: any): string[] => {
|
||||||
if (node.type === 'playlist' && node.tracks) {
|
if (node.type === 'playlist') {
|
||||||
return node.tracks;
|
const base = Array.isArray(node.tracks) ? node.tracks : [];
|
||||||
|
const order = Array.isArray(node.order) ? node.order : [];
|
||||||
|
if (order.length === 0) return base;
|
||||||
|
const setBase = new Set(base);
|
||||||
|
const orderedKnown = order.filter((id: string) => setBase.has(id));
|
||||||
|
const missing = base.filter((id: string) => !order.includes(id));
|
||||||
|
return [...orderedKnown, ...missing];
|
||||||
}
|
}
|
||||||
if (node.type === 'folder' && node.children) {
|
if (node.type === 'folder' && node.children) {
|
||||||
return node.children.flatMap((child: any) => getAllTrackIds(child));
|
return node.children.flatMap((child: any) => getAllTrackIds(child));
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user