зеркало из https://github.com/nextcloud/text.git
Implement placeholders for non-image files
Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
Родитель
1824f1065c
Коммит
e5ffd43de6
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче