mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
ui: quick emoji input support
This commit is contained in:
1 parent
402a58cd47
commit
fae452cc94
6 files changed
+255
-108
No files matched your search
@@ -55,8 +55,7 @@ export default class Editor extends DOMAttachedObject {
|
|||||||
// eslint-disable-next-line no-nested-ternary
|
// eslint-disable-next-line no-nested-ternary
|
||||||
this.model = typeof model === 'string'
|
this.model = typeof model === 'string'
|
||||||
? monaco.editor.getModel(monaco.Uri.parse(model))
|
? monaco.editor.getModel(monaco.Uri.parse(model))
|
||||||
? monaco.editor.getModel(monaco.Uri.parse(model))
|
|| monaco.editor.createModel(value, language, monaco.Uri.parse(model))
|
||||||
: monaco.editor.createModel(value, language, monaco.Uri.parse(model))
|
|
||||||
: model;
|
: model;
|
||||||
this.model.setValue(value);
|
this.model.setValue(value);
|
||||||
this.model.updateOptions({ language });
|
this.model.updateOptions({ language });
|
||||||
@@ -111,6 +110,8 @@ export default class Editor extends DOMAttachedObject {
|
|||||||
this.isValid = true;
|
this.isValid = true;
|
||||||
if (hasFocus) this.focus();
|
if (hasFocus) this.focus();
|
||||||
if (autoResize) updateEditorHeight();
|
if (autoResize) updateEditorHeight();
|
||||||
|
window.model = this.model;
|
||||||
|
window.editor = this.editor;
|
||||||
}
|
}
|
||||||
|
|
||||||
async initVditor() {
|
async initVditor() {
|
||||||
|
|||||||
@@ -1,111 +1,9 @@
|
|||||||
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
||||||
import loadFormatter from 'vj/components/wastyle/index';
|
import loadFormatter from 'vj/components/wastyle/index';
|
||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
|
import './languages/markdown';
|
||||||
monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
|
import './languages/typescript';
|
||||||
noSemanticValidation: false,
|
import './languages/yaml';
|
||||||
noSyntaxValidation: false,
|
|
||||||
});
|
|
||||||
monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
|
|
||||||
target: monaco.languages.typescript.ScriptTarget.ES6,
|
|
||||||
allowNonTsExtensions: true,
|
|
||||||
});
|
|
||||||
const libSource = [
|
|
||||||
'declare function readline(): string;',
|
|
||||||
'declare function print(content: string): void;',
|
|
||||||
].join('\n');
|
|
||||||
const libUri = 'ts:filename/basic.d.ts';
|
|
||||||
monaco.languages.typescript.javascriptDefaults.addExtraLib(libSource, libUri);
|
|
||||||
monaco.editor.createModel(libSource, 'typescript', monaco.Uri.parse(libUri));
|
|
||||||
|
|
||||||
/** @type {Record<string, import('json-schema').JSONSchema7Definition>} */
|
|
||||||
const problemConfigSchemaDef = {
|
|
||||||
cases: { type: 'array', items: { $ref: '#/def/case' } },
|
|
||||||
case: {
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
input: { type: 'string' },
|
|
||||||
output: { type: 'string' },
|
|
||||||
},
|
|
||||||
required: ['input'],
|
|
||||||
additionalProperties: false,
|
|
||||||
},
|
|
||||||
subtask: {
|
|
||||||
description: 'Subtask Info',
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
type: { enum: ['min', 'max', 'sum'] },
|
|
||||||
time: { $ref: '#/def/time' },
|
|
||||||
memory: { $ref: '#/def/memory' },
|
|
||||||
score: { $ref: '#/def/score', description: 'score' },
|
|
||||||
cases: { $ref: '#/def/cases' },
|
|
||||||
if: { type: 'array', items: { type: 'integer' } },
|
|
||||||
id: { type: 'integer' },
|
|
||||||
},
|
|
||||||
required: ['score'],
|
|
||||||
additionalProperties: false,
|
|
||||||
},
|
|
||||||
time: { type: 'string', pattern: '^([0-9]+(?:\\.[0-9]*)?)([mu]?)s?$' },
|
|
||||||
memory: { type: 'string', pattern: '^([0-9]+(?:\\.[0-9]*)?)([kmg])b?$' },
|
|
||||||
score: { type: 'integer', maximum: 100, minimum: 1 },
|
|
||||||
};
|
|
||||||
|
|
||||||
/** @type {import('json-schema').JSONSchema7Definition} */
|
|
||||||
const problemConfigSchema = {
|
|
||||||
type: 'object',
|
|
||||||
def: problemConfigSchemaDef,
|
|
||||||
properties: {
|
|
||||||
key: { type: 'string', pattern: '[0-9a-f]{32}' },
|
|
||||||
type: { enum: ['default', 'interactive', 'submit_answer', 'objective', 'remote_judge'] },
|
|
||||||
subType: { type: 'string' },
|
|
||||||
langs: { type: 'array', items: { type: 'string' } },
|
|
||||||
target: { type: 'string' },
|
|
||||||
checker_type: { enum: ['default', 'lemon', 'syzoj', 'hustoj', 'testlib', 'strict', 'qduoj'] },
|
|
||||||
checker: { type: 'string', pattern: '\\.' },
|
|
||||||
interactor: { type: 'string', pattern: '\\.' },
|
|
||||||
user_extra_files: { type: 'array', items: { type: 'string' } },
|
|
||||||
judge_extra_files: { type: 'array', items: { type: 'string' } },
|
|
||||||
cases: { $ref: '#/def/cases' },
|
|
||||||
subtasks: { type: 'array', items: { $ref: '#/def/subtask' } },
|
|
||||||
filename: { type: 'string' },
|
|
||||||
detail: { type: 'boolean' },
|
|
||||||
time: { $ref: '#/def/time' },
|
|
||||||
memory: { $ref: '#/def/memory' },
|
|
||||||
score: { $ref: '#/def/score' },
|
|
||||||
template: {
|
|
||||||
type: 'object',
|
|
||||||
patternProperties: {
|
|
||||||
'^.*$': {
|
|
||||||
type: 'array',
|
|
||||||
minLength: 2,
|
|
||||||
maxLength: 2,
|
|
||||||
items: { type: 'string' },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
additionalProperties: false,
|
|
||||||
},
|
|
||||||
outputs: {
|
|
||||||
type: 'array',
|
|
||||||
minLength: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
additionalProperties: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
monaco.languages.yaml.yamlDefaults.setDiagnosticsOptions({
|
|
||||||
validate: true,
|
|
||||||
enableSchemaRequest: true,
|
|
||||||
hover: true,
|
|
||||||
completion: true,
|
|
||||||
format: true,
|
|
||||||
schemas: [
|
|
||||||
{
|
|
||||||
uri: 'https://hydro.js.org/schema/problemConfig.json',
|
|
||||||
fileMatch: ['hydro://problem/file/config.yaml'],
|
|
||||||
schema: problemConfigSchema,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
export default monaco;
|
export default monaco;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,138 @@
|
|||||||
|
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
||||||
|
import list from 'emojis-list';
|
||||||
|
import keyword from 'emojis-keywords';
|
||||||
|
|
||||||
|
const qqEmojies = [
|
||||||
|
'weixiao',
|
||||||
|
'piezui',
|
||||||
|
'se',
|
||||||
|
'fadai',
|
||||||
|
'deyi',
|
||||||
|
'liulei',
|
||||||
|
'haixiu',
|
||||||
|
'bizui',
|
||||||
|
'shui',
|
||||||
|
'daku',
|
||||||
|
'ganga',
|
||||||
|
'fanu',
|
||||||
|
'tiaopi',
|
||||||
|
'ciya',
|
||||||
|
'jingya',
|
||||||
|
'nanguo',
|
||||||
|
'ku',
|
||||||
|
'lenghan',
|
||||||
|
'zhuakuang',
|
||||||
|
'tu',
|
||||||
|
'touxiao',
|
||||||
|
'keai',
|
||||||
|
'baiyan',
|
||||||
|
'aoman',
|
||||||
|
'jie',
|
||||||
|
'kun',
|
||||||
|
'jingkong',
|
||||||
|
'liuhan',
|
||||||
|
'hanxiao',
|
||||||
|
'dabing',
|
||||||
|
'fendou',
|
||||||
|
'zhouma',
|
||||||
|
'yiwen',
|
||||||
|
'xu',
|
||||||
|
'yun',
|
||||||
|
'zhemo',
|
||||||
|
'shuai',
|
||||||
|
'kulou',
|
||||||
|
'qiaoda',
|
||||||
|
'zaijian',
|
||||||
|
'cahan',
|
||||||
|
'koubi',
|
||||||
|
'guzhang',
|
||||||
|
'qiudale',
|
||||||
|
'huaixiao',
|
||||||
|
'zuohengheng',
|
||||||
|
'youhengheng',
|
||||||
|
'haqian',
|
||||||
|
'bishi',
|
||||||
|
'weiqu',
|
||||||
|
'kuaikule',
|
||||||
|
'yinxian',
|
||||||
|
'qinqin',
|
||||||
|
'xia',
|
||||||
|
'kelian',
|
||||||
|
'caidao',
|
||||||
|
'xigua',
|
||||||
|
'pijiu',
|
||||||
|
'lanqiu',
|
||||||
|
'pingpang',
|
||||||
|
'kafei',
|
||||||
|
'fan',
|
||||||
|
'zhutou',
|
||||||
|
'meigui',
|
||||||
|
'diaoxie',
|
||||||
|
'shiai',
|
||||||
|
'aixin',
|
||||||
|
'xinsui',
|
||||||
|
'dangao',
|
||||||
|
'shandian',
|
||||||
|
'zhadan',
|
||||||
|
'dao',
|
||||||
|
'zuqiu',
|
||||||
|
'piaochong',
|
||||||
|
'bianbian',
|
||||||
|
'yueliang',
|
||||||
|
'taiyang',
|
||||||
|
'liwu',
|
||||||
|
'yongbao',
|
||||||
|
'qiang',
|
||||||
|
'ruo',
|
||||||
|
'woshou',
|
||||||
|
'shengli',
|
||||||
|
'baoquan',
|
||||||
|
'gouyin',
|
||||||
|
'quantou',
|
||||||
|
'chajin',
|
||||||
|
'aini',
|
||||||
|
'no',
|
||||||
|
'ok',
|
||||||
|
];
|
||||||
|
|
||||||
|
function emoji(range) {
|
||||||
|
return keyword.map((i, index) => ({
|
||||||
|
label: `${list[index]} ${i}`,
|
||||||
|
kind: monaco.languages.CompletionItemKind.Keyword,
|
||||||
|
documentation: i,
|
||||||
|
insertText: list[index],
|
||||||
|
range,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function qqEmoji(range) {
|
||||||
|
return qqEmojies.map((i, index) => ({
|
||||||
|
label: `/${i}`,
|
||||||
|
kind: monaco.languages.CompletionItemKind.Keyword,
|
||||||
|
documentation: `/${i}`,
|
||||||
|
insertText: ` `,
|
||||||
|
range,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
monaco.languages.registerCompletionItemProvider('markdown', {
|
||||||
|
provideCompletionItems(model, position) {
|
||||||
|
const word = model.getWordAtPosition(position);
|
||||||
|
const prefix = model.getValueInRange({
|
||||||
|
startLineNumber: position.lineNumber,
|
||||||
|
endLineNumber: position.lineNumber,
|
||||||
|
startColumn: word.startColumn - 1,
|
||||||
|
endColumn: position.column - 1,
|
||||||
|
});
|
||||||
|
if (![':', '/'].includes(prefix)) return { suggestions: [] };
|
||||||
|
const range = {
|
||||||
|
startLineNumber: position.lineNumber,
|
||||||
|
endLineNumber: position.lineNumber,
|
||||||
|
startColumn: word.startColumn - 1,
|
||||||
|
endColumn: word.endColumn,
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
suggestions: prefix === ':' ? emoji(range) : qqEmoji(range),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
||||||
|
|
||||||
|
monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
|
||||||
|
noSemanticValidation: false,
|
||||||
|
noSyntaxValidation: false,
|
||||||
|
});
|
||||||
|
monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
|
||||||
|
target: monaco.languages.typescript.ScriptTarget.ES2020,
|
||||||
|
allowNonTsExtensions: true,
|
||||||
|
});
|
||||||
|
const libSource = [
|
||||||
|
'declare function readline(): string;',
|
||||||
|
'declare function print(content: string): void;',
|
||||||
|
].join('\n');
|
||||||
|
const libUri = 'ts:filename/basic.d.ts';
|
||||||
|
monaco.languages.typescript.javascriptDefaults.addExtraLib(libSource, libUri);
|
||||||
|
monaco.editor.createModel(libSource, 'typescript', monaco.Uri.parse(libUri));
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
||||||
|
|
||||||
|
/** @type {Record<string, import('json-schema').JSONSchema7Definition>} */
|
||||||
|
const problemConfigSchemaDef = {
|
||||||
|
cases: { type: 'array', items: { $ref: '#/def/case' } },
|
||||||
|
case: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
input: { type: 'string' },
|
||||||
|
output: { type: 'string' },
|
||||||
|
},
|
||||||
|
required: ['input'],
|
||||||
|
additionalProperties: false,
|
||||||
|
},
|
||||||
|
subtask: {
|
||||||
|
description: 'Subtask Info',
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
type: { enum: ['min', 'max', 'sum'] },
|
||||||
|
time: { $ref: '#/def/time' },
|
||||||
|
memory: { $ref: '#/def/memory' },
|
||||||
|
score: { $ref: '#/def/score', description: 'score' },
|
||||||
|
cases: { $ref: '#/def/cases' },
|
||||||
|
if: { type: 'array', items: { type: 'integer' } },
|
||||||
|
id: { type: 'integer' },
|
||||||
|
},
|
||||||
|
required: ['score'],
|
||||||
|
additionalProperties: false,
|
||||||
|
},
|
||||||
|
time: { type: 'string', pattern: '^([0-9]+(?:\\.[0-9]*)?)([mu]?)s?$' },
|
||||||
|
memory: { type: 'string', pattern: '^([0-9]+(?:\\.[0-9]*)?)([kmg])b?$' },
|
||||||
|
score: { type: 'integer', maximum: 100, minimum: 1 },
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @type {import('json-schema').JSONSchema7Definition} */
|
||||||
|
const problemConfigSchema = {
|
||||||
|
type: 'object',
|
||||||
|
def: problemConfigSchemaDef,
|
||||||
|
properties: {
|
||||||
|
key: { type: 'string', pattern: '[0-9a-f]{32}' },
|
||||||
|
type: { enum: ['default', 'interactive', 'submit_answer', 'objective', 'remote_judge'] },
|
||||||
|
subType: { type: 'string' },
|
||||||
|
langs: { type: 'array', items: { type: 'string' } },
|
||||||
|
target: { type: 'string' },
|
||||||
|
checker_type: { enum: ['default', 'lemon', 'syzoj', 'hustoj', 'testlib', 'strict', 'qduoj'] },
|
||||||
|
checker: { type: 'string', pattern: '\\.' },
|
||||||
|
interactor: { type: 'string', pattern: '\\.' },
|
||||||
|
user_extra_files: { type: 'array', items: { type: 'string' } },
|
||||||
|
judge_extra_files: { type: 'array', items: { type: 'string' } },
|
||||||
|
cases: { $ref: '#/def/cases' },
|
||||||
|
subtasks: { type: 'array', items: { $ref: '#/def/subtask' } },
|
||||||
|
filename: { type: 'string' },
|
||||||
|
detail: { type: 'boolean' },
|
||||||
|
time: { $ref: '#/def/time' },
|
||||||
|
memory: { $ref: '#/def/memory' },
|
||||||
|
score: { $ref: '#/def/score' },
|
||||||
|
template: {
|
||||||
|
type: 'object',
|
||||||
|
patternProperties: {
|
||||||
|
'^.*$': {
|
||||||
|
type: 'array',
|
||||||
|
minLength: 2,
|
||||||
|
maxLength: 2,
|
||||||
|
items: { type: 'string' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
additionalProperties: false,
|
||||||
|
},
|
||||||
|
outputs: {
|
||||||
|
type: 'array',
|
||||||
|
minLength: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
additionalProperties: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
monaco.languages.yaml.yamlDefaults.setDiagnosticsOptions({
|
||||||
|
validate: true,
|
||||||
|
enableSchemaRequest: true,
|
||||||
|
hover: true,
|
||||||
|
completion: true,
|
||||||
|
format: true,
|
||||||
|
schemas: [
|
||||||
|
{
|
||||||
|
uri: 'https://hydro.js.org/schema/problemConfig.json',
|
||||||
|
fileMatch: ['hydro://problem/file/config.yaml'],
|
||||||
|
schema: problemConfigSchema,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@hydrooj/ui-default",
|
"name": "@hydrooj/ui-default",
|
||||||
"version": "4.20.1",
|
"version": "4.20.2",
|
||||||
"author": "undefined <i@undefined.moe>",
|
"author": "undefined <i@undefined.moe>",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "hydro.js",
|
"main": "hydro.js",
|
||||||
@@ -32,6 +32,8 @@
|
|||||||
"diff-dom": "^4.2.2",
|
"diff-dom": "^4.2.2",
|
||||||
"echarts": "^5.2.0",
|
"echarts": "^5.2.0",
|
||||||
"emojify.js": "^1.1.0",
|
"emojify.js": "^1.1.0",
|
||||||
|
"emojis-keywords": "2.0.0",
|
||||||
|
"emojis-list": "2.1.0",
|
||||||
"esbuild-loader": "^2.15.1",
|
"esbuild-loader": "^2.15.1",
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^7.32.0",
|
||||||
"eslint-config-airbnb": "^18.2.1",
|
"eslint-config-airbnb": "^18.2.1",
|
||||||
|
|||||||
Reference in new issue
Block a user