« get me outta code hell

Try a slightly different shuffle-groups process - mtui - Music Text User Interface - user-friendly command line music player
about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlorrie <towerofnix@gmail.com>2018-12-19 22:26:10 -0400
committerFlorrie <towerofnix@gmail.com>2018-12-19 22:27:00 -0400
commit9b9c091437caf5373284e09b756dce21bcbb0a91 (patch)
tree023d230a4131b9a44f269fcc72e81c367fed2759
parentf50c1fe7e7d5f29e9b943f9843663a3800949b18 (diff)
Try a slightly different shuffle-groups process
This should be more intuitive and useful...most of the time. :)
-rw-r--r--playlist-utils.js41
1 files 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) {