From 8438f8319149dae9f594a57eb0807ba2f8bba7d8 Mon Sep 17 00:00:00 2001 From: Florrie Date: Fri, 21 Dec 2018 10:58:28 -0400 Subject: "Distribute" options E.g. to interweave two groups together. --- ui.js | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 72 insertions(+), 8 deletions(-) (limited to 'ui.js') 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?', [ -- cgit 1.3.0-6-gf8a5