Implement placeholders for non-image files

Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
Julius Härtl 2019-06-15 13:38:01 +02:00
Родитель 1824f1065c
Коммит e5ffd43de6
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4C614C6ED2CDE6DF
5 изменённых файлов: 145 добавлений и 9 удалений

13
package-lock.json сгенерированный
Просмотреть файл

@ -1512,6 +1512,11 @@
"@types/istanbul-lib-report": "*"
}
},
"@types/jquery": {
"version": "2.0.53",
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-2.0.53.tgz",
"integrity": "sha512-MZKPWUhp5TKkoJ/58NSq6io+CSUCOHm2b3Z6U4+r9v70kktB0JM+eRjdp6YmDHtw0kK2XB7L2K7/FMIoziHjUA=="
},
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
@ -8276,6 +8281,14 @@
"axios": "^0.19.0"
}
},
"nextcloud-server": {
"version": "0.15.10",
"resolved": "https://registry.npmjs.org/nextcloud-server/-/nextcloud-server-0.15.10.tgz",
"integrity": "sha512-pCROf5Rz8TaIZDZMED4mJ/iUa/u03+h5r0OKBXG8Aw1Hn2GHX6SX82RD12+QMtL+5LPLxmoVNLAA8ngIUasHZQ==",
"requires": {
"@types/jquery": "^2.0.50"
}
},
"nextcloud-vue": {
"version": "0.11.4",
"resolved": "https://registry.npmjs.org/nextcloud-vue/-/nextcloud-vue-0.11.4.tgz",

Просмотреть файл

@ -23,6 +23,7 @@
"dependencies": {
"lodash": "^4.17.11",
"nextcloud-axios": "^0.2.0",
"nextcloud-server": "^0.15.10",
"nextcloud-vue": "^0.11.4",
"prosemirror-example-setup": "^1.0.1",
"prosemirror-markdown": "^1.3.1",

Просмотреть файл

@ -62,6 +62,7 @@
import { EditorMenuBar } from 'tiptap'
import Tooltip from 'nextcloud-vue/dist/Directives/Tooltip'
import { iconBar } from './../mixins/menubar'
import { fetchFileInfo } from './../helpers'
import Actions from 'nextcloud-vue/dist/Components/Actions'
import ActionButton from 'nextcloud-vue/dist/Components/ActionButton'
@ -97,12 +98,33 @@ export default {
},
methods: {
showImagePrompt(command) {
const currentUser = OC.getCurrentUser()
if (!currentUser) {
return
}
const _command = command
OC.dialogs.filepicker('Insert an image', (file) => {
const src = OC.generateUrl('/core/preview.png?') + `file=${file}&x=1024&y=1024&a=true`
_command({ src, alt: file })
// TODO: check permissions
// TODO: check for available preview
fetchFileInfo(currentUser.uid, file).then((info) => {
const fileInfo = info[0]
console.debug(fileInfo)
const previewUrl = OC.generateUrl('/core/preview?') + `fileId=${fileInfo.id}&x=1024&y=1024&a=true`
const internalLink = OC.generateUrl('/f/' + fileInfo.id)
// dirty but works so we have the information stored in markdown
const appendMeta = {
mimetype: fileInfo.mimetype,
hasPreview: fileInfo.hasPreview,
fileId: fileInfo.id
}
const src = (fileInfo.hasPreview ? previewUrl : internalLink)
+ '#'
+ Object.entries(appendMeta).map(([key, val]) => `${key}=${encodeURIComponent(val)}`).join('&')
_command({
src: src,
alt: fileInfo.name
})
})
}, false, false, true)
}
}

Просмотреть файл

@ -24,6 +24,9 @@
* Callback that should be executed after the document is ready
* @param callback
*/
import axios from 'axios'
import { generateRemoteUrl } from 'nextcloud-server/dist/router'
const documentReady = function(callback) {
const fn = () => setTimeout(callback, 0)
if (document.attachEvent ? document.readyState === 'complete' : document.readyState !== 'loading') {
@ -46,8 +49,50 @@ const getRandomGuestName = () => {
return randomGuestNames[Math.floor(Math.random() * randomGuestNames.length)]
}
const fetchFileInfo = async function(user, path) {
const response = await axios({
method: 'PROPFIND',
url: generateRemoteUrl(`dav/files/${user}${path}`),
headers: {
requesttoken: OC.requestToken,
'content-Type': 'text/xml'
},
data: `<?xml version="1.0"?>
<d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns" xmlns:ocs="http://open-collaboration-services.org/ns">
<d:prop>
<d:getlastmodified />
<d:getetag />
<d:getcontenttype />
<d:resourcetype />
<oc:fileid />
<oc:permissions />
<oc:size />
<d:getcontentlength />
<nc:has-preview />
<nc:mount-type />
<nc:is-encrypted />
<ocs:share-permissions />
<oc:tags />
<oc:favorite />
<oc:comments-unread />
<oc:owner-id />
<oc:owner-display-name />
<oc:share-types />
</d:prop>
</d:propfind>`
})
const files = OCA.Files.App.fileList.filesClient._client.parseMultiStatus(response.data)
return files.map(file => {
const fileInfo = OCA.Files.App.fileList.filesClient._parseFileInfo(file)
fileInfo.href = file.href
return fileInfo
})
}
export {
documentReady,
endpointUrl,
getRandomGuestName
getRandomGuestName,
fetchFileInfo
}

Просмотреть файл

@ -21,8 +21,8 @@
-->
<template>
<div class="image" :class="{'icon-loading': !loaded}">
<div v-if="imageLoaded">
<div class="image" :class="{'icon-loading': !loaded}" :data-src="src">
<div v-if="imageLoaded && isSupportedImage">
<transition name="fade">
<img v-show="loaded" :src="src"
class="image__main" @load="onLoaded">
@ -37,8 +37,8 @@
<div v-else class="image__placeholder">
<transition name="fade">
<div v-show="loaded" class="image__main">
<div class="icon-image" />
<p>{{ t('text', 'Insufficient permissions to view image') }}</p>
<div class="icon-image" :style="mimeIcon" />
<p><a :href="internalLinkOrImage" target="_blank">{{ t('text', 'Show file') }}</a></p>
</div>
</transition>
<transition name="fade">
@ -52,6 +52,33 @@
</template>
<script>
const imageMimes = [
'image/png',
'image/jpeg',
'image/gif',
'image/x-xbitmap',
'image/bmp',
'image/svg+xml'
]
const getQueryVariable = (src, variable) => {
var query = src.split('#')[1]
if (typeof query === 'undefined') {
return
}
var vars = query.split('&')
if (typeof vars === 'undefined') {
return
}
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split('=')
if (decodeURIComponent(pair[0]) === variable) {
return decodeURIComponent(pair[1])
}
}
}
export default {
name: 'ImageView',
props: ['node', 'updateAttrs', 'view'], // eslint-disable-line
@ -63,6 +90,26 @@ export default {
}
},
computed: {
mimeIcon() {
const mime = getQueryVariable(this.src, 'mimetype')
if (mime) {
return {
backgroundImage: 'url(' + window.OC.MimeType.getIconUrl(mime) + ')'
}
}
return {}
},
isSupportedImage() {
const mime = getQueryVariable(this.src, 'mimetype')
return typeof mime === 'undefined' || imageMimes.indexOf(mime) !== -1
},
internalLinkOrImage() {
const fileId = getQueryVariable(this.src, 'fileId')
if (fileId) {
return OC.generateUrl('/f/' + fileId)
}
return this.src
},
src: {
get() {
return this.node.attrs.src
@ -88,6 +135,13 @@ export default {
}
},
beforeMount() {
if (!this.isSupportedImage) {
// TODO check if hasPreview and render a file preview if available
this.failed = true
this.imageLoaded = false
this.loaded = true
return
}
var img = new Image()
img.src = this.node.attrs.src
img.onload = () => {
@ -130,6 +184,7 @@ export default {
margin-top: 10px;
height: 32px;
padding: 20px;
background-size: contain;
}
.image__loading {
height: 100px;