Now use vuex to manage state for favorites
This commit is contained in:
parent
b5ce65fc3e
commit
5d35a3659e
|
@ -58,7 +58,7 @@
|
|||
Keep your PRIVATE_TOKEN secret as it gives access to your account.
|
||||
</div>
|
||||
<pre>
|
||||
export PRIVATE_TOKEN="{{ $store.state.auth.token ()}}"
|
||||
export PRIVATE_TOKEN="{{ $store.state.auth.token }}"
|
||||
<template v-for="track in tracks"><template v-if="track.files.length > 0">
|
||||
curl -G -o "{{ track.files[0].filename }}" <template v-if="$store.state.auth.authenticated">--header "Authorization: JWT $PRIVATE_TOKEN"</template> "{{ backend.absoluteUrl(track.files[0].path) }}"</template></template>
|
||||
</pre>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
</div>
|
||||
<h2 v-if="results" class="ui center aligned icon header">
|
||||
<i class="circular inverted heart pink icon"></i>
|
||||
{{ favoriteTracks.count }} favorites
|
||||
{{ $store.state.favorites.count }} favorites
|
||||
</h2>
|
||||
<radio-button type="favorites"></radio-button>
|
||||
</div>
|
||||
|
@ -55,10 +55,8 @@
|
|||
|
||||
<script>
|
||||
import $ from 'jquery'
|
||||
import Vue from 'vue'
|
||||
import logger from '@/logging'
|
||||
import config from '@/config'
|
||||
import favoriteTracks from '@/favorites/tracks'
|
||||
import TrackTable from '@/components/audio/track/Table'
|
||||
import RadioButton from '@/components/radios/Button'
|
||||
import Pagination from '@/components/Pagination'
|
||||
|
@ -80,7 +78,6 @@ export default {
|
|||
isLoading: false,
|
||||
nextLink: null,
|
||||
previousLink: null,
|
||||
favoriteTracks,
|
||||
page: parseInt(this.defaultPage),
|
||||
paginateBy: parseInt(this.defaultPaginateBy || 25),
|
||||
orderingDirection: defaultOrdering.direction,
|
||||
|
@ -122,10 +119,9 @@ export default {
|
|||
self.results = response.data
|
||||
self.nextLink = response.data.next
|
||||
self.previousLink = response.data.previous
|
||||
Vue.set(favoriteTracks, 'count', response.data.count)
|
||||
favoriteTracks.count = response.data.count
|
||||
self.$store.commit('favorites/count', response.data.count)
|
||||
self.results.results.forEach((track) => {
|
||||
Vue.set(favoriteTracks.objects, track.id, true)
|
||||
self.$store.commit('favorites/track', {id: track.id, value: true})
|
||||
})
|
||||
logger.default.timeEnd('Loading user favorites')
|
||||
self.isLoading = false
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<button @click="favoriteTracks.set(track.id, !isFavorite)" v-if="button" :class="['ui', 'pink', {'inverted': isFavorite}, {'favorited': isFavorite}, 'button']">
|
||||
<button @click="$store.dispatch('favorites/set', {id: track.id, value: !isFavorite})" v-if="button" :class="['ui', 'pink', {'inverted': isFavorite}, {'favorited': isFavorite}, 'button']">
|
||||
<i class="heart icon"></i>
|
||||
<template v-if="isFavorite">
|
||||
In favorites
|
||||
|
@ -8,23 +8,23 @@
|
|||
Add to favorites
|
||||
</template>
|
||||
</button>
|
||||
<i v-else @click="favoriteTracks.set(track.id, !isFavorite)" :class="['favorite-icon', 'heart', {'pink': isFavorite}, {'favorited': isFavorite}, 'link', 'icon']" :title="title"></i>
|
||||
<i v-else @click="$store.dispatch('favorites/set', {id: track.id, value: !isFavorite})" :class="['favorite-icon', 'heart', {'pink': isFavorite}, {'favorited': isFavorite}, 'link', 'icon']" :title="title"></i>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import favoriteTracks from '@/favorites/tracks'
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
track: {type: Object},
|
||||
button: {type: Boolean, default: false}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
favoriteTracks
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
favorites: state => {
|
||||
return state.favorites.tracks
|
||||
}
|
||||
}),
|
||||
title () {
|
||||
if (this.isFavorite) {
|
||||
return 'Remove from favorites'
|
||||
|
@ -33,7 +33,7 @@ export default {
|
|||
}
|
||||
},
|
||||
isFavorite () {
|
||||
return favoriteTracks.objects[this.track.id]
|
||||
return this.$store.getters['favorites/isFavorite'](this.track.id)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
import config from '@/config'
|
||||
import logger from '@/logging'
|
||||
import Vue from 'vue'
|
||||
|
||||
const REMOVE_URL = config.API_URL + 'favorites/tracks/remove/'
|
||||
const FAVORITES_URL = config.API_URL + 'favorites/tracks/'
|
||||
|
||||
export default {
|
||||
objects: {},
|
||||
count: 0,
|
||||
set (id, newValue) {
|
||||
let self = this
|
||||
Vue.set(self.objects, id, newValue)
|
||||
if (newValue) {
|
||||
Vue.set(self, 'count', self.count + 1)
|
||||
let resource = Vue.resource(FAVORITES_URL)
|
||||
resource.save({}, {'track': id}).then((response) => {
|
||||
logger.default.info('Successfully added track to favorites')
|
||||
}, (response) => {
|
||||
logger.default.info('Error while adding track to favorites')
|
||||
Vue.set(self.objects, id, !newValue)
|
||||
Vue.set(self, 'count', self.count - 1)
|
||||
})
|
||||
} else {
|
||||
Vue.set(self, 'count', self.count - 1)
|
||||
let resource = Vue.resource(REMOVE_URL)
|
||||
resource.delete({}, {'track': id}).then((response) => {
|
||||
logger.default.info('Successfully removed track from favorites')
|
||||
}, (response) => {
|
||||
logger.default.info('Error while removing track from favorites')
|
||||
Vue.set(self.objects, id, !newValue)
|
||||
Vue.set(self, 'count', self.count + 1)
|
||||
})
|
||||
}
|
||||
},
|
||||
toggle (id) {
|
||||
let isFavorite = this.objects[id]
|
||||
this.set(id, !isFavorite)
|
||||
},
|
||||
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(result => {
|
||||
Vue.set(self.objects, result.track, true)
|
||||
})
|
||||
if (response.data.next) {
|
||||
self.fetch(response.data.next)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
|
@ -34,6 +34,9 @@ export default {
|
|||
},
|
||||
token: (state, value) => {
|
||||
state.token = value
|
||||
},
|
||||
permission: (state, {key, status}) => {
|
||||
state.availablePermissions[key] = status
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
|
@ -77,17 +80,16 @@ export default {
|
|||
commit('authenticated', false)
|
||||
}
|
||||
},
|
||||
fetchProfile ({commit, state}) {
|
||||
fetchProfile ({commit, dispatch, state}) {
|
||||
let resource = Vue.resource(USER_PROFILE_URL)
|
||||
return resource.get({}).then((response) => {
|
||||
logger.default.info('Successfully fetched user profile')
|
||||
let data = response.data
|
||||
commit('profile', data)
|
||||
// favoriteTracks.fetch()
|
||||
console.log('AFTER')
|
||||
dispatch('favorites/fetch', null, {root: true})
|
||||
Object.keys(data.permissions).forEach(function (key) {
|
||||
// this makes it easier to check for permissions in templates
|
||||
state.availablePermissions[key] = data.permissions[String(key)].status
|
||||
commit('permission', {key, status: data.permissions[String(key)].status})
|
||||
})
|
||||
return response.data
|
||||
}, (response) => {
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
import Vue from 'vue'
|
||||
import config from '@/config'
|
||||
import logger from '@/logging'
|
||||
|
||||
const REMOVE_URL = config.API_URL + 'favorites/tracks/remove/'
|
||||
const FAVORITES_URL = config.API_URL + 'favorites/tracks/'
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
tracks: [],
|
||||
count: 0
|
||||
},
|
||||
mutations: {
|
||||
track: (state, {id, value}) => {
|
||||
if (value) {
|
||||
state.tracks.push(id)
|
||||
} else {
|
||||
let i = state.tracks.indexOf(id)
|
||||
if (i > -1) {
|
||||
state.tracks.splice(i, 1)
|
||||
}
|
||||
}
|
||||
},
|
||||
count: (state, value) => {
|
||||
state.count = value
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
isFavorite: (state) => (id) => {
|
||||
return state.tracks.indexOf(id) > -1
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
set ({commit, state}, {id, value}) {
|
||||
commit('track', {id, value})
|
||||
if (value) {
|
||||
commit('count', state.count + 1)
|
||||
let resource = Vue.resource(FAVORITES_URL)
|
||||
resource.save({}, {'track': id}).then((response) => {
|
||||
logger.default.info('Successfully added track to favorites')
|
||||
}, (response) => {
|
||||
logger.default.info('Error while adding track to favorites')
|
||||
commit('track', {id, value: !value})
|
||||
commit('count', state.count - 1)
|
||||
})
|
||||
} else {
|
||||
commit('count', state.count - 1)
|
||||
let resource = Vue.resource(REMOVE_URL)
|
||||
resource.delete({}, {'track': id}).then((response) => {
|
||||
logger.default.info('Successfully removed track from favorites')
|
||||
}, (response) => {
|
||||
logger.default.info('Error while removing track from favorites')
|
||||
commit('track', {id, value: !value})
|
||||
commit('count', state.count + 1)
|
||||
})
|
||||
}
|
||||
},
|
||||
toggle ({getters, dispatch}, id) {
|
||||
dispatch('set', {id, value: getters['isFavorite'](id)})
|
||||
},
|
||||
fetch ({dispatch, state, commit}, url) {
|
||||
// will fetch favorites by batches from API to have them locally
|
||||
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')
|
||||
response.data.results.forEach(result => {
|
||||
commit('track', {id: result.track, value: true})
|
||||
})
|
||||
commit('count', state.tracks.length)
|
||||
if (response.data.next) {
|
||||
dispatch('fetch', response.data.next)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
|
||||
import favorites from './favorites'
|
||||
import auth from './auth'
|
||||
import queue from './queue'
|
||||
import radios from './radios'
|
||||
|
@ -11,6 +12,7 @@ Vue.use(Vuex)
|
|||
export default new Vuex.Store({
|
||||
modules: {
|
||||
auth,
|
||||
favorites,
|
||||
queue,
|
||||
radios,
|
||||
player
|
||||
|
|
Loading…
Reference in New Issue