« get me outta code hell

mtui - Music Text User Interface - user-friendly command line music player
about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--todo.txt28
-rw-r--r--ui.js35
2 files changed, 54 insertions, 9 deletions
diff --git a/todo.txt b/todo.txt
index a7e02f5..3683ecc 100644
--- a/todo.txt
+++ b/todo.txt
@@ -144,10 +144,12 @@ TODO: If a track's file is a symlink, the "From:" label should show where it
 TODO: The "Up (to <group>)" and "(This group has no items)" elements are not
       quite buttons nor grouplike items. They should be more consistent with
       actual grouplike items (i.e. same behavior and appearance), and should
-      be less buggy. (Done!)
+      be less buggy.
+      (Done!)
 
 TODO: "Distribute" options in play/queue menu -- "don't distribute", "spread
-      (across queue?) evenly", "spread randomly". (Done!)
+      (across queue?) evenly", "spread randomly".
+      (Done!)
 
 TODO: Investigate how to make "distribute" options work better when the
       currently-playing song is contained in the group to be distributed.
@@ -164,3 +166,25 @@ TODO: If you remove tracks from the queue that are above the currently selected
 
 TODO: Arbitrary queue! I.e, you specify the downloadURL, then it queues that
       item.
+
+TODO: A "distribute children" option (with better wording)! Like manually
+      queueing each child group to be distributed evenly one by one, but
+      automatic.
+
+      More on that thought...I don't think I want to have "clumps" of like,
+      one of a song from EVERY album right at the start and the end, when we
+      do that. (Well maybe not the end, but definitely at the start.) If we
+      pretend there's "fake" items at the start of the group before we
+      distribute it, I think we'll get better results - that fake item will be
+      placed at the start, letting the rest of the group get distributed in
+      better order. (Of course, the fake item is just an offset in the math.
+      It isn't an actual item that will get added to the queue.)
+
+TODO: Remove ALL children before queueing, THEN queue them - including any math
+      for distribution. Might give interesting results...or maybe it wouldn't
+      be any different. Worth investigating!
+
+TODO: A "play later" option for songs in the queue, identical to distributing
+      randomly the single track; if the track is already playing, it should
+      skip to the next song before shuffling.
+      (Done!)
diff --git a/ui.js b/ui.js
index 4d6b637..310db41 100644
--- a/ui.js
+++ b/ui.js
@@ -128,7 +128,6 @@ class AppElement extends FocusElement {
 
     grouplikeListing.on('download', item => this.downloadGrouplikeItem(item))
     grouplikeListing.on('browse', item => grouplikeListing.loadGrouplike(item))
-    grouplikeListing.on('menu', (item, el) => this.showMenuForItemElement(el))
     grouplikeListing.on('queue', (item, opts) => this.handleQueueOptions(item, opts))
 
     const updateListingsFor = item => {
@@ -234,9 +233,10 @@ class AppElement extends FocusElement {
     }
 
     grouplikeListing.pathElement.on('select', item => handleSelectFromPathElement(item))
+    grouplikeListing.on('menu', (item, el) => this.showMenuForItemElement(el, grouplikeListing))
   }
 
-  showMenuForItemElement(el) {
+  showMenuForItemElement(el, listing) {
     const emitControls = play => () => {
       this.handleQueueOptions(item, {
         where: this.whereControl.curValue,
@@ -248,10 +248,18 @@ class AppElement extends FocusElement {
     const { item, isGroup, isMarked } = el
     const { editMode } = this
     const anyMarked = editMode && this.markGrouplike.items.length > 0
-    this.menu.show({
-      x: el.absLeft,
-      y: el.absTop + 1,
-      items: [
+
+    let items;
+    if (listing.grouplike.isTheQueue) {
+      items = [
+        {label: 'Play later', action: () => this.handleQueueOptions(item, {
+          where: 'distribute-randomly',
+          skip: true
+        })},
+        {label: 'Remove from queue', action: () => this.unqueueGrouplikeItem(item)}
+      ]
+    } else {
+      items = [
         // A label that just shows some brief information about the item.
         isGroup && {label:
           `(${item.name ? `"${item.name}"` : 'Unnamed'} -` +
@@ -281,6 +289,12 @@ class AppElement extends FocusElement {
 
         {label: 'Remove from queue', action: () => this.unqueueGrouplikeItem(item)}
       ]
+    }
+
+    this.menu.show({
+      x: el.absLeft,
+      y: el.absTop + 1,
+      items
     })
   }
 
@@ -493,13 +507,20 @@ class AppElement extends FocusElement {
   // TODO: I'd like to name/incorporate this function better.. for now it's
   // just directly moved from the old event listener on grouplikeListings for
   // 'queue'.
-  handleQueueOptions(item, {where = 'end', order = 'normal', play = false} = {}) {
+  handleQueueOptions(item, {where = 'end', order = 'normal', play = false, skip = false} = {}) {
+    if (skip && this.playingTrack === item) {
+      this.playNextTrack(this.playingTrack)
+    }
+
     if (isGroup(item)) {
       if (order === 'shuffle') {
         item = {items: shuffleArray(flattenGrouplike(item).items)}
       } else if (order === 'shuffle-groups') {
         item = shuffleOrderOfGroups(item)
       }
+    } else {
+      // Make it into a grouplike that just contains itself.
+      item = {items: [item]}
     }
 
     if (where === 'next' || where === 'end') {