« get me outta code hell

support queue controls over socket clients - mtui - Music Text User Interface - user-friendly command line music player
about summary refs log tree commit diff
path: root/serialized-backend.js
diff options
context:
space:
mode:
authorFlorrie <towerofnix@gmail.com>2020-07-11 16:22:01 -0300
committerFlorrie <towerofnix@gmail.com>2020-07-11 16:22:01 -0300
commit991b2f0a8280c31b93ad91d6a215b74183417352 (patch)
tree010b6edb291b6bb9c1689708bc40d9a2f797e91d /serialized-backend.js
parentd00b26b23d9b3fc1e54a4d117366f0f22e664135 (diff)
support queue controls over socket clients
Diffstat (limited to 'serialized-backend.js')
-rw-r--r--serialized-backend.js109
1 files changed, 82 insertions, 27 deletions
diff --git a/serialized-backend.js b/serialized-backend.js
index 041f668..a3f02fa 100644
--- a/serialized-backend.js
+++ b/serialized-backend.js
@@ -22,8 +22,12 @@
 'use strict'
 
 const {
-  findTrackObject,
+  isGroup,
+  isTrack,
+  findItemObject,
   flattenGrouplike,
+  getFlatGroupList,
+  getFlatTrackList,
   getItemPath
 } = require('./playlist-utils')
 
@@ -40,25 +44,11 @@ function getPlayerInfo(queuePlayer) {
 }
 
 function saveBackend(backend) {
-  function referenceTrack(track) {
-    if (track) {
-      // This is the same format used as referenceData in findTrackObject
-      // (in playlist-utils.js).
-      return {
-        name: track.name,
-        downloaderArg: track.downloaderArg,
-        path: getItemPath(track).slice(0, -1).map(group => group.name)
-      }
-    } else {
-      return null
-    }
-  }
-
   return {
     queuePlayers: backend.queuePlayers.map(QP => ({
       id: QP.id,
-      playingTrack: referenceTrack(QP.playingTrack),
-      queuedTracks: QP.queueGrouplike.items.map(referenceTrack),
+      playingTrack: saveItemReference(QP.playingTrack),
+      queuedTracks: QP.queueGrouplike.items.map(saveItemReference),
       pauseNextTrack: QP.pauseNextTrack,
       playerInfo: getPlayerInfo(QP)
     }))
@@ -77,11 +67,7 @@ async function restoreBackend(backend, data) {
 
       QP.id = qpData.id
 
-      QP.queueGrouplike.items = qpData.queuedTracks.map(refData => ({
-        [referenceDataSymbol]: refData,
-        name: refData.name,
-        downloaderArg: refData.downloaderArg
-      }))
+      QP.queueGrouplike.items = qpData.queuedTracks.map(refData => restoreNewItem(refData))
 
       QP.player.setVolume(qpData.playerInfo.volume)
       QP.player.setLoop(qpData.playerInfo.isLooping)
@@ -122,7 +108,7 @@ function updateRestoredTracksUsingPlaylists(backend, playlists) {
   //
   // How well provided tracks resemble the ones existing in the backend (which
   // have not already been replaced by an existing track) is calculated with
-  // the algorithm implemented in findTrackObject, combining all provided
+  // the algorithm implemented in findItemObject, combining all provided
   // playlists (simply putting them all in a group) to allow the algorithm to
   // choose from all playlists equally at once.
   //
@@ -140,8 +126,7 @@ function updateRestoredTracksUsingPlaylists(backend, playlists) {
   // lessened in the UI by simply opening a new view (rather than a whole new
   // load, with new track identities) when a playlist is opened twice at once.
 
-  const combinedPlaylist = {items: playlists}
-  const flattenedPlaylist = flattenGrouplike(combinedPlaylist)
+  const possibleChoices = getFlatTrackList({items: playlists})
 
   for (const QP of backend.queuePlayers) {
     let playingDataToRestore
@@ -155,7 +140,7 @@ function updateRestoredTracksUsingPlaylists(backend, playlists) {
     }
 
     if (playingDataToRestore) {
-      const found = findTrackObject(playingDataToRestore, combinedPlaylist, flattenedPlaylist)
+      const found = findItemObject(playingDataToRestore, possibleChoices)
       if (found) {
         restorePlayingTrack(QP, found, qpData.playerInfo || getPlayerInfo(QP))
       }
@@ -167,13 +152,81 @@ function updateRestoredTracksUsingPlaylists(backend, playlists) {
         return track
       }
 
-      return findTrackObject(refData, combinedPlaylist, flattenedPlaylist) || track
+      return findItemObject(refData, possibleChoices) || track
     })
 
     QP.emit('queue updated')
   }
 }
 
+function saveItemReference(item) {
+  // Utility function to generate reference data for a track or grouplike,
+  // according to the format taken by findItemObject.
+
+  if (isTrack(item)) {
+    return {
+      name: item.name,
+      path: getItemPath(item).slice(0, -1).map(group => group.name),
+      downloaderArg: item.downloaderArg
+    }
+  } else if (isGroup(item)) {
+    return {
+      name: item.name,
+      path: getItemPath(item).slice(0, -1).map(group => group.name),
+      items: item.items.map(saveItemReference)
+    }
+  } else if (item) {
+    return item
+  } else {
+    return null
+  }
+}
+
+function restoreNewItem(referenceData, playlists) {
+  // Utility function to restore a new item. If you're restoring tracks
+  // already present in a backend, use the specific function for that,
+  // updateRestoredTracksUsingPlaylists.
+  //
+  // This function takes a playlists array like the function for restoring
+  // tracks in a backend, but in this function, it's optional: if not provided,
+  // it will simply skip searching for a resembling track and return a new
+  // track object right away.
+
+  let found
+  if (playlists) {
+    let possibleChoices
+    if (referenceData.downloaderArg) {
+      possibleChoices = getFlatTrackList({items: playlists})
+    } else if (referenceData.items) {
+      possibleChoices = getFlatGroupList({items: playlists})
+    }
+    if (possibleChoices) {
+      found = findItemObject(referenceData, possibleChoices)
+    }
+  }
+
+  if (found) {
+    return found
+  } else if (referenceData.downloaderArg) {
+    return {
+      [referenceDataSymbol]: referenceData,
+      name: referenceData.name,
+      downloaderArg: referenceData.downloaderArg
+    }
+  } else if (referenceData.items) {
+    return {
+      [referenceDataSymbol]: referenceData,
+      name: referenceData.name,
+      items: referenceData.items.map(item => restoreNewItem(item, playlists))
+    }
+  } else {
+    return {
+      [referenceDataSymbol]: referenceData,
+      name: referenceData.name
+    }
+  }
+}
+
 function getWaitingTrackData(queuePlayer) {
   // Utility function to get reference data for the track which is currently
   // waiting to be played, once a resembling track is found. This should only
@@ -186,5 +239,7 @@ Object.assign(module.exports, {
   saveBackend,
   restoreBackend,
   updateRestoredTracksUsingPlaylists,
+  saveItemReference,
+  restoreNewItem,
   getWaitingTrackData
 })