Commit 5f49e014 by Jonathan Thomas

Improving preview title (and hiding it sometimes) for a smoother flow for new…

Improving preview title (and hiding it sometimes) for a smoother flow for new users (upload a file to begin, choose a file to create your first clip, etc...)
parent 8e28b73b
<template> <template>
<!-- File header & Upload button --> <!-- File header & Upload button -->
<div class="row"> <div class="row">
<h3>Files <button type="button" class="btn btn-primary upload-btn" @click="chooseFiles">Upload</button></h3> <div class="col-12">
<div class="col-sm-12"> <div class="files-header">
<h3 class="mb-0">Files</h3>
<div class="btn-group" role="group" aria-label="File actions">
<button
v-if="hasFiles"
type="button"
class="btn filter-btn"
:class="{ active: filterVisible }"
title="Toggle search filter"
:aria-pressed="filterVisible"
@click="toggleFilter"
>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-funnel" viewBox="0 0 16 16">
<path d="M1.5 1.5A.5.5 0 0 1 2 1h12a.5.5 0 0 1 .39.812L10 7.07v6.43a.5.5 0 0 1-.757.429l-2-1.2A.5.5 0 0 1 7 12.3V7.07L1.11 1.812A.5.5 0 0 1 1.5 1.5z"/>
</svg>
</button>
<button
type="button"
class="btn btn-primary upload-btn"
title="Upload new files"
@click="chooseFiles"
>
Upload
</button>
</div>
</div>
</div>
<div class="col-sm-12" v-if="filterVisible && hasFiles">
<div class="form-floating mb-3"> <div class="form-floating mb-3">
<input type="text" class="form-control" id="floatingInput" placeholder="Search" v-model="search"> <input type="text" class="form-control" id="floatingInput" placeholder="Search" v-model="search">
<label for="floatingInput">Search</label> <label for="floatingInput">Search</label>
...@@ -65,13 +92,17 @@ export default { ...@@ -65,13 +92,17 @@ export default {
data() { data() {
return { return {
search: "", search: "",
show_spinner: false show_spinner: false,
filterVisible: false
} }
}, },
methods: { methods: {
chooseFiles() { chooseFiles() {
this.$refs.fileUpload.click() this.$refs.fileUpload.click()
}, },
toggleFilter() {
this.filterVisible = !this.filterVisible
},
async fileChanged(event) { async fileChanged(event) {
let results = [] let results = []
for (let file of event.target.files) { for (let file of event.target.files) {
...@@ -122,7 +153,19 @@ export default { ...@@ -122,7 +153,19 @@ export default {
}, },
computed: { computed: {
searchedFiles() { searchedFiles() {
return this.files.filter(file => path.basename(file.media).toLowerCase().includes(this.search.toLowerCase()) && file.thumbnail) const query = this.filterVisible ? this.search.toLowerCase().trim() : ''
return this.files.filter(file => {
if (!file.thumbnail) {
return false
}
if (!query) {
return true
}
return path.basename(file.media).toLowerCase().includes(query)
})
},
hasFiles() {
return Array.isArray(this.files) && this.files.length > 0
}, },
...mapState(['files', 'preview', 'uploads']) ...mapState(['files', 'preview', 'uploads'])
}, },
...@@ -144,8 +187,27 @@ export default { ...@@ -144,8 +187,27 @@ export default {
height: 18vh; height: 18vh;
overflow: auto; overflow: auto;
} }
.upload-btn { .files-header {
float: right; display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 0.5rem;
}
.filter-btn {
background-color: #e0e0e0;
border-color: #e0e0e0;
color: #495057;
display: inline-flex;
align-items: center;
justify-content: center;
}
.filter-btn svg {
display: block;
}
.filter-btn.active {
background-color: #0d6efd;
border-color: #0d6efd;
color: #fff;
} }
.selected { .selected {
border: #0d6efd 4px solid; border: #0d6efd 4px solid;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<!-- Preview header --> <!-- Preview header -->
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-xs-12">
<h3>{{ previewHeading }}</h3> <h3 v-if="previewHeading">{{ previewHeading }}</h3>
</div> </div>
</div> </div>
...@@ -78,7 +78,7 @@ ...@@ -78,7 +78,7 @@
<!-- No Preview / No File message --> <!-- No Preview / No File message -->
<div v-if="!hasPreviewFile" class="mb-5 text-center" style="margin-top: 7em;"> <div v-if="!hasPreviewFile" class="mb-5 text-center" style="margin-top: 7em;">
<div class="col-lg-6 mx-auto"> <div class="col-lg-6 mx-auto">
<p class="lead">Upload or select a video to begin!</p> <p class="lead">{{ emptyStateMessage }}</p>
</div> </div>
</div> </div>
...@@ -515,7 +515,7 @@ export default { ...@@ -515,7 +515,7 @@ export default {
...mapMutations(['setPreview', 'setPreviewPosition', 'setPreviewFile']) ...mapMutations(['setPreview', 'setPreviewPosition', 'setPreviewFile'])
}, },
computed: { computed: {
...mapState(['preview']), ...mapState(['preview', 'files', 'clips']),
...mapGetters(['totalClipDuration']), ...mapGetters(['totalClipDuration']),
isEditingClip() { isEditingClip() {
return !!this.preview.clip return !!this.preview.clip
...@@ -525,7 +525,7 @@ export default { ...@@ -525,7 +525,7 @@ export default {
}, },
previewHeading() { previewHeading() {
if (!this.hasPreviewFile) { if (!this.hasPreviewFile) {
return 'Preview' return ''
} }
return this.isEditingClip ? 'Edit Clip' : 'Create Clip' return this.isEditingClip ? 'Edit Clip' : 'Create Clip'
}, },
...@@ -536,6 +536,21 @@ export default { ...@@ -536,6 +536,21 @@ export default {
return false return false
} }
}, },
hasAnyFiles() {
return Array.isArray(this.files) && this.files.length > 0
},
hasAnyClips() {
return Array.isArray(this.clips) && this.clips.length > 0
},
emptyStateMessage() {
if (!this.hasAnyFiles) {
return 'Upload a file to begin'
}
if (this.hasAnyFiles && !this.hasAnyClips) {
return 'Choose a file to add your first clip'
}
return 'Choose a file or clip to continue'
},
mediaExtension() { mediaExtension() {
if (!this.preview.file || !this.preview.file.media) { if (!this.preview.file || !this.preview.file.media) {
return '' return ''
......
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