Commit 21d1ad5c by Jonathan Thomas

Refactored preview data to live in Vuex. Made clip seconds label react different…

Refactored preview data to live in Vuex. Made clip seconds label react different when it's too small. Added drop-shadow style to context menu buttons. Added editClip action, but not connected yet.
parent f9452bb5
<template>
<div class="row mb-3 p-2 scrolling-container">
<h3>Clips</h3>
<div class="row mb-3 gx-2 p-2 scrolling-container">
<h3>Clips <button v-if="clips" type="button" class="btn btn-danger export-btn">Export</button></h3>
<div class="col-12">
<div class="row gy-2 gx-2 mb-2" v-for="clip in thumbnailedClips" :key="clip.id">
<div class="row gy-2 gx-2 mb-2" v-for="(clip, index) in thumbnailedClips" :key="clip.id">
<div class="col-12 text-center img-parent">
<span class="clip-badge badge">{{ index + 1 }}</span>
<div class="btn-group dropstart context-menu">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="dropdown-toggle bi bi-three-dots-vertical" data-bs-toggle="dropdown" aria-expanded="false" viewBox="0 0 16 16">
<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"/>
......@@ -18,7 +20,7 @@
</ul>
</div>
<div class="clip-label">
<div ref="clip" class="clip-label">
{{ (clip.end - clip.start).toFixed(1) }} Seconds
</div>
......@@ -45,14 +47,14 @@ export default {
this.deleteClip(clip_id)
},
toggleSelection(clipObj) {
if (clipObj.fileObj != this.previewFile) {
if (clipObj.fileObj != this.preview.file) {
this.setPreviewFile(clipObj.fileObj)
} else {
this.setPreviewFile(null)
}
},
getSelectedClass(clipObj) {
if (this.previewFile && clipObj.fileObj.id == this.previewFile.id) {
if (this.preview.file && clipObj.fileObj.id == this.preview.file.id) {
return 'selected'
} else {
return ''
......@@ -65,10 +67,10 @@ export default {
thumbnailedClips() {
return this.clips.filter(clip => clip.thumbnail)
},
...mapState(['clips', 'previewFile', 'latestClip'])
...mapState(['clips', 'preview', 'scrollToClip'])
},
watch: {
latestClip() {
scrollToClip() {
this.$nextTick(() => {
this.$refs.bottom.scrollIntoView({behavior: 'smooth', block: 'end'})
})
......@@ -116,9 +118,28 @@ export default {
.clip-label {
color: #ffffff;
position: absolute;
top: 88%;
bottom: 5%;
z-index: 999;
right: 5%;
font-size: .8em;
background-color: #000000;
border-radius: 4px;
padding: 3px;
opacity: 75%;
}
.export-btn {
float: right;
}
.dropdown-toggle {
filter: drop-shadow(0px 0px 2px #000000);
}
.clip-badge {
position: absolute;
bottom: 5%;
left: 5%;
padding: 8px;
opacity: 75%;
background-color: #000000;
border-radius: 4px;
}
</style>
\ No newline at end of file
<template>
<div class="row mb-3 gy-2 gx-2 p-2 scrolling-container">
<div class="row mb-3 gx-2 p-2 scrolling-container">
<h3>Files <button type="button" class="btn btn-primary upload-btn" @click="chooseFiles">Upload</button></h3>
<div class="col-sm-12">
<div class="form-floating mb-3">
......@@ -75,14 +75,14 @@ export default {
await this.deleteFile(file.id)
},
toggleSelection(fileObject) {
if (fileObject != this.previewFile) {
if (fileObject != this.preview.file) {
this.setPreviewFile(fileObject)
} else {
this.setPreviewFile(null)
}
},
getSelectedClass(fileObject) {
if (this.previewFile && fileObject.id == this.previewFile.id) {
if (this.preview.file && fileObject.id == this.preview.file.id) {
return 'selected'
} else {
return ''
......@@ -103,7 +103,7 @@ export default {
searchedFiles() {
return this.files.filter(file => path.basename(file.media).toLowerCase().includes(this.search.toLowerCase()) && file.thumbnail)
},
...mapState(['files', 'previewFile', 'uploads'])
...mapState(['files', 'preview', 'uploads'])
},
mounted() {
this.setFiles([])
......@@ -145,4 +145,7 @@ export default {
min-width: 5em;
opacity: 80%;
}
.dropdown-toggle {
filter: drop-shadow(0px 0px 2px #000000);
}
</style>
\ No newline at end of file
......@@ -12,8 +12,14 @@ export default createStore({
uploads: [],
project: null,
user: null,
previewFile: null,
latestClip: null,
preview: {
file: null,
clip: null,
start: 0.0,
end: 1.0,
position: 0.0
},
scrollToClip: null,
},
mutations: {
......@@ -69,9 +75,15 @@ export default createStore({
state.clips = clips
if (!clips) {
// clear latest clip if no clips
state.latestClip = null
state.scrollToClip = null
}
},
setClip(state, clipObj) {
state.clips = [
...state.clips = state.clips.filter(clip => clip.id != clipObj.id),
clipObj
]
},
deleteClip(state, clip_id) {
state.clips = state.clips.filter(clip => clip.id != clip_id)
},
......@@ -82,12 +94,27 @@ export default createStore({
payload.obj
]
if (payload.latest) {
state.latestClip = payload.obj
state.scrollToClip = payload.obj
}
}
},
setPreview(state, payload) {
state.preview.start = payload.start
state.preview.end = payload.end
},
setPreviewPosition(state, position) {
state.preview.position = position
},
setPreviewFile(state, file) {
state.previewFile = file
state.preview.file = file
state.preview.start = 0.0
state.preview.end = 1.0
},
setPreviewClip(state, clipObj) {
state.preview.clip = clipObj
state.preview.start = clipObj.start
state.preview.end = clipObj.end
state.preview.position = clipObj.start
},
addUpload(state, upload) {
state.uploads.push(upload)
......@@ -203,6 +230,21 @@ export default createStore({
commit('addError', err.response.data)
}
},
async editClip({dispatch, commit}, payload) {
try {
const response = await instance.post(`${payload.project_url}clips/`, payload.data)
let clipObj = response.data
const file_response = await instance.get(clipObj.file)
clipObj.fileObj = file_response.data
commit('addClip', clipObj)
let fps = clipObj.json.reader.fps.num / clipObj.json.reader.fps.den
let thumbnail_payload = { obj: clipObj, frame: clipObj.start * fps, latest: true }
dispatch('attachThumbnail', thumbnail_payload)
} catch(err) {
commit('addError', err.response.data)
}
},
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