better media modal loading

This commit is contained in:
Henry Jameson 2021-08-16 01:02:56 +03:00
parent 0507eb6550
commit 7cc19ef2ea
2 changed files with 56 additions and 9 deletions

View file

@ -7,12 +7,14 @@ import Flash from 'src/components/flash/flash.vue'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { import {
faChevronLeft, faChevronLeft,
faChevronRight faChevronRight,
faCircleNotch
} from '@fortawesome/free-solid-svg-icons' } from '@fortawesome/free-solid-svg-icons'
library.add( library.add(
faChevronLeft, faChevronLeft,
faChevronRight faChevronRight,
faCircleNotch
) )
const MediaModal = { const MediaModal = {
@ -22,6 +24,11 @@ const MediaModal = {
Modal, Modal,
Flash Flash
}, },
data () {
return {
loading: false
}
},
computed: { computed: {
showing () { showing () {
return this.$store.state.mediaViewer.activated return this.$store.state.mediaViewer.activated
@ -42,7 +49,7 @@ const MediaModal = {
return this.media.length > 1 return this.media.length > 1
}, },
type () { type () {
return this.currentMedia ? fileTypeService.fileType(this.currentMedia.mimetype) : null return this.currentMedia ? this.getType(this.currentMedia) : null
} }
}, },
created () { created () {
@ -58,6 +65,9 @@ const MediaModal = {
) )
}, },
methods: { methods: {
getType (media) {
return fileTypeService.fileType(media.mimetype)
},
mediaTouchStart (e) { mediaTouchStart (e) {
GestureService.beginSwipe(e, this.mediaSwipeGestureRight) GestureService.beginSwipe(e, this.mediaSwipeGestureRight)
GestureService.beginSwipe(e, this.mediaSwipeGestureLeft) GestureService.beginSwipe(e, this.mediaSwipeGestureLeft)
@ -72,14 +82,25 @@ const MediaModal = {
goPrev () { goPrev () {
if (this.canNavigate) { if (this.canNavigate) {
const prevIndex = this.currentIndex === 0 ? this.media.length - 1 : (this.currentIndex - 1) 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 () { goNext () {
if (this.canNavigate) { if (this.canNavigate) {
const nextIndex = this.currentIndex === this.media.length - 1 ? 0 : (this.currentIndex + 1) 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) { handleKeyupEvent (e) {
if (this.showing && e.keyCode === 27) { // escape if (this.showing && e.keyCode === 27) { // escape

View file

@ -6,27 +6,26 @@
> >
<img <img
v-if="type === 'image'" v-if="type === 'image'"
:class="{ loading }"
class="modal-image" class="modal-image"
:src="currentMedia.url" :src="currentMedia.url"
:key="currentMedia.url"
:alt="currentMedia.description" :alt="currentMedia.description"
:title="currentMedia.description" :title="currentMedia.description"
@touchstart.stop="mediaTouchStart" @touchstart.stop="mediaTouchStart"
@touchmove.stop="mediaTouchMove" @touchmove.stop="mediaTouchMove"
@click="hide" @click="hide"
@load="onImageLoaded"
> >
<VideoAttachment <VideoAttachment
v-if="type === 'video'" v-if="type === 'video'"
class="modal-image" class="modal-image"
:attachment="currentMedia" :attachment="currentMedia"
:controls="true" :controls="true"
:key="currentMedia.url"
/> />
<audio <audio
v-if="type === 'audio'" v-if="type === 'audio'"
class="modal-image" class="modal-image"
:src="currentMedia.url" :src="currentMedia.url"
:key="currentMedia.url"
:alt="currentMedia.description" :alt="currentMedia.description"
:title="currentMedia.description" :title="currentMedia.description"
controls controls
@ -34,7 +33,6 @@
<Flash <Flash
v-if="type === 'flash'" v-if="type === 'flash'"
class="modal-image" class="modal-image"
:key="currentMedia.url"
:src="currentMedia.url" :src="currentMedia.url"
:alt="currentMedia.description" :alt="currentMedia.description"
:title="currentMedia.description" :title="currentMedia.description"
@ -67,6 +65,16 @@
> >
{{ description }} {{ description }}
</span> </span>
<span
v-if="loading"
class="loading-spinner"
>
<FAIcon
spin
icon="circle-notch"
size="5x"
/>
</span>
</Modal> </Modal>
</template> </template>
@ -85,6 +93,7 @@
outline: none; outline: none;
box-shadow: none; box-shadow: none;
} }
&:hover { &:hover {
opacity: 1; opacity: 1;
} }
@ -118,6 +127,23 @@
box-shadow: 0px 5px 15px 0 rgba(0, 0, 0, 0.5); box-shadow: 0px 5px 15px 0 rgba(0, 0, 0, 0.5);
image-orientation: from-image; // NOTE: only FF supports this image-orientation: from-image; // NOTE: only FF supports this
animation: 0.1s cubic-bezier(0.7, 0, 1, 0.6) media-fadein; 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 { .modal-view-button-arrow {