mirror of
https://github.com/nextcloud/server.git
synced 2026-04-21 14:23:17 -04:00
feat(files): add Folder Preview ressource handler
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
This commit is contained in:
parent
bfa65cf0cb
commit
3f8a66f25d
3 changed files with 92 additions and 50 deletions
|
|
@ -33,13 +33,14 @@ Vue.mixin({
|
|||
},
|
||||
})
|
||||
|
||||
registerWidget('file', (el, { richObjectType, richObject, accessible }) => {
|
||||
registerWidget('file', (el, { richObjectType, richObject, accessible, interactive }) => {
|
||||
const Widget = Vue.extend(FileWidget)
|
||||
new Widget({
|
||||
propsData: {
|
||||
richObjectType,
|
||||
richObject,
|
||||
accessible,
|
||||
interactive,
|
||||
},
|
||||
}).$mount(el)
|
||||
}, { hasInteractiveView: true })
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
4
apps/settings/js/map-test.js.map
Normal file
4
apps/settings/js/map-test.js.map
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
/**
|
||||
* This is a dummy file for testing webserver support of JavaScript map files.
|
||||
*/
|
||||
{}
|
||||
Loading…
Reference in a new issue