From c3b6885388df51df054ac0ea150ae79de2eeaab0 Mon Sep 17 00:00:00 2001 From: Florrie Date: Thu, 10 Jan 2019 00:37:29 -0400 Subject: Queue item menu, "Play later" option Items in the queue now have a menu, and if you pick "play later" from it (the other option is "remove from queue"), it'll move that item into somewhere further down in the queue. If it was already playing when you select play later, it'll first skip it, then move it. --- todo.txt | 28 ++++++++++++++++++++++++++-- ui.js | 35 ++++++++++++++++++++++++++++------- 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 )" 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') { -- cgit 1.3.0-6-gf8a5