|
|
@@ -21,21 +21,24 @@ |
|
|
|
|
|
|
|
<template> |
|
|
|
<div v-if="!accessible" class="widget-file widget-file--no-access"> |
|
|
|
<div class="widget-file--image widget-file--image--icon icon-folder" /> |
|
|
|
<div class="widget-file--details"> |
|
|
|
<p class="widget-file--title"> |
|
|
|
<span class="widget-file__image widget-file__image--icon"> |
|
|
|
<FolderIcon v-if="isFolder" :size="88" /> |
|
|
|
<FileIcon v-else :size="88" /> |
|
|
|
</span> |
|
|
|
<span class="widget-file__details"> |
|
|
|
<p class="widget-file__title"> |
|
|
|
{{ t('files', 'File cannot be accessed') }} |
|
|
|
</p> |
|
|
|
<p class="widget-file--description"> |
|
|
|
<p class="widget-file__description"> |
|
|
|
{{ t('files', 'The file could not be found or you do not have permissions to view it. Ask the sender to share it.') }} |
|
|
|
</p> |
|
|
|
</div> |
|
|
|
</span> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- Live preview if a handler is available --> |
|
|
|
<component :is="viewerHandler.component" |
|
|
|
v-else-if="viewerHandler && !failedViewer" |
|
|
|
:active="true" |
|
|
|
:active="false" |
|
|
|
:can-swipe="false" |
|
|
|
:can-zoom="false" |
|
|
|
:is-embedded="true" |
|
|
@@ -43,28 +46,38 @@ |
|
|
|
:file-list="[viewerFile]" |
|
|
|
:is-full-screen="false" |
|
|
|
:is-sidebar-shown="false" |
|
|
|
class="widget-file" |
|
|
|
class="widget-file widget-file--preview" |
|
|
|
@error="failedViewer = true" /> |
|
|
|
|
|
|
|
<!-- The file is accessible --> |
|
|
|
<a v-else |
|
|
|
class="widget-file" |
|
|
|
class="widget-file widget-file--link" |
|
|
|
:href="richObject.link" |
|
|
|
@click.prevent="navigate"> |
|
|
|
<div class="widget-file--image" :class="filePreviewClass" :style="filePreview" /> |
|
|
|
<div class="widget-file--details"> |
|
|
|
<p class="widget-file--title">{{ richObject.name }}</p> |
|
|
|
<p class="widget-file--description">{{ fileSize }}<br>{{ fileMtime }}</p> |
|
|
|
<p class="widget-file--link">{{ filePath }}</p> |
|
|
|
</div> |
|
|
|
target="_blank" |
|
|
|
@click="navigate"> |
|
|
|
<span class="widget-file__image" :class="filePreviewClass" :style="filePreviewStyle"> |
|
|
|
<template v-if="!previewUrl"> |
|
|
|
<FolderIcon v-if="isFolder" :size="88" /> |
|
|
|
<FileIcon v-else :size="88" /> |
|
|
|
</template> |
|
|
|
</span> |
|
|
|
<span class="widget-file__details"> |
|
|
|
<p class="widget-file__title">{{ richObject.name }}</p> |
|
|
|
<p class="widget-file__description">{{ fileSize }}<br>{{ fileMtime }}</p> |
|
|
|
<p class="widget-file__link">{{ filePath }}</p> |
|
|
|
</span> |
|
|
|
</a> |
|
|
|
</template> |
|
|
|
|
|
|
|
<script lang="ts"> |
|
|
|
import { defineComponent, type Component, type PropType } from 'vue' |
|
|
|
import { generateRemoteUrl, generateUrl } from '@nextcloud/router' |
|
|
|
import path from 'path' |
|
|
|
import { getCurrentUser } from '@nextcloud/auth' |
|
|
|
import { getFilePickerBuilder } from '@nextcloud/dialogs' |
|
|
|
import { Node } from '@nextcloud/files' |
|
|
|
import FileIcon from 'vue-material-design-icons/File.vue' |
|
|
|
import FolderIcon from 'vue-material-design-icons/Folder.vue' |
|
|
|
import path from 'path' |
|
|
|
|
|
|
|
// see lib/private/Collaboration/Reference/File/FileReferenceProvider.php |
|
|
|
type Ressource = { |
|
|
@@ -105,6 +118,10 @@ type ViewerFile = { |
|
|
|
|
|
|
|
export default defineComponent({ |
|
|
|
name: 'ReferenceFileWidget', |
|
|
|
components: { |
|
|
|
FolderIcon, |
|
|
|
FileIcon, |
|
|
|
}, |
|
|
|
props: { |
|
|
|
richObject: { |
|
|
|
type: Object as PropType<Ressource>, |
|
|
@@ -115,14 +132,14 @@ export default defineComponent({ |
|
|
|
default: true, |
|
|
|
}, |
|
|
|
interactive: { |
|
|
|
type: Bool, |
|
|
|
type: Boolean, |
|
|
|
default: true, |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
data() { |
|
|
|
return { |
|
|
|
previewUrl: window.OC.MimeType.getIconUrl(this.richObject.mimetype), |
|
|
|
previewUrl: null as string | null, |
|
|
|
failedViewer: false, |
|
|
|
} |
|
|
|
}, |
|
|
@@ -162,25 +179,24 @@ export default defineComponent({ |
|
|
|
filePath() { |
|
|
|
return path.dirname(this.richObject.path) |
|
|
|
}, |
|
|
|
filePreview() { |
|
|
|
filePreviewStyle() { |
|
|
|
if (this.previewUrl) { |
|
|
|
return { |
|
|
|
backgroundImage: 'url(' + this.previewUrl + ')', |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return { |
|
|
|
backgroundImage: 'url(' + window.OC.MimeType.getIconUrl(this.richObject.mimetype) + ')', |
|
|
|
} |
|
|
|
|
|
|
|
return {} |
|
|
|
}, |
|
|
|
filePreviewClass() { |
|
|
|
if (this.previewUrl) { |
|
|
|
return 'widget-file--image--preview' |
|
|
|
return 'widget-file__image--preview' |
|
|
|
} |
|
|
|
return 'widget-file--image--icon' |
|
|
|
return 'widget-file__image--icon' |
|
|
|
|
|
|
|
}, |
|
|
|
isFolder() { |
|
|
|
return this.richObject.mimetype === 'httpd/unix-directory' |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
mounted() { |
|
|
@@ -197,16 +213,36 @@ export default defineComponent({ |
|
|
|
} |
|
|
|
img.src = previewUrl |
|
|
|
} |
|
|
|
|
|
|
|
console.debug('ReferenceFileWidget', this.richObject) |
|
|
|
}, |
|
|
|
methods: { |
|
|
|
navigate() { |
|
|
|
if (OCA.Viewer && OCA.Viewer.mimetypes.indexOf(this.richObject.mimetype) !== -1) { |
|
|
|
OCA.Viewer.open({ path: this.richObject.path }) |
|
|
|
return |
|
|
|
navigate(event) { |
|
|
|
if (this.isFolder) { |
|
|
|
event.stopPropagation() |
|
|
|
event.preventDefault() |
|
|
|
this.openFilePicker() |
|
|
|
} |
|
|
|
window.location = this.richObject.link |
|
|
|
}, |
|
|
|
|
|
|
|
openFilePicker() { |
|
|
|
const picker = getFilePickerBuilder(t('settings', 'Your files')) |
|
|
|
.allowDirectories(true) |
|
|
|
.setMultiSelect(false) |
|
|
|
.addButton({ |
|
|
|
id: 'open', |
|
|
|
label: this.t('settings', 'Open in files'), |
|
|
|
callback(nodes: Node[]) { |
|
|
|
if (nodes[0]) { |
|
|
|
window.open(generateUrl('/f/{fileid}', { |
|
|
|
fileid: nodes[0].fileid, |
|
|
|
})) |
|
|
|
} |
|
|
|
}, |
|
|
|
type: 'primary', |
|
|
|
}) |
|
|
|
.disableNavigation() |
|
|
|
.startAt(this.richObject.path) |
|
|
|
.build() |
|
|
|
picker.pick() |
|
|
|
}, |
|
|
|
}, |
|
|
|
}) |
|
|
@@ -218,27 +254,35 @@ export default defineComponent({ |
|
|
|
flex-grow: 1; |
|
|
|
color: var(--color-main-text) !important; |
|
|
|
text-decoration: none !important; |
|
|
|
padding: 0 !important; |
|
|
|
|
|
|
|
&--image { |
|
|
|
min-width: 40%; |
|
|
|
&__image { |
|
|
|
width: 30%; |
|
|
|
min-width: 160px; |
|
|
|
max-width: 320px; |
|
|
|
background-position: center; |
|
|
|
background-size: cover; |
|
|
|
background-repeat: no-repeat; |
|
|
|
|
|
|
|
&.widget-file--image--icon { |
|
|
|
&--icon { |
|
|
|
min-width: 88px; |
|
|
|
background-size: 44px; |
|
|
|
max-width: 88px; |
|
|
|
padding: 12px; |
|
|
|
padding-right: 0; |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
justify-content: center; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
&--title { |
|
|
|
&__title { |
|
|
|
overflow: hidden; |
|
|
|
text-overflow: ellipsis; |
|
|
|
white-space: nowrap; |
|
|
|
font-weight: bold; |
|
|
|
} |
|
|
|
|
|
|
|
&--details { |
|
|
|
&__details { |
|
|
|
padding: 12px; |
|
|
|
flex-grow: 1; |
|
|
|
display: flex; |
|
|
@@ -250,7 +294,7 @@ export default defineComponent({ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
&--description { |
|
|
|
&__description { |
|
|
|
overflow: hidden; |
|
|
|
text-overflow: ellipsis; |
|
|
|
display: -webkit-box; |
|
|
@@ -259,16 +303,9 @@ export default defineComponent({ |
|
|
|
-webkit-box-orient: vertical; |
|
|
|
} |
|
|
|
|
|
|
|
// No preview, standard link to ressource |
|
|
|
&--link { |
|
|
|
color: var(--color-text-maxcontrast); |
|
|
|
} |
|
|
|
|
|
|
|
&.widget-file--no-access { |
|
|
|
padding: 12px; |
|
|
|
|
|
|
|
.widget-file--details { |
|
|
|
padding: 0; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
</style> |