media_modal.js (4487B)
- import StillImage from '../still-image/still-image.vue'
- import VideoAttachment from '../video_attachment/video_attachment.vue'
- import Modal from '../modal/modal.vue'
- import PinchZoom from '../pinch_zoom/pinch_zoom.vue'
- import SwipeClick from '../swipe_click/swipe_click.vue'
- import GestureService from '../../services/gesture_service/gesture_service'
- import Flash from 'src/components/flash/flash.vue'
- import fileTypeService from '../../services/file_type/file_type.service.js'
- import { library } from '@fortawesome/fontawesome-svg-core'
- import {
- faChevronLeft,
- faChevronRight,
- faCircleNotch,
- faTimes
- } from '@fortawesome/free-solid-svg-icons'
- library.add(
- faChevronLeft,
- faChevronRight,
- faCircleNotch,
- faTimes
- )
- const MediaModal = {
- components: {
- StillImage,
- VideoAttachment,
- PinchZoom,
- SwipeClick,
- Modal,
- Flash
- },
- data () {
- return {
- loading: false,
- swipeDirection: GestureService.DIRECTION_LEFT,
- swipeThreshold: () => {
- const considerableMoveRatio = 1 / 4
- return window.innerWidth * considerableMoveRatio
- },
- pinchZoomMinScale: 1,
- pinchZoomScaleResetLimit: 1.2
- }
- },
- computed: {
- showing () {
- return this.$store.state.mediaViewer.activated
- },
- media () {
- return this.$store.state.mediaViewer.media
- },
- description () {
- return this.currentMedia.description
- },
- currentIndex () {
- return this.$store.state.mediaViewer.currentIndex
- },
- currentMedia () {
- return this.media[this.currentIndex]
- },
- canNavigate () {
- return this.media.length > 1
- },
- type () {
- return this.currentMedia ? this.getType(this.currentMedia) : null
- },
- swipeDisableClickThreshold () {
- // If there is only one media, allow more mouse movements to close the modal
- // because there is less chance that the user wants to switch to another image
- return () => this.canNavigate ? 1 : 30
- }
- },
- methods: {
- getType (media) {
- return fileTypeService.fileType(media.mimetype)
- },
- hide () {
- // HACK: Closing immediately via a touch will cause the click
- // to be processed on the content below the overlay
- const transitionTime = 100 // ms
- setTimeout(() => {
- this.$store.dispatch('closeMediaViewer')
- }, transitionTime)
- },
- hideIfNotSwiped (event) {
- // If we have swiped over SwipeClick, do not trigger hide
- const comp = this.$refs.swipeClick
- if (!comp) {
- this.hide()
- } else {
- comp.$gesture.click(event)
- }
- },
- goPrev () {
- if (this.canNavigate) {
- const prevIndex = this.currentIndex === 0 ? this.media.length - 1 : (this.currentIndex - 1)
- 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)
- const newMedia = this.media[nextIndex]
- if (this.getType(newMedia) === 'image') {
- this.loading = true
- }
- this.$store.dispatch('setCurrentMedia', newMedia)
- }
- },
- onImageLoaded () {
- this.loading = false
- },
- handleSwipePreview (offsets) {
- this.$refs.pinchZoom.setTransform({ scale: 1, x: offsets[0], y: 0 })
- },
- handleSwipeEnd (sign) {
- this.$refs.pinchZoom.setTransform({ scale: 1, x: 0, y: 0 })
- if (sign > 0) {
- this.goNext()
- } else if (sign < 0) {
- this.goPrev()
- }
- },
- handleKeyupEvent (e) {
- if (this.showing && e.keyCode === 27) { // escape
- this.hide()
- }
- },
- handleKeydownEvent (e) {
- if (!this.showing) {
- return
- }
- if (e.keyCode === 39) { // arrow right
- this.goNext()
- } else if (e.keyCode === 37) { // arrow left
- this.goPrev()
- }
- }
- },
- mounted () {
- window.addEventListener('popstate', this.hide)
- document.addEventListener('keyup', this.handleKeyupEvent)
- document.addEventListener('keydown', this.handleKeydownEvent)
- },
- unmounted () {
- window.removeEventListener('popstate', this.hide)
- document.removeEventListener('keyup', this.handleKeyupEvent)
- document.removeEventListener('keydown', this.handleKeydownEvent)
- }
- }
- export default MediaModal