|
|
|
|
@ -170,8 +170,12 @@ import _ from 'lodash'
|
|
|
|
|
import { get, sync } from 'vuex-pathify'
|
|
|
|
|
import markdownHelp from './markdown/help.vue'
|
|
|
|
|
import gql from 'graphql-tag'
|
|
|
|
|
import Cookies from 'js-cookie'
|
|
|
|
|
import DOMPurify from 'dompurify'
|
|
|
|
|
|
|
|
|
|
import listFolderAssetQuery from 'gql/editor/editor-media-query-folder-list.gql'
|
|
|
|
|
import createAssetFolderMutation from 'gql/editor/editor-media-mutation-folder-create.gql'
|
|
|
|
|
|
|
|
|
|
/* global siteConfig, siteLangs */
|
|
|
|
|
|
|
|
|
|
// ========================================
|
|
|
|
|
@ -432,22 +436,91 @@ export default {
|
|
|
|
|
onCmInput: _.debounce(function (newContent) {
|
|
|
|
|
this.processContent(newContent)
|
|
|
|
|
}, 600),
|
|
|
|
|
onCmPaste (cm, ev) {
|
|
|
|
|
// const clipItems = (ev.clipboardData || ev.originalEvent.clipboardData).items
|
|
|
|
|
// for (let clipItem of clipItems) {
|
|
|
|
|
// if (_.startsWith(clipItem.type, 'image/')) {
|
|
|
|
|
// const file = clipItem.getAsFile()
|
|
|
|
|
// const reader = new FileReader()
|
|
|
|
|
// reader.onload = evt => {
|
|
|
|
|
// this.$store.commit(`loadingStart`, 'editor-paste-image')
|
|
|
|
|
// this.insertAfter({
|
|
|
|
|
// content: ``,
|
|
|
|
|
// newLine: true
|
|
|
|
|
// })
|
|
|
|
|
// }
|
|
|
|
|
// reader.readAsDataURL(file)
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
async onCmPaste (cm, ev) {
|
|
|
|
|
const clipItems = (ev.clipboardData || ev.originalEvent.clipboardData).items
|
|
|
|
|
// In Chromium kernel the paste event will be released after callback return
|
|
|
|
|
// Since this is an async function, the file must be get before 'await' keyword
|
|
|
|
|
const files = Array.from(clipItems).filter(item=>_.startsWith(item.type, 'image/')).map(item=>item.getAsFile())
|
|
|
|
|
// upload all file
|
|
|
|
|
for (const file of files) {
|
|
|
|
|
// get parent directory
|
|
|
|
|
let folderID = 0
|
|
|
|
|
let folderPath = "/assets/" + this.locale
|
|
|
|
|
try {
|
|
|
|
|
if(this.path.includes("/")){
|
|
|
|
|
// path to lowercase, the wikijs foldre does not support case sensitivity.
|
|
|
|
|
folderPath += "/" + this.path.toLowerCase().split('/').slice(0,-1).join('/')
|
|
|
|
|
}
|
|
|
|
|
// try to get the folder id, create it if does not exists.
|
|
|
|
|
folderID = await this.createFolder(folderPath)
|
|
|
|
|
} catch (err) {
|
|
|
|
|
this.$store.commit('pushGraphError', err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
const now = new Date()
|
|
|
|
|
// file name format yyyy-MM-dd_random.png
|
|
|
|
|
let filename = `${now.getFullYear()}-${now.getMonth()+1}-${now.getDate()}_${parseInt(Math.random() * (10**5))}`
|
|
|
|
|
filename += file.name.slice(file.name.lastIndexOf('.'))
|
|
|
|
|
// upload file
|
|
|
|
|
const form = new FormData()
|
|
|
|
|
form.append('mediaUpload', JSON.stringify({ 'folderId': folderID }))
|
|
|
|
|
form.append('mediaUpload', file, filename)
|
|
|
|
|
const jwtToken = Cookies.get('jwt')
|
|
|
|
|
this.$store.commit('showNotification', {
|
|
|
|
|
message: this.$t('editor:assets.uploading'),
|
|
|
|
|
style: 'primary',
|
|
|
|
|
icon: 'primary'
|
|
|
|
|
})
|
|
|
|
|
try {
|
|
|
|
|
const resp = await fetch('/u', { method: 'POST', body: form, headers: { 'Authorization': `Bearer ${jwtToken}` }})
|
|
|
|
|
if( resp.status != 200 ){
|
|
|
|
|
throw resp.statusText
|
|
|
|
|
}
|
|
|
|
|
this.insertAtCursor({content: ``})
|
|
|
|
|
} catch (err) {
|
|
|
|
|
return this.$store.commit('showNotification', {
|
|
|
|
|
message: this.$t('editor:assets.uploadFailed'),
|
|
|
|
|
style: 'error',
|
|
|
|
|
icon: 'error'
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
async createFolder(path) {
|
|
|
|
|
let folderID = 0
|
|
|
|
|
for(const folderName of path.split("/").slice(1)){
|
|
|
|
|
let folders = await this.getSubFolder(folderID)
|
|
|
|
|
// api case-insensitive for folder name
|
|
|
|
|
let folder = folders.find(folder => folder.slug === folderName)
|
|
|
|
|
if (!folder) {
|
|
|
|
|
const resp = await this.$apollo.mutate({
|
|
|
|
|
mutation: createAssetFolderMutation,
|
|
|
|
|
variables: {
|
|
|
|
|
parentFolderId: folderID,
|
|
|
|
|
slug: folderName
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
if (! _.get(resp, 'data.assets.createFolder.responseResult.succeeded', false)) {
|
|
|
|
|
const message = _.get(resp, 'data.assets.createFolder.responseResult.message')
|
|
|
|
|
this.$store.commit('pushGraphError', new Error(message))
|
|
|
|
|
throw new Error(message);
|
|
|
|
|
}
|
|
|
|
|
folders = await this.getSubFolder(folderID)
|
|
|
|
|
folder = folders.find(folder => folder.slug === folderName)
|
|
|
|
|
}
|
|
|
|
|
folderID = folder.id
|
|
|
|
|
}
|
|
|
|
|
return folderID
|
|
|
|
|
},
|
|
|
|
|
async getSubFolder(folderID){
|
|
|
|
|
const resp = await this.$apollo.query({
|
|
|
|
|
query: listFolderAssetQuery,
|
|
|
|
|
variables: {
|
|
|
|
|
parentFolderId: folderID,
|
|
|
|
|
},
|
|
|
|
|
fetchPolicy: 'network-only'
|
|
|
|
|
})
|
|
|
|
|
return _.get(resp, "data.assets.folders", [])
|
|
|
|
|
},
|
|
|
|
|
processContent (newContent) {
|
|
|
|
|
linesMap = []
|
|
|
|
|
|