diff --git a/packages/ui-default/components/message/index.page.js b/packages/ui-default/components/message/index.page.js index 337f97487..ed84b1de9 100644 --- a/packages/ui-default/components/message/index.page.js +++ b/packages/ui-default/components/message/index.page.js @@ -42,7 +42,7 @@ const messagePage = new AutoloadPage('messagePage', (pagename) => { }).open(); } else if (msg.udoc._id === 1 && msg.mdoc.flag & 4) { new VjNotification({ - message: 'You received a system message, click here to view.', + message: i18n('You received a system message, click here to view.'), duration: 15000, action: () => window.open(`/home/messages?uid=${msg.udoc._id}`, '_blank'), }).show(); diff --git a/packages/ui-default/components/scratchpad/ScratchpadEditorContainer.jsx b/packages/ui-default/components/scratchpad/ScratchpadEditorContainer.jsx index c347b6030..af055197d 100644 --- a/packages/ui-default/components/scratchpad/ScratchpadEditorContainer.jsx +++ b/packages/ui-default/components/scratchpad/ScratchpadEditorContainer.jsx @@ -46,6 +46,8 @@ export default connect(mapStateToProps, mapDispatchToProps)(class MonacoEditor e } }), ); + window.editor = this.editor; + window.monaco = monaco; } } @@ -72,8 +74,11 @@ export default connect(mapStateToProps, mapDispatchToProps)(class MonacoEditor e const { load } = await import('vj/components/monaco/loader'); const { monaco } = await load([language]); if (prevProps.language !== language) { - monaco.editor.setModelLanguage(model, language); - editor.updateOptions({ mode: language }); + const val = model.getValue(); + model.dispose(); + const uri = monaco.Uri.parse(`hydro://${UiContext.pdoc.pid || UiContext.pdoc.docId}.${language}`); + this.model = monaco.editor.createModel(val, language, uri); + editor.setModel(this.model); } if (editor) { if (prevProps.mainSize !== mainSize diff --git a/packages/ui-default/components/scratchpad/ScratchpadToolbarContainer.jsx b/packages/ui-default/components/scratchpad/ScratchpadToolbarContainer.jsx index 89383d9c9..e1e6cef48 100644 --- a/packages/ui-default/components/scratchpad/ScratchpadToolbarContainer.jsx +++ b/packages/ui-default/components/scratchpad/ScratchpadToolbarContainer.jsx @@ -66,27 +66,36 @@ const mapDispatchToProps = (dispatch) => ({ }, }); +const LANGS = {}; +const prefix = new Set(Object.keys(window.LANGS).filter((i) => i.includes('.')).map((i) => i.split('.')[0])); +const domainId = UiContext.pdoc.reference?.domainId || UiContext.pdoc.domainId; +for (const key in window.LANGS) { + if (prefix.has(key)) continue; + if (UiContext.pdoc.config.langs && !UiContext.pdoc.config.langs.includes(key)) continue; + if (window.LANGS[key].domain && !window.LANGS[key].domain.includes(domainId)) continue; + LANGS[key] = window.LANGS[key]; +} +const keys = Object.keys(LANGS); + export default connect(mapStateToProps, mapDispatchToProps)(class ScratchpadToolbarContainer extends React.PureComponent { static contextTypes = { store: PropTypes.object, }; + constructor(props) { + super(props); + if (!LANGS[this.props.editorLang]) { + // preference not allowed + const key = keys.find((i) => LANGS[i].pretest === this.props.editorLang); + this.props.setEditorLanguage(key || Object.keys(LANGS)[0]); + } + } + componentDidMount() { if (this.props.recordsVisible) this.props.loadSubmissions(); } render() { - const LANGS = {}; - const prefix = new Set(Object.keys(window.LANGS).filter((i) => i.includes('.')).map((i) => i.split('.')[0])); - const domainId = UiContext.pdoc.reference?.domainId || UiContext.pdoc.domainId; - for (const key in window.LANGS) { - if (prefix.has(key)) continue; - if (UiContext.pdoc.config.langs && !UiContext.pdoc.config.langs.includes(key)) continue; - if (window.LANGS[key].domain && !window.LANGS[key].domain.includes(domainId)) continue; - LANGS[key] = window.LANGS[key]; - } - const keys = Object.keys(LANGS); - if (!keys.includes(this.props.editorLang)) this.props.setEditorLanguage(keys[0]); let canUsePretest = ['default', 'fileio'].includes(UiContext.pdoc.config?.type); if (UiContext.pdoc.config?.type === 'remote_judge') { if (window.LANGS[this.props.editorLang].pretest) canUsePretest = true; diff --git a/packages/ui-default/components/scratchpad/reducers/editor.js b/packages/ui-default/components/scratchpad/reducers/editor.js index 6d8acecc6..ef1c4b68c 100644 --- a/packages/ui-default/components/scratchpad/reducers/editor.js +++ b/packages/ui-default/components/scratchpad/reducers/editor.js @@ -2,24 +2,22 @@ let cacheKey = `${UserContext._id}/${UiContext.pdoc.domainId}/${UiContext.pdoc.d if (UiContext.tdoc?._id && UiContext.tdoc.rule !== 'homework') cacheKey += `@${UiContext.tdoc._id}`; export default function reducer(state = { - lang: UiContext.codeLang, + lang: localStorage.getItem(`${cacheKey}#lang`) || UiContext.codeLang, code: localStorage.getItem(cacheKey) || UiContext.codeTemplate, }, action) { - switch (action.type) { - case 'SCRATCHPAD_EDITOR_UPDATE_CODE': { + if (action.type === 'SCRATCHPAD_EDITOR_UPDATE_CODE') { localStorage.setItem(cacheKey, action.payload); return { ...state, code: action.payload, }; } - case 'SCRATCHPAD_EDITOR_SET_LANG': { + if (action.type === 'SCRATCHPAD_EDITOR_SET_LANG') { + localStorage.setItem(`${cacheKey}#lang`, action.payload); return { ...state, lang: action.payload, }; } - default: - return state; - } + return state; } diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index 3572957c6..2b4ee808f 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.32.11", + "version": "4.32.12", "author": "undefined ", "license": "AGPL-3.0", "main": "hydro.js", @@ -21,7 +21,7 @@ "@fontsource/ubuntu-mono": "^4.5.3", "@hydrooj/utils": "workspace:*", "@types/gulp-if": "^0.0.34", - "@types/jquery": "^3.5.13", + "@types/jquery": "^3.5.14", "@types/json-schema": "^7.0.9", "@types/katex": "^0.11.1", "@types/qrcode": "^1.4.2", @@ -41,16 +41,16 @@ "emojis-keywords": "2.0.0", "emojis-list": "2.1.0", "esbuild-loader": "^2.18.0", - "eslint": "^8.9.0", + "eslint": "^8.10.0", "eslint-config-airbnb": "^18.2.1", "eslint-import-resolver-webpack": "^0.13.2", "eslint-plugin-import": "^2.25.4", "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-react": "^7.28.0", + "eslint-plugin-react": "^7.29.2", "fancy-log": "^1.3.3", "file-loader": "^6.2.0", "friendly-errors-webpack-plugin": "^1.7.0", - "graphiql": "^1.5.19", + "graphiql": "^1.6.0", "gulp": "^4.0.2", "gulp-cli": "^2.3.0", "gulp-iconfont": "^11.0.1", @@ -67,14 +67,14 @@ "monaco-editor-nls": "^2.0.0", "monaco-editor-webpack-plugin": "^7.0.1", "monaco-themes": "^0.4.0", - "nanoid": "^3.3.0", + "nanoid": "^3.3.1", "normalize.css": "^8.0.1", "nprogress": "^0.2.0", "pickadate": "^3.6.4", "plugin-error": "^1.0.1", "postcss-loader": "^3.0.0", "prism-themes": "^1.9.0", - "prismjs": "^1.26.0", + "prismjs": "^1.27.0", "prop-types": "^15.8.1", "qrcode": "^1.5.0", "raw-loader": "^4.0.2", @@ -89,7 +89,7 @@ "redux-thunk": "^2.4.1", "rupture": "^0.7.1", "slideout": "^1.0.1", - "sockjs-client": "^1.5.2", + "sockjs-client": "^1.6.0", "speed-measure-webpack-plugin": "^1.5.0", "sticky-kit": "^1.1.3", "style-loader": "^2.0.0", @@ -111,7 +111,7 @@ }, "dependencies": { "esbuild": "0.14.3", - "fs-extra": "^10.0.0", + "fs-extra": "^10.0.1", "js-yaml": "^4.1.0", "jsesc": "^3.0.2", "katex": "^0.15.2", @@ -125,7 +125,7 @@ "markdown-it-table-of-contents": "^0.6.0", "mongodb": "^3.7.3", "nunjucks": "^3.2.3", - "react-query": "^3.34.15", + "react-query": "^3.34.16", "streamsaver": "^2.0.6", "xss": "^1.0.10" }