« get me outta code hell

"Distribute" options - mtui - Music Text User Interface - user-friendly command line music player
about summary refs log tree commit diff
path: root/ui.js
diff options
context:
space:
mode:
authorFlorrie <towerofnix@gmail.com>2018-12-21 10:58:28 -0400
committerFlorrie <towerofnix@gmail.com>2018-12-21 11:07:40 -0400
commit8438f8319149dae9f594a57eb0807ba2f8bba7d8 (patch)
tree23ebdb1525e6b6d2f23d6f7446ded2eb0e9133c9 /ui.js
parent4d1702b630b6f8f4893e35bb11f5bc6a342731a1 (diff)
"Distribute" options
E.g. to interweave two groups together.
Diffstat (limited to 'ui.js')
-rw-r--r--ui.js80
1 files changed, 72 insertions, 8 deletions
diff --git a/ui.js b/ui.js
index 6f8b07a..3496d97 100644
--- a/ui.js
+++ b/ui.js
@@ -118,14 +118,18 @@ class AppElement extends FocusElement {
         }
       }
 
-      let afterItem = null
-      if (where === 'next') {
-        afterItem = this.playingTrack
-      }
+      if (where === 'next' || where === 'end') {
+        let afterItem = null
+        if (where === 'next') {
+          afterItem = this.playingTrack
+        }
 
-      this.queueGrouplikeItem(item, afterItem, {
-        movePlayingTrack: order === 'normal'
-      })
+        this.queueGrouplikeItem(item, afterItem, {
+          movePlayingTrack: order === 'normal'
+        })
+      } else if (where.startsWith('distribute-')) {
+        this.distributeQueueGrouplikeItem(item, where.slice('distribute-'.length))
+      }
 
       if (play) {
         this.playGrouplikeItem(item)
@@ -505,6 +509,64 @@ class AppElement extends FocusElement {
     return newTrack
   }
 
+  distributeQueueGrouplikeItem(grouplike, how = 'evenly') {
+    const queue = this.queueGrouplike
+    const newItems = flattenGrouplike(grouplike).items
+
+    // Expressly do an initial pass and unqueue the items we want to queue -
+    // otherwise they would mess with the math we do afterwords.
+    for (const item of newItems) {
+      if (queue.items.includes(item)) {
+        /*
+        if (!movePlayingTrack && item === this.playingTrack) {
+          // NB: if uncommenting this code, splice item from newItems and do
+          // continue instead of return!
+          return
+        }
+        */
+        queue.items.splice(queue.items.indexOf(item), 1)
+      }
+    }
+
+    const distributeStart = queue.items.indexOf(this.playingTrack) + 1
+    const distributeEnd = queue.items.length
+    const distributeSize = distributeEnd - distributeStart
+
+    const queueItem = (item, insertIndex) => {
+      if (queue.items.includes(item)) {
+        /*
+        if (!movePlayingTrack && item === this.playingTrack) {
+          return
+        }
+        */
+        queue.items.splice(queue.items.indexOf(item), 1)
+      } else {
+        offset++
+      }
+      queue.items.splice(insertIndex, 0, item)
+    }
+
+    if (how === 'evenly') {
+      let offset = 0
+      for (const item of newItems) {
+        const insertIndex = distributeStart + Math.floor(offset)
+        queue.items.splice(insertIndex, 0, item)
+        offset++
+        offset += distributeSize / newItems.length
+      }
+    } else if (how === 'randomly') {
+      const indexes = newItems.map(() => Math.floor(Math.random() * distributeSize))
+      indexes.sort()
+      for (let i = 0; i < newItems.length; i++) {
+        const item = newItems[i]
+        const insertIndex = distributeStart + indexes[i] + i
+        queue.items.splice(insertIndex, 0, item)
+      }
+    }
+
+    this.queueListingElement.buildItems()
+  }
+
   unqueueGrouplikeItem(topItem) {
     // This function has support to unqueue groups - it removes all tracks in
     // the group recursively. (You can never unqueue a group itself from the
@@ -1177,7 +1239,9 @@ class InteractiveGrouplikeItemElement extends BasicGrouplikeItemElement {
 
     this.whereControl = new InlineListPickerElement('Where?', [
       {value: 'next', label: 'After current song'},
-      {value: 'end', label: 'At end of queue'}
+      {value: 'end', label: 'At end of queue'},
+      {value: 'distribute-evenly', label: 'Distributed across queue evenly'},
+      {value: 'distribute-randomly', label: 'Distributed across queue randomly'}
     ])
 
     this.orderControl = new InlineListPickerElement('Order?', [