diff --git a/front/src/components/audio/track/Table.vue b/front/src/components/audio/track/Table.vue index 4932318603e2c3eb2263b0c152e26fade0aa6fc1..8a591d3bd05e9542484a2b8bf8ef9b931363a837 100644 --- a/front/src/components/audio/track/Table.vue +++ b/front/src/components/audio/track/Table.vue @@ -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> diff --git a/front/src/components/favorites/List.vue b/front/src/components/favorites/List.vue index 91efd72907e745244f5a74d7cdc3547e750611d2..aef4bea93c1a0a6bfdbd695098619f1d45d6af22 100644 --- a/front/src/components/favorites/List.vue +++ b/front/src/components/favorites/List.vue @@ -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 diff --git a/front/src/components/favorites/TrackFavoriteIcon.vue b/front/src/components/favorites/TrackFavoriteIcon.vue index 5e3e5b07e68bede9300a0b95fb68ac2927a4b936..5abc57a952446b6b9d34e366f09c8af7e617dcd0 100644 --- a/front/src/components/favorites/TrackFavoriteIcon.vue +++ b/front/src/components/favorites/TrackFavoriteIcon.vue @@ -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) } } diff --git a/front/src/favorites/tracks.js b/front/src/favorites/tracks.js deleted file mode 100644 index 45d05c50d250f06466c3eb3bf610d9536329b28e..0000000000000000000000000000000000000000 --- a/front/src/favorites/tracks.js +++ /dev/null @@ -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) - } - }) - } - -} diff --git a/front/src/store/auth.js b/front/src/store/auth.js index 851d9c214ba70bfc8831bd4798be2fa01e3c92b7..d4b23adcb03401d75721310b22383460d64fe113 100644 --- a/front/src/store/auth.js +++ b/front/src/store/auth.js @@ -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) => { diff --git a/front/src/store/favorites.js b/front/src/store/favorites.js new file mode 100644 index 0000000000000000000000000000000000000000..8bb4bb5afe6add992547b631a91c3683e00fbb6d --- /dev/null +++ b/front/src/store/favorites.js @@ -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) + } + }) + } + } +} diff --git a/front/src/store/index.js b/front/src/store/index.js index 35e50e0304f352315a7134f8370d63757114234f..99e466e510f0cad3de2abfdaad4847bd0083defd 100644 --- a/front/src/store/index.js +++ b/front/src/store/index.js @@ -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