Now use vuex to manage state for favorites

This commit is contained in:
Eliot Berriot 2017-12-23 21:37:11 +01:00
parent b5ce65fc3e
commit 5d35a3659e
No known key found for this signature in database
GPG Key ID: DD6965E2476E5C27
7 changed files with 99 additions and 78 deletions

View File

@ -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>

View File

@ -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

View File

@ -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)
}
}

View File

@ -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)
}
})
}
}

View File

@ -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) => {

View File

@ -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)
}
})
}
}
}

View File

@ -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