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.
|
Keep your PRIVATE_TOKEN secret as it gives access to your account.
|
||||||
</div>
|
</div>
|
||||||
<pre>
|
<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">
|
<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>
|
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>
|
</pre>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
</div>
|
</div>
|
||||||
<h2 v-if="results" class="ui center aligned icon header">
|
<h2 v-if="results" class="ui center aligned icon header">
|
||||||
<i class="circular inverted heart pink icon"></i>
|
<i class="circular inverted heart pink icon"></i>
|
||||||
{{ favoriteTracks.count }} favorites
|
{{ $store.state.favorites.count }} favorites
|
||||||
</h2>
|
</h2>
|
||||||
<radio-button type="favorites"></radio-button>
|
<radio-button type="favorites"></radio-button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -55,10 +55,8 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import $ from 'jquery'
|
import $ from 'jquery'
|
||||||
import Vue from 'vue'
|
|
||||||
import logger from '@/logging'
|
import logger from '@/logging'
|
||||||
import config from '@/config'
|
import config from '@/config'
|
||||||
import favoriteTracks from '@/favorites/tracks'
|
|
||||||
import TrackTable from '@/components/audio/track/Table'
|
import TrackTable from '@/components/audio/track/Table'
|
||||||
import RadioButton from '@/components/radios/Button'
|
import RadioButton from '@/components/radios/Button'
|
||||||
import Pagination from '@/components/Pagination'
|
import Pagination from '@/components/Pagination'
|
||||||
|
@ -80,7 +78,6 @@ export default {
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
nextLink: null,
|
nextLink: null,
|
||||||
previousLink: null,
|
previousLink: null,
|
||||||
favoriteTracks,
|
|
||||||
page: parseInt(this.defaultPage),
|
page: parseInt(this.defaultPage),
|
||||||
paginateBy: parseInt(this.defaultPaginateBy || 25),
|
paginateBy: parseInt(this.defaultPaginateBy || 25),
|
||||||
orderingDirection: defaultOrdering.direction,
|
orderingDirection: defaultOrdering.direction,
|
||||||
|
@ -122,10 +119,9 @@ export default {
|
||||||
self.results = response.data
|
self.results = response.data
|
||||||
self.nextLink = response.data.next
|
self.nextLink = response.data.next
|
||||||
self.previousLink = response.data.previous
|
self.previousLink = response.data.previous
|
||||||
Vue.set(favoriteTracks, 'count', response.data.count)
|
self.$store.commit('favorites/count', response.data.count)
|
||||||
favoriteTracks.count = response.data.count
|
|
||||||
self.results.results.forEach((track) => {
|
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')
|
logger.default.timeEnd('Loading user favorites')
|
||||||
self.isLoading = false
|
self.isLoading = false
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<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>
|
<i class="heart icon"></i>
|
||||||
<template v-if="isFavorite">
|
<template v-if="isFavorite">
|
||||||
In favorites
|
In favorites
|
||||||
|
@ -8,23 +8,23 @@
|
||||||
Add to favorites
|
Add to favorites
|
||||||
</template>
|
</template>
|
||||||
</button>
|
</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>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import favoriteTracks from '@/favorites/tracks'
|
import {mapState} from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
track: {type: Object},
|
track: {type: Object},
|
||||||
button: {type: Boolean, default: false}
|
button: {type: Boolean, default: false}
|
||||||
},
|
},
|
||||||
data () {
|
|
||||||
return {
|
|
||||||
favoriteTracks
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
favorites: state => {
|
||||||
|
return state.favorites.tracks
|
||||||
|
}
|
||||||
|
}),
|
||||||
title () {
|
title () {
|
||||||
if (this.isFavorite) {
|
if (this.isFavorite) {
|
||||||
return 'Remove from favorites'
|
return 'Remove from favorites'
|
||||||
|
@ -33,7 +33,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
isFavorite () {
|
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) => {
|
token: (state, value) => {
|
||||||
state.token = value
|
state.token = value
|
||||||
|
},
|
||||||
|
permission: (state, {key, status}) => {
|
||||||
|
state.availablePermissions[key] = status
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
@ -77,17 +80,16 @@ export default {
|
||||||
commit('authenticated', false)
|
commit('authenticated', false)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
fetchProfile ({commit, state}) {
|
fetchProfile ({commit, dispatch, state}) {
|
||||||
let resource = Vue.resource(USER_PROFILE_URL)
|
let resource = Vue.resource(USER_PROFILE_URL)
|
||||||
return resource.get({}).then((response) => {
|
return resource.get({}).then((response) => {
|
||||||
logger.default.info('Successfully fetched user profile')
|
logger.default.info('Successfully fetched user profile')
|
||||||
let data = response.data
|
let data = response.data
|
||||||
commit('profile', data)
|
commit('profile', data)
|
||||||
// favoriteTracks.fetch()
|
dispatch('favorites/fetch', null, {root: true})
|
||||||
console.log('AFTER')
|
|
||||||
Object.keys(data.permissions).forEach(function (key) {
|
Object.keys(data.permissions).forEach(function (key) {
|
||||||
// this makes it easier to check for permissions in templates
|
// 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
|
return response.data
|
||||||
}, (response) => {
|
}, (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 Vue from 'vue'
|
||||||
import Vuex from 'vuex'
|
import Vuex from 'vuex'
|
||||||
|
|
||||||
|
import favorites from './favorites'
|
||||||
import auth from './auth'
|
import auth from './auth'
|
||||||
import queue from './queue'
|
import queue from './queue'
|
||||||
import radios from './radios'
|
import radios from './radios'
|
||||||
|
@ -11,6 +12,7 @@ Vue.use(Vuex)
|
||||||
export default new Vuex.Store({
|
export default new Vuex.Store({
|
||||||
modules: {
|
modules: {
|
||||||
auth,
|
auth,
|
||||||
|
favorites,
|
||||||
queue,
|
queue,
|
||||||
radios,
|
radios,
|
||||||
player
|
player
|
||||||
|
|
Loading…
Reference in New Issue