Commit 8be13de4 by Jonathan Thomas

Adding loading spinners to projects, files, clips, and preview media (image and video)

parent c49e48a7
<template> <template>
<div class="row mb-3 gx-2 p-2 scrolling-container"> <div class="row mb-3 gx-2 p-2 scrolling-container">
<h3 v-if="thumbnailedClips.length > 0">Clips <button type="button" class="btn btn-danger export-btn">Export {{clips.length}} Clips</button></h3> <h3 v-if="thumbnailedClips.length > 0">Clips <button type="button" class="btn btn-danger export-btn">Export {{clips.length}} Clips</button></h3>
<div class="col-12">
<!-- Loading spinner -->
<div v-if="show_spinner" class="md-5 p-4 text-center">
<div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
<div class="col-12">
<div class="row gy-2 gx-2 mb-2" v-for="(clip, index) 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"> <div class="col-12 text-center img-parent">
...@@ -38,7 +45,9 @@ export default { ...@@ -38,7 +45,9 @@ export default {
name: "Clips.vue", name: "Clips.vue",
props: ['project'], props: ['project'],
data() { data() {
return {} return {
show_spinner: false
}
}, },
methods: { methods: {
deleteClipBtn(clip_id) { deleteClipBtn(clip_id) {
...@@ -123,8 +132,10 @@ export default { ...@@ -123,8 +132,10 @@ export default {
} }
}, },
async mounted() { async mounted() {
this.show_spinner = true
this.setClips([]) this.setClips([])
await this.loadClips(this.project.id) await this.loadClips(this.project.id)
this.show_spinner = false
}, },
unmounted() { unmounted() {
this.setClips([]) this.setClips([])
......
...@@ -7,6 +7,14 @@ ...@@ -7,6 +7,14 @@
<label for="floatingInput">Search</label> <label for="floatingInput">Search</label>
</div> </div>
</div> </div>
<!-- Loading spinner -->
<div v-if="show_spinner" class="md-5 p-4 text-center">
<div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
<div v-for="file in searchedFiles" :key="file.id" class="col-sm-12 col-lg-4" style="position: relative;"> <div v-for="file in searchedFiles" :key="file.id" class="col-sm-12 col-lg-4" style="position: relative;">
<div class="btn-group dropstart context-menu"> <div class="btn-group dropstart context-menu">
...@@ -43,7 +51,8 @@ export default { ...@@ -43,7 +51,8 @@ export default {
props: ['project'], props: ['project'],
data() { data() {
return { return {
search: "" search: "",
show_spinner: false
} }
}, },
methods: { methods: {
...@@ -105,9 +114,11 @@ export default { ...@@ -105,9 +114,11 @@ export default {
}, },
...mapState(['files', 'preview', 'uploads']) ...mapState(['files', 'preview', 'uploads'])
}, },
mounted() { async mounted() {
this.show_spinner = true
this.setFiles([]) this.setFiles([])
this.loadFiles(this.project.id) await this.loadFiles(this.project.id)
this.show_spinner = false
}, },
unmounted() { unmounted() {
this.setFiles([]) this.setFiles([])
......
...@@ -6,11 +6,19 @@ ...@@ -6,11 +6,19 @@
</div> </div>
<div class="row"> <div class="row">
<!-- Loading spinner -->
<div v-if="show_spinner" class="md-5 p-5 text-center spinner-container">
<div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
<div class="col-sm-12"> <div class="col-sm-12">
<video ref="video" v-if="!isImage && hasPreviewFile" @loadeddata="videoLoaded" @timeupdate="videoTimeUpdate" @pause="togglePause" @play="togglePause" loop preload="" poster="" class="video-responsive"> <video ref="video" v-if="!isImage && hasPreviewFile" v-show="media_loaded" @loadeddata="videoLoaded" @timeupdate="videoTimeUpdate" @pause="togglePause" @play="togglePause" loop preload="" poster="" class="video-responsive">
<source :type="previewFormat" :src="preview.file.media"> <source :type="previewFormat" :src="preview.file.media">
</video> </video>
<img v-if="isImage && hasPreviewFile" :src="preview.file.media" class="img-fluid img-thumbnail" /> <img v-if="isImage && hasPreviewFile" v-show="media_loaded" :src="preview.file.media" @load="imageLoaded" class="img-fluid img-thumbnail" />
</div> </div>
</div> </div>
...@@ -57,7 +65,6 @@ ...@@ -57,7 +65,6 @@
<p class="lead">Upload or select a video to begin!</p> <p class="lead">Upload or select a video to begin!</p>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
...@@ -72,7 +79,9 @@ export default { ...@@ -72,7 +79,9 @@ export default {
is_paused: true, is_paused: true,
marker_width: 12, marker_width: 12,
marker_width_percent: 0.0, marker_width_percent: 0.0,
clipSizeClass: "" clipSizeClass: "",
show_spinner: false,
media_loaded: false
} }
}, },
methods: { methods: {
...@@ -120,10 +129,16 @@ export default { ...@@ -120,10 +129,16 @@ export default {
} }
}, },
videoLoaded() { videoLoaded() {
this.show_spinner = false
this.media_loaded = true
if (this.$refs.video && this.preview.clip) { if (this.$refs.video && this.preview.clip) {
this.$refs.video.currentTime = this.preview.clip.start this.$refs.video.currentTime = this.preview.clip.start
} }
}, },
imageLoaded() {
this.show_spinner = false
this.media_loaded = true
},
startDrag(e, marker) { startDrag(e, marker) {
if (e) { if (e) {
e.preventDefault() e.preventDefault()
...@@ -239,6 +254,10 @@ export default { ...@@ -239,6 +254,10 @@ export default {
}, },
watch: { watch: {
'preview.file': function() { 'preview.file': function() {
if (this.preview.file) {
this.show_spinner = true
this.media_loaded = false
}
if (this.$refs.video) { if (this.$refs.video) {
this.is_paused = true this.is_paused = true
this.$refs.video.pause() this.$refs.video.pause()
...@@ -316,4 +335,12 @@ video { ...@@ -316,4 +335,12 @@ video {
.img-thumbnail { .img-thumbnail {
width: 100%!important; width: 100%!important;
} }
.spinner-border {
margin-top: 100px;
width: 4em;
height: 4em;
}
.spinner-container {
min-height: 300px;
}
</style> </style>
\ No newline at end of file
...@@ -9,6 +9,13 @@ ...@@ -9,6 +9,13 @@
</div> </div>
</div> </div>
<!-- Loading spinner -->
<div v-if="show_spinner" class="md-5 p-4 text-center">
<div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
<!-- Project cards --> <!-- Project cards -->
<div class="row gy-3 gx-3"> <div class="row gy-3 gx-3">
<div class="col-sm-3" v-for="project in projects" :key="project.id" > <div class="col-sm-3" v-for="project in projects" :key="project.id" >
...@@ -94,7 +101,8 @@ export default { ...@@ -94,7 +101,8 @@ export default {
project_fps_num: 30, project_fps_num: 30,
project_fps_den: 1, project_fps_den: 1,
project_width: 1920, project_width: 1920,
project_height: 1080 project_height: 1080,
show_spinner: false
} }
}, },
methods: { methods: {
...@@ -141,7 +149,9 @@ export default { ...@@ -141,7 +149,9 @@ export default {
...mapState(['projects']) ...mapState(['projects'])
}, },
async mounted() { async mounted() {
this.show_spinner = true
await this.loadProjects() await this.loadProjects()
this.show_spinner = false
} }
} }
</script> </script>
...@@ -150,4 +160,8 @@ export default { ...@@ -150,4 +160,8 @@ export default {
button { button {
margin-left: 5px; margin-left: 5px;
} }
.spinner-border {
width: 3em!important;
height: 3em!important;
}
</style> </style>
\ No newline at end of file
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