- pdf implementation

- file preview refactoring
This commit is contained in:
Peter Papp
2021-04-16 10:27:09 +02:00
parent 9105ce8bb1
commit b105c9fc8f
15 changed files with 2339 additions and 1514 deletions

View File

@@ -267,13 +267,14 @@ export default {
events.$emit('popup:open', {name: 'move', item: [this.item]})
},
shareItem() {
if (this.item.shared) {
// Open edit share popup
events.$emit('popup:open', {name: 'share-edit', item: this.item})
} else {
// Open create share popup
events.$emit('popup:open', {name: 'share-create', item: this.item})
}
let event = this.item.shared
? 'share-edit'
: 'share-create'
events.$emit('popup:open', {
name: event,
item: this.item
})
},
addToFavourites() {
// Check if folder is in favourites and then add/remove from favourites
@@ -385,12 +386,6 @@ export default {
}
}
},
mounted() {
events.$on('actualShowingImage:ContextMenu', (item) => {
this.item = item
})
},
created() {
events.$on('showContextMenuPreview:show', (item) => {
if (!this.showFromPreview) {

View File

@@ -213,20 +213,14 @@ export default {
events.$emit('popup:open', { name: 'move', item: this.fileInfoDetail })
},
shareItem() {
if (this.fileInfoDetail[0]) {
//ADD BY M
if (this.fileInfoDetail[0].shared) {
events.$emit('popup:open', {
name: 'share-edit',
item: this.fileInfoDetail[0]
})
} else {
events.$emit('popup:open', {
name: 'share-create',
item: this.fileInfoDetail[0]
})
}
}
let event = this.fileInfoDetail[0].shared
? 'share-edit'
: 'share-create'
events.$emit('popup:open', {
name: event,
item: this.fileInfoDetail[0]
})
}
},
mounted() {

View File

@@ -226,9 +226,9 @@ export default {
}
if (this.$isMobile()) {
if (this.isImage || this.isVideo || this.isAudio) {
if (this.isImage || this.isVideo || this.isAudio || this.isPdf) {
this.$store.commit('GET_FILEINFO_DETAIL', this.item)
events.$emit('fileFullPreview:show')
events.$emit('file-preview:show')
}
}
}
@@ -242,10 +242,10 @@ export default {
}
},
goToItem() {
if (this.isImage || this.isVideo || this.isAudio) {
events.$emit('fileFullPreview:show')
if (this.isImage || this.isVideo || this.isAudio || this.isPdf) {
events.$emit('file-preview:show')
} else if (this.isFile || !this.isFolder && !this.isPdf && !this.isVideo && !this.isAudio && !this.isImage) {
} else if (this.isFile || !this.isFolder && !this.isVideo && !this.isAudio && !this.isImage) {
this.$downloadFile(this.item.file_url, this.item.name + '.' + this.item.mimetype)
} else if (this.isFolder) {

View File

@@ -222,9 +222,9 @@ export default {
}
if (this.$isMobile()) {
if (this.isImage || this.isVideo || this.isAudio) {
if (this.isImage || this.isVideo || this.isAudio || this.isPdf) {
this.$store.commit('GET_FILEINFO_DETAIL', this.item)
events.$emit('fileFullPreview:show')
events.$emit('file-preview:show')
}
}
}
@@ -238,10 +238,10 @@ export default {
}
},
goToItem() {
if (this.isImage || this.isVideo || this.isAudio) {
events.$emit('fileFullPreview:show')
if (this.isImage || this.isVideo || this.isAudio || this.isPdf) {
events.$emit('file-preview:show')
} else if (this.isFile || !this.isFolder && !this.isPdf && !this.isVideo && !this.isAudio && !this.isImage) {
} else if (this.isFile || !this.isFolder && !this.isVideo && !this.isAudio && !this.isImage) {
this.$downloadFile(this.item.file_url, this.item.name + '.' + this.item.mimetype)
} else if (this.isFolder) {

View File

@@ -133,17 +133,14 @@ export default {
events.$emit('popup:open', {name: 'move', item: [this.fileInfoDetail[0]]})
},
shareItem() {
if (this.fileInfoDetail[0].shared) {
events.$emit('popup:open', {
name: 'share-edit',
item: this.fileInfoDetail[0]
})
} else {
events.$emit('popup:open', {
name: 'share-create',
item: this.fileInfoDetail[0]
})
}
let event = this.fileInfoDetail[0].shared
? 'share-edit'
: 'share-create'
events.$emit('popup:open', {
name: event,
item: this.fileInfoDetail[0]
})
},
addToFavourites() {
if (this.favourites && !this.favourites.find(el => el.id === this.fileInfoDetail[0].id)) {

View File

@@ -1,94 +1,93 @@
<template>
<div
v-if="showFullPreview"
class="file-full-preview-wrapper"
id="fileFullPreview"
ref="filePreview"
tabindex="-1"
@click="closeContextMenu"
@keydown.esc=";(showFullPreview = false), hideContextMenu()"
@keydown.right="next"
@keydown.left="prev"
>
v-if="showFullPreview"
class="file-full-preview-wrapper"
id="fileFullPreview"
ref="filePreview"
tabindex="-1"
@click="closeContextMenu"
@keydown.esc="(showFullPreview = false), hideContextMenu()"
@keydown.right="next"
@keydown.left="prev"
>
<FilePreviewNavigationPanel />
<MediaFullPreview />
<FilePreviewActions />
</div>
</template>
<script>
import { events } from '@/bus'
import { mapGetters } from 'vuex'
import FilePreviewNavigationPanel from '@/components/FilesView/FilePreviewNavigationPanel'
import MediaFullPreview from '@/components/FilesView/MediaFullPreview'
import {mapGetters} from 'vuex'
import {events} from '@/bus'
import MediaFullPreview from '@/components/FilesView/MediaFullPreview'
import FilePreviewActions from '@/components/FilesView/FilePreviewActions'
import FilePreviewNavigationPanel from '@/components/FilesView/FilePreviewNavigationPanel'
export default {
name: 'FilePreview',
components: {
FilePreviewNavigationPanel,
MediaFullPreview,
},
computed: {
...mapGetters([
'fileInfoDetail',
'data'
])
},
data() {
return {
showFullPreview: false
}
},
methods: {
closeContextMenu(event) {
if ((event.target.parentElement.id || event.target.id) === 'fast-preview-menu') {
return
}
export default {
name: 'FilePreview',
components: {
MediaFullPreview,
FilePreviewNavigationPanel,
FilePreviewActions
},
computed: {
...mapGetters(['fileInfoDetail', 'data'])
},
data() {
return {
showFullPreview: false
}
},
methods: {
closeContextMenu(event) {
if ((event.target.parentElement.id || event.target.id) === 'fast-preview-menu') {
return
} else {
events.$emit('showContextMenuPreview:hide')
}
},
next: function() {
events.$emit('filePreviewAction:next')
},
prev: function() {
events.$emit('filePreviewAction:prev')
},
hideContextMenu() {
events.$emit('showContextMenuPreview:hide')
}
},
events.$emit('showContextMenuPreview:hide')
},
next() {
events.$emit('file-preview:next')
},
prev() {
events.$emit('file-preview:prev')
},
hideContextMenu() {
events.$emit('showContextMenuPreview:hide')
}
},
updated() {
//Focus file preview for key binding
if (this.showFullPreview) {
this.$refs.filePreview.focus()
}
},
mounted() {
events.$on('fileFullPreview:show', () => {
this.showFullPreview = true
})
events.$on('fileFullPreview:hide', () => {
this.showFullPreview = false
})
}
}
updated() {
//Focus file preview for key binding
if (this.showFullPreview) {
this.$refs.filePreview.focus()
}
},
mounted() {
events.$on('file-preview:show', () => {
this.showFullPreview = true
})
events.$on('file-preview:hide', () => {
this.showFullPreview = false
})
}
}
</script>
<style lang="scss" scoped>
@import '@assets/vuefilemanager/_variables';
.file-full-preview-wrapper {
width: 100%;
height: 100%;
position: absolute;
z-index: 7;
background-color: white;
width: 100%;
height: 100%;
position: absolute;
z-index: 7;
background-color: white;
}
@media (prefers-color-scheme: dark) {
.file-full-preview-wrapper {
background-color: $dark_mode_background;
}
.file-full-preview-wrapper {
background-color: $dark_mode_background;
}
}
</style>

View File

@@ -1,78 +0,0 @@
<template>
<div v-if="filteredFiles.length > 1">
<div @click.prevent="prev" class="prev">
<chevron-left-icon size="17"></chevron-left-icon>
</div>
<div @click.prevent="next" class="next">
<chevron-right-icon size="17"></chevron-right-icon>
</div>
</div>
</template>
<script>
import { events } from '@/bus'
import { mapGetters } from 'vuex'
import { ChevronLeftIcon, ChevronRightIcon } from 'vue-feather-icons'
export default {
name: 'FilePreviewActions',
components: {
ChevronLeftIcon,
ChevronRightIcon
},
computed: {
...mapGetters(['fileInfoDetail', 'data']),
filteredFiles() {
let filteredData = []
this.data.filter((element) => {
if (element.type == this.fileInfoDetail[0].type) {
filteredData.push(element)
}
})
return filteredData
}
},
methods: {
next: function() {
events.$emit('filePreviewAction:next')
},
prev: function() {
events.$emit('filePreviewAction:prev')
}
}
}
</script>
<style lang="scss" scoped>
@import '@assets/vuefilemanager/_variables';
.prev,
.next {
cursor: pointer;
position: absolute;
top: 53.5%;
display: flex;
justify-content: center;
color: $text;
border-radius: 50%;
text-decoration: none;
user-select: none;
filter: drop-shadow(0px 1px 0 rgba(255, 255, 255, 1));
padding: 10px;
}
.next {
right: 0;
}
.prev {
left: 0;
}
@media (prefers-color-scheme: dark) {
.prev,
.next {
color: $light-text;
filter: drop-shadow(0px 1px 0 rgba(17, 19, 20, 1));
}
}
</style>

View File

@@ -4,9 +4,9 @@
<x-icon @click="closeFullPreview" size="22" class="icon-close hover-text-theme" />
<div class="name-count-wrapper">
<p class="title">{{ fileInfoDetail[0].name }}</p>
<span class="file-count"> ({{ showingImageIndex + ' ' + $t('pronouns.of') + ' ' + filteredFiles.length }}) </span>
<span class="file-count"> ({{ showingImageIndex + ' ' + $t('pronouns.of') + ' ' + files.length }}) </span>
</div>
<span id="fast-preview-menu" class="fast-menu-icon group" @click.stop="menuOpen" v-if="$checkPermission(['master', 'editor', 'visitor'])">
<span @click.stop="menuOpen" id="fast-preview-menu" class="fast-menu-icon group">
<more-horizontal-icon class="more-icon group-hover-text-theme" size="14" />
</span>
</div>
@@ -14,96 +14,112 @@
<div class="created-at-wrapper">
<p>{{ fileInfoDetail[0].filesize }}, {{ fileInfoDetail[0].created_at }}</p>
</div>
<div class="navigation-icons">
<div class="navigation-tool-wrapper">
<ToolbarButton source="download" class="mobile-hide" @click.native="downloadItem" :action="$t('actions.download')" />
<ToolbarButton v-if="canShowShareView" :class="{ 'is-inactive': canShareInView }" @click.native="shareItem" source="share" class="mobile-hide" :action="$t('actions.share')" />
<ToolbarButton v-if="this.fileInfoDetail[0].type === 'image'" source="print" :action="$t('actions.print')" @click.native="printMethod()" />
<ToolbarButton @click.native="downloadItem" class="mobile-hide" source="download" :action="$t('actions.download')" />
<ToolbarButton v-if="canShareItem" @click.native="shareItem" class="mobile-hide" :class="{ 'is-inactive': !canShareItem }" source="share" :action="$t('actions.share')" />
<ToolbarButton v-if="isImage" @click.native="printMethod()" source="print" :action="$t('actions.print')" />
</div>
</div>
</div>
</template>
<script>
import { events } from '@/bus'
import { mapGetters } from 'vuex'
import { XIcon, MoreHorizontalIcon } from 'vue-feather-icons'
import ToolbarButton from '@/components/FilesView/ToolbarButton'
import {XIcon, MoreHorizontalIcon} from 'vue-feather-icons'
import {mapGetters} from 'vuex'
import {events} from '@/bus'
import ToolbarButton from '@/components/FilesView/ToolbarButton'
export default {
name: 'FilePreviewNavigationPanel',
components: { ToolbarButton, XIcon, MoreHorizontalIcon },
computed: {
...mapGetters(['fileInfoDetail', 'data']),
filteredFiles() {
let files = []
this.data.filter((element) => {
if (element.type == this.fileInfoDetail[0].type) {
files.push(element)
}
})
return files
},
showingImageIndex() {
let activeIndex = ''
this.filteredFiles.filter((element, index) => {
if (element.id === this.fileInfoDetail[0].id) {
activeIndex = index + 1
}
})
return activeIndex
},
canShowShareView() {
return this.$isThisLocation(['base', 'participant_uploads', 'latest', 'shared'])
export default {
name: 'FilePreviewNavigationPanel',
components: {
MoreHorizontalIcon,
ToolbarButton,
XIcon,
},
canShareInView() {
return ! this.$isThisLocation(['base', 'participant_uploads', 'latest', 'shared'])
}
},
data() {
return {
showContextMenu: false
}
},
methods: {
printMethod() {
var tab = document.getElementById('image')
var win = window.open('', '', 'height=700,width=700')
win.document.write(tab.outerHTML)
win.document.close()
win.print()
},
downloadItem() {
// Download file
this.$downloadFile(this.fileInfoDetail[0].file_url, this.fileInfoDetail[0].name + '.' + this.fileInfoDetail[0].mimetype)
},
shareItem() {
if (this.fileInfoDetail[0].shared) {
events.$emit('popup:open', {
name: 'share-edit',
item: this.fileInfoDetail[0]
})
} else {
events.$emit('popup:open', {
name: 'share-create',
item: this.fileInfoDetail[0]
})
}
},
menuOpen() {
if (this.$isMobile()) {
events.$emit('mobile-menu:show', 'file-menu')
} else {
events.$emit('showContextMenuPreview:show', this.fileInfoDetail[0])
}
},
closeFullPreview() {
events.$emit('fileFullPreview:hide')
events.$emit('showContextMenuPreview:hide')
}
}
}
computed: {
...mapGetters([
'fileInfoDetail',
'data'
]),
isImage() {
return this.fileInfoDetail[0].type === 'image'
},
files() {
let files = []
this.data.map(element => {
if (this.fileInfoDetail[0].mimetype === 'pdf') {
if (element.mimetype === 'pdf')
files.push(element)
} else {
if (element.type === this.fileInfoDetail[0].type)
files.push(element)
}
})
return files
},
showingImageIndex() {
let activeIndex = undefined
this.files.forEach((element, index) => {
if (element.id === this.fileInfoDetail[0].id) {
activeIndex = index + 1
}
})
return activeIndex
},
canShareItem() {
return this.$isThisLocation([
'base', 'participant_uploads', 'latest', 'shared'
])
},
},
methods: {
printMethod() {
let tab = document.getElementById('printable-file')
let win = window.open('', '', 'height=700,width=700')
win.document.write(tab.outerHTML)
win.document.close()
win.print()
},
downloadItem() {
this.$downloadFile(
this.fileInfoDetail[0].file_url,
this.fileInfoDetail[0].name + '.' + this.fileInfoDetail[0].mimetype
)
},
shareItem() {
let event = this.fileInfoDetail[0].shared
? 'share-edit'
: 'share-create'
events.$emit('popup:open', {
name: event,
item: this.fileInfoDetail[0]
})
},
menuOpen() {
if (this.$isMobile()) {
events.$emit('mobile-menu:show', 'file-menu')
} else {
events.$emit('showContextMenuPreview:show', this.fileInfoDetail[0])
}
},
closeFullPreview() {
events.$emit('file-preview:hide')
events.$emit('showContextMenuPreview:hide')
}
}
}
</script>
<style lang="scss" scoped>
@@ -111,150 +127,158 @@ export default {
@import '@assets/vuefilemanager/_mixins';
.name-wrapper {
width: 33%;
height: 22px;
display: flex;
position: relative;
align-items: center;
flex-grow: 1;
align-self: center;
white-space: nowrap;
width: 33%;
height: 22px;
display: flex;
position: relative;
align-items: center;
flex-grow: 1;
align-self: center;
white-space: nowrap;
.name-count-wrapper {
.name-count-wrapper {
margin-left: 6px;
margin-right: 6px;
.file-count {
@include font-size(15);
line-height: 1;
font-weight: 700;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
vertical-align: middle;
align-self: center;
color: $text;
}
.title {
@include font-size(15);
max-width: 250px;
line-height: 1;
font-weight: 700;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
vertical-align: middle;
color: $text;
}
@media (max-width: 570px) {
.title{
max-width: 180px;
@include font-size(17);
}
.file-count {
@include font-size(17);
}
}
}
.icon-close {
min-width: 22px;
padding: 1px 4px;
border-radius: 6px;
vertical-align: middle;
cursor: pointer;
@include transition(150ms);
@include font-size(15);
line-height: 1;
font-weight: 700;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
vertical-align: middle;
align-self: center;
color: $text;
}
&:hover {
background: $light_background;
.title {
@include font-size(15);
max-width: 250px;
line-height: 1;
font-weight: 700;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
vertical-align: middle;
color: $text;
}
line {
color: inherit;
}
}
}
.fast-menu-icon {
height: 24px;
display: flex;
align-items: center;
vertical-align: middle;
padding: 1px 4px;
line-height: 0;
border-radius: 3px;
cursor: pointer;
@include transition(150ms);
@media (max-width: 570px) {
.title {
max-width: 180px;
@include font-size(17);
}
.file-count {
@include font-size(17);
}
}
}
svg circle {
@include transition(150ms);
}
&:hover {
background: $light_background;
.icon-close {
min-width: 22px;
padding: 1px 4px;
border-radius: 6px;
vertical-align: middle;
cursor: pointer;
@include transition(150ms);
svg circle {
color: inherit;
}
}
.more-icon {
vertical-align: middle;
cursor: pointer;
}
}
&:hover {
background: $light_background;
line {
color: inherit;
}
}
}
.fast-menu-icon {
height: 24px;
display: flex;
align-items: center;
vertical-align: middle;
padding: 1px 4px;
line-height: 0;
border-radius: 3px;
cursor: pointer;
@include transition(150ms);
svg circle {
@include transition(150ms);
}
&:hover {
background: $light_background;
svg circle {
color: inherit;
}
}
.more-icon {
vertical-align: middle;
cursor: pointer;
}
}
}
.context-menu {
min-width: 250px;
position: absolute;
z-index: 99;
box-shadow: $shadow;
background: white;
border-radius: 8px;
overflow: hidden;
top: 29px;
&.showed {
display: block;
}
.context-menu {
min-width: 250px;
position: absolute;
z-index: 99;
box-shadow: $shadow;
background: white;
border-radius: 8px;
overflow: hidden;
top: 29px;
&.showed {
display: block;
}
}
.created-at-wrapper {
width: 33%;
display: flex;
text-align: center;
justify-content: center;
width: 33%;
display: flex;
text-align: center;
justify-content: center;
p {
display: flex;
align-items: center;
@include font-size(11);
}
p {
display: flex;
align-items: center;
@include font-size(11);
}
}
.navigation-icons {
width: 33%;
text-align: right;
width: 33%;
text-align: right;
.navigation-tool-wrapper {
margin-left: 28px;
display: inline-block;
vertical-align: middle;
}
.navigation-tool-wrapper {
margin-left: 28px;
display: inline-block;
vertical-align: middle;
}
.button {
margin-left: 5px;
&:hover {
background: $light_background;
}
}
.button {
margin-left: 5px;
&:hover {
background: $light_background;
}
}
}
.navigation-panel {
height: 63px;
width: 100%;
padding: 10px 15px;
display: flex;
position: absolute;
z-index: 8;
align-items: center;
background-color: white;
color: $text;
height: 63px;
width: 100%;
padding: 10px 15px;
display: flex;
position: absolute;
z-index: 8;
align-items: center;
background-color: white;
color: $text;
}
@media (max-width: 960px) {
@@ -287,33 +311,34 @@ export default {
}
@media (prefers-color-scheme: dark) {
.navigation-panel {
background-color: $dark_mode_background;
color: $dark_mode_text_primary;
.navigation-panel {
background-color: $dark_mode_background;
color: $dark_mode_text_primary;
.icon-close {
color: $dark_mode_text_primary;
&:hover {
background-color: $dark_mode_background;
}
}
.icon-close {
color: $dark_mode_text_primary;
.fast-menu-icon:hover {
background: $dark_mode_background;
}
}
&:hover {
background-color: $dark_mode_background;
}
}
.name-wrapper {
.title,
.file-count {
color: $dark_mode_text_primary !important;
}
}
.fast-menu-icon:hover {
background: $dark_mode_background;
}
}
.navigation-icons {
.button:hover {
background: $dark_mode_background;
}
}
.name-wrapper {
.title,
.file-count {
color: $dark_mode_text_primary !important;
}
}
.navigation-icons {
.button:hover {
background: $dark_mode_background;
}
}
}
</style>

View File

@@ -1,11 +1,59 @@
<template>
<div class="media-full-preview" id="mediaPreview" v-if="this.isMedia && fileInfoDetail[0]">
<div class="file-wrapper-preview" v-for="i in [currentIndex]" :key="i">
<div class="file-wrapper">
<audio class="file audio" :class="{ 'file-shadow': !isMobileDevice }" v-if="fileInfoDetail[0].type == 'audio'" :src="currentFile.file_url" controlsList="nodownload" controls></audio>
<img v-if="fileInfoDetail[0].type === 'image' && currentFile.thumbnail" class="file" :class="{ 'file-shadow': !isMobileDevice }" id="image" :src="currentFile.file_url" />
<div class="video-wrapper" v-if="fileInfoDetail[0].type === 'video' && currentFile.file_url">
<video :src="currentFile.file_url" class="video" :class="{ 'file-shadow': !isMobileDevice }" controlsList="nodownload" disablePictureInPicture playsinline controls autoplay />
<div class="media-full-preview" id="mediaPreview" v-if="fileInfoDetail[0]">
<!--Arrow navigation-->
<div v-if="files.length > 1" class="navigation-arrows">
<div @click.prevent="prev" class="prev">
<chevron-left-icon size="17" />
</div>
<div @click.prevent="next" class="next">
<chevron-right-icon size="17" />
</div>
</div>
<!--File preview-->
<div class="file-wrapper-preview">
<!--Show PDF-->
<div v-if="isPDF" id="pdf-wrapper">
<pdf :src="pdfdata" v-for="i in numPages" :key="i" :page="i" scale="page-width" style="width:100%; margin:20px auto;" id="printable-file">
<template slot="loading">
<h1>loading content...</h1>
</template>
</pdf>
</div>
<!--Show Audio, Video and Image-->
<div v-if="!isPDF" class="file-wrapper">
<audio
v-if="isAudio"
:class="{ 'file-shadow': !$isMobile() }"
class="file audio"
:src="currentFile.file_url"
controls>
</audio>
<img
id="printable-file"
v-if="isImage"
class="file"
:class="{'file-shadow': !$isMobile() }"
:src="currentFile.file_url"
/>
<div class="video-wrapper" v-if="isVideo">
<video
:src="currentFile.file_url"
class="video"
:class="{'file-shadow': !$isMobile() }"
controlsList="nodownload"
disablePictureInPicture
playsinline
controls
autoplay
/>
</div>
</div>
</div>
@@ -13,224 +61,285 @@
</template>
<script>
import { events } from '@/bus'
import { mapGetters } from 'vuex'
import {ChevronLeftIcon, ChevronRightIcon} from 'vue-feather-icons'
import ToolbarButton from '@/components/FilesView/ToolbarButton'
import Spinner from '@/components/FilesView/Spinner'
import {mapGetters} from 'vuex'
import {events} from '@/bus'
import pdf from 'pdfvuer'
export default {
name: 'MediaFullPreview',
components: { ToolbarButton, Spinner },
computed: {
...mapGetters(['fileInfoDetail', 'data']),
name: 'MediaFullPreview',
components: {
ChevronRightIcon,
ChevronLeftIcon,
ToolbarButton,
Spinner,
pdf,
},
computed: {
...mapGetters([
'fileInfoDetail',
'data',
]),
currentFile() {
return this.files[Math.abs(this.currentIndex) % this.files.length]
},
isPDF() {
return this.fileInfoDetail[0].mimetype === 'pdf'
},
isVideo() {
return this.fileInfoDetail[0].type === 'video'
},
isAudio() {
return this.fileInfoDetail[0].type === 'audio'
},
isImage() {
return this.fileInfoDetail[0].type === 'image'
}
},
data() {
return {
pdfdata: undefined,
numPages: 0,
currentIndex: 0,
files: [],
}
},
watch: {
files() {
if (this.files.length === 0)
events.$emit('file-preview:hide')
},
currentFile() {
if (this.fileInfoDetail[0]) {
this.$store.commit('CLEAR_FILEINFO_DETAIL')
this.$store.commit('GET_FILEINFO_DETAIL', this.currentFile)
isMobileDevice() {
return this.$isMobile()
},
// Init pdf instance
if (this.fileInfoDetail[0].mimetype === 'pdf') {
this.getPdf()
}
}
},
fileInfoDetail() {
if (!this.fileInfoDetail[0]) {
this.currentIndex -= 1
currentFile: function() {
return this.sliderFile[Math.abs(this.currentIndex) % this.sliderFile.length]
},
isMedia() {
return this.fileInfoDetail[0] === 'image' || 'video' || 'audio'
},
this.$store.commit('GET_FILEINFO_DETAIL', this.currentFile)
canShareInView() {
return !this.$isThisLocation(['base', 'participant_uploads', 'latest', 'shared', 'public'])
}
},
data() {
return {
currentIndex: 1,
sliderFile: []
// loaded: false
}
},
this.files = []
//this.getFilesForView()
}
},
data(newValue, oldValue) {
if (newValue !== oldValue) {
this.files = []
//this.getFilesForView()
}
},
},
methods: {
next() {
if (!this.files.length > 1) return
watch: {
sliderFile() {
//Close file preview after delete all items
if (this.sliderFile.length == 0) {
events.$emit('fileFullPreview:hide')
}
},
currentFile() {
//Handle actual view image in fileInfoDetail
if (this.fileInfoDetail[0]) {
this.$store.commit('CLEAR_FILEINFO_DETAIL')
this.$store.commit('GET_FILEINFO_DETAIL', this.currentFile)
events.$emit('actualShowingImage:ContextMenu', this.currentFile)
// this.loaded = false
}
},
fileInfoDetail() {
//File delete handling - show next image after delete one
if (!this.fileInfoDetail[0]) {
this.currentIndex = this.currentIndex - 1
this.$store.commit('GET_FILEINFO_DETAIL', this.currentFile)
this.sliderFile = []
this.filteredFiles()
}
},
data(newValue, oldValue) {
//Move item handling
if (newValue != oldValue) {
this.sliderFile = []
this.filteredFiles()
}
}
},
methods: {
filteredFiles() {
this.data.filter((element) => {
if (element.type == this.fileInfoDetail[0].type) {
this.sliderFile.push(element)
}
})
this.choseActiveFile()
},
choseActiveFile() {
this.sliderFile.forEach((element, index) => {
if (element.id == this.fileInfoDetail[0].id) {
this.currentIndex = index
}
})
}
},
mounted() {
if (this.sliderFile.length > 1) {
events.$on('filePreviewAction:next', () => {
this.currentIndex += 1
this.slideType = 'next'
if (this.currentIndex > this.sliderFile.length - 1) {
this.currentIndex = 0
}
})
events.$on('filePreviewAction:prev', () => {
this.slideType = 'prev'
this.currentIndex -= 1
if (this.currentIndex < 0) {
this.currentIndex = this.sliderFile.length - 1
}
})
}
},
created() {
this.filteredFiles()
}
this.pdfdata = undefined
this.currentIndex += 1
if (this.currentIndex > this.files.length - 1) {
this.currentIndex = 0
}
},
prev() {
if (!this.files.length > 1) return
this.pdfdata = undefined
this.currentIndex -= 1
if (this.currentIndex < 0) {
this.currentIndex = this.files.length - 1
}
},
getPdf() {
this.pdfdata = undefined
this.numPages = 0
let self = this;
self.pdfdata = pdf.createLoadingTask(this.currentFile.file_url);
self.pdfdata.then(pdf => self.numPages = pdf.numPages);
},
getFilesForView() {
let requestedFile = this.fileInfoDetail[0]
this.data.map(element => {
if (requestedFile.mimetype === 'pdf') {
if (element.mimetype === 'pdf')
this.files.push(element)
} else {
if (element.type === requestedFile.type)
this.files.push(element)
}
})
this.files.forEach((element, index) => {
if (element.id === this.fileInfoDetail[0].id) {
this.currentIndex = index
}
})
},
},
created() {
events.$on('file-preview:next', () => this.next())
events.$on('file-preview:prev', () => this.prev())
this.getFilesForView()
}
}
</script>
<style lang="scss" scoped>
<style src="pdfvuer/dist/pdfvuer.css" lang="css"></style>
<style lang="scss">
@import '@assets/vuefilemanager/_variables';
@import '@assets/vuefilemanager/_mixins';
.navigation-arrows {
.prev, .next {
cursor: pointer;
position: absolute;
top: 35%;
display: flex;
justify-content: center;
color: $text;
border-radius: 50%;
text-decoration: none;
user-select: none;
filter: drop-shadow(0px 1px 0 rgba(255, 255, 255, 1));
padding: 10px;
}
.next {
right: 0;
}
.prev {
left: 0;
}
}
#pdf-wrapper {
overflow-y: scroll;
width: 80%;
margin: 0 auto;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.media-full-preview {
height: calc(100% - 72px);
top: 72px;
position: relative;
background-color: white;
}
.navigation-panel {
width: 100%;
height: 7%;
display: flex;
align-items: center;
padding: 20px;
justify-content: space-between;
background-color: $light-background;
color: $text;
.icon-close {
color: $text;
@include font-size(21);
&:hover {
color: $theme;
}
}
}
.loading-spinner {
position: relative;
height: calc(100% - 72px);
top: 72px;
position: relative;
background-color: white;
}
.file-wrapper-preview {
width: 100%;
height: 100%;
padding: 30px 0px;
display: flex;
overflow: hidden;
justify-content: center;
align-items: center;
background-color: white;
width: 100%;
height: 100%;
padding: 30px 0px;
display: flex;
overflow: hidden;
justify-content: center;
align-items: center;
background-color: white;
.file-wrapper {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.file-wrapper {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.file-shadow {
box-shadow: 0 8px 40px rgba(17, 26, 52, 0.05);
}
.file-shadow {
box-shadow: 0 8px 40px rgba(17, 26, 52, 0.05);
}
.file {
max-width: 100%;
max-height: 100%;
align-self: center;
}
.file {
max-width: 100%;
max-height: 100%;
align-self: center;
}
.audio {
border-radius: 28px;
}
.audio {
border-radius: 28px;
}
img {
border-radius: 4px;
}
.video-wrapper {
max-width: 1080px;
max-height: 100%;
.video-wrapper {
max-width: 1080px;
max-height: 100%;
@media (min-width: 1200px) {
& {
max-width: 800px;
}
}
@media (min-width: 1200px) {
& {
max-width: 800px;
}
}
@media (min-width: 1920px) and (max-width: 2560px) {
& {
max-width: 1080px;
}
}
@media (min-width: 2560px) and (max-width: 3840px) {
& {
max-width: 1440px;
}
}
@media (min-width: 3840px) {
& {
max-width: 2160px;
}
}
.video {
max-width: 100%;
max-height: 100%;
align-self: center;
}
}
}
@media (min-width: 1920px) and (max-width: 2560px) {
& {
max-width: 1080px;
}
}
@media (min-width: 2560px) and (max-width: 3840px) {
& {
max-width: 1440px;
}
}
@media (min-width: 3840px) {
& {
max-width: 2160px;
}
}
.video {
max-width: 100%;
max-height: 100%;
align-self: center;
}
}
}
}
@media (prefers-color-scheme: dark) {
.file-wrapper-preview {
background-color: $dark_mode_background;
.file-wrapper {
.file-shadow {
box-shadow: 0 8px 40px rgba(0, 0, 0, 0.1);
}
}
}
.navigation-arrows {
.prev, .next {
color: $light-text;
filter: drop-shadow(0px 1px 0 rgba(17, 19, 20, 1));
}
}
.file-wrapper-preview {
background-color: $dark_mode_background;
.file-wrapper {
.file-shadow {
box-shadow: 0 8px 40px rgba(0, 0, 0, 0.1);
}
}
}
}
</style>

View File

@@ -47,7 +47,10 @@ import SortingAndPreviewIcon from '@/components/FilesView/Icons/SortingAndPrevie
export default {
name: "ToolbarButton",
props: ["source", "action"],
props: [
'source',
'action'
],
components: {
SortingAndPreviewIcon,
CornerDownRightIcon,