« get me outta code hell

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:
Diffstat (limited to 'ui.js')
-rw-r--r--ui.js72
1 files changed, 54 insertions, 18 deletions
diff --git a/ui.js b/ui.js
index 65ca2d1..b9c417a 100644
--- a/ui.js
+++ b/ui.js
@@ -195,7 +195,8 @@ export default class AppElement extends FocusElement {
       themeColor: 4, // blue
       seekToStartThreshold: 3,
       showTabberPane: true,
-      stopPlayingUponQuit: true
+      stopPlayingUponQuit: true,
+      showPartyControls: false
     }, config)
 
     // TODO: Move edit mode stuff to the backend!
@@ -478,7 +479,9 @@ export default class AppElement extends FocusElement {
       'handleAddedQueuePlayer',
       'handleRemovedQueuePlayer',
       'handleSetLoopQueueAtEnd',
-      'handleLogMessage'
+      'handleLogMessage',
+      'handleGotPartyGrouplike',
+      'handlePartyGrouplikeUpdated'
     ]) {
       this[key] = this[key].bind(this)
     }
@@ -551,6 +554,8 @@ export default class AppElement extends FocusElement {
     this.backend.on('removed queue player', this.handleRemovedQueuePlayer)
     this.backend.on('set-loop-queue-at-end', this.handleSetLoopQueueAtEnd)
     this.backend.on('log message', this.handleLogMessage)
+    this.backend.on('got party grouplike', this.handleGotPartyGrouplike)
+    this.backend.on('party grouplike updated', this.handlePartyGrouplikeUpdated)
   }
 
   removeBackendListeners() {
@@ -559,6 +564,8 @@ export default class AppElement extends FocusElement {
     this.backend.removeListener('removed queue player', this.handleRemovedQueuePlayer)
     this.backend.removeListener('set-loop-queue-at-end', this.handleSetLoopQueueAtEnd)
     this.backend.removeListener('log message', this.handleLogMessage)
+    this.backend.removeListener('got party grouplike', this.handleGotPartyGrouplike)
+    this.backend.removeListener('party grouplike updated', this.handlePartyGrouplikeUpdated)
   }
 
   handleAddedQueuePlayer(queuePlayer) {
@@ -580,6 +587,18 @@ export default class AppElement extends FocusElement {
     this.log.newLogMessage(messageInfo)
   }
 
+  handleGotPartyGrouplike(partyGrouplike) {
+    this.newPartyTab(partyGrouplike)
+  }
+
+  handlePartyGrouplikeUpdated(partyGrouplike) {
+    for (const grouplikeListing of this.tabber.tabberElements) {
+      if (grouplikeListing.grouplike === partyGrouplike) {
+        grouplikeListing.loadGrouplike(partyGrouplike, false)
+      }
+    }
+  }
+
   async handlePlayingDetails(track, oldTrack, startTime, queuePlayer) {
     const PIE = this.getPlaybackInfoElementForQueuePlayer(queuePlayer)
     if (PIE) {
@@ -942,6 +961,10 @@ export default class AppElement extends FocusElement {
     this.queueListingElement.selectAndShow(item)
   }
 
+  shareWithParty(item) {
+    this.backend.shareWithParty(item)
+  }
+
   replaceMark(items) {
     this.markGrouplike.items = items.slice(0) // Don't share the array! :)
     this.emitMarkChanged()
@@ -1474,6 +1497,7 @@ export default class AppElement extends FocusElement {
       // TODO: Implement this! :P
       // const isMarked = false
 
+      const rootGroup = getItemPath(item)[0]
       // const hasNotesFile = !!getCorrespondingFileForItem(item, '.txt')
       const timestampsItem = this.hasTimestampsFile(item) && (this.timestampsExpanded(item, listing)
         ? {label: 'Collapse saved timestamps', action: () => this.collapseTimestamps(item, listing)}
@@ -1525,22 +1549,29 @@ export default class AppElement extends FocusElement {
           // anyMarked && !this.isReal && {label: 'Paste', action: () => this.emit('paste')}, // No "above" or "elow" in the label because the "fake" item/row will be replaced (it'll disappear, since there'll be an item in the group)
           // {divider: true},
 
-          canControlQueue && isPlayable(item) && {element: this.whereControl},
-          canControlQueue && isGroup(item) && {element: this.orderControl},
-          canControlQueue && isPlayable(item) && {label: 'Play!', action: emitControls(true)},
-          canControlQueue && isPlayable(item) && {label: 'Queue!', action: emitControls(false)},
-          {divider: true},
-
-          canProcessMetadata && isGroup(item) && {label: 'Process metadata (new entries)', action: () => setTimeout(() => this.processMetadata(item, false))},
-          canProcessMetadata && isGroup(item) && {label: 'Process metadata (reprocess)', action: () => setTimeout(() => this.processMetadata(item, true))},
-          canProcessMetadata && isTrack(item) && {label: 'Process metadata', action: () => setTimeout(() => this.processMetadata(item, true))},
-          isOpenable(item) && item.url.endsWith('.json') && {label: 'Open (JSON Playlist)', action: () => this.openSpecialOrThroughSystem(item)},
-          isOpenable(item) && {label: 'Open (System)', action: () => this.openThroughSystem(item)},
-          // !hasNotesFile && isPlayable(item) && {label: 'Create notes file', action: () => this.editNotesFile(item, true)},
-          // hasNotesFile && isPlayable(item) && {label: 'Edit notes file', action: () => this.editNotesFile(item, true)},
-          canControlQueue && isPlayable(item) && {label: 'Remove from queue', action: () => this.unqueue(item)},
-          isTrack(item) && isQueued && {label: 'Reveal in queue', action: () => this.revealInQueue(item)},
-          {divider: true},
+          ...((this.config.showPartyControls && !rootGroup.isPartySources)
+            ? [
+              {label: 'Share with party', action: () => this.shareWithParty(item)},
+              {divider: true}
+            ]
+            : [
+              canControlQueue && isPlayable(item) && {element: this.whereControl},
+              canControlQueue && isGroup(item) && {element: this.orderControl},
+              canControlQueue && isPlayable(item) && {label: 'Play!', action: emitControls(true)},
+              canControlQueue && isPlayable(item) && {label: 'Queue!', action: emitControls(false)},
+              {divider: true},
+
+              canProcessMetadata && isGroup(item) && {label: 'Process metadata (new entries)', action: () => setTimeout(() => this.processMetadata(item, false))},
+              canProcessMetadata && isGroup(item) && {label: 'Process metadata (reprocess)', action: () => setTimeout(() => this.processMetadata(item, true))},
+              canProcessMetadata && isTrack(item) && {label: 'Process metadata', action: () => setTimeout(() => this.processMetadata(item, true))},
+              isOpenable(item) && item.url.endsWith('.json') && {label: 'Open (JSON Playlist)', action: () => this.openSpecialOrThroughSystem(item)},
+              isOpenable(item) && {label: 'Open (System)', action: () => this.openThroughSystem(item)},
+              // !hasNotesFile && isPlayable(item) && {label: 'Create notes file', action: () => this.editNotesFile(item, true)},
+              // hasNotesFile && isPlayable(item) && {label: 'Edit notes file', action: () => this.editNotesFile(item, true)},
+              canControlQueue && isPlayable(item) && {label: 'Remove from queue', action: () => this.unqueue(item)},
+              isTrack(item) && isQueued && {label: 'Reveal in queue', action: () => this.revealInQueue(item)},
+              {divider: true},
+            ]),
 
           timestampsItem,
           ...(item === this.markGrouplike
@@ -1919,6 +1950,11 @@ export default class AppElement extends FocusElement {
     })
   }
 
+  newPartyTab(partyGrouplike) {
+    const listing = this.newGrouplikeListing()
+    listing.loadGrouplike(partyGrouplike)
+  }
+
   cloneCurrentTab() {
     const grouplike = this.tabber.currentElement.grouplike
     const listing = this.newGrouplikeListing()