summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>2024-03-05 17:29:17 +0100
committerJohn Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>2024-03-07 11:06:36 +0100
commitbfa65cf0cb6875a4e62955be962e082d727f713d (patch)
treedb7414c3505572716884283d5427898f2d014ebe
parent6c04942e2b82ea50929507b4c59610ca45332b12 (diff)
downloadnextcloud-server-bfa65cf0cb6875a4e62955be962e082d727f713d.tar.gz
nextcloud-server-bfa65cf0cb6875a4e62955be962e082d727f713d.zip
feat(files): add Viewer Files ressource handler
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
-rw-r--r--apps/files/src/reference-files.ts (renamed from apps/files/src/reference-files.js)2
-rw-r--r--apps/files/src/views/ReferenceFileWidget.vue102
-rw-r--r--webpack.modules.js2
3 files changed, 99 insertions, 7 deletions
diff --git a/apps/files/src/reference-files.js b/apps/files/src/reference-files.ts
index db563200cd0..74a64b43df6 100644
--- a/apps/files/src/reference-files.js
+++ b/apps/files/src/reference-files.ts
@@ -42,7 +42,7 @@ registerWidget('file', (el, { richObjectType, richObject, accessible }) => {
accessible,
},
}).$mount(el)
-})
+}, { hasInteractiveView: true })
registerCustomPickerElement('files', (el, { providerId, accessible }) => {
const Element = Vue.extend(FileReferencePickerElement)
diff --git a/apps/files/src/views/ReferenceFileWidget.vue b/apps/files/src/views/ReferenceFileWidget.vue
index 311c105055a..db2baffce65 100644
--- a/apps/files/src/views/ReferenceFileWidget.vue
+++ b/apps/files/src/views/ReferenceFileWidget.vue
@@ -31,6 +31,22 @@
</p>
</div>
</div>
+
+ <!-- Live preview if a handler is available -->
+ <component :is="viewerHandler.component"
+ v-else-if="viewerHandler && !failedViewer"
+ :active="true"
+ :can-swipe="false"
+ :can-zoom="false"
+ :is-embedded="true"
+ v-bind="viewerFile"
+ :file-list="[viewerFile]"
+ :is-full-screen="false"
+ :is-sidebar-shown="false"
+ class="widget-file"
+ @error="failedViewer = true" />
+
+ <!-- The file is accessible -->
<a v-else
class="widget-file"
:href="richObject.link"
@@ -43,28 +59,100 @@
</div>
</a>
</template>
-<script>
-import { generateUrl } from '@nextcloud/router'
+
+<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'
+
+// see lib/private/Collaboration/Reference/File/FileReferenceProvider.php
+type Ressource = {
+ id: number
+ name: string
+ size: number
+ path: string
+ link: string
+ mimetype: string
+ mtime: number // as unix timestamp
+ 'preview-available': boolean
+}
-export default {
+type ViewerHandler = {
+ id: string
+ group: string
+ mimes: string[]
+ component: Component
+}
+
+/**
+ * Minimal mock of the legacy Viewer FileInfo
+ * TODO: replace by Node object
+ */
+type ViewerFile = {
+ filename: string // the path to the root folder
+ basename: string // the file name
+ lastmod: Date // the last modification date
+ size: number // the file size in bytes
+ type: string
+ mime: string
+ fileid: number
+ failed: boolean
+ loaded: boolean
+ davPath: string
+ source: string
+}
+
+export default defineComponent({
name: 'ReferenceFileWidget',
props: {
richObject: {
- type: Object,
+ type: Object as PropType<Ressource>,
required: true,
},
accessible: {
type: Boolean,
default: true,
},
+ interactive: {
+ type: Bool,
+ default: true,
+ }
},
+
data() {
return {
previewUrl: window.OC.MimeType.getIconUrl(this.richObject.mimetype),
+ failedViewer: false,
}
},
+
computed: {
+ availableViewerHandlers(): ViewerHandler[] {
+ return (window?.OCA?.Viewer?.availableHandlers || []) as ViewerHandler[]
+ },
+ viewerHandler(): ViewerHandler | undefined {
+ return this.availableViewerHandlers
+ .find(handler => handler.mimes.includes(this.richObject.mimetype))
+ },
+ viewerFile(): ViewerFile {
+ const davSource = generateRemoteUrl(`dav/files/${getCurrentUser()?.uid}/${this.richObject.path}`)
+ .replace(/\/\/$/, '/')
+ return {
+ filename: this.richObject.path,
+ basename: this.richObject.name,
+ lastmod: new Date(this.richObject.mtime * 1000),
+ size: this.richObject.size,
+ type: 'file',
+ mime: this.richObject.mimetype,
+ fileid: this.richObject.id,
+ failed: false,
+ loaded: true,
+ davPath: davSource,
+ source: davSource,
+ }
+ },
+
fileSize() {
return window.OC.Util.humanFileSize(this.richObject.size)
},
@@ -94,6 +182,7 @@ export default {
},
},
+
mounted() {
if (this.richObject['preview-available']) {
const previewUrl = generateUrl('/core/preview?fileId={fileId}&x=250&y=250', {
@@ -108,6 +197,8 @@ export default {
}
img.src = previewUrl
}
+
+ console.debug('ReferenceFileWidget', this.richObject)
},
methods: {
navigate() {
@@ -118,8 +209,9 @@ export default {
window.location = this.richObject.link
},
},
-}
+})
</script>
+
<style lang="scss" scoped>
.widget-file {
display: flex;
diff --git a/webpack.modules.js b/webpack.modules.js
index dc319e39780..c6662e7ee81 100644
--- a/webpack.modules.js
+++ b/webpack.modules.js
@@ -54,7 +54,7 @@ module.exports = {
main: path.join(__dirname, 'apps/files/src', 'main.ts'),
init: path.join(__dirname, 'apps/files/src', 'init.ts'),
'personal-settings': path.join(__dirname, 'apps/files/src', 'main-personal-settings.js'),
- 'reference-files': path.join(__dirname, 'apps/files/src', 'reference-files.js'),
+ 'reference-files': path.join(__dirname, 'apps/files/src', 'reference-files.ts'),
},
files_external: {
init: path.join(__dirname, 'apps/files_external/src', 'init.ts'),