diff --git a/packages/ui-default/backendlib/template.js b/packages/ui-default/backendlib/template.js index 120863f85..d3d237f68 100644 --- a/packages/ui-default/backendlib/template.js +++ b/packages/ui-default/backendlib/template.js @@ -142,8 +142,11 @@ class Nunjucks extends nunjucks.Environment { s = content; } if (typeof s === 'object' && !(s instanceof Array)) { + const langs = Object.keys(s); + const f = langs.filter(i => i.startsWith(language)); if (s[language]) s = s[language]; - else s = s[Object.keys(s)[0]]; + else if (f.length) s = s[f[0]]; + else s = s[langs[0]]; } if (s instanceof Array) s = buildContent(s, html ? 'html' : 'markdown', (str) => str.translate(language)); return html ? xss.process(s) : markdown.render(s); diff --git a/packages/ui-default/components/cmeditor/index.js b/packages/ui-default/components/cmeditor/index.js index 05a731273..ca164758f 100644 --- a/packages/ui-default/components/cmeditor/index.js +++ b/packages/ui-default/components/cmeditor/index.js @@ -40,12 +40,17 @@ export default class CmEditor extends DOMAttachedObject { const origin = $dom.get(0); const ele = document.createElement('div'); const value = $dom.val(); + const onChange = this.options.onChange; await new Promise((resolve) => { this.editor = new Vditor(ele, { ...config, ...this.options, after: resolve, - input(v) { $dom.val(v); $dom.text(v); }, + input(v) { + $dom.val(v); + $dom.text(v); + if (onChange) onChange(v); + }, value, cache: { id: Math.random().toString() }, }); diff --git a/packages/ui-default/components/tab/Tab.js b/packages/ui-default/components/tab/Tab.js index b357169d6..9a60471b1 100644 --- a/packages/ui-default/components/tab/Tab.js +++ b/packages/ui-default/components/tab/Tab.js @@ -28,12 +28,8 @@ export default class Tab extends DOMAttachedObject { } async switchToTab(idx) { - if (idx === this.currentIndex) { - return; - } - if (this.isAnimating) { - return; - } + if (idx === this.currentIndex) return; + if (this.isAnimating) return; const $tabs = this.$content.children(); const $currentTab = $tabs.eq(this.currentIndex); diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index 9742c664b..32122d57c 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.6.17", + "version": "4.6.18", "author": "undefined ", "license": "AGPL-3.0", "main": "hydro.js", diff --git a/packages/ui-default/pages/problem_edit.page.js b/packages/ui-default/pages/problem_edit.page.js index 7070a7991..9ea296dc8 100644 --- a/packages/ui-default/pages/problem_edit.page.js +++ b/packages/ui-default/pages/problem_edit.page.js @@ -177,50 +177,78 @@ export default new NamedPage(['problem_create', 'problem_edit'], (pagename) => { }); }, 50); - CmEditor.getOrConstruct($('textarea[data-markdown-upload]'), { - 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: {}, - }, - }); - } + const $main = $('textarea[data-markdown-upload]'); + let content = $main.val(); + let isObject = false; + try { + content = JSON.parse(content); + isObject = !(content instanceof Array); + if (!isObject) content = JSON.stringify(content); + } catch (e) { } + 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: '', - code: 0, + msg: res.error.message, + code: -1, data: { - errFiles: [], - succMap: { - [files[0].name]: `file://${files[0].name.replace(/[^(a-zA-Z0-9\u4e00-\u9fa5.)]/g, '') - .replace(/[?\\/:|<>*[\]()$%{}@~]/g, '') - .replace('/\\s/g', '')}`, - }, + errFiles: [files[0].name], + succMap: {}, }, }); - }, - 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), + } + 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), + }; + $('textarea[data-content]').each(function () { + const $dom = $(this); + let i = $dom.attr('data-content'); + let c = ''; + if (isObject) { + if (content[i]) c = content[i]; + else { + const list = Object.keys(content).filter(l => l.startsWith(i)); + if (list.length) c = content[list[0]]; + i = list[0]; + } + } else c = content; + if (typeof c !== 'string') c = JSON.stringify(c); + $dom.val(c); + function onChange(val) { + const empty = /^\s*$/g.test(val); + if (empty) delete content[i]; + else content[i] = val; + $main.val(JSON.stringify(content)); + } + CmEditor.getOrConstruct($dom, { upload, onChange }); + }) }); diff --git a/packages/ui-default/pages/problem_import.page.js b/packages/ui-default/pages/problem_import.page.js deleted file mode 100644 index 14fa8c9cd..000000000 --- a/packages/ui-default/pages/problem_import.page.js +++ /dev/null @@ -1,6 +0,0 @@ -import { NamedPage } from 'vj/misc/Page'; - -const page = new NamedPage('problem_import', async () => { -}); - -export default page; diff --git a/packages/ui-default/templates/fs_upload.html b/packages/ui-default/templates/fs_upload.html deleted file mode 100644 index 398962734..000000000 --- a/packages/ui-default/templates/fs_upload.html +++ /dev/null @@ -1,21 +0,0 @@ -{% extends 'layout/simple.html' %} -{% block body %} -{% if fdoc %} -
{{ _('Uploaded file info') }}:
-{{ _('ID') }}: {{ fdoc['_id'] }}
-{{ _('Userfile doc_id') }}: {{ ufid }}
-{{ _('MD5') }}: {{ fdoc['md5'] }}
-{{ _('URL') }}: {{ model.file.url(fdoc) }}
-{% endif %} - -{% endblock %} diff --git a/packages/ui-default/templates/problem_edit.html b/packages/ui-default/templates/problem_edit.html index f9c91d03d..e97949449 100644 --- a/packages/ui-default/templates/problem_edit.html +++ b/packages/ui-default/templates/problem_edit.html @@ -37,12 +37,31 @@ name:'tag', value:pdoc['tag']|default([])|join(', ') }) }} -