mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
ui: vditor upload image support (#317)
This commit is contained in:
1 parent
c4521d9ce3
commit
dbbc0c5e1d
2 files changed
+53
-47
No files matched your search
@@ -1,6 +1,9 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
|
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
|
||||||
|
import { nanoid } from 'nanoid';
|
||||||
|
import i18n from 'vj/utils/i18n';
|
||||||
|
import request from 'vj/utils/request';
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
toolbar: [
|
toolbar: [
|
||||||
@@ -158,6 +161,8 @@ export default class Editor extends DOMAttachedObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async initVditor() {
|
async initVditor() {
|
||||||
|
const pagename = document.documentElement.getAttribute('data-page');
|
||||||
|
const isProblemEdit = pagename === 'problem_edit';
|
||||||
const { default: Vditor } = await import('vditor');
|
const { default: Vditor } = await import('vditor');
|
||||||
const { $dom } = this;
|
const { $dom } = this;
|
||||||
const hasFocus = $dom.is(':focus') || $dom.hasClass('autofocus');
|
const hasFocus = $dom.is(':focus') || $dom.hasClass('autofocus');
|
||||||
@@ -167,7 +172,52 @@ export default class Editor extends DOMAttachedObject {
|
|||||||
const { onChange } = this.options;
|
const { onChange } = this.options;
|
||||||
await new Promise((resolve) => {
|
await new Promise((resolve) => {
|
||||||
this.vditor = new Vditor(ele, {
|
this.vditor = new Vditor(ele, {
|
||||||
...config,
|
upload: {
|
||||||
|
multiple: false,
|
||||||
|
handler: (files) => {
|
||||||
|
let wrapper = ['', ''];
|
||||||
|
let ext: string;
|
||||||
|
const matches = files[0].type.match(/^image\/(png|jpg|jpeg|gif)$/i);
|
||||||
|
if (matches) {
|
||||||
|
wrapper = [''];
|
||||||
|
[, ext] = matches;
|
||||||
|
} else if (files[0].type === 'application/x-zip-compressed') {
|
||||||
|
wrapper = ['[file](', ')'];
|
||||||
|
ext = 'zip';
|
||||||
|
}
|
||||||
|
if (!ext) return i18n('No Supported file type.');
|
||||||
|
const filename = `${nanoid()}.${ext}`;
|
||||||
|
const data = new FormData();
|
||||||
|
data.append('filename', filename);
|
||||||
|
data.append('file', files[0]);
|
||||||
|
data.append('operation', 'upload_file');
|
||||||
|
if (isProblemEdit) data.append('type', 'additional_file');
|
||||||
|
let progress = 0;
|
||||||
|
request.postFile(isProblemEdit ? './files' : '/file', data, {
|
||||||
|
xhr: () => {
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
xhr.upload.addEventListener('loadstart', () => this.vditor.vditor.tip.show(i18n('Uploading...'), 0));
|
||||||
|
xhr.upload.addEventListener('progress', (e) => {
|
||||||
|
if (!e.lengthComputable) return;
|
||||||
|
const percentComplete = Math.round((e.loaded / e.total) * 100);
|
||||||
|
if (percentComplete === progress) return;
|
||||||
|
progress = percentComplete;
|
||||||
|
this.vditor.vditor.tip.show(`${i18n('Uploading...')} ${percentComplete}%`, 0);
|
||||||
|
}, false);
|
||||||
|
return xhr;
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.vditor.insertValue(`${wrapper.join(`file://${filename}`)} `);
|
||||||
|
this.vditor.vditor.tip.hide();
|
||||||
|
})
|
||||||
|
.catch((e: { message: string; }) => {
|
||||||
|
console.error(e);
|
||||||
|
return `${i18n('Upload Failed')}: ${e.message}`;
|
||||||
|
});
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
},
|
||||||
...this.options,
|
...this.options,
|
||||||
after: () => {
|
after: () => {
|
||||||
const pos = $(ele).find('button[data-mode="sv"]').get();
|
const pos = $(ele).find('button[data-mode="sv"]').get();
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ export default new NamedPage(['problem_create', 'problem_edit'], (pagename) => {
|
|||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
$('img').each(function () {
|
$('img').each(function () {
|
||||||
if (this.src.startsWith('file://')) {
|
if (this.src.startsWith('file://')) {
|
||||||
this.setAttribute('src', this.src.replace('file://', './file/').replace(/\/$/, ''));
|
$(this).attr('src', $(this).attr('src').replace('file://', (pagename === 'problem_create' ? `/file/${UserContext._id}/` : './file/')));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, 500);
|
}, 500);
|
||||||
@@ -189,50 +189,6 @@ export default new NamedPage(['problem_create', 'problem_edit'], (pagename) => {
|
|||||||
if (!isObject) content = JSON.stringify(content);
|
if (!isObject) content = JSON.stringify(content);
|
||||||
} catch (e) { }
|
} catch (e) { }
|
||||||
if (!isObject) content = { [activeTab]: content };
|
if (!isObject) content = { [activeTab]: content };
|
||||||
const upload = {
|
|
||||||
accept: 'image/*,.mp3, .wav, .zip',
|
|
||||||
url: './files',
|
|
||||||
extraData: {
|
|
||||||
type: 'additional_file',
|
|
||||||
operation: 'upload_file',
|
|
||||||
},
|
|
||||||
multiple: false,
|
|
||||||
fieldName: 'file',
|
|
||||||
setHeaders() {
|
|
||||||
return { accept: 'application/json' };
|
|
||||||
},
|
|
||||||
format(files, resp) {
|
|
||||||
const res = JSON.parse(resp);
|
|
||||||
if (res.error) {
|
|
||||||
return JSON.stringify({
|
|
||||||
msg: res.error.message,
|
|
||||||
code: -1,
|
|
||||||
data: {
|
|
||||||
errFiles: [files[0].name],
|
|
||||||
succMap: {},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return JSON.stringify({
|
|
||||||
msg: '',
|
|
||||||
code: 0,
|
|
||||||
data: {
|
|
||||||
errFiles: [],
|
|
||||||
succMap: {
|
|
||||||
[files[0].name]: `file://${files[0].name.replace(/[^(a-zA-Z0-9\u4e00-\u9fa5.)]/g, '')
|
|
||||||
.replace(/[?\\/:|<>*[\]()$%{}@~]/g, '')
|
|
||||||
.replace(/\s/g, '')}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
filename(name) {
|
|
||||||
return name.replace(/[^(a-zA-Z0-9\u4e00-\u9fa5.)]/g, '')
|
|
||||||
.replace(/[?\\/:|<>*[\]()$%{}@~]/g, '')
|
|
||||||
.replace(/\s/g, '');
|
|
||||||
},
|
|
||||||
validate: () => (pagename === 'problem_create' ? i18n('Cannot upload file before problem is created.') : true),
|
|
||||||
};
|
|
||||||
function getContent(lang) {
|
function getContent(lang) {
|
||||||
let c = '';
|
let c = '';
|
||||||
if (content[lang]) c = content[lang];
|
if (content[lang]) c = content[lang];
|
||||||
@@ -255,7 +211,7 @@ export default new NamedPage(['problem_create', 'problem_edit'], (pagename) => {
|
|||||||
if (!Object.keys(content).length) $field.text('');
|
if (!Object.keys(content).length) $field.text('');
|
||||||
else $field.text(JSON.stringify(content));
|
else $field.text(JSON.stringify(content));
|
||||||
}
|
}
|
||||||
const editor = Editor.getOrConstruct($main, { upload, onChange });
|
const editor = Editor.getOrConstruct($main, { onChange });
|
||||||
$('[data-lang]').on('click', (ev) => {
|
$('[data-lang]').on('click', (ev) => {
|
||||||
$('[data-lang]').removeClass('tab--active');
|
$('[data-lang]').removeClass('tab--active');
|
||||||
$(ev.currentTarget).addClass('tab--active');
|
$(ev.currentTarget).addClass('tab--active');
|
||||||
|
|||||||
Reference in new issue
Block a user