commit: 7cc19ef2eadd9d2c41f46917b2ce80035712aec7
parent 0507eb6550830f7b76910d51200675de0aa9b1de
Author: Henry Jameson <me@hjkos.com>
Date: Mon, 16 Aug 2021 01:02:56 +0300
better media modal loading
Diffstat:
2 files changed, 56 insertions(+), 9 deletions(-)
diff --git a/src/components/media_modal/media_modal.js b/src/components/media_modal/media_modal.js
@@ -7,12 +7,14 @@ import Flash from 'src/components/flash/flash.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faChevronLeft,
- faChevronRight
+ faChevronRight,
+ faCircleNotch
} from '@fortawesome/free-solid-svg-icons'
library.add(
faChevronLeft,
- faChevronRight
+ faChevronRight,
+ faCircleNotch
)
const MediaModal = {
@@ -22,6 +24,11 @@ const MediaModal = {
Modal,
Flash
},
+ data () {
+ return {
+ loading: false
+ }
+ },
computed: {
showing () {
return this.$store.state.mediaViewer.activated
@@ -42,7 +49,7 @@ const MediaModal = {
return this.media.length > 1
},
type () {
- return this.currentMedia ? fileTypeService.fileType(this.currentMedia.mimetype) : null
+ return this.currentMedia ? this.getType(this.currentMedia) : null
}
},
created () {
@@ -58,6 +65,9 @@ const MediaModal = {
)
},
methods: {
+ getType (media) {
+ return fileTypeService.fileType(media.mimetype)
+ },
mediaTouchStart (e) {
GestureService.beginSwipe(e, this.mediaSwipeGestureRight)
GestureService.beginSwipe(e, this.mediaSwipeGestureLeft)
@@ -72,15 +82,26 @@ const MediaModal = {
goPrev () {
if (this.canNavigate) {
const prevIndex = this.currentIndex === 0 ? this.media.length - 1 : (this.currentIndex - 1)
- this.$store.dispatch('setCurrentMedia', this.media[prevIndex])
+ const newMedia = this.media[prevIndex]
+ if (this.getType(newMedia) === 'image') {
+ this.loading = true
+ }
+ this.$store.dispatch('setCurrentMedia', newMedia)
}
},
goNext () {
if (this.canNavigate) {
const nextIndex = this.currentIndex === this.media.length - 1 ? 0 : (this.currentIndex + 1)
- this.$store.dispatch('setCurrentMedia', this.media[nextIndex])
+ const newMedia = this.media[nextIndex]
+ if (this.getType(newMedia) === 'image') {
+ this.loading = true
+ }
+ this.$store.dispatch('setCurrentMedia', newMedia)
}
},
+ onImageLoaded () {
+ this.loading = false
+ },
handleKeyupEvent (e) {
if (this.showing && e.keyCode === 27) { // escape
this.hide()
diff --git a/src/components/media_modal/media_modal.vue b/src/components/media_modal/media_modal.vue
@@ -6,27 +6,26 @@
>
<img
v-if="type === 'image'"
+ :class="{ loading }"
class="modal-image"
:src="currentMedia.url"
- :key="currentMedia.url"
:alt="currentMedia.description"
:title="currentMedia.description"
@touchstart.stop="mediaTouchStart"
@touchmove.stop="mediaTouchMove"
@click="hide"
+ @load="onImageLoaded"
>
<VideoAttachment
v-if="type === 'video'"
class="modal-image"
:attachment="currentMedia"
:controls="true"
- :key="currentMedia.url"
/>
<audio
v-if="type === 'audio'"
class="modal-image"
:src="currentMedia.url"
- :key="currentMedia.url"
:alt="currentMedia.description"
:title="currentMedia.description"
controls
@@ -34,7 +33,6 @@
<Flash
v-if="type === 'flash'"
class="modal-image"
- :key="currentMedia.url"
:src="currentMedia.url"
:alt="currentMedia.description"
:title="currentMedia.description"
@@ -67,6 +65,16 @@
>
{{ description }}
</span>
+ <span
+ v-if="loading"
+ class="loading-spinner"
+ >
+ <FAIcon
+ spin
+ icon="circle-notch"
+ size="5x"
+ />
+ </span>
</Modal>
</template>
@@ -85,6 +93,7 @@
outline: none;
box-shadow: none;
}
+
&:hover {
opacity: 1;
}
@@ -118,6 +127,23 @@
box-shadow: 0px 5px 15px 0 rgba(0, 0, 0, 0.5);
image-orientation: from-image; // NOTE: only FF supports this
animation: 0.1s cubic-bezier(0.7, 0, 1, 0.6) media-fadein;
+
+ &.loading {
+ opacity: 0.5;
+ }
+ }
+
+ .loading-spinner {
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ pointer-events: none;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ svg {
+ color: white;
+ }
}
.modal-view-button-arrow {