From 9b9c091437caf5373284e09b756dce21bcbb0a91 Mon Sep 17 00:00:00 2001 From: Florrie Date: Wed, 19 Dec 2018 22:26:10 -0400 Subject: Try a slightly different shuffle-groups process This should be more intuitive and useful...most of the time. :) --- playlist-utils.js | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/playlist-utils.js b/playlist-utils.js index ac6a929..4367fb0 100644 --- a/playlist-utils.js +++ b/playlist-utils.js @@ -191,14 +191,41 @@ function countTotalItems(grouplike) { } function shuffleOrderOfGroups(grouplike) { - if (isGroup(grouplike) && grouplike.items.every(isGroup)) { - const items = grouplike.items.map(shuffleOrderOfGroups) - const shuffled = shuffleArray(items) - - return Object.assign({}, grouplike, {items: shuffled}) - } else { - return grouplike + // OK, this is opinionated on how it should work, but I think it Makes Sense. + // Also sorry functional-programming friends, I'm sure this is a horror. + // (FYI, this is the same as how http-music used to work with shuffle-groups, + // *if* you also did --collapse-groups first. That was how shuffle-groups was + // usually used (by me) anyway, so I figure bringing it over (with simpler + // code) is reasonable. The only potentially confusing part is the behavior + // when a group contains both tracks and groups (the tracks are all + // considered "leftover" and randomly shuffled between the flat groups in the + // end result)... but I couldn't think of any better way to incorporate such + // "leftover" items into the result.) + + // First filter the given grouplike into a list of "flat" groups, which are + // groups that only contain tracks - no groups. When a group contains both + // groups and tracks, add these "leftover" tracks to the list too. + const flatItems = [] + const recursive = group => { + for (const item of group.items) { + if (isGroup(item) && item.items.every(isTrack)) { + flatItems.push(item) + } else if (isGroup(item)) { + recursive(item) + } else { + flatItems.push(item) + } + } } + recursive(grouplike) + + // Now shuffle this list of groups (and potentially tracks). This won't + // shuffle the *contents* of the groups; only the order in which the whole + // list of groups (and tracks) plays. + const shuffled = shuffleArray(flatItems) + + // And we're done! Return the shuffled list as a grouplike. + return {items: shuffled} } function collectGrouplikeChildren(grouplike, filter = null) { -- cgit 1.3.0-6-gf8a5