ui: problem_edit: fix multi-lang

This commit is contained in:
undefined committed 2021-05-05 17:34:25 +08:00
1 parent a5e3cf2c9b
commit 0c5f941203
5 files changed
+59 -62

No files matched your search

@@ -119,7 +119,7 @@ export default class Editor extends DOMAttachedObject {
value(val) { value(val) {
this.ensureValid(); this.ensureValid();
if (val) return this.editor.setValue(val); if (typeof val === 'string') return this.editor.setValue(val);
return this.editor.getValue(); return this.editor.getValue();
} }
+16 -16
View File
@@ -13,7 +13,7 @@ export default class Tab extends DOMAttachedObject {
} }
static initEventListeners() { static initEventListeners() {
$(document).on('click', '.section__tab-header-item', (ev) => { $(document).on('click', '[data-tab-index]', (ev) => {
const targetIndex = $(ev.currentTarget).attr('data-tab-index'); const targetIndex = $(ev.currentTarget).attr('data-tab-index');
const $container = $(ev.currentTarget).closest('.section__tab-container'); const $container = $(ev.currentTarget).closest('.section__tab-container');
const tabInstance = Tab.get($container); const tabInstance = Tab.get($container);
@@ -61,19 +61,21 @@ export default class Tab extends DOMAttachedObject {
// 2. Animate transition // 2. Animate transition
$currentTab $currentTab
.transition({ .transition(
opacity: 0, { opacity: 0 },
}, { {
duration: TAB_TRANSITION_DURATION, duration: TAB_TRANSITION_DURATION,
easing: 'linear', easing: 'linear',
}); }
);
$newTab $newTab
.transition({ .transition(
opacity: 1, { opacity: 1 },
}, { {
duration: TAB_TRANSITION_DURATION, duration: TAB_TRANSITION_DURATION,
easing: 'linear', easing: 'linear',
}); }
);
await this.$content await this.$content
.transition({ .transition({
x: animateParameter.to, x: animateParameter.to,
@@ -97,9 +99,7 @@ export default class Tab extends DOMAttachedObject {
} }
attach() { attach() {
if (this.attached) { if (this.attached) return false;
return false;
}
const $container = this.$dom const $container = this.$dom
.closest('.section__tab-container'); .closest('.section__tab-container');
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@hydrooj/ui-default", "name": "@hydrooj/ui-default",
"version": "4.6.31", "version": "4.6.32",
"author": "undefined <i@undefined.moe>", "author": "undefined <i@undefined.moe>",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"main": "hydro.js", "main": "hydro.js",
+33 -25
View File
@@ -177,14 +177,17 @@ export default new NamedPage(['problem_create', 'problem_edit'], (pagename) => {
}); });
}, 50); }, 50);
const $main = $('textarea[data-markdown-upload]'); const $main = $('textarea[data-editor]');
let content = $main.val(); const $field = $('textarea[data-markdown-upload]');
let content = $field.val();
let isObject = false; let isObject = false;
let activeTab = $('[data-lang]').first().attr('data-lang');
try { try {
content = JSON.parse(content); content = JSON.parse(content);
isObject = !(content instanceof Array); isObject = !(content instanceof Array);
if (!isObject) content = JSON.stringify(content); if (!isObject) content = JSON.stringify(content);
} catch (e) { } } catch (e) { }
if (!isObject) content = { [activeTab]: content };
const upload = { const upload = {
accept: 'image/*,.mp3, .wav, .zip', accept: 'image/*,.mp3, .wav, .zip',
url: './files', url: './files',
@@ -229,30 +232,35 @@ export default new NamedPage(['problem_create', 'problem_edit'], (pagename) => {
}, },
validate: () => (pagename === 'problem_create' ? i18n('Cannot upload file before problem is created.') : true), validate: () => (pagename === 'problem_create' ? i18n('Cannot upload file before problem is created.') : true),
}; };
$('textarea[data-content]').each(function () { function getContent(lang) {
const $dom = $(this);
let i = $dom.attr('data-content');
let c = ''; let c = '';
if (isObject) { if (content[lang]) c = content[lang];
if (content[i]) c = content[i]; else {
else { const list = Object.keys(content).filter((l) => l.startsWith(lang));
const list = Object.keys(content).filter((l) => l.startsWith(i)); if (list.length) c = content[list[0]];
if (list.length) c = content[list[0]];
[i] = list;
}
} else c = content;
if (typeof c !== 'string') c = JSON.stringify(c);
$dom.val(c);
function onChange(val) {
if (!isObject) {
content = { [i]: val };
isObject = true;
}
const empty = /^\s*$/g.test(val);
if (empty) delete content[i];
else content[i] = val;
$main.val(JSON.stringify(content));
} }
Editor.getOrConstruct($dom, { upload, onChange }); if (typeof c !== 'string') c = JSON.stringify(c);
return c;
}
$main.val(getContent(activeTab));
function onChange(val) {
console.log('onChange', activeTab, val);
try {
val = JSON.parse(val);
if (!(val instanceof Array)) val = JSON.stringify(val);
} catch { }
const empty = /^\s*$/g.test(val);
if (empty) delete content[activeTab];
else content[activeTab] = val;
console.log(content);
if (!Object.keys(content).length) $field.text('');
else $field.text(JSON.stringify(content));
}
const editor = Editor.getOrConstruct($main, { upload, onChange });
$('[data-lang]').on('click', (ev) => {
const lang = $(ev.currentTarget).attr('data-lang');
activeTab = lang;
const val = getContent(lang);
editor.value(val);
}); });
}); });
@@ -38,29 +38,18 @@
value:pdoc['tag']|default([])|join(', ') value:pdoc['tag']|default([])|join(', ')
}) }} }) }}
<div class="section__tab-container nojs--hide"> <div class="section__tab-container nojs--hide">
<ul class="section__tabs immersive"> <div class="section__tab-header-wrapper">
<li class="section__tab-item"> <ul class="section__tab-header">
<h1 class="section__tab-title">{{ _('__langname') }}</h1> <li class="section__tab-header-item" data-lang="{{ _('__id') }}">{{ _('__langname') }}</li>
<div class="section__tab-main">
<div class="section__body">
<textarea data-content="{{ _('__id') }}" class="textbox" style="height: 500px"></textarea>
</div>
</div>
</li>
{% for k, v in model.setting.SETTINGS_BY_KEY['viewLang'].range %} {% for k, v in model.setting.SETTINGS_BY_KEY['viewLang'].range %}
{% if k != handler.user.viewLang %} {% if k != handler.user.viewLang %}
<li class="section__tab-item"> <li class="section__tab-header-item" data-lang="{{ k }}">{{ v }}</li>
<h1 class="section__tab-title">{{ v }}</h1> {% endif %}
<div class="section__tab-main"> {% endfor %}
<div class="section__body">
<textarea data-content="{{ k }}" class="textbox" style="height: 500px"></textarea>
</div>
</div>
</li>
{% endif %}
{% endfor %}
</ul> </ul>
</div>
</div> </div>
<div><textarea data-editor class="nojs--hide"></textarea></div>
<textarea name="content" class="textbox hasjs--hide" data-markdown-upload style="height: 500px">{% if pdoc %}{{ pdoc['content']|toString }}{% else %}{% include 'partials/problem_default.md' %}{% endif %}</textarea> <textarea name="content" class="textbox hasjs--hide" data-markdown-upload style="height: 500px">{% if pdoc %}{{ pdoc['content']|toString }}{% else %}{% include 'partials/problem_default.md' %}{% endif %}</textarea>
<div class="row"><div class="columns"> <div class="row"><div class="columns">
<input type="hidden" name="csrfToken" value="{{ handler.csrfToken }}"> <input type="hidden" name="csrfToken" value="{{ handler.csrfToken }}">