Commit 0448bd13 by Jonathan Thomas

Refactored moveClip into Vuex action, and invoke this action on both 'Move Clip'…

Refactored moveClip into Vuex action, and invoke this action on both 'Move Clip' and 'Update Clip'... to fix all clip 'positions'
parent d1d3690c
......@@ -20,8 +20,8 @@
<path d="M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z"/>
</svg>
<ul class="dropdown-menu small-dropdown">
<li><a v-if="index > 0" class="dropdown-item" href="#" @click="moveClip('up', clip, index, index - 1)">Move Up</a></li>
<li><a v-if="index < clips.length - 1" class="dropdown-item" href="#" @click="moveClip('down', clip, index, index + 1)">Move Down</a></li>
<li><a v-if="index > 0" class="dropdown-item" href="#" @click="moveClipBtn('up', clip, index, index - 1)">Move Up</a></li>
<li><a v-if="index < clips.length - 1" class="dropdown-item" href="#" @click="moveClipBtn('down', clip, index, index + 1)">Move Down</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#" @click="deleteClipBtn(clip.id)">Delete</a></li>
</ul>
......@@ -53,36 +53,9 @@ export default {
deleteClipBtn(clip_id) {
this.deleteClip(clip_id)
},
moveClip(direction, clipObj, start_index, dest_index) {
let local_clips = [...this.thumbnailedClips]
let reordered_clips = this.reorder(local_clips, start_index, dest_index)
let pos = 0.0
for (let clip of reordered_clips) {
clip.position = pos
let payload = { data: clip, latest: false, thumbnail: false }
if (clip.id == clipObj.id) {
payload.latest = true
}
this.editClip(payload)
pos += (clip.end - clip.start)
}
},
reorder(array, sourceIndex, destinationIndex) {
const smallerIndex = Math.min(sourceIndex, destinationIndex)
const largerIndex = Math.max(sourceIndex, destinationIndex)
return [
...array.slice(0, smallerIndex),
...(sourceIndex < destinationIndex
? array.slice(smallerIndex + 1, largerIndex + 1)
: []),
array[sourceIndex],
...(sourceIndex > destinationIndex
? array.slice(smallerIndex, largerIndex)
: []),
...array.slice(largerIndex + 1),
]
moveClipBtn(direction, clip, current, dest) {
let payload = {direction, clip, current, dest }
this.moveClip(payload)
},
toggleSelection(clipObj) {
if (clipObj != this.preview.clip) {
......@@ -108,14 +81,11 @@ export default {
this.setScrollToClip(null)
}
},
...mapActions(['loadClips', 'createClip', 'deleteClip', 'editClip']),
...mapActions(['loadClips', 'createClip', 'deleteClip', 'editClip', 'moveClip']),
...mapMutations((['setPreviewClip', 'setClips', 'setScrollToClip']))
},
computed: {
thumbnailedClips() {
return this.clips.filter(clip => clip.thumbnail).sort((a, b) => a.position - b.position)
},
...mapGetters(['totalClipDuration']),
...mapGetters(['totalClipDuration', 'thumbnailedClips']),
...mapState(['clips', 'preview', 'scrollToClip'])
},
watch: {
......
......@@ -69,6 +69,7 @@
<script>
import {mapState, mapActions, mapGetters, mapMutations} from "vuex";
import {fixImageDuration} from "../store/axios";
export default {
name: "Preview.vue",
......@@ -86,21 +87,34 @@ export default {
},
methods: {
async createClipBtn() {
let data = {
"file": this.preview.file.url,
"position": this.totalClipDuration,
"start": this.preview.start * this.preview.file.json.duration,
"end": this.preview.end * this.preview.file.json.duration,
"layer": 1,
"project": this.project.url,
"json": {}
if (!this.preview.clip) {
// Create new clip
let data = {
"file": this.preview.file.url,
"position": this.totalClipDuration,
"start": this.preview.start * fixImageDuration(this.preview.file.json.duration),
"end": this.preview.end * fixImageDuration(this.preview.file.json.duration),
"layer": 1,
"project": this.project.url,
"json": {}
}
let payload = {project_id: this.project.id, project_url: this.project.url, data}
await this.createClip(payload)
}
let payload = {
project_id: this.project.id,
project_url: this.project.url,
data
else
{
// Edit existing clip
let clipObj = this.preview.clip
clipObj.start = this.preview.start * fixImageDuration(this.preview.file.json.duration)
clipObj.end = this.preview.end * fixImageDuration(this.preview.file.json.duration)
let payload = { data: clipObj, latest: false, thumbnail: true }
await this.editClip(payload)
// Re-order clips (and fix 'position' to be valid again)
let move_payload = {direction: null, clip: clipObj, current: -1, dest: -1 }
await this.moveClip(move_payload)
}
await this.createClip(payload)
this.setPreviewFile(null)
},
togglePause() {
if (this.$refs.video) {
......@@ -228,8 +242,8 @@ export default {
let percent_x = (relative_x / timeline_bounds.width)
return percent_x
},
...mapActions(['createClip']),
...mapMutations(['setPreview', 'setPreviewPosition'])
...mapActions(['createClip', 'editClip', 'moveClip']),
...mapMutations(['setPreview', 'setPreviewPosition', 'setPreviewFile'])
},
computed: {
...mapState(['preview']),
......
......@@ -24,4 +24,21 @@ function fixImageDuration(duration) {
}
}
export { instance, blob_instance, fixImageDuration };
\ No newline at end of file
function reorderArray(array, sourceIndex, destinationIndex) {
const smallerIndex = Math.min(sourceIndex, destinationIndex)
const largerIndex = Math.max(sourceIndex, destinationIndex)
return [
...array.slice(0, smallerIndex),
...(sourceIndex < destinationIndex
? array.slice(smallerIndex + 1, largerIndex + 1)
: []),
array[sourceIndex],
...(sourceIndex > destinationIndex
? array.slice(smallerIndex, largerIndex)
: []),
...array.slice(largerIndex + 1),
]
}
export { instance, blob_instance, fixImageDuration, reorderArray };
\ No newline at end of file
import { createStore } from 'vuex'
import { v4 as uuidv4 } from "uuid"
import { instance, blob_instance, fixImageDuration } from "./axios"
import { instance, blob_instance, fixImageDuration, reorderArray } from "./axios"
export default createStore({
......@@ -165,6 +165,9 @@ export default createStore({
isAuthenticated: state => !!state.user,
totalClipDuration: state => {
return state.clips.map(clip => clip.end - clip.start).reduce((prev, curr) => prev + curr, 0.0)
},
thumbnailedClips: state => {
return state.clips.filter(clip => clip.thumbnail).sort((a, b) => a.position - b.position)
}
},
actions: {
......@@ -276,6 +279,23 @@ export default createStore({
commit('addError', err.response.data)
}
},
async moveClip({dispatch, getters}, payload) {
let local_clips = [...getters.thumbnailedClips]
let reordered_clips = local_clips
if (payload.current != payload.dest) {
reordered_clips = reorderArray(local_clips, payload.current, payload.dest)
}
let pos = 0.0
for (let c of reordered_clips) {
c.position = pos
let edit_payload = { data: c, latest: false, thumbnail: false }
if (c.id == payload.clip.id) {
edit_payload.latest = true
}
dispatch('editClip', edit_payload)
pos += (c.end - c.start)
}
},
async deleteClip({commit}, clip_id) {
try {
await instance.delete(`clips/${clip_id}/`)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment