mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
ui: frontend api (#470) [skip-cache]
This commit is contained in:
1 parent
6d69e88739
commit
96fa6cc7b9
116 files changed
+599
-629
No files matched your search
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
dist
|
dist
|
||||||
*.d.ts
|
*.d.ts
|
||||||
node_modules
|
node_modules
|
||||||
public
|
public/**/*.js
|
||||||
+21
-3
@@ -3,7 +3,7 @@ extends:
|
|||||||
- airbnb-base
|
- airbnb-base
|
||||||
- airbnb-typescript/base
|
- airbnb-typescript/base
|
||||||
env:
|
env:
|
||||||
jquery: true
|
es6: true
|
||||||
globals:
|
globals:
|
||||||
Atomics: readonly
|
Atomics: readonly
|
||||||
SharedArrayBuffer: readonly
|
SharedArrayBuffer: readonly
|
||||||
@@ -14,8 +14,26 @@ plugins:
|
|||||||
- simple-import-sort
|
- simple-import-sort
|
||||||
- eslint-plugin-import
|
- eslint-plugin-import
|
||||||
ignorePatterns:
|
ignorePatterns:
|
||||||
- public/
|
- public/**/*.js
|
||||||
- '*.spec.ts'
|
- packages/ui-default
|
||||||
|
overrides:
|
||||||
|
- files:
|
||||||
|
- '**/public/**/*.ts'
|
||||||
|
- '**/public/**/*.page.js'
|
||||||
|
rules:
|
||||||
|
'@typescript-eslint/indent':
|
||||||
|
- warn
|
||||||
|
- 2
|
||||||
|
env:
|
||||||
|
browser: true
|
||||||
|
es6: true
|
||||||
|
jquery: true
|
||||||
|
globals:
|
||||||
|
UiContext: true
|
||||||
|
UserContext: true
|
||||||
|
externalModules: true
|
||||||
|
LOCALES: true
|
||||||
|
LANGS: true
|
||||||
rules:
|
rules:
|
||||||
'@typescript-eslint/no-shadow': 1
|
'@typescript-eslint/no-shadow': 1
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const child = require('child_process');
|
||||||
|
|
||||||
|
if (fs.existsSync('plugins/patch-package/package.json') && fs.existsSync('node_modules/patch-package/package.json')) {
|
||||||
|
child.execSync('npx patch-package --patch-dir=plugins/patch-package/patches', { stdio: 'inherit' });
|
||||||
|
}
|
||||||
|
|
||||||
const dir = path.dirname(path.dirname(require.resolve('@types/node/package.json')));
|
const dir = path.dirname(path.dirname(require.resolve('@types/node/package.json')));
|
||||||
const types = fs.readdirSync(dir).filter((i) => !['sharedworker', 'serviceworker'].includes(i));
|
const types = fs.readdirSync(dir).filter((i) => !['sharedworker', 'serviceworker'].includes(i));
|
||||||
@@ -51,6 +56,8 @@ const configFlat = (name) => ({
|
|||||||
|
|
||||||
if (!fs.existsSync(path.resolve(process.cwd(), 'plugins'))) {
|
if (!fs.existsSync(path.resolve(process.cwd(), 'plugins'))) {
|
||||||
fs.mkdirSync(path.resolve(process.cwd(), 'plugins'));
|
fs.mkdirSync(path.resolve(process.cwd(), 'plugins'));
|
||||||
|
// Write an empty file to make eslint happy
|
||||||
|
fs.writeFileSync(path.resolve(process.cwd(), 'plugins/eslint.ts'), '');
|
||||||
}
|
}
|
||||||
|
|
||||||
const modules = [
|
const modules = [
|
||||||
|
|||||||
+2
-2
@@ -17,8 +17,8 @@
|
|||||||
"build:ui:production:webpack": "cross-env NODE_OPTIONS=--max_old_space_size=8192 node packages/ui-default/build --production",
|
"build:ui:production:webpack": "cross-env NODE_OPTIONS=--max_old_space_size=8192 node packages/ui-default/build --production",
|
||||||
"test": "mocha",
|
"test": "mocha",
|
||||||
"benchmark": "cross-env BENCHMARK=true mocha",
|
"benchmark": "cross-env BENCHMARK=true mocha",
|
||||||
"lint": "eslint packages --ext ts --fix",
|
"lint": "eslint packages plugins --ext ts --fix",
|
||||||
"lint:ci": "eslint packages --ext ts",
|
"lint:ci": "eslint packages plugins --ext ts",
|
||||||
"lint:ui": "yarn workspace @hydrooj/ui-default lint --ext .js,.ts,.jsx,.tsx . --fix",
|
"lint:ui": "yarn workspace @hydrooj/ui-default lint --ext .js,.ts,.jsx,.tsx . --fix",
|
||||||
"lint:ui:ci": "yarn workspace @hydrooj/ui-default lint --ext .js,.ts,.jsx,.tsx .",
|
"lint:ui:ci": "yarn workspace @hydrooj/ui-default lint --ext .js,.ts,.jsx,.tsx .",
|
||||||
"debug": "node --trace-warnings --async-stack-traces --trace-deprecation node_modules/hydrooj/bin/hydrooj --debug --template",
|
"debug": "node --trace-warnings --async-stack-traces --trace-deprecation node_modules/hydrooj/bin/hydrooj --debug --template",
|
||||||
|
|||||||
@@ -1,82 +1,81 @@
|
|||||||
(() => {
|
import { $ } from '@hydrooj/ui-default';
|
||||||
const { AutoloadPage } = window.Hydro;
|
|
||||||
const { $ } = window.node_modules;
|
|
||||||
|
|
||||||
let loaded = false;
|
const { AutoloadPage } = window.Hydro;
|
||||||
async function load() {
|
|
||||||
if (loaded) return Promise.resolve();
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const scriptElement = document.createElement('script');
|
|
||||||
scriptElement.src = UiContext.onlyofficeApi;
|
|
||||||
scriptElement.async = true;
|
|
||||||
document.head.appendChild(scriptElement);
|
|
||||||
scriptElement.onload = resolve;
|
|
||||||
scriptElement.onerror = reject;
|
|
||||||
loaded = true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const loader = mode => async (element) => {
|
let loaded = false;
|
||||||
const id = `${mode}-${Math.random().toString()}`;
|
async function load() {
|
||||||
$(element).attr('id', id);
|
if (loaded) return Promise.resolve();
|
||||||
const url = $(element).text();
|
return new Promise((resolve, reject) => {
|
||||||
const t = new URL(url, window.location.href).pathname.split('.');
|
const scriptElement = document.createElement('script');
|
||||||
const n = new URL(url, window.location.href).pathname.split('/');
|
scriptElement.src = UiContext.onlyofficeApi;
|
||||||
const lang = UserContext.viewLang.includes('_') ? UserContext.viewLang.split('_')[0] : UserContext.viewLang;
|
scriptElement.async = true;
|
||||||
// eslint-disable-next-line no-undef
|
document.head.appendChild(scriptElement);
|
||||||
window.editor = new DocsAPI.DocEditor(id, {
|
scriptElement.onload = resolve;
|
||||||
document: {
|
scriptElement.onerror = reject;
|
||||||
fileType: t[t.length - 1],
|
loaded = true;
|
||||||
key: Math.random().toString(16),
|
});
|
||||||
title: decodeURIComponent(n[n.length - 1]),
|
}
|
||||||
url: new URL(url, window.location.href),
|
|
||||||
permissions: {
|
|
||||||
comment: false,
|
|
||||||
copy: true,
|
|
||||||
download: true,
|
|
||||||
edit: false,
|
|
||||||
fillForms: false,
|
|
||||||
modifyContentControl: false,
|
|
||||||
modifyFilter: false,
|
|
||||||
print: true,
|
|
||||||
protect: false,
|
|
||||||
review: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
editorConfig: {
|
|
||||||
lang,
|
|
||||||
mode: 'view',
|
|
||||||
user: {
|
|
||||||
group: "Hydro",
|
|
||||||
id: UserContext._id.toString(),
|
|
||||||
name: UserContext.uname,
|
|
||||||
},
|
|
||||||
customization: {
|
|
||||||
chat: false,
|
|
||||||
comments: false,
|
|
||||||
help: false,
|
|
||||||
hideRulers: true,
|
|
||||||
plugins: false,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
documentType: mode,
|
|
||||||
height: mode === 'slide' ? '560px' : '900px',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const getEles = types => {
|
const loader = (mode) => async (element) => {
|
||||||
const eles = [];
|
const id = `${mode}-${Math.random().toString()}`;
|
||||||
for (const type of types) eles.push(...$('div[data-' + type + ']').get());
|
$(element).attr('id', id);
|
||||||
return eles;
|
const url = $(element).text();
|
||||||
}
|
const t = new URL(url, window.location.href).pathname.split('.');
|
||||||
|
const n = new URL(url, window.location.href).pathname.split('/');
|
||||||
|
const lang = UserContext.viewLang.includes('_') ? UserContext.viewLang.split('_')[0] : UserContext.viewLang;
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
window.editor = new DocsAPI.DocEditor(id, {
|
||||||
|
document: {
|
||||||
|
fileType: t[t.length - 1],
|
||||||
|
key: Math.random().toString(16),
|
||||||
|
title: decodeURIComponent(n[n.length - 1]),
|
||||||
|
url: new URL(url, window.location.href),
|
||||||
|
permissions: {
|
||||||
|
comment: false,
|
||||||
|
copy: true,
|
||||||
|
download: true,
|
||||||
|
edit: false,
|
||||||
|
fillForms: false,
|
||||||
|
modifyContentControl: false,
|
||||||
|
modifyFilter: false,
|
||||||
|
print: true,
|
||||||
|
protect: false,
|
||||||
|
review: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
editorConfig: {
|
||||||
|
lang,
|
||||||
|
mode: 'view',
|
||||||
|
user: {
|
||||||
|
group: 'Hydro',
|
||||||
|
id: UserContext._id.toString(),
|
||||||
|
name: UserContext.uname,
|
||||||
|
},
|
||||||
|
customization: {
|
||||||
|
chat: false,
|
||||||
|
comments: false,
|
||||||
|
help: false,
|
||||||
|
hideRulers: true,
|
||||||
|
plugins: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
documentType: mode,
|
||||||
|
height: mode === 'slide' ? '560px' : '900px',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const page = new AutoloadPage('onlyoffice', async () => {
|
const getEles = (types) => {
|
||||||
let all = getEles(['doc', 'docx', 'cell', 'xls', 'xlsx', 'slide', 'ppt', 'pptx']);
|
const eles = [];
|
||||||
if (all.length) await load();
|
for (const type of types) eles.push(...$(`div[data-${type}]`).get());
|
||||||
getEles(['doc', 'docx']).forEach(loader('word'));
|
return eles;
|
||||||
getEles(['cell', 'xls', 'xlsx']).forEach(loader('cell'))
|
};
|
||||||
getEles(['slide', 'ppt', 'pptx']).forEach(loader('slide'));
|
|
||||||
});
|
|
||||||
|
|
||||||
window.Hydro.extraPages.push(page);
|
const page = new AutoloadPage('onlyoffice', async () => {
|
||||||
})();
|
const all = getEles(['doc', 'docx', 'cell', 'xls', 'xlsx', 'slide', 'ppt', 'pptx']);
|
||||||
|
if (all.length) await load();
|
||||||
|
getEles(['doc', 'docx']).forEach(loader('word'));
|
||||||
|
getEles(['cell', 'xls', 'xlsx']).forEach(loader('cell'));
|
||||||
|
getEles(['slide', 'ppt', 'pptx']).forEach(loader('slide'));
|
||||||
|
});
|
||||||
|
|
||||||
|
window.Hydro.extraPages.push(page);
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
export * from './utils';
|
||||||
|
export { default as Notification } from './components/notification';
|
||||||
|
export * from './components/dialog';
|
||||||
|
export * as bus from './bus';
|
||||||
|
export { default as loadMonaco } from './components/monaco/loader';
|
||||||
|
export * as redux from 'react-redux';
|
||||||
|
export * from './components/zipDownloader';
|
||||||
|
export { default as $ } from 'jquery';
|
||||||
|
export { default as _ } from 'lodash';
|
||||||
|
export { default as React } from 'react';
|
||||||
|
export { default as ReactDOM } from 'react-dom/client';
|
||||||
|
export * from './misc/Page';
|
||||||
|
|
||||||
|
export default async function load(name: string) {
|
||||||
|
if (window.node_modules[name]) return window.node_modules[name];
|
||||||
|
if (name === 'echarts') return import('echarts');
|
||||||
|
if (name === 'moment') return import('moment');
|
||||||
|
throw new Error(`Module ${name} not found`);
|
||||||
|
}
|
||||||
|
|
||||||
|
import AutoComplete from './components/autocomplete';
|
||||||
|
import CustomSelectAutoComplete from './components/autocomplete/CustomSelectAutoComplete';
|
||||||
|
import DomainSelectAutoComplete from './components/autocomplete/DomainSelectAutoComplete';
|
||||||
|
import ProblemSelectAutoComplete from './components/autocomplete/ProblemSelectAutoComplete';
|
||||||
|
import UserSelectAutoComplete from './components/autocomplete/UserSelectAutoComplete';
|
||||||
|
|
||||||
|
export {
|
||||||
|
load, AutoComplete, UserSelectAutoComplete, ProblemSelectAutoComplete, DomainSelectAutoComplete, CustomSelectAutoComplete,
|
||||||
|
};
|
||||||
|
export const { UserContext, UiContext } = window;
|
||||||
|
export function addPage(page: import('./misc/Page').Page | (() => Promise<void> | void)) {
|
||||||
|
window.Hydro.extraPages.push(page);
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
LANGS: Record<string, any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
let UserContext: Record<string, any>;
|
||||||
|
let UiContext: Record<string, any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Below are old version api compat
|
||||||
|
/* eslint-disable import/order */
|
||||||
|
import $ from 'jquery';
|
||||||
|
import _ from 'lodash';
|
||||||
|
import React from 'react';
|
||||||
|
import ReactDOM from 'react-dom/client';
|
||||||
|
import * as redux from 'react-redux';
|
||||||
|
|
||||||
|
const modules = {
|
||||||
|
_, $, React, redux, ReactDOM, load,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
node_modules: typeof modules;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(window, { node_modules: modules, $, jQuery: $ });
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable */
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
export default function root(fn = '.') {
|
export default function root(fn = '.') {
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
/* eslint-disable no-await-in-loop */
|
/* eslint-disable no-await-in-loop */
|
||||||
|
import type * as monaco from 'monaco-editor';
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||||
const _hooks: Record<keyof any, Array<(...args: any[]) => any>> = {};
|
const _hooks: Record<keyof any, Array<(...args: any[]) => any>> = {};
|
||||||
@@ -11,7 +12,7 @@ export type Disposable = () => void;
|
|||||||
export type VoidReturn = Promise<any> | any;
|
export type VoidReturn = Promise<any> | any;
|
||||||
|
|
||||||
export interface EventMap extends Record<string, any> {
|
export interface EventMap extends Record<string, any> {
|
||||||
'scratchpadEditorCreate': (editor, monaco) => any;
|
'scratchpadEditorCreate': (editor: monaco.editor.IStandaloneCodeEditor, monaco: typeof import('monaco-editor')) => any;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getHooks<K extends keyof EventMap>(name: K) {
|
function getHooks<K extends keyof EventMap>(name: K) {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ function monitorResource(resource) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class DOMAttachedObject {
|
class DOMAttachedObject {
|
||||||
static uniqueIdCounter = 0;
|
static uniqueIdCounter = 0;
|
||||||
static DOMAttachKey: string;
|
static DOMAttachKey: string;
|
||||||
static DOMAttachSelector: string;
|
static DOMAttachSelector: string;
|
||||||
@@ -127,3 +127,5 @@ export default class DOMAttachedObject {
|
|||||||
if (monitorDetach) monitorResource(this);
|
if (monitorDetach) monitorResource(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default DOMAttachedObject as typeof DOMAttachedObject & DOMAttachedObject;
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { DomainDoc } from 'hydrooj/src/interface';
|
import type { DomainDoc } from 'hydrooj/src/interface';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { forwardRef } from 'react';
|
import React, { forwardRef } from 'react';
|
||||||
import request from 'vj/utils/request';
|
import { request } from 'vj/utils';
|
||||||
import AutoComplete, { AutoCompleteHandle, AutoCompleteProps } from './AutoComplete';
|
import AutoComplete, { AutoCompleteHandle, AutoCompleteProps } from './AutoComplete';
|
||||||
|
|
||||||
const DomainSelectAutoComplete = forwardRef<AutoCompleteHandle<DomainDoc>, AutoCompleteProps<DomainDoc>>((props, ref) => (
|
const DomainSelectAutoComplete = forwardRef<AutoCompleteHandle<DomainDoc>, AutoCompleteProps<DomainDoc>>((props, ref) => (
|
||||||
|
|||||||
+1
-2
@@ -1,8 +1,7 @@
|
|||||||
import type { ProblemDoc } from 'hydrooj/src/interface';
|
import type { ProblemDoc } from 'hydrooj/src/interface';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { forwardRef } from 'react';
|
import React, { forwardRef } from 'react';
|
||||||
import api, { gql } from 'vj/utils/api';
|
import { api, gql, request } from 'vj/utils';
|
||||||
import request from 'vj/utils/request';
|
|
||||||
import AutoComplete, { AutoCompleteHandle, AutoCompleteProps } from './AutoComplete';
|
import AutoComplete, { AutoCompleteHandle, AutoCompleteProps } from './AutoComplete';
|
||||||
|
|
||||||
const ProblemSelectAutoComplete = forwardRef<AutoCompleteHandle<ProblemDoc>, AutoCompleteProps<ProblemDoc>>((props, ref) => (
|
const ProblemSelectAutoComplete = forwardRef<AutoCompleteHandle<ProblemDoc>, AutoCompleteProps<ProblemDoc>>((props, ref) => (
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { Udoc } from 'hydrooj/src/interface';
|
import type { Udoc } from 'hydrooj/src/interface';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { forwardRef } from 'react';
|
import React, { forwardRef } from 'react';
|
||||||
import api, { gql } from 'vj/utils/api';
|
import { api, gql } from 'vj/utils';
|
||||||
import AutoComplete, { AutoCompleteHandle, AutoCompleteProps } from './AutoComplete';
|
import AutoComplete, { AutoCompleteHandle, AutoCompleteProps } from './AutoComplete';
|
||||||
|
|
||||||
// eslint-disable-next-line prefer-arrow-callback
|
// eslint-disable-next-line prefer-arrow-callback
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { AutoloadPage } from 'vj/misc/Page';
|
import { AutoloadPage } from 'vj/misc/Page';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n, tpl } from 'vj/utils';
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
import { InfoDialog } from './dialog';
|
import { InfoDialog } from './dialog';
|
||||||
|
|
||||||
function isSupported() {
|
function isSupported() {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import tpl from 'vj/utils/tpl';
|
import { tpl } from 'vj/utils';
|
||||||
|
|
||||||
export default class Calendar {
|
export default class Calendar {
|
||||||
constructor(events) {
|
constructor(events) {
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import Clipboard from 'clipboard';
|
import Clipboard from 'clipboard';
|
||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
import { AutoloadPage } from 'vj/misc/Page';
|
import { AutoloadPage } from 'vj/misc/Page';
|
||||||
import base64 from 'vj/utils/base64';
|
import { base64, i18n, substitute } from 'vj/utils';
|
||||||
import i18n from 'vj/utils/i18n';
|
|
||||||
import substitute from 'vj/utils/substitute';
|
|
||||||
|
|
||||||
export default new AutoloadPage('clipboard', () => {
|
export default new AutoloadPage('clipboard', () => {
|
||||||
$('[data-copy]').get().forEach((el) => {
|
$('[data-copy]').get().forEach((el) => {
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
import { AutoloadPage } from 'vj/misc/Page';
|
import { AutoloadPage } from 'vj/misc/Page';
|
||||||
import delay from 'vj/utils/delay';
|
import { delay, i18n, request } from 'vj/utils';
|
||||||
import i18n from 'vj/utils/i18n';
|
|
||||||
import request from 'vj/utils/request';
|
|
||||||
|
|
||||||
const contestPage = new AutoloadPage('contestPage', () => {
|
const contestPage = new AutoloadPage('contestPage', () => {
|
||||||
$('[data-contest-code]').on('click', (ev) => {
|
$('[data-contest-code]').on('click', (ev) => {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
|
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
|
||||||
import zIndexManager from 'vj/utils/zIndexManager';
|
import { zIndexManager } from 'vj/utils';
|
||||||
|
|
||||||
export interface DialogOptions {
|
export interface DialogOptions {
|
||||||
classes: string;
|
classes: string;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n, tpl } from 'vj/utils';
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
import DomDialog, { DialogOptions } from './DomDialog';
|
import DomDialog, { DialogOptions } from './DomDialog';
|
||||||
|
|
||||||
export class Dialog {
|
export class Dialog {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import _ from 'lodash';
|
|||||||
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
|
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
|
||||||
import TextareaHandler from 'vj/components/editor/textareaHandler';
|
import TextareaHandler from 'vj/components/editor/textareaHandler';
|
||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
import request from 'vj/utils/request';
|
import { request } from 'vj/utils';
|
||||||
|
|
||||||
let initialized = false;
|
let initialized = false;
|
||||||
const $template = $('.dczcomments__box').eq(0).clone();
|
const $template = $('.dczcomments__box').eq(0).clone();
|
||||||
|
|||||||
@@ -4,11 +4,9 @@ import $ from 'jquery';
|
|||||||
import { ConfirmDialog } from 'vj/components/dialog';
|
import { ConfirmDialog } from 'vj/components/dialog';
|
||||||
import CommentBox from 'vj/components/discussion/CommentBox';
|
import CommentBox from 'vj/components/discussion/CommentBox';
|
||||||
import { AutoloadPage } from 'vj/misc/Page';
|
import { AutoloadPage } from 'vj/misc/Page';
|
||||||
import delay from 'vj/utils/delay';
|
import {
|
||||||
import i18n from 'vj/utils/i18n';
|
delay, i18n, request, slideDown, slideUp, tpl,
|
||||||
import request from 'vj/utils/request';
|
} from 'vj/utils';
|
||||||
import { slideDown, slideUp } from 'vj/utils/slide';
|
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
const $replyTemplate = $('.commentbox-container').eq(0).clone();
|
const $replyTemplate = $('.commentbox-container').eq(0).clone();
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,7 @@ import { QueryClient, QueryClientProvider, useQuery } from 'react-query';
|
|||||||
import TimeAgo from 'timeago-react';
|
import TimeAgo from 'timeago-react';
|
||||||
import { InfoDialog } from 'vj/components/dialog';
|
import { InfoDialog } from 'vj/components/dialog';
|
||||||
import { AutoloadPage } from 'vj/misc/Page';
|
import { AutoloadPage } from 'vj/misc/Page';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n, request, tpl } from 'vj/utils';
|
||||||
import request from 'vj/utils/request';
|
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
async function historyDialog(payload, time, uid) {
|
async function historyDialog(payload, time, uid) {
|
||||||
const ts = new Date(time).getTime();
|
const ts = new Date(time).getTime();
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { chunk } from 'lodash';
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import ReactDOM from 'react-dom/client';
|
import ReactDOM from 'react-dom/client';
|
||||||
import { AutoloadPage } from 'vj/misc/Page';
|
import { AutoloadPage } from 'vj/misc/Page';
|
||||||
import request from 'vj/utils/request';
|
import { request } from 'vj/utils';
|
||||||
|
|
||||||
function renderReactions(reactions, self, rootEle) {
|
function renderReactions(reactions, self, rootEle) {
|
||||||
let html = '';
|
let html = '';
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ import _ from 'lodash';
|
|||||||
import Drop from 'tether-drop';
|
import Drop from 'tether-drop';
|
||||||
import responsiveCutoff from 'vj/breakpoints.json';
|
import responsiveCutoff from 'vj/breakpoints.json';
|
||||||
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
|
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
|
||||||
import { isBelow } from 'vj/utils/mediaQuery';
|
import { mediaQuery, zIndexManager } from 'vj/utils';
|
||||||
import zIndexManager from 'vj/utils/zIndexManager';
|
|
||||||
|
|
||||||
export default class Dropdown extends DOMAttachedObject {
|
export default class Dropdown extends DOMAttachedObject {
|
||||||
static DOMAttachKey = 'vjDropdownInstance';
|
static DOMAttachKey = 'vjDropdownInstance';
|
||||||
@@ -12,7 +11,7 @@ export default class Dropdown extends DOMAttachedObject {
|
|||||||
|
|
||||||
constructor($dom, options = {}) {
|
constructor($dom, options = {}) {
|
||||||
if ($dom.attr('data-dropdown-trigger-desktop-only') !== undefined) {
|
if ($dom.attr('data-dropdown-trigger-desktop-only') !== undefined) {
|
||||||
if (isBelow(responsiveCutoff.mobile)) {
|
if (mediaQuery.isBelow(responsiveCutoff.mobile)) {
|
||||||
super(null);
|
super(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { AutoloadPage } from 'vj/misc/Page';
|
import { AutoloadPage } from 'vj/misc/Page';
|
||||||
import delay from 'vj/utils/delay';
|
import { delay } from 'vj/utils';
|
||||||
import CmEditor from '.';
|
import CmEditor from '.';
|
||||||
|
|
||||||
function runSubstitute($container: JQuery<Document | HTMLElement>) {
|
function runSubstitute($container: JQuery<Document | HTMLElement>) {
|
||||||
|
|||||||
@@ -3,8 +3,7 @@ import _ from 'lodash';
|
|||||||
import { nanoid } from 'nanoid';
|
import { nanoid } from 'nanoid';
|
||||||
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
|
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
|
||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n, request } from 'vj/utils';
|
||||||
import request from 'vj/utils/request';
|
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
toolbar: [
|
toolbar: [
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { AutoloadPage } from 'vj/misc/Page';
|
import { AutoloadPage } from 'vj/misc/Page';
|
||||||
import delay from 'vj/utils/delay';
|
import { delay } from 'vj/utils';
|
||||||
|
|
||||||
const formPage = new AutoloadPage('formPage', () => {
|
const formPage = new AutoloadPage('formPage', () => {
|
||||||
$(document).on('vjFormDisableUpdate', 'input, select, textarea', (ev) => {
|
$(document).on('vjFormDisableUpdate', 'input, select, textarea', (ev) => {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { AutoloadPage } from 'vj/misc/Page';
|
import { AutoloadPage } from 'vj/misc/Page';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n, tpl } from 'vj/utils';
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
const highlighterPage = new AutoloadPage('highlighterPage', () => {
|
const highlighterPage = new AutoloadPage('highlighterPage', () => {
|
||||||
import('./prismjs').then(({ default: prismjs }) => {
|
import('./prismjs').then(({ default: prismjs }) => {
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import $ from 'jquery';
|
|||||||
import components from 'prismjs/components';
|
import components from 'prismjs/components';
|
||||||
import getLoader from 'prismjs/dependencies';
|
import getLoader from 'prismjs/dependencies';
|
||||||
import Notification from 'vj/components/notification/index';
|
import Notification from 'vj/components/notification/index';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n } from 'vj/utils';
|
||||||
import languageMeta from './meta';
|
import languageMeta from './meta';
|
||||||
|
|
||||||
const files = require.context('prismjs/components/', true, /prism-[a-z0-9-]+\.js/);
|
const files = require.context('prismjs/components/', true, /prism-[a-z0-9-]+\.js/);
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { InfoDialog } from 'vj/components/dialog';
|
import { InfoDialog } from 'vj/components/dialog';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n, tpl } from 'vj/utils';
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
export default function createHint(message: string, element?: any) {
|
export default function createHint(message: string, element?: any) {
|
||||||
if (i18n(message) === message || !element) return;
|
if (i18n(message) === message || !element) return;
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n, request, tpl } from 'vj/utils';
|
||||||
import request from 'vj/utils/request';
|
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
export default new NamedPage('homepage', () => {
|
export default new NamedPage('homepage', () => {
|
||||||
function getHitokoto($containers) {
|
function getHitokoto($containers) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom/client';
|
import ReactDOM from 'react-dom/client';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n } from 'vj/utils';
|
||||||
|
|
||||||
export default function LanguageSelect({
|
export default function LanguageSelect({
|
||||||
fieldSelector, firstLoadMain, firstLoadSub, availableLangs, mainLangs,
|
fieldSelector, firstLoadMain, firstLoadSub, availableLangs, mainLangs,
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import Tooltip from 'vj/components/tooltip/Tooltip';
|
import Tooltip from 'vj/components/tooltip/Tooltip';
|
||||||
import delay from 'vj/utils/delay';
|
import { delay, i18n } from 'vj/utils';
|
||||||
import i18n from 'vj/utils/i18n';
|
|
||||||
|
|
||||||
const MARKER_ID = `marker_${Math.floor(Math.random() * 0xFFFFFF).toString(16)}`;
|
const MARKER_ID = `marker_${Math.floor(Math.random() * 0xFFFFFF).toString(16)}`;
|
||||||
const MARKER_OFFSET = 20;
|
const MARKER_OFFSET = 20;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
|
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
|
||||||
import delay from 'vj/utils/delay';
|
import { delay } from 'vj/utils';
|
||||||
import Marker from './Marker';
|
import Marker from './Marker';
|
||||||
|
|
||||||
export default class MarkerReactive extends DOMAttachedObject {
|
export default class MarkerReactive extends DOMAttachedObject {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { AutoloadPage } from 'vj/misc/Page';
|
import { AutoloadPage } from 'vj/misc/Page';
|
||||||
import request from 'vj/utils/request';
|
import { request } from 'vj/utils';
|
||||||
|
|
||||||
export default new AutoloadPage('media', async () => {
|
export default new AutoloadPage('media', async () => {
|
||||||
async function parseMedia($dom = $(document.body)) {
|
async function parseMedia($dom = $(document.body)) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { AutoloadPage } from 'vj/misc/Page';
|
import { AutoloadPage } from 'vj/misc/Page';
|
||||||
import tpl from 'vj/utils/tpl';
|
import { tpl } from 'vj/utils';
|
||||||
|
|
||||||
const menuHeadingPage = new AutoloadPage('menuHeadingPage', null, () => {
|
const menuHeadingPage = new AutoloadPage('menuHeadingPage', null, () => {
|
||||||
$('[data-heading-extract-to]').get().forEach((container) => {
|
$('[data-heading-extract-to]').get().forEach((container) => {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { AutoloadPage } from 'vj/misc/Page';
|
import { AutoloadPage } from 'vj/misc/Page';
|
||||||
import delay from 'vj/utils/delay';
|
import { delay, slideDown } from 'vj/utils';
|
||||||
import { slideDown } from 'vj/utils/slide';
|
|
||||||
|
|
||||||
function expandMenu($menu) {
|
function expandMenu($menu) {
|
||||||
slideDown($menu, 500, { opacity: 0 }, { opacity: 1 });
|
slideDown($menu, 500, { opacity: 0 }, { opacity: 1 });
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import { InfoDialog } from 'vj/components/dialog';
|
|||||||
import VjNotification from 'vj/components/notification/index';
|
import VjNotification from 'vj/components/notification/index';
|
||||||
import { FLAG_ALERT } from 'vj/constant/message';
|
import { FLAG_ALERT } from 'vj/constant/message';
|
||||||
import { AutoloadPage } from 'vj/misc/Page';
|
import { AutoloadPage } from 'vj/misc/Page';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n, tpl } from 'vj/utils';
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
const onmessage = (msg) => {
|
const onmessage = (msg) => {
|
||||||
console.log('Received message', msg);
|
console.log('Received message', msg);
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ import moment from 'moment';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import TimeAgo from 'timeago-react';
|
import TimeAgo from 'timeago-react';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n, mongoId } from 'vj/utils';
|
||||||
import { parse as parseMongoId } from 'vj/utils/mongoId';
|
|
||||||
import Message from './MessageComponent';
|
import Message from './MessageComponent';
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
const mapStateToProps = (state) => ({
|
||||||
@@ -70,7 +69,7 @@ export default connect(mapStateToProps)(class MessagePadDialogueContentContainer
|
|||||||
renderInner() {
|
renderInner() {
|
||||||
if (this.props.activeId === null) return [];
|
if (this.props.activeId === null) return [];
|
||||||
const sorted = this.props.item.messages
|
const sorted = this.props.item.messages
|
||||||
.sort((msg1, msg2) => parseMongoId(msg1._id).timestamp - parseMongoId(msg2._id).timestamp);
|
.sort((msg1, msg2) => mongoId(msg1._id).timestamp - mongoId(msg2._id).timestamp);
|
||||||
return sorted.map((msg) => (
|
return sorted.map((msg) => (
|
||||||
<Message
|
<Message
|
||||||
key={msg._id}
|
key={msg._id}
|
||||||
@@ -82,8 +81,8 @@ export default connect(mapStateToProps)(class MessagePadDialogueContentContainer
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div>{this.renderContent(msg)}</div>
|
<div>{this.renderContent(msg)}</div>
|
||||||
<time data-tooltip={moment(parseMongoId(msg._id).timestamp * 1000).format('YYYY-MM-DD HH:mm:ss')}>
|
<time data-tooltip={moment(mongoId(msg._id).timestamp * 1000).format('YYYY-MM-DD HH:mm:ss')}>
|
||||||
<TimeAgo datetime={parseMongoId(msg._id).timestamp * 1000} locale={i18n('timeago_locale')} />
|
<TimeAgo datetime={mongoId(msg._id).timestamp * 1000} locale={i18n('timeago_locale')} />
|
||||||
</time>
|
</time>
|
||||||
</Message>
|
</Message>
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import $ from 'jquery';
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n } from 'vj/utils';
|
||||||
import ListItem from './DialogueListItemComponent';
|
import ListItem from './DialogueListItemComponent';
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
const mapStateToProps = (state) => ({
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import Icon from 'vj/components/react/IconComponent';
|
import Icon from 'vj/components/react/IconComponent';
|
||||||
import request from 'vj/utils/request';
|
import { request } from 'vj/utils';
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
const mapStateToProps = (state) => ({
|
||||||
activeId: state.activeId,
|
activeId: state.activeId,
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ import PropTypes from 'prop-types';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import Icon from 'vj/components/react/IconComponent';
|
import Icon from 'vj/components/react/IconComponent';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n, request } from 'vj/utils';
|
||||||
import request from 'vj/utils/request';
|
|
||||||
import MessagePadDialogueContent from './MessagePadDialogueContentContainer';
|
import MessagePadDialogueContent from './MessagePadDialogueContentContainer';
|
||||||
import MessagePadDialogueList from './MessagePadDialogueListContainer';
|
import MessagePadDialogueList from './MessagePadDialogueListContainer';
|
||||||
import MessagePadInput from './MessagePadInputContainer';
|
import MessagePadInput from './MessagePadInputContainer';
|
||||||
|
|||||||
@@ -6,8 +6,7 @@ import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
|||||||
import { IQuickInputService } from 'monaco-editor/esm/vs/platform/quickinput/common/quickInput';
|
import { IQuickInputService } from 'monaco-editor/esm/vs/platform/quickinput/common/quickInput';
|
||||||
import list from 'monaco-themes/themes/themelist.json';
|
import list from 'monaco-themes/themes/themelist.json';
|
||||||
import { nanoid } from 'nanoid';
|
import { nanoid } from 'nanoid';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n, request } from 'vj/utils';
|
||||||
import request from 'vj/utils/request';
|
|
||||||
|
|
||||||
export default monaco;
|
export default monaco;
|
||||||
export const customOptions: monaco.editor.IStandaloneDiffEditorConstructionOptions = JSON.parse(localStorage.getItem('editor.config') || '{}');
|
export const customOptions: monaco.editor.IStandaloneDiffEditorConstructionOptions = JSON.parse(localStorage.getItem('editor.config') || '{}');
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import keyword from 'emojis-keywords';
|
import keyword from 'emojis-keywords';
|
||||||
import list from 'emojis-list';
|
import list from 'emojis-list';
|
||||||
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
|
||||||
import api, { gql } from 'vj/utils/api';
|
import { api, gql } from 'vj/utils';
|
||||||
|
|
||||||
const qqEmojies = [
|
const qqEmojies = [
|
||||||
'weixiao',
|
'weixiao',
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import loadExternalModule from 'vj/utils/loadModule';
|
import { loadExternalModule } from 'vj/utils';
|
||||||
|
|
||||||
let loaded;
|
let loaded;
|
||||||
const loaders = {
|
const loaders = {
|
||||||
|
|||||||
@@ -3,9 +3,7 @@ import Slideout from 'slideout';
|
|||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
import selectUser from 'vj/components/selectUser';
|
import selectUser from 'vj/components/selectUser';
|
||||||
import { AutoloadPage } from 'vj/misc/Page';
|
import { AutoloadPage } from 'vj/misc/Page';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n, request, tpl } from 'vj/utils';
|
||||||
import request from 'vj/utils/request';
|
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
function handleNavLogoutClick(ev) {
|
function handleNavLogoutClick(ev) {
|
||||||
const $logoutLink = $(ev.currentTarget);
|
const $logoutLink = $(ev.currentTarget);
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { Intent, Position, Toaster } from '@blueprintjs/core';
|
import { Intent, Position, Toaster } from '@blueprintjs/core';
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import tpl from 'vj/utils/tpl';
|
import { tpl, zIndexManager } from 'vj/utils/base';
|
||||||
import zIndexManager from 'vj/utils/zIndexManager';
|
|
||||||
|
|
||||||
const ToasterContainer = document.createElement('div');
|
const ToasterContainer = document.createElement('div');
|
||||||
ToasterContainer.style.position = 'fixed';
|
ToasterContainer.style.position = 'fixed';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import Notification from 'vj/components/notification/index';
|
import Notification from 'vj/components/notification/index';
|
||||||
import { AutoloadPage } from 'vj/misc/Page';
|
import { AutoloadPage } from 'vj/misc/Page';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n } from 'vj/utils';
|
||||||
|
|
||||||
export default new AutoloadPage('notificationPage', (pagename) => {
|
export default new AutoloadPage('notificationPage', (pagename) => {
|
||||||
const message = i18n(`Hint::Page::${pagename}`);
|
const message = i18n(`Hint::Page::${pagename}`);
|
||||||
|
|||||||
@@ -4,10 +4,9 @@ import { nanoid } from 'nanoid';
|
|||||||
import { ActionDialog, InfoDialog } from 'vj/components/dialog/index';
|
import { ActionDialog, InfoDialog } from 'vj/components/dialog/index';
|
||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
import { AutoloadPage } from 'vj/misc/Page';
|
import { AutoloadPage } from 'vj/misc/Page';
|
||||||
import i18n from 'vj/utils/i18n';
|
import {
|
||||||
import pjax from 'vj/utils/pjax';
|
i18n, pjax, request, tpl,
|
||||||
import request from 'vj/utils/request';
|
} from 'vj/utils';
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
async function startEdit(filename, value, fileCategory = 'file') {
|
async function startEdit(filename, value, fileCategory = 'file') {
|
||||||
const { default: Editor } = await import('vj/components/editor/index');
|
const { default: Editor } = await import('vj/components/editor/index');
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { InfoDialog } from 'vj/components/dialog';
|
import { InfoDialog } from 'vj/components/dialog';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n, tpl } from 'vj/utils';
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
export default new NamedPage(['problem_create', 'problem_edit'], () => {
|
export default new NamedPage(['problem_create', 'problem_edit'], () => {
|
||||||
$('input[name="pid"]').on('blur', () => {
|
$('input[name="pid"]').on('blur', () => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n } from 'vj/utils';
|
||||||
import FileSelectAutoComplete from '../autocomplete/components/FileSelectAutoComplete';
|
import FileSelectAutoComplete from '../autocomplete/components/FileSelectAutoComplete';
|
||||||
import type { RootState } from './reducer/index';
|
import type { RootState } from './reducer/index';
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import {
|
|||||||
} from '@blueprintjs/core';
|
} from '@blueprintjs/core';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n } from 'vj/utils';
|
||||||
import CustomSelectAutoComplete from '../autocomplete/components/CustomSelectAutoComplete';
|
import CustomSelectAutoComplete from '../autocomplete/components/CustomSelectAutoComplete';
|
||||||
import FileSelectAutoComplete from '../autocomplete/components/FileSelectAutoComplete';
|
import FileSelectAutoComplete from '../autocomplete/components/FileSelectAutoComplete';
|
||||||
import { FormItem } from './BasicForm';
|
import { FormItem } from './BasicForm';
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import {
|
|||||||
} from '@blueprintjs/core';
|
} from '@blueprintjs/core';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n } from 'vj/utils';
|
||||||
import { FormItem, ManagedSelect, SingleFileSelect } from './BasicForm';
|
import { FormItem, ManagedSelect, SingleFileSelect } from './BasicForm';
|
||||||
import type { RootState } from './reducer/index';
|
import type { RootState } from './reducer/index';
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import type { SubtaskConfig } from 'hydrooj/src/interface';
|
|||||||
import { isEqual, pick } from 'lodash';
|
import { isEqual, pick } from 'lodash';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n } from 'vj/utils';
|
||||||
import CustomSelectAutoComplete from '../autocomplete/components/CustomSelectAutoComplete';
|
import CustomSelectAutoComplete from '../autocomplete/components/CustomSelectAutoComplete';
|
||||||
import { FormItem } from './BasicForm';
|
import { FormItem } from './BasicForm';
|
||||||
import { RootState } from './reducer';
|
import { RootState } from './reducer';
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import type { SubtaskConfig } from 'hydrooj/src/interface';
|
|||||||
import { isEqual } from 'lodash';
|
import { isEqual } from 'lodash';
|
||||||
import React, { useEffect, useRef } from 'react';
|
import React, { useEffect, useRef } from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n } from 'vj/utils';
|
||||||
import FileSelectAutoComplete from '../autocomplete/components/FileSelectAutoComplete';
|
import FileSelectAutoComplete from '../autocomplete/components/FileSelectAutoComplete';
|
||||||
import type { RootState } from './reducer/index';
|
import type { RootState } from './reducer/index';
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
|
import DOMAttachedObject from 'vj/components/DOMAttachedObject';
|
||||||
import delay from 'vj/utils/delay';
|
import { delay } from 'vj/utils';
|
||||||
|
|
||||||
const ANIMATION_DURATION = 4000;
|
const ANIMATION_DURATION = 4000;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import AnsiUp from 'ansi_up';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import Icon from 'vj/components/react/IconComponent';
|
import Icon from 'vj/components/react/IconComponent';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n } from 'vj/utils';
|
||||||
import DataInput from './DataInputComponent';
|
import DataInput from './DataInputComponent';
|
||||||
import Panel from './PanelComponent';
|
import Panel from './PanelComponent';
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import classNames from 'classnames';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import Icon from 'vj/components/react/IconComponent';
|
import Icon from 'vj/components/react/IconComponent';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n } from 'vj/utils';
|
||||||
import Panel from './PanelComponent';
|
import Panel from './PanelComponent';
|
||||||
import ScratchpadRecordsRow from './ScratchpadRecordsRowContainer';
|
import ScratchpadRecordsRow from './ScratchpadRecordsRowContainer';
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,9 @@ import React from 'react';
|
|||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import TimeAgo from 'timeago-react';
|
import TimeAgo from 'timeago-react';
|
||||||
import * as recordEnum from 'vj/constant/record';
|
import * as recordEnum from 'vj/constant/record';
|
||||||
import emulateAnchorClick from 'vj/utils/emulateAnchorClick';
|
import {
|
||||||
import i18n from 'vj/utils/i18n';
|
emulateAnchorClick, i18n, mongoId, substitute,
|
||||||
import { parse as parseMongoId } from 'vj/utils/mongoId';
|
} from 'vj/utils';
|
||||||
import substitute from 'vj/utils/substitute';
|
|
||||||
|
|
||||||
const shouldShowDetail = (data) => recordEnum.STATUS_SCRATCHPAD_SHOW_DETAIL_FLAGS[data.status];
|
const shouldShowDetail = (data) => recordEnum.STATUS_SCRATCHPAD_SHOW_DETAIL_FLAGS[data.status];
|
||||||
|
|
||||||
@@ -58,7 +57,7 @@ export default connect(mapStateToProps, null, mergeProps)(class ScratchpadRecord
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { data } = this.props;
|
const { data } = this.props;
|
||||||
const submitAt = parseMongoId(data._id).timestamp * 1000;
|
const submitAt = mongoId(data._id).timestamp * 1000;
|
||||||
// Is pretest
|
// Is pretest
|
||||||
return data.contest?.toString() === '000000000000000000000000' ? null : (
|
return data.contest?.toString() === '000000000000000000000000' ? null : (
|
||||||
<tr onClick={(ev) => this.handleRowClick(ev, data._id)}>
|
<tr onClick={(ev) => this.handleRowClick(ev, data._id)}>
|
||||||
|
|||||||
@@ -4,9 +4,7 @@ import PropTypes from 'prop-types';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import Icon from 'vj/components/react/IconComponent';
|
import Icon from 'vj/components/react/IconComponent';
|
||||||
import getAvailableLangs from 'vj/utils/availableLangs';
|
import { getAvailableLangs, i18n, request } from 'vj/utils';
|
||||||
import i18n from 'vj/utils/i18n';
|
|
||||||
import request from 'vj/utils/request';
|
|
||||||
import Toolbar, {
|
import Toolbar, {
|
||||||
ToolbarButtonComponent as ToolbarButton,
|
ToolbarButtonComponent as ToolbarButton,
|
||||||
ToolbarItemComponent as ToolbarItem,
|
ToolbarItemComponent as ToolbarItem,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n } from 'vj/utils';
|
||||||
|
|
||||||
export default function reducer(state = {
|
export default function reducer(state = {
|
||||||
main: {
|
main: {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import UserSelectAutoComplete from 'vj/components/autocomplete/UserSelectAutoComplete';
|
import UserSelectAutoComplete from 'vj/components/autocomplete/UserSelectAutoComplete';
|
||||||
import { ActionDialog } from 'vj/components/dialog';
|
import { ActionDialog } from 'vj/components/dialog';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n, tpl } from 'vj/utils';
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
import createHint from './hint';
|
import createHint from './hint';
|
||||||
|
|
||||||
let hintInserted = false;
|
let hintInserted = false;
|
||||||
|
|||||||
@@ -3,9 +3,7 @@ import responsiveCutoff from 'vj/breakpoints.json';
|
|||||||
import DomDialog from 'vj/components/dialog/DomDialog';
|
import DomDialog from 'vj/components/dialog/DomDialog';
|
||||||
import { InfoDialog } from 'vj/components/dialog/index';
|
import { InfoDialog } from 'vj/components/dialog/index';
|
||||||
import { AutoloadPage } from 'vj/misc/Page';
|
import { AutoloadPage } from 'vj/misc/Page';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n, mediaQuery, tpl } from 'vj/utils';
|
||||||
import { isBelow } from 'vj/utils/mediaQuery';
|
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
const signinDialogPage = new AutoloadPage('signinDialogPage', null, () => {
|
const signinDialogPage = new AutoloadPage('signinDialogPage', null, () => {
|
||||||
const signInDialog = DomDialog.getOrConstruct($('.dialog--signin'), {
|
const signInDialog = DomDialog.getOrConstruct($('.dialog--signin'), {
|
||||||
@@ -17,7 +15,7 @@ const signinDialogPage = new AutoloadPage('signinDialogPage', null, () => {
|
|||||||
if ($('[name="nav_login"]').length > 0) {
|
if ($('[name="nav_login"]').length > 0) {
|
||||||
// nav
|
// nav
|
||||||
$('[name="nav_login"]').on('click', (ev) => {
|
$('[name="nav_login"]').on('click', (ev) => {
|
||||||
if (isBelow(responsiveCutoff.mobile)) return;
|
if (mediaQuery.isBelow(responsiveCutoff.mobile)) return;
|
||||||
if (ev.shiftKey || ev.metaKey || ev.ctrlKey) return;
|
if (ev.shiftKey || ev.metaKey || ev.ctrlKey) return;
|
||||||
signInDialog.show();
|
signInDialog.show();
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
@@ -32,7 +30,7 @@ const signinDialogPage = new AutoloadPage('signinDialogPage', null, () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
window.showSignInDialog = () => {
|
window.showSignInDialog = () => {
|
||||||
if (isBelow(responsiveCutoff.mobile)) {
|
if (mediaQuery.isBelow(responsiveCutoff.mobile)) {
|
||||||
if ($('[name="nav_login"]').length > 0) {
|
if ($('[name="nav_login"]').length > 0) {
|
||||||
window.location.href = $('[name="nav_login"]').attr('href');
|
window.location.href = $('[name="nav_login"]').attr('href');
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { AutoloadPage } from 'vj/misc/Page';
|
import { AutoloadPage } from 'vj/misc/Page';
|
||||||
import request from 'vj/utils/request';
|
import { request } from 'vj/utils';
|
||||||
|
|
||||||
function setStarButtonState($starButton, star) {
|
function setStarButtonState($starButton, star) {
|
||||||
if (star) {
|
if (star) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import * as timeago from 'timeago.js';
|
import * as timeago from 'timeago.js';
|
||||||
import { AutoloadPage } from 'vj/misc/Page';
|
import { AutoloadPage } from 'vj/misc/Page';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n } from 'vj/utils';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const locales = require.context('timeago.js/lib/lang', false, /\.js$/);
|
const locales = require.context('timeago.js/lib/lang', false, /\.js$/);
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import { Dialog } from 'vj/components/dialog/index';
|
import { Dialog } from 'vj/components/dialog/index';
|
||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
import delay from 'vj/utils/delay';
|
import {
|
||||||
import i18n from 'vj/utils/i18n';
|
delay, i18n, pjax, request,
|
||||||
import pjax from 'vj/utils/pjax';
|
} from 'vj/utils';
|
||||||
import request from 'vj/utils/request';
|
|
||||||
|
|
||||||
function onBeforeUnload(e) {
|
function onBeforeUnload(e) {
|
||||||
e.returnValue = '';
|
e.returnValue = '';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import Rotator from 'vj/components/rotator';
|
import Rotator from 'vj/components/rotator';
|
||||||
import { AutoloadPage } from 'vj/misc/Page';
|
import { AutoloadPage } from 'vj/misc/Page';
|
||||||
import request from 'vj/utils/request';
|
import { request } from 'vj/utils';
|
||||||
|
|
||||||
function setVoteState($container, value, status) {
|
function setVoteState($container, value, status) {
|
||||||
const $num = $container.find('.vote-number');
|
const $num = $container.find('.vote-number');
|
||||||
|
|||||||
+5
-7
@@ -2,11 +2,9 @@ import { dump } from 'js-yaml';
|
|||||||
import PQueue from 'p-queue';
|
import PQueue from 'p-queue';
|
||||||
import streamsaver from 'streamsaver';
|
import streamsaver from 'streamsaver';
|
||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
import api, { gql } from 'vj/utils/api';
|
import {
|
||||||
import i18n from 'vj/utils/i18n';
|
api, createZipStream, gql, i18n, pipeStream, request,
|
||||||
import pipeStream from 'vj/utils/pipeStream';
|
} from 'vj/utils';
|
||||||
import request from 'vj/utils/request';
|
|
||||||
import { createZipStream } from 'vj/utils/zip';
|
|
||||||
|
|
||||||
let isBeforeUnloadTriggeredByLibrary = !window.isSecureContext;
|
let isBeforeUnloadTriggeredByLibrary = !window.isSecureContext;
|
||||||
function onBeforeUnload(e) {
|
function onBeforeUnload(e) {
|
||||||
@@ -29,8 +27,8 @@ export default async function download(filename, targets) {
|
|||||||
await waitForWritableStream;
|
await waitForWritableStream;
|
||||||
const fileStream = streamsaver.createWriteStream(filename);
|
const fileStream = streamsaver.createWriteStream(filename);
|
||||||
const queue = new PQueue({ concurrency: 5 });
|
const queue = new PQueue({ concurrency: 5 });
|
||||||
const abortCallbackReceiver = {};
|
const abortCallbackReceiver: any = {};
|
||||||
function stopDownload() { abortCallbackReceiver.abort(); }
|
function stopDownload() { abortCallbackReceiver.abort?.(); }
|
||||||
let i = 0;
|
let i = 0;
|
||||||
async function downloadFile(target) {
|
async function downloadFile(target) {
|
||||||
try {
|
try {
|
||||||
@@ -46,10 +46,11 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
try { __webpack_public_path__ = UiContext.cdn_prefix; } catch (e) { }
|
try { __webpack_public_path__ = UiContext.cdn_prefix; } catch (e) { }
|
||||||
|
|
||||||
const [data] = await Promise.all([
|
const [data, HydroExports] = await Promise.all([
|
||||||
(await fetch(`/constant/${UiContext.constantVersion}`, { cache: 'force-cache' })).json(),
|
fetch(`/constant/${UiContext.constantVersion}`, { cache: 'force-cache' }).then((r) => r.json()),
|
||||||
await import('./modules'),
|
import('./api'),
|
||||||
]);
|
]);
|
||||||
|
Object.assign(window, { HydroExports });
|
||||||
eval(data[0]); // eslint-disable-line no-eval
|
eval(data[0]); // eslint-disable-line no-eval
|
||||||
data.shift();
|
data.shift();
|
||||||
window.Hydro.preload = data;
|
window.Hydro.preload = data;
|
||||||
|
|||||||
@@ -4,16 +4,15 @@ import $ from 'jquery';
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
import PageLoader from 'vj/misc/PageLoader';
|
import PageLoader from 'vj/misc/PageLoader';
|
||||||
import delay from 'vj/utils/delay';
|
import { delay } from 'vj/utils';
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
UserContext: any;
|
UserContext: any;
|
||||||
UiContext: any;
|
UiContext: any;
|
||||||
Hydro: any;
|
Hydro: any;
|
||||||
// eslint-disable-next-line camelcase
|
|
||||||
node_modules: any;
|
|
||||||
externalModules: Record<string, string>;
|
externalModules: Record<string, string>;
|
||||||
|
captureException?: (e: Error) => void;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,22 @@ export async function buildUI() {
|
|||||||
target: [
|
target: [
|
||||||
'chrome60',
|
'chrome60',
|
||||||
],
|
],
|
||||||
plugins: global.Hydro.ui.esbuildPlugins || [],
|
plugins: [
|
||||||
|
...(global.Hydro.ui.esbuildPlugins || []),
|
||||||
|
{
|
||||||
|
name: 'federation',
|
||||||
|
setup(b) {
|
||||||
|
b.onResolve({ filter: /^@hydrooj\/ui-default/ }, () => ({
|
||||||
|
path: 'api',
|
||||||
|
namespace: 'ui-default',
|
||||||
|
}));
|
||||||
|
b.onLoad({ filter: /.*/, namespace: 'ui-default' }, () => ({
|
||||||
|
contents: 'module.exports = window.HydroExports;',
|
||||||
|
loader: 'tsx',
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
minify: !process.env.DEV,
|
minify: !process.env.DEV,
|
||||||
});
|
});
|
||||||
if (build.errors.length) console.error(build.errors);
|
if (build.errors.length) console.error(build.errors);
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
import './utils/delay';
|
|
||||||
import './utils/emulateAnchorClick';
|
|
||||||
import './utils/i18n';
|
|
||||||
import './utils/loadReactRedux';
|
|
||||||
import './utils/mediaQuery';
|
|
||||||
import './utils/mongoId';
|
|
||||||
import './utils/pipeStream';
|
|
||||||
import './utils/pjax';
|
|
||||||
import './utils/request';
|
|
||||||
import './utils/slide';
|
|
||||||
import './utils/substitute';
|
|
||||||
import './utils/tpl';
|
|
||||||
import './utils/zIndexManager';
|
|
||||||
import './utils/zip';
|
|
||||||
import './components/autocomplete';
|
|
||||||
import './components/dialog';
|
|
||||||
import './components/notification';
|
|
||||||
import './components/monaco/loader';
|
|
||||||
|
|
||||||
import $ from 'jquery';
|
|
||||||
import _ from 'lodash';
|
|
||||||
import React from 'react';
|
|
||||||
import ReactDOM from 'react-dom/client';
|
|
||||||
import * as redux from 'react-redux';
|
|
||||||
|
|
||||||
const modules = {
|
|
||||||
_, $, React, redux, ReactDOM,
|
|
||||||
};
|
|
||||||
export default async function load(name) {
|
|
||||||
if (modules[name]) return modules[name];
|
|
||||||
if (name === 'echarts') return import('echarts');
|
|
||||||
if (name === 'moment') return import('moment');
|
|
||||||
throw new Error(`Module ${name} not found`);
|
|
||||||
}
|
|
||||||
window.node_modules = { ...modules, load };
|
|
||||||
window.$ = $;
|
|
||||||
window.jQuery = $;
|
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
"author": "undefined <i@undefined.moe>",
|
"author": "undefined <i@undefined.moe>",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "index.ts",
|
"main": "index.ts",
|
||||||
|
"types": "api.ts",
|
||||||
"repository": "https://github.com/hydro-dev/Hydro.git",
|
"repository": "https://github.com/hydro-dev/Hydro.git",
|
||||||
"preferUnplugged": true,
|
"preferUnplugged": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -29,6 +30,7 @@
|
|||||||
"@types/markdown-it": "^12.2.3",
|
"@types/markdown-it": "^12.2.3",
|
||||||
"@types/pickadate": "^3.5.32",
|
"@types/pickadate": "^3.5.32",
|
||||||
"@types/qrcode": "^1.5.0",
|
"@types/qrcode": "^1.5.0",
|
||||||
|
"@types/react": "^18.0.26",
|
||||||
"@types/react-dom": "^18.0.9",
|
"@types/react-dom": "^18.0.9",
|
||||||
"@types/redux-logger": "^3.0.9",
|
"@types/redux-logger": "^3.0.9",
|
||||||
"@types/serviceworker": "^0.0.57",
|
"@types/serviceworker": "^0.0.57",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { pick } from 'lodash';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { createRoot } from 'react-dom/client';
|
import { createRoot } from 'react-dom/client';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import request from 'vj/utils/request';
|
import { request } from 'vj/utils';
|
||||||
|
|
||||||
const defaultQuery = `\
|
const defaultQuery = `\
|
||||||
query Example(
|
query Example(
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { formatSeconds } from '@hydrooj/utils/lib/common';
|
import { formatSeconds } from '@hydrooj/utils/lib/common';
|
||||||
import NProgress from 'nprogress';
|
import NProgress from 'nprogress';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import tpl from 'vj/utils/tpl';
|
import { tpl } from 'vj/utils';
|
||||||
|
|
||||||
const contestTimer = $(tpl`<pre class="contest-timer" style="display:none"></pre>`);
|
const contestTimer = $(tpl`<pre class="contest-timer" style="display:none"></pre>`);
|
||||||
contestTimer.appendTo(document.body);
|
contestTimer.appendTo(document.body);
|
||||||
|
|||||||
@@ -2,9 +2,7 @@ import $ from 'jquery';
|
|||||||
import ProblemSelectAutoComplete from 'vj/components/autocomplete/ProblemSelectAutoComplete';
|
import ProblemSelectAutoComplete from 'vj/components/autocomplete/ProblemSelectAutoComplete';
|
||||||
import { ConfirmDialog } from 'vj/components/dialog';
|
import { ConfirmDialog } from 'vj/components/dialog';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n, request, tpl } from 'vj/utils';
|
||||||
import request from 'vj/utils/request';
|
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
const page = new NamedPage(['contest_edit', 'contest_create', 'homework_create', 'homework_edit'], (pagename) => {
|
const page = new NamedPage(['contest_edit', 'contest_create', 'homework_create', 'homework_edit'], (pagename) => {
|
||||||
ProblemSelectAutoComplete.getOrConstruct($('[name="pids"]'), { multi: true, clearDefaultValue: false });
|
ProblemSelectAutoComplete.getOrConstruct($('[name="pids"]'), { multi: true, clearDefaultValue: false });
|
||||||
|
|||||||
@@ -4,10 +4,9 @@ import UserSelectAutoComplete from 'vj/components/autocomplete/UserSelectAutoCom
|
|||||||
import { ActionDialog, ConfirmDialog } from 'vj/components/dialog';
|
import { ActionDialog, ConfirmDialog } from 'vj/components/dialog';
|
||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import api, { gql } from 'vj/utils/api';
|
import {
|
||||||
import delay from 'vj/utils/delay';
|
api, delay, gql, i18n, tpl,
|
||||||
import i18n from 'vj/utils/i18n';
|
} from 'vj/utils';
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
function update(name: string, uids: number[]) {
|
function update(name: string, uids: number[]) {
|
||||||
return api(gql`
|
return api(gql`
|
||||||
|
|||||||
@@ -3,10 +3,9 @@ import _ from 'lodash';
|
|||||||
import { ActionDialog, ConfirmDialog } from 'vj/components/dialog';
|
import { ActionDialog, ConfirmDialog } from 'vj/components/dialog';
|
||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import delay from 'vj/utils/delay';
|
import {
|
||||||
import i18n from 'vj/utils/i18n';
|
delay, i18n, request, tpl,
|
||||||
import request from 'vj/utils/request';
|
} from 'vj/utils';
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
const page = new NamedPage('domain_role', () => {
|
const page = new NamedPage('domain_role', () => {
|
||||||
const createRoleDialog = new ActionDialog({
|
const createRoleDialog = new ActionDialog({
|
||||||
|
|||||||
@@ -4,10 +4,9 @@ import UserSelectAutoComplete from 'vj/components/autocomplete/UserSelectAutoCom
|
|||||||
import { ActionDialog, ConfirmDialog } from 'vj/components/dialog';
|
import { ActionDialog, ConfirmDialog } from 'vj/components/dialog';
|
||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import delay from 'vj/utils/delay';
|
import {
|
||||||
import i18n from 'vj/utils/i18n';
|
delay, i18n, request, tpl,
|
||||||
import request from 'vj/utils/request';
|
} from 'vj/utils';
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
const page = new NamedPage('domain_user', () => {
|
const page = new NamedPage('domain_user', () => {
|
||||||
const addUserSelector = UserSelectAutoComplete.getOrConstruct($('.dialog__body--add-user [name="user"]'));
|
const addUserSelector = UserSelectAutoComplete.getOrConstruct($('.dialog__body--add-user [name="user"]'));
|
||||||
|
|||||||
@@ -4,10 +4,9 @@ import { ConfirmDialog } from 'vj/components/dialog/index';
|
|||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
import uploadFiles from 'vj/components/upload';
|
import uploadFiles from 'vj/components/upload';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import i18n from 'vj/utils/i18n';
|
import {
|
||||||
import pjax from 'vj/utils/pjax';
|
i18n, pjax, request, tpl,
|
||||||
import request from 'vj/utils/request';
|
} from 'vj/utils';
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
function ensureAndGetSelectedFiles() {
|
function ensureAndGetSelectedFiles() {
|
||||||
const files = _.map(
|
const files = _.map(
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import { createRoot } from 'react-dom/client';
|
|||||||
import VjNotification from 'vj/components/notification';
|
import VjNotification from 'vj/components/notification';
|
||||||
import selectUser from 'vj/components/selectUser';
|
import selectUser from 'vj/components/selectUser';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import api, { gql } from 'vj/utils/api';
|
import { api, gql, loadReactRedux } from 'vj/utils';
|
||||||
import loadReactRedux from 'vj/utils/loadReactRedux';
|
|
||||||
|
|
||||||
const page = new NamedPage('home_messages', () => {
|
const page = new NamedPage('home_messages', () => {
|
||||||
let reduxStore;
|
let reduxStore;
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { renderLanguageSelect } from 'vj/components/languageselect';
|
import { renderLanguageSelect } from 'vj/components/languageselect';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import getAvailableLangs from 'vj/utils/availableLangs';
|
import {
|
||||||
import delay from 'vj/utils/delay';
|
delay, getAvailableLangs, i18n, tpl,
|
||||||
import i18n from 'vj/utils/i18n';
|
} from 'vj/utils';
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
async function initCodeLangHelper() {
|
async function initCodeLangHelper() {
|
||||||
const $el = $(tpl`<div class="row" id="codelang-select"></div>`);
|
const $el = $(tpl`<div class="row" id="codelang-select"></div>`);
|
||||||
|
|||||||
@@ -3,10 +3,9 @@ import QRCode from 'qrcode';
|
|||||||
import { ActionDialog } from 'vj/components/dialog';
|
import { ActionDialog } from 'vj/components/dialog';
|
||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import api, { gql } from 'vj/utils/api';
|
import {
|
||||||
import delay from 'vj/utils/delay';
|
api, delay, gql, i18n, tpl,
|
||||||
import i18n from 'vj/utils/i18n';
|
} from 'vj/utils';
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
export default new NamedPage('home_security', () => {
|
export default new NamedPage('home_security', () => {
|
||||||
$(document).on('click', '[name="tfa_enable"]', async () => {
|
$(document).on('click', '[name="tfa_enable"]', async () => {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n, mongoId } from 'vj/utils';
|
||||||
import { parse as parseMongoId } from 'vj/utils/mongoId';
|
|
||||||
|
|
||||||
const page = new NamedPage('homework_main', async () => {
|
const page = new NamedPage('homework_main', async () => {
|
||||||
// Homework Calendar
|
// Homework Calendar
|
||||||
@@ -13,7 +12,7 @@ const page = new NamedPage('homework_main', async () => {
|
|||||||
title: doc.title,
|
title: doc.title,
|
||||||
maskFrom: doc.penaltySince ? doc.penaltySince : null,
|
maskFrom: doc.penaltySince ? doc.penaltySince : null,
|
||||||
maskTitle: i18n('Time Extension'),
|
maskTitle: i18n('Time Extension'),
|
||||||
colorIndex: parseMongoId(doc._id).timestamp % 12,
|
colorIndex: mongoId(doc._id).timestamp % 12,
|
||||||
link: doc.url,
|
link: doc.url,
|
||||||
}));
|
}));
|
||||||
const calendar = new Calendar(events);
|
const calendar = new Calendar(events);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import $ from 'jquery';
|
|||||||
import { ActionDialog } from 'vj/components/dialog';
|
import { ActionDialog } from 'vj/components/dialog';
|
||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import request from 'vj/utils/request';
|
import { request } from 'vj/utils';
|
||||||
|
|
||||||
const page = new NamedPage('manage_script', () => {
|
const page = new NamedPage('manage_script', () => {
|
||||||
const runScriptDialog = new ActionDialog({
|
const runScriptDialog = new ActionDialog({
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import delay from 'vj/utils/delay';
|
import { delay, i18n, request } from 'vj/utils';
|
||||||
import i18n from 'vj/utils/i18n';
|
|
||||||
import request from 'vj/utils/request';
|
|
||||||
|
|
||||||
const page = new NamedPage('manage_user_import', () => {
|
const page = new NamedPage('manage_user_import', () => {
|
||||||
async function post(draft) {
|
async function post(draft) {
|
||||||
|
|||||||
@@ -3,9 +3,7 @@ import { ActionDialog } from 'vj/components/dialog';
|
|||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
import selectUser from 'vj/components/selectUser';
|
import selectUser from 'vj/components/selectUser';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n, pjax, request } from 'vj/utils';
|
||||||
import pjax from 'vj/utils/pjax';
|
|
||||||
import request from 'vj/utils/request';
|
|
||||||
|
|
||||||
const page = new NamedPage('manage_user_priv', () => {
|
const page = new NamedPage('manage_user_priv', () => {
|
||||||
const setPrivDialog = new ActionDialog({
|
const setPrivDialog = new ActionDialog({
|
||||||
|
|||||||
@@ -10,10 +10,9 @@ import { configYamlFormat } from 'vj/components/problemconfig/ProblemConfigEdito
|
|||||||
import uploadFiles from 'vj/components/upload';
|
import uploadFiles from 'vj/components/upload';
|
||||||
import download from 'vj/components/zipDownloader';
|
import download from 'vj/components/zipDownloader';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import i18n from 'vj/utils/i18n';
|
import {
|
||||||
import loadReactRedux from 'vj/utils/loadReactRedux';
|
i18n, loadReactRedux, request, tpl,
|
||||||
import request from 'vj/utils/request';
|
} from 'vj/utils';
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
const page = new NamedPage('problem_config', () => {
|
const page = new NamedPage('problem_config', () => {
|
||||||
let reduxStore;
|
let reduxStore;
|
||||||
@@ -72,7 +71,7 @@ const page = new NamedPage('problem_config', () => {
|
|||||||
async function handleClickDownloadAll() {
|
async function handleClickDownloadAll() {
|
||||||
const files = reduxStore.getState().testdata.map((i) => i.name);
|
const files = reduxStore.getState().testdata.map((i) => i.name);
|
||||||
const { links, pdoc } = await request.post('./files', { operation: 'get_links', files, type: 'testdata' });
|
const { links, pdoc } = await request.post('./files', { operation: 'get_links', files, type: 'testdata' });
|
||||||
const targets = [];
|
const targets: { filename: string, url: string }[] = [];
|
||||||
for (const filename of Object.keys(links)) targets.push({ filename, url: links[filename] });
|
for (const filename of Object.keys(links)) targets.push({ filename, url: links[filename] });
|
||||||
await download(`${pdoc.docId} ${pdoc.title}.zip`, targets);
|
await download(`${pdoc.docId} ${pdoc.title}.zip`, targets);
|
||||||
}
|
}
|
||||||
@@ -103,7 +102,7 @@ const page = new NamedPage('problem_config', () => {
|
|||||||
|
|
||||||
store.dispatch({
|
store.dispatch({
|
||||||
type: 'CONFIG_LOAD',
|
type: 'CONFIG_LOAD',
|
||||||
payload: request.get(),
|
payload: request.get(''),
|
||||||
});
|
});
|
||||||
const unsubscribe = store.subscribe(() => {
|
const unsubscribe = store.subscribe(() => {
|
||||||
// TODO set yaml schema
|
// TODO set yaml schema
|
||||||
@@ -124,7 +123,7 @@ const page = new NamedPage('problem_config', () => {
|
|||||||
subtasks: normalizeSubtasks(subtasks, (i) => i, state.config.time, state.config.memory, true),
|
subtasks: normalizeSubtasks(subtasks, (i) => i, state.config.time, state.config.memory, true),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
createRoot($('#ProblemConfig').get(0)).render(
|
createRoot(document.getElementById('ProblemConfig')!).render(
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="medium-5 columns">
|
<div className="medium-5 columns">
|
||||||
|
|||||||
@@ -6,12 +6,9 @@ import { createRoot } from 'react-dom/client';
|
|||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
import { downloadProblemSet } from 'vj/components/zipDownloader';
|
import { downloadProblemSet } from 'vj/components/zipDownloader';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import delay from 'vj/utils/delay';
|
import {
|
||||||
import i18n from 'vj/utils/i18n';
|
delay, i18n, loadReactRedux, pjax, request, tpl,
|
||||||
import loadReactRedux from 'vj/utils/loadReactRedux';
|
} from 'vj/utils';
|
||||||
import pjax from 'vj/utils/pjax';
|
|
||||||
import request from 'vj/utils/request';
|
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
class ProblemPageExtender {
|
class ProblemPageExtender {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|||||||
@@ -8,10 +8,9 @@ import Notification from 'vj/components/notification';
|
|||||||
import uploadFiles from 'vj/components/upload';
|
import uploadFiles from 'vj/components/upload';
|
||||||
import download from 'vj/components/zipDownloader';
|
import download from 'vj/components/zipDownloader';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import i18n from 'vj/utils/i18n';
|
import {
|
||||||
import request from 'vj/utils/request';
|
i18n, request, slideDown, slideUp, tpl,
|
||||||
import { slideDown, slideUp } from 'vj/utils/slide';
|
} from 'vj/utils';
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
const categories = {};
|
const categories = {};
|
||||||
const dirtyCategories = [];
|
const dirtyCategories = [];
|
||||||
|
|||||||
@@ -7,10 +7,9 @@ import { previewFile } from 'vj/components/preview/preview.page';
|
|||||||
import uploadFiles from 'vj/components/upload';
|
import uploadFiles from 'vj/components/upload';
|
||||||
import download from 'vj/components/zipDownloader';
|
import download from 'vj/components/zipDownloader';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import i18n from 'vj/utils/i18n';
|
import {
|
||||||
import pjax from 'vj/utils/pjax';
|
i18n, pjax, request, tpl,
|
||||||
import request from 'vj/utils/request';
|
} from 'vj/utils';
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
async function downloadProblemFilesAsArchive(type, files) {
|
async function downloadProblemFilesAsArchive(type, files) {
|
||||||
const { links, pdoc } = await request.post('', { operation: 'get_links', files, type });
|
const { links, pdoc } = await request.post('', { operation: 'get_links', files, type });
|
||||||
|
|||||||
@@ -6,11 +6,9 @@ import createHint from 'vj/components/hint';
|
|||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
import { downloadProblemSet } from 'vj/components/zipDownloader';
|
import { downloadProblemSet } from 'vj/components/zipDownloader';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import delay from 'vj/utils/delay';
|
import {
|
||||||
import i18n from 'vj/utils/i18n';
|
delay, i18n, pjax, request, tpl,
|
||||||
import pjax from 'vj/utils/pjax';
|
} from 'vj/utils';
|
||||||
import request from 'vj/utils/request';
|
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
const categories = {};
|
const categories = {};
|
||||||
const dirtyCategories = [];
|
const dirtyCategories = [];
|
||||||
|
|||||||
@@ -2,9 +2,7 @@ import $ from 'jquery';
|
|||||||
import { ActionDialog, ConfirmDialog } from 'vj/components/dialog';
|
import { ActionDialog, ConfirmDialog } from 'vj/components/dialog';
|
||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n, request, tpl } from 'vj/utils';
|
||||||
import request from 'vj/utils/request';
|
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
const page = new NamedPage([
|
const page = new NamedPage([
|
||||||
'problem_create', 'problem_edit', 'problem_solution', 'problem_submit',
|
'problem_create', 'problem_edit', 'problem_solution', 'problem_submit',
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { renderLanguageSelect } from 'vj/components/languageselect';
|
import { renderLanguageSelect } from 'vj/components/languageselect';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import getAvailableLangs from 'vj/utils/availableLangs';
|
import { getAvailableLangs } from 'vj/utils';
|
||||||
|
|
||||||
const page = new NamedPage(['problem_submit', 'contest_detail_problem_submit', 'homework_detail_problem_submit'], async () => {
|
const page = new NamedPage(['problem_submit', 'contest_detail_problem_submit', 'homework_detail_problem_submit'], async () => {
|
||||||
const { config } = UiContext.pdoc;
|
const { config } = UiContext.pdoc;
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ import $ from 'jquery';
|
|||||||
import ProblemSelectAutoComplete from 'vj/components/autocomplete/ProblemSelectAutoComplete';
|
import ProblemSelectAutoComplete from 'vj/components/autocomplete/ProblemSelectAutoComplete';
|
||||||
import UserSelectAutoComplete from 'vj/components/autocomplete/UserSelectAutoComplete';
|
import UserSelectAutoComplete from 'vj/components/autocomplete/UserSelectAutoComplete';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import getAvailableLangs from 'vj/utils/availableLangs';
|
import { getAvailableLangs, tpl } from 'vj/utils';
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
const page = new NamedPage('record_main', async () => {
|
const page = new NamedPage('record_main', async () => {
|
||||||
const [{ default: WebSocket }, { DiffDOM }] = await Promise.all([
|
const [{ default: WebSocket }, { DiffDOM }] = await Promise.all([
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import yaml from 'js-yaml';
|
|||||||
import Schema from 'schemastery';
|
import Schema from 'schemastery';
|
||||||
import Notification from 'vj/components/notification';
|
import Notification from 'vj/components/notification';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import request from 'vj/utils/request';
|
import { request } from 'vj/utils';
|
||||||
|
|
||||||
const page = new NamedPage('manage_config', async () => {
|
const page = new NamedPage('manage_config', async () => {
|
||||||
const schema = new Schema(UiContext.schema);
|
const schema = new Schema(UiContext.schema);
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { ConfirmDialog } from 'vj/components/dialog';
|
import { ConfirmDialog } from 'vj/components/dialog';
|
||||||
import { NamedPage } from 'vj/misc/Page';
|
import { NamedPage } from 'vj/misc/Page';
|
||||||
import i18n from 'vj/utils/i18n';
|
import { i18n, request, tpl } from 'vj/utils';
|
||||||
import request from 'vj/utils/request';
|
|
||||||
import tpl from 'vj/utils/tpl';
|
|
||||||
|
|
||||||
export default new NamedPage('training_edit', () => {
|
export default new NamedPage('training_edit', () => {
|
||||||
let confirmed = false;
|
let confirmed = false;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import { AutoloadPage } from 'vj/misc/Page';
|
import { AutoloadPage } from 'vj/misc/Page';
|
||||||
import api, { gql } from 'vj/utils/api';
|
import { api, gql } from 'vj/utils';
|
||||||
|
|
||||||
export default new AutoloadPage('user_login', (pagename) => {
|
export default new AutoloadPage('user_login', (pagename) => {
|
||||||
(pagename === 'user_login' ? $(document) : $('.dialog--signin__main')).on('blur', '[name="uname"]', async () => {
|
(pagename === 'user_login' ? $(document) : $('.dialog--signin__main')).on('blur', '[name="uname"]', async () => {
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
declare global {
|
|
||||||
interface Window {
|
|
||||||
node_modules: any;
|
|
||||||
LANGS: Record<string, any>;
|
|
||||||
}
|
|
||||||
|
|
||||||
let UserContext: Record<string, any>;
|
|
||||||
let UiContext: Record<string, any>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export { };
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
import request from './request';
|
|
||||||
|
|
||||||
export default async (q: string, path: string[] = []) => {
|
|
||||||
let query = q.trim();
|
|
||||||
if (!query.startsWith('query')) query = `query{${query}}`;
|
|
||||||
const res = await request.post(`/d/${UiContext.domainId}/api`, { query });
|
|
||||||
if (res.errors) throw new Error(res.errors[0].message);
|
|
||||||
let cursor = res;
|
|
||||||
for (const p of path) {
|
|
||||||
cursor = cursor[p];
|
|
||||||
if (!cursor) return undefined;
|
|
||||||
}
|
|
||||||
return cursor;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const gql = (
|
|
||||||
pieces: TemplateStringsArray,
|
|
||||||
...templates: (string | number | string[] | number[])[]
|
|
||||||
) => {
|
|
||||||
let res = '';
|
|
||||||
for (let i = 0; i < pieces.length; i++) {
|
|
||||||
res += pieces[i];
|
|
||||||
if (templates[i]) res += JSON.stringify(templates[i]);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
const prefixes = new Set(Object.keys(window.LANGS).filter((i) => i.includes('.')).map((i) => i.split('.')[0]));
|
|
||||||
|
|
||||||
export default function getAvailableLangs(langsList?: string[]) {
|
|
||||||
const Langs = {};
|
|
||||||
for (const key in window.LANGS) {
|
|
||||||
if (prefixes.has(key)) continue;
|
|
||||||
if (langsList && langsList.length && langsList.join('') && !langsList.includes(key)) continue;
|
|
||||||
else if (window.LANGS[key].hidden && !langsList?.includes(key)) continue;
|
|
||||||
Langs[key] = window.LANGS[key];
|
|
||||||
}
|
|
||||||
return Langs;
|
|
||||||
}
|
|
||||||
Loaded 100 of 116 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user