From c3c17c1cafe8d33dfdbb3196819d53edcdda02ab Mon Sep 17 00:00:00 2001 From: jeffreybiles Date: Sun, 6 Oct 2019 22:22:28 -0700 Subject: [PATCH] Tags module --- src/App.vue | 2 +- src/components/VideoListVideo.vue | 5 +- src/store/index.js | 68 ++------------------------- src/store/tags.js | 77 +++++++++++++++++++++++++++++++ src/views/AdminTagList.vue | 10 ++-- src/views/AdminVideoShow.vue | 17 ++++--- src/views/TagVideoList.vue | 4 +- src/views/VideoWatch.vue | 5 +- 8 files changed, 109 insertions(+), 79 deletions(-) create mode 100644 src/store/tags.js diff --git a/src/App.vue b/src/App.vue index 7f02504..d4f929d 100644 --- a/src/App.vue +++ b/src/App.vue @@ -44,7 +44,7 @@ export default { created(){ this.$store.dispatch('loadVideos'); this.$store.dispatch('loadCurrentUser'); - this.$store.dispatch('loadAllTags'); + this.$store.dispatch('tags/loadAll'); }, components: { }, diff --git a/src/components/VideoListVideo.vue b/src/components/VideoListVideo.vue index 1b359a9..54f4f02 100644 --- a/src/components/VideoListVideo.vue +++ b/src/components/VideoListVideo.vue @@ -29,7 +29,10 @@ import { mapGetters } from 'vuex'; export default { computed: { - ...mapGetters(['getTag', 'isPlayed']) + ...mapGetters({ + getTag: 'tags/get', + isPlayed: 'isPlayed' + }) }, props: ['video'], diff --git a/src/store/index.js b/src/store/index.js index 710cfac..4ca2605 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -2,16 +2,17 @@ import Vue from "vue"; import Vuex from "vuex"; import Api from "@/services/api"; import snackbarModule from './snackbar'; +import tagsModule from './tags'; Vue.use(Vuex); export default new Vuex.Store({ modules: { - snackbar: snackbarModule + snackbar: snackbarModule, + tags: tagsModule }, state: { videos: [], - tags: [], users: [], currentUser: {} }, @@ -19,9 +20,6 @@ export default new Vuex.Store({ SET_VIDEOS(state, videos) { state.videos = videos; }, - SET_TAGS(state, tags) { - state.tags = tags; - }, SET_PLAYED_VIDEOS(state, playedVideos) { Vue.set(state.currentUser, 'playedVideos', playedVideos); }, @@ -52,24 +50,6 @@ export default new Vuex.Store({ state.currentUser = user; window.localStorage.currentUser = JSON.stringify(user); }, - CONNECT_TAG_TO_VIDEO(state, {video, tag}) { - video.tag_ids = video.tag_ids.concat(tag.id.toString()); - tag.video_ids = tag.video_ids.concat(video.id.toString()); - }, - DISCONNECT_TAG_FROM_VIDEO(state, {video, tag}) { - video.tag_ids = video.tag_ids.filter(t_id => t_id != tag.id); - tag.video_ids = tag.video_ids.filter(v_id => v_id != video.id); - }, - CREATE_TAG(state, {tag}) { - state.tags = state.tags.concat(tag); - }, - UPDATE_TAG_NAME(state, {tag}) { - let tagToUpdate = state.tags.find(t => t.id == tag.id) - tagToUpdate.name = tag.name - }, - DELETE_TAG(state, {tag}) { - state.tags = state.tags.filter(t => t.id != tag.id) - } }, actions: { async loadVideos({commit, dispatch}){ @@ -81,15 +61,6 @@ export default new Vuex.Store({ commit('SET_VIDEOS', videos.map(v => v.attributes)); }, - async loadAllTags({commit, dispatch}) { - let response = await Api().get('/tags'); - let tags = response.data.data; - tags.forEach(t => { - t.attributes.id = t.id; - t.attributes.video_ids = t.relationships.videos.data.map(v => v.id); - }); - commit('SET_TAGS', tags.map(t => t.attributes)); - }, async loadUsers({commit}) { let response = await Api().get('/users'); let users = response.data.data; @@ -159,41 +130,8 @@ export default new Vuex.Store({ return { error: "There was an error. Please try again." } } }, - connectTagToVideo({commit}, {video, tag}) { - Api().post('/video_tags', { - video_id: video.id, - tag_id: tag.id - }); - commit('CONNECT_TAG_TO_VIDEO', {video, tag}); - }, - disconnectTagFromVideo({commit}, {video, tag}) { - Api().post('video_tags/delete', { - video_id: video.id, - tag_id: tag.id - }); - commit('DISCONNECT_TAG_FROM_VIDEO', {video, tag}); - }, - async createTag({commit}, {name}) { - let response = await Api().post('/tags', {name}); - let createdTag = response.data.data.attributes; - createdTag.id = response.data.data.id; - createdTag.video_ids = []; - commit('CREATE_TAG', {tag: createdTag}); - return createdTag; - }, - async updateTagName({commit}, {tag}) { - Api().put(`/tags/${tag.id}`, tag) - commit('UPDATE_TAG_NAME', {tag}); - }, - deleteTag({commit}, {tag}) { - Api().delete(`/tags/${tag.id}`); - commit('DELETE_TAG', {tag}) - } }, getters: { - getTag: state => id => { - return state.tags.find(t => t.id == id) - }, playedVideos: state => { return state.currentUser.playedVideos || []; }, diff --git a/src/store/tags.js b/src/store/tags.js new file mode 100644 index 0000000..7c99c90 --- /dev/null +++ b/src/store/tags.js @@ -0,0 +1,77 @@ +import Api from "@/services/api"; + +export default { + namespaced: true, + state: { + tags: [] + }, + mutations: { + SET_TAGS(state, tags) { + state.tags = tags; + }, + CREATE_TAG(state, {tag}) { + state.tags = state.tags.concat(tag); + }, + UPDATE_TAG_NAME(state, {tag}) { + let tagToUpdate = state.tags.find(t => t.id == tag.id) + tagToUpdate.name = tag.name + }, + DELETE_TAG(state, {tag}) { + state.tags = state.tags.filter(t => t.id != tag.id) + }, + CONNECT_TAG_TO_VIDEO(state, {video, tag}) { + video.tag_ids = video.tag_ids.concat(tag.id.toString()); + tag.video_ids = tag.video_ids.concat(video.id.toString()); + }, + DISCONNECT_TAG_FROM_VIDEO(state, {video, tag}) { + video.tag_ids = video.tag_ids.filter(t_id => t_id != tag.id); + tag.video_ids = tag.video_ids.filter(v_id => v_id != video.id); + }, + }, + actions: { + async loadAll({commit, dispatch}) { + let response = await Api().get('/tags'); + let tags = response.data.data; + tags.forEach(t => { + t.attributes.id = t.id; + t.attributes.video_ids = t.relationships.videos.data.map(v => v.id); + }); + commit('SET_TAGS', tags.map(t => t.attributes)); + }, + connectToVideo({commit}, {video, tag}) { + Api().post('/video_tags', { + video_id: video.id, + tag_id: tag.id + }); + commit('CONNECT_TAG_TO_VIDEO', {video, tag}); + }, + disconnectTagFromVideo({commit}, {video, tag}) { + Api().post('video_tags/delete', { + video_id: video.id, + tag_id: tag.id + }); + commit('DISCONNECT_TAG_FROM_VIDEO', {video, tag}); + }, + async create({commit}, {name}) { + let response = await Api().post('/tags', {name}); + let createdTag = response.data.data.attributes; + createdTag.id = response.data.data.id; + createdTag.video_ids = []; + commit('CREATE_TAG', {tag: createdTag}); + return createdTag; + }, + async updateName({commit}, {tag}) { + Api().put(`/tags/${tag.id}`, tag) + commit('UPDATE_TAG_NAME', {tag}); + }, + delete({commit}, {tag}) { + Api().delete(`/tags/${tag.id}`); + commit('DELETE_TAG', {tag}) + } + }, + getters: { + get: state => id => { + return state.tags.find(t => t.id == id) + }, + } +} \ No newline at end of file diff --git a/src/views/AdminTagList.vue b/src/views/AdminTagList.vue index 983b9ea..3d29415 100644 --- a/src/views/AdminTagList.vue +++ b/src/views/AdminTagList.vue @@ -50,7 +50,9 @@ import { mapState } from 'vuex'; } }, computed: { - ...mapState(['tags']) + ...mapState({ + tags: state => state.tags.tags + }) }, methods: { setToEditing(tag) { @@ -61,14 +63,14 @@ import { mapState } from 'vuex'; }, 1) }, updateTagName(tag) { - this.$store.dispatch('updateTagName', {tag}) + this.$store.dispatch('tags/updateName', {tag}) this.tagEditingId = '' }, deleteTag(tag) { let confirmed = confirm(`Are you sure you want to delete tag ${tag.name}? It is connected to ${tag.video_ids.length} videos.`) if(confirmed){ - this.$store.dispatch('deleteTag', {tag}); + this.$store.dispatch('tags/delete', {tag}); } }, startNewTag(){ @@ -80,7 +82,7 @@ import { mapState } from 'vuex'; }, createTag(){ if(this.newTagName.length > 0) { - this.$store.dispatch('createTag', {name: this.newTagName}) + this.$store.dispatch('tags/create', {name: this.newTagName}) this.newTagName = '' } this.isEditingNewTag = false diff --git a/src/views/AdminVideoShow.vue b/src/views/AdminVideoShow.vue index de9b092..74a2485 100644 --- a/src/views/AdminVideoShow.vue +++ b/src/views/AdminVideoShow.vue @@ -21,8 +21,13 @@ export default { computed: { - ...mapState(['videos', 'tags']), - ...mapGetters(['getTag']), + ...mapState({ + videos: 'videos', + tags: state => state.tags.tags + }), + ...mapGetters({ + getTag: 'tags/get' + }), video(){ return this.videos.find(v => v.id == this.$route.params.id) || {}; }, @@ -34,17 +39,17 @@ async set(newTags) { let createdTag = newTags.find(t => typeof t == 'string') if(createdTag){ - createdTag = await this.$store.dispatch('createTag', {name: createdTag}); - this.$store.dispatch('connectTagToVideo', {tag: createdTag, video: this.video}) + createdTag = await this.$store.dispatch('tags/create', {name: createdTag}); + this.$store.dispatch('tags/connectToVideo', {tag: createdTag, video: this.video}) } else { let addedTags = _.differenceBy(newTags, this.videoTags, 'id'); let removedTags = _.differenceBy(this.videoTags, newTags, 'id'); if(addedTags.length > 0) { - this.$store.dispatch('connectTagToVideo', {tag: addedTags[0], video: this.video}) + this.$store.dispatch('tags/connectToVideo', {tag: addedTags[0], video: this.video}) } if(removedTags.length > 0) { - this.$store.dispatch('disconnectTagFromVideo', {tag: removedTags[0], video: this.video}) + this.$store.dispatch('tags/disconnectFromVideo', {tag: removedTags[0], video: this.video}) } } } diff --git a/src/views/TagVideoList.vue b/src/views/TagVideoList.vue index ea44953..919c8ee 100644 --- a/src/views/TagVideoList.vue +++ b/src/views/TagVideoList.vue @@ -22,7 +22,9 @@ export default { }, computed: { ...mapState(['videos']), - ...mapGetters(['getTag']), + ...mapGetters({ + getTag: 'tags/get' + }), tag(){ return this.getTag(this.$route.params.id) }, diff --git a/src/views/VideoWatch.vue b/src/views/VideoWatch.vue index fbfa3de..eca7181 100644 --- a/src/views/VideoWatch.vue +++ b/src/views/VideoWatch.vue @@ -48,8 +48,11 @@ export default { video(){ return this.videos.find(vid => vid.id == this.$route.params.id) || {} }, - ...mapGetters(['getTag', 'isPlayed']), ...mapState(['videos', 'currentUser']), + ...mapGetters({ + getTag: 'tags/get', + isPlayed: 'isPlayed' + }), playerOptions(){ return { language: 'en',