From fc04ad548f8756af79cee6d3cbbe294701f7ee25 Mon Sep 17 00:00:00 2001
From: Eliot Berriot <contact@eliotberriot.com>
Date: Wed, 14 Jun 2017 06:01:51 +0200
Subject: [PATCH] Fixed cyclic errors in queue caching and restoring

---
 src/audio/queue.js      | 24 +++++++++++++++++++++++-
 src/auth/index.js       | 10 +++++++++-
 src/favorites/tracks.js | 21 +++++++++++++++++++--
 src/main.js             |  2 +-
 4 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/src/audio/queue.js b/src/audio/queue.js
index 1f10c4d..6a1a414 100644
--- a/src/audio/queue.js
+++ b/src/audio/queue.js
@@ -37,7 +37,29 @@ class Queue {
 
   cache () {
     let cached = {
-      tracks: this.tracks,
+      tracks: this.tracks.map(track => {
+        // we keep only valuable fields to make the cache lighter and avoid
+        // cyclic value serialization errors
+        let artist = {
+          id: track.artist.id,
+          mbid: track.artist.mbid,
+          name: track.artist.name
+        }
+        return {
+          id: track.id,
+          title: track.title,
+          mbid: track.mbid,
+          album: {
+            id: track.album.id,
+            title: track.album.title,
+            mbid: track.album.mbid,
+            cover: track.album.cover,
+            artist: artist
+          },
+          artist: artist,
+          files: track.files
+        }
+      }),
       currentIndex: this.currentIndex
     }
     cache.set('queue', cached)
diff --git a/src/auth/index.js b/src/auth/index.js
index bfb778d..dc4c07d 100644
--- a/src/auth/index.js
+++ b/src/auth/index.js
@@ -1,6 +1,7 @@
 import logger from '@/logging'
 import config from '@/config'
 import cache from '@/cache'
+// import favoriteTracks from '@/favorites/tracks'
 
 // URL and endpoint constants
 const LOGIN_URL = config.API_URL + 'token/'
@@ -23,7 +24,7 @@ export default {
 
       this.user.authenticated = true
       this.user.username = creds.username
-
+      this.connect()
       // Redirect to a specified route
       if (redirect) {
         context.$router.push(redirect)
@@ -52,6 +53,7 @@ export default {
       this.user.authenticated = true
       this.user.username = username
       logger.default.info('Logged back in as ' + username)
+      this.connect()
     } else {
       logger.default.info('Anonymous user')
       this.user.authenticated = false
@@ -61,5 +63,11 @@ export default {
   // The object to be passed as a header for authenticated requests
   getAuthHeader () {
     return 'JWT ' + cache.get('token')
+  },
+
+  connect () {
+    // called once user has logged in successfully / reauthenticated
+    // e.g. after a page refresh
+    // favoriteTracks.fetch()
   }
 }
diff --git a/src/favorites/tracks.js b/src/favorites/tracks.js
index 84d9c31..32b5343 100644
--- a/src/favorites/tracks.js
+++ b/src/favorites/tracks.js
@@ -3,7 +3,7 @@ import logger from '@/logging'
 import Vue from 'vue'
 
 const REMOVE_URL = config.API_URL + 'favorites/tracks/remove/'
-const ADD_URL = config.API_URL + 'favorites/tracks/'
+const FAVORITES_URL = config.API_URL + 'favorites/tracks/'
 
 export default {
   objects: {},
@@ -13,7 +13,7 @@ export default {
     Vue.set(self.objects, id, newValue)
     if (newValue) {
       Vue.set(self, 'count', self.count + 1)
-      let resource = Vue.resource(ADD_URL)
+      let resource = Vue.resource(FAVORITES_URL)
       resource.save({}, {'track': id}).then((response) => {
         logger.default.info('Successfully added track to favorites')
       }, (response) => {
@@ -32,5 +32,22 @@ export default {
         Vue.set(self, 'count', self.count + 1)
       })
     }
+  },
+  fetch (url) {
+    // will fetch favorites by batches from API to have them locally
+    var self = this
+    url = url || FAVORITES_URL
+    let resource = Vue.resource(url)
+    resource.get().then((response) => {
+      logger.default.info('Fetched a batch of ' + response.data.results.length + ' favorites')
+      Vue.set(self, 'count', response.data.count)
+      response.data.results.forEach(track => {
+        Vue.set(self.objects, track.id, true)
+      })
+      if (response.data.next) {
+        self.fetch(response.data.next)
+      }
+    })
   }
+
 }
diff --git a/src/main.js b/src/main.js
index 58afa70..02e4a99 100644
--- a/src/main.js
+++ b/src/main.js
@@ -20,7 +20,6 @@ require('semantic-ui-css/semantic.js')
 
 Vue.use(VueResource)
 Vue.config.productionTip = false
-auth.checkAuth()
 
 Vue.http.interceptors.push(function (request, next) {
   // modify headers
@@ -36,6 +35,7 @@ Vue.http.interceptors.push(function (request, next) {
   })
 })
 
+auth.checkAuth()
 /* eslint-disable no-new */
 new Vue({
   el: '#app',
-- 
GitLab