1
0
Arsekl 3 лет назад
Родитель
Сommit
a24fe12ee9

+ 7 - 2
src/api/index.ts

@@ -249,8 +249,13 @@ const api = {
         })
     },
 
-    getQuestion(examId: number, questionId: number) {
-        return http.get(`${apiPath}/exam/${examId}/onlinecode/${questionId}`)
+    // getQuestion(examId: number, questionId: number) {
+    //     return http.get(`${apiPath}/exam/${examId}/onlinecode/${questionId}`)
+    // },
+
+    getQuestion(examId: number, userId: number) {
+        if (userId) return http.get(`${apiPath}/exam/${examId}/onlinecode`, {userId: userId})
+        else return http.get(`${apiPath}/exam/${examId}/onlinecode`)
     }
 }
 

+ 8 - 8
src/components/questionListPanel/index.tsx

@@ -5,10 +5,10 @@ import {
     editorTreeClassName, editorTreeFileIconClassName, editorTreeFileNameClassName,
     editorTreeItemClassName
 } from "@dtinsight/molecule/esm/workbench/sidebar/explore/base";
-import {CodeSerializer, ProblemSerializer} from "@/api";
+import {CodeSerializer, NestedCodeItemVO, ProblemSerializer} from "@/api";
 import {store} from "@/redux/store";
 import classNames from "classnames";
-import {getQuestion} from "@/utils";
+import {changeQuestion, getQuestion} from "@/utils";
 import {IStoreState} from "@/redux/reducer/reducer";
 import {connect} from "react-redux";
 import Scrollbar from "react-scrollbars-custom";
@@ -65,8 +65,8 @@ const QuestionListView = (props: IQuestionListProps) => {
                                 key={`${index}_${question.id}`}
                                 onClick={
                                     () => {
-                                        if (!isActive && store.getState().loadQuestion.examId)
-                                            getQuestion(store.getState().loadQuestion.examId as unknown as string, question.id as unknown as string)
+                                        if (!isActive && question.id)
+                                            changeQuestion(question.id)
                                     }
                                 }
                             >
@@ -92,16 +92,16 @@ const QuestionListView = (props: IQuestionListProps) => {
     )
 }
 
-function getCurrentId(question: CodeSerializer): number {
-    if (question && question.codeList && question.codeList[0] && question.codeList[0].questionId)
-        return question.codeList[0].questionId
+function getCurrentId(question: NestedCodeItemVO): number {
+    if (question && question.questionId)
+        return question.questionId
     else return 0
 }
 
 const mapStateToProps = (state: IStoreState): IQuestionListProps => {
     return {
         questions: state.loadQuestionList,
-        currentId: getCurrentId(state.loadQuestion)
+        currentId: getCurrentId(state.loadCurrentQuestion)
     }
 }
 

+ 13 - 0
src/extensions/QuietLight/.vscode/launch.json

@@ -0,0 +1,13 @@
+// A launch configuration that launches the extension inside a new window
+{
+    "version": "0.1.0",
+    "configurations": [
+        {
+            "name": "Launch Extension",
+            "type": "extensionHost",
+            "request": "launch",
+            "runtimeExecutable": "${execPath}",
+            "args": ["--extensionDevelopmentPath=${workspaceRoot}" ]
+        }
+    ]
+}

+ 1 - 0
src/extensions/QuietLight/.vscodeignore

@@ -0,0 +1 @@
+images/

+ 22 - 0
src/extensions/QuietLight/CHANGELOG.md

@@ -0,0 +1,22 @@
+# Change Log
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/).
+
+## [v1.1.0] - 2019-02-28
+### Added
+- New colors for the editor sidebar, along with improvements to search highlighting and other editor colors
+
+## [v1.0.2] - 2017-02-05
+### Fixed
+- Fixed many coloration problems introduced by VSC 1.9's new scope matching engine (so long, sensical CSS logic; hello overly verbose and horrifically dated TextMate approach!)
+
+## [v1.0.1] - 2017-02-01
+### Fixed
+- Fixed background color for word highlights
+
+## [v1.0.0] - 2017-29-01
+- Initial release
+- Officially supports HTML, CSS / LESS / SCSS, JavaScript, PHP, Python, and Markdown
+

+ 7 - 0
src/extensions/QuietLight/LICENSE

@@ -0,0 +1,7 @@
+Copyright 2017 Ian Beck
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 27 - 0
src/extensions/QuietLight/README.md

@@ -0,0 +1,27 @@
+# Quiet Light for VSC
+
+Quiet Light for VSC is a light, peaceful theme, ported to Visual Studio Code by me, the designer of the original Quiet Light theme for MacRabbit's Espresso text editor on macOS.
+
+![Quiet Light screenshot](images/screenshot.png)
+
+When I launched Visual Studio Code for the first time I was surprised and delighted to find that my Quiet Light theme was included by default. However, it was a little rough around the edges (I didn't have anything to do with the Textmate port of the theme), and thus Quiet Light for VSC was born.
+
+I hope you enjoy working by Quiet Light! Please [let me know](http://onecrayon.com/about/contact/) if you run across any problems or have any suggestions to make it better (or alternately [submit a pull request on GitHub](https://github.com/onecrayon/theme-quietlight-vsc)).
+
+## Officially tested for:
+
+* HTML
+* CSS / LESS / SCSS
+* JavaScript
+* PHP
+* Python
+* Markdown
+
+**Please note** that Quiet Light 1.0.2+ requires Visual Studio Code 1.9 or greater.
+
+## Known issues
+
+* No background colors (see [VSC issue #3429](https://github.com/Microsoft/vscode/issues/3429))
+* PHP coloration in HTML attribute strings is currently borked
+* SCSS commas in selectors (and some tag names) are uncolored (no syntax zone)
+* HTML `<style>` tag attribute equal signs are miscolored (no syntax zone)

BIN
src/extensions/QuietLight/icon.png


BIN
src/extensions/QuietLight/images/screenshot.png


+ 18 - 0
src/extensions/QuietLight/index.ts

@@ -0,0 +1,18 @@
+import { IExtension } from "@dtinsight/molecule/esm/model";
+
+const QuietLight: IExtension = require('./package.json');
+const themes = [
+    require('./themes/QuietLight.json')
+];
+
+const packageThemes = QuietLight.contributes?.themes || [];
+
+QuietLight.contributes!.themes = packageThemes.map((theme, index) => {
+    theme.id = theme.label;
+    theme = Object.assign({}, theme, themes[index]);
+    return theme;
+});
+
+QuietLight.id = 'BracketLightPro';
+
+export { QuietLight };

+ 31 - 0
src/extensions/QuietLight/package.json

@@ -0,0 +1,31 @@
+{
+    "name": "theme-quietlight-vsc",
+    "displayName": "Quiet Light for VSC",
+    "description": "Light, peaceful coding (from the original designer).",
+    "repository": {
+        "type": "git",
+        "url": "https://github.com/onecrayon/theme-quietlight-vsc.git"
+    },
+    "galleryBanner": {
+        "color": "#e6ebf2",
+        "theme": "light"
+    },
+    "icon": "icon.png",
+    "version": "1.1.0",
+    "publisher": "onecrayon",
+    "engines": {
+        "vscode": "^1.9.0"
+    },
+    "categories": [
+        "Themes"
+    ],
+    "contributes": {
+        "themes": [
+            {
+                "label": "Quiet Light for VSC",
+                "uiTheme": "vs",
+                "path": "./themes/QuietLight.json"
+            }
+        ]
+    }
+}

+ 760 - 0
src/extensions/QuietLight/themes/QuietLight.json

@@ -0,0 +1,760 @@
+{
+	"author": "Ian Beck",
+	"comment": "Light, peaceful coding.",
+	"name": "Quiet Light for VSC",
+	"tokenColors": [
+		{
+			"name": "Comments",
+			"scope": [
+				"comment",
+				"punctuation.definition.comment"
+			],
+			"settings": {
+				"foreground": "#aaaaaa"
+			}
+		},
+		{
+			"name": "Comments: Keywords",
+			"scope": [
+				"comment.keyword",
+				"keyword.codetag",
+				"keyword.phpdoc"
+			],
+			"settings": {
+				"fontStyle": "bold",
+				"foreground": "#aaaaaa"
+			}
+		},
+		{
+			"name": "Invalid - Deprecated",
+			"scope": [
+				"invalid.deprecated"
+			],
+			"settings": {
+				"background": "#96000014"
+			}
+		},
+		{
+			"name": "Invalid - Illegal",
+			"scope": [
+				"invalid.illegal"
+			],
+			"settings": {
+				"background": "#96000014",
+				"foreground": "#660000"
+			}
+		},
+		{
+			"name": "Operators",
+			"scope": [
+				"keyword.operator"
+			],
+			"settings": {
+				"foreground": "#777777"
+			}
+		},
+		{
+			"name": "Keywords",
+			"scope": [
+				"keyword",
+				"keyword.operator.expression",
+				"keyword.control.at-rule.css",
+				"source.php storage.modifier",
+				"source.php storage.type"
+			],
+			"settings": {
+				"foreground": "#4b83cd"
+			}
+		},
+		{
+			"name": "Keywords: Punctuation",
+			"scope": [
+				"punctuation.definition.keyword",
+				"keyword.control.at-rule.css punctuation"
+			],
+			"settings": {
+				"foreground": "#91b3e0"
+			}
+		},
+		{
+			"name": "Keywords: new",
+			"scope": [
+				"keyword.operator.new"
+			],
+			"settings": {
+				"foreground": "#7a3e9d"
+			}
+		},
+		{
+			"name": "Types",
+			"scope": [
+				"storage",
+				"storage.type",
+				"storage.modifier",
+				"support.type"
+			],
+			"settings": {
+				"foreground": "#7a3e9d"
+			}
+		},
+		{
+			"name": "Language Constants",
+			"scope": [
+				"constant.language",
+				"support.constant",
+				"variable.language",
+				"variable.language.this"
+			],
+			"settings": {
+				"foreground": "#ab6526"
+			}
+		},
+		{
+			"name": "Variables",
+			"scope": [
+				"variable",
+				"support.variable"
+			],
+			"settings": {
+				"foreground": "#7a3e9d"
+			}
+		},
+		{
+			"name": "Variables: Punctuation",
+			"scope": [
+				"punctuation.definition.variable"
+			],
+			"settings": {
+				"foreground": "#b19bbd"
+			}
+		},
+		{
+			"name": "Functions",
+			"scope": [
+				"entity.name.function",
+				"entity.name.class",
+				"entity.method.name",
+				"support.function",
+				"meta.function-call"
+			],
+			"settings": {
+				"foreground": "#aa3731"
+			}
+		},
+		{
+			"name": "Functions: definitions",
+			"scope": [
+				"entity.name.function",
+				"entity.name.class",
+				"entity.method.name"
+			],
+			"settings": {
+				"fontStyle": "bold"
+			}
+		},
+		{
+			"name": "Functions: parameters",
+			"scope": [
+				"meta.function-call.arguments"
+			],
+			"settings": {
+				"foreground": "#333333"
+			}
+		},
+		{
+			"name": "Classes",
+			"scope": [
+				"entity.name.type",
+				"entity.other.inherited-class",
+				"support.class"
+			],
+			"settings": {
+				"foreground": "#aa3731",
+				"fontStyle": " bold"
+			}
+		},
+		{
+			"name": "Exceptions",
+			"scope": [
+				"entity.name.exception"
+			],
+			"settings": {
+				"foreground": "#660000"
+			}
+		},
+		{
+			"name": "Sections",
+			"scope": [
+				"entity.name.section"
+			],
+			"settings": {
+				"fontStyle": "bold"
+			}
+		},
+		{
+			"name": "Numbers, Characters",
+			"scope": [
+				"constant.numeric",
+				"constant.character",
+				"constant"
+			],
+			"settings": {
+				"foreground": "#ab6526"
+			}
+		},
+		{
+			"name": "Strings",
+			"scope": [
+				"string",
+				"string.quoted",
+				"punctuation.definition.string",
+				"string.regexp",
+				"storage.type.string"
+			],
+			"settings": {
+				"foreground": "#448c27"
+			}
+		},
+		{
+			"name": "Strings: Escape Sequences",
+			"scope": [
+				"constant.character.escape"
+			],
+			"settings": {
+				"foreground": "#ab6526"
+			}
+		},
+		{
+			"name": "Strings: Regex",
+			"scope": [
+				"string.regex"
+			],
+			"settings": {
+				"foreground": "#333333"
+			}
+		},
+		{
+			"name": "Strings: Regex operators",
+			"scope": [
+				"string.regexp keyword",
+				"string.regexp keyword.operator",
+				"string.regexp constant",
+				"string.regexp constant.character",
+				"string.regexp punctuation"
+			],
+			"settings": {
+				"foreground": "#7a3e9d"
+			}
+		},
+		{
+			"name": "Strings: Symbols",
+			"scope": [
+				"constant.other.symbol"
+			],
+			"settings": {
+				"foreground": "#ab6526"
+			}
+		},
+		{
+			"name": "Strings: Interpolation",
+			"scope": [
+				"punctuation.definition.template-expression.begin.ts",
+				"punctuation.definition.template-expression.end.ts"
+			],
+			"settings": {
+				"foreground": "#ab6526"
+			}
+		},
+		{
+			"name": "Punctuation",
+			"scope": [
+				"punctuation",
+				"punctuation.separator"
+			],
+			"settings": {
+				"foreground": "#777777"
+			}
+		},
+		{
+			"name": "HTML: Doctype Declaration",
+			"scope": [
+				"meta.tag.sgml.doctype",
+				"meta.tag.sgml.doctype string",
+				"meta.tag.sgml.doctype entity.name.tag",
+				"meta.tag.sgml punctuation.definition.tag.html",
+				"meta.tag.preprocessor",
+				"meta.tag.preprocessor entity.name.tag",
+				"meta.tag.preprocessor entity.other.attribute-name"
+			],
+			"settings": {
+				"foreground": "#aaaaaa"
+			}
+		},
+		{
+			"name": "HTML: Tags",
+			"scope": [
+				"meta.tag",
+				"entity.attribute-name",
+				"punctuation.definition.tag.html",
+				"punctuation.definition.tag.begin.html",
+				"punctuation.definition.tag.end.html",
+				"entity.other.attribute-name.html",
+				"punctuation.separator.key-value.html"
+			],
+			"settings": {
+				"foreground": "#91b3e0"
+			}
+		},
+		{
+			"name": "HTML: Tag Names",
+			"scope": [
+				"entity.name.tag"
+			],
+			"settings": {
+				"foreground": "#4b83cd"
+			}
+		},
+		{
+			"name": "HTML: Attribute Values",
+			"scope": [
+				"meta.tag string.quoted",
+				"meta.tag punctuation.definition.string"
+			],
+			"settings": {
+				"foreground": "#448c27"
+			}
+		},
+		{
+			"name": "HTML: Entities",
+			"scope": [
+				"constant.character.entity",
+				"punctuation.definition.entity"
+			],
+			"settings": {
+				"foreground": "#ab6526"
+			}
+		},
+		{
+			"name": "CSS: Selectors",
+			"scope": [
+				"meta.selector",
+				"selector.css",
+				"entity.name.selector",
+				"entity.other.attribute-name.id.css",
+				"source.css entity.name.tag",
+				"entity.other.attribute-name.class",
+				"entity.other.attribute-name.pseudo-class",
+				"entity.other.attribute-name.parent-selector",
+				"entity.other.attribute-name.pseudo-element",
+				"punctuation.definition.entity.css",
+
+				"entity.id.scss",
+				"entity.tag.scss",
+				"entity.class.scss",
+				"entity.pseudo-class.scss",
+				"entity.parent-selector.scss",
+				"entity.pseudo-element.scss",
+
+				"punctuation.separator.list.css",
+				"meta.property-list keyword.operator.less",
+
+				"source.css.less entity.other.attribute-name.id",
+				"entity.other.attribute-name.attribute.scss",
+				"entity.other.attribute-name.scss",
+				"entity.name.function.scss"
+			],
+			"settings": {
+				"foreground": "#7a3e9d"
+			}
+		},
+		{
+			"name": "CSS: Property Names",
+			"scope": [
+				"meta.property-name",
+				"support.type.property-name"
+			],
+			"settings": {
+				"foreground": "#ab6526"
+			}
+		},
+		{
+			"name": "CSS: Property Values",
+			"scope": [
+				"meta.property-value",
+				"source.css keyword.other",
+				"source.css constant",
+				"source.css constant.numeric",
+				"source.css constant.numeric punctuation",
+				"meta.property-value support.constant"
+			],
+			"settings": {
+				"foreground": "#448c27"
+			}
+		},
+		{
+			"name": "CSS: Variable",
+			"scope": [
+				"source.css variable",
+				"source.css.less variable",
+				"source.css.scss variable"
+			],
+			"settings": {
+				"foreground": "#aa3731"
+			}
+		},
+		{
+			"name": "CSS: Important Keyword",
+			"scope": [
+				"keyword.other.important"
+			],
+			"settings": {
+				"fontStyle": "bold"
+			}
+		},
+		{
+			"name": "JS: Variables",
+			"scope": [
+				"variable.js",
+				"source.js variable",
+				"source.js support.variable",
+				"source.js support.type"
+			],
+			"settings": {
+				"foreground": "#333333"
+			}
+		},
+		{
+			"name": "JS: Function overrides",
+			"scope": [
+				"entity.name.function.js"
+			],
+			"settings": {
+				"fontStyle": ""
+			}
+		},
+		{
+			"name": "JS: Embedded",
+			"scope": [
+				"source.embedded"
+			],
+			"settings": {
+				"background": "#eaebe6"
+			}
+		},
+		{
+			"name": "JSON: Properties",
+			"scope": [
+				"punctuation.support.type.property-name"
+			],
+			"settings": {
+				"foreground": "#ab6526"
+			}
+		},
+		{
+			"name": "PHP: Background",
+			"scope": [
+				"source.php"
+			],
+			"settings": {
+				"background": "#e6ebf2"
+			}
+		},
+		{
+			"name": "PHP: Delimiters",
+			"scope": [
+				"punctuation.section.embedded.metatag.php"
+			],
+			"settings": {
+				"foreground": "#aa3731",
+				"fontStyle": "bold"
+			}
+		},
+		{
+			"name": "Python: Decorators",
+			"scope": [
+				"entity.name.function.decorator",
+				"meta.function.decorator punctuation.definition",
+				"meta.function.decorator string.quoted",
+				"meta.function.decorator punctuation.definition.string",
+				"meta.function.decorator meta.function-call.arguments",
+				"meta.function.decorator variable.parameter",
+				"meta.function.decorator keyword.operator"
+			],
+			"settings": {
+				"foreground": "#aaaaaa"
+			}
+		},
+		{
+			"name": "Python: Parameters",
+			"scope": [
+				"source.python variable.parameter"
+			],
+			"settings": {
+				"foreground": "#333333"
+			}
+		},
+		{
+			"name": "Python: Support Type",
+			"scope": [
+				"source.python support.type"
+			],
+			"settings": {
+				"foreground": "#333333"
+			}
+		},
+		{
+			"name": "Python: Function calls",
+			"scope": [
+				"source.python meta.function-call support.type"
+			],
+			"settings": {
+				"foreground": "#aa3731"
+			}
+		},
+		{
+			"name": "Markup: Changed",
+			"scope": [
+				"markup.changed"
+			],
+			"settings": {
+				"background": "#fffab7"
+			}
+		},
+		{
+			"name": "Markup: Deletion",
+			"scope": [
+				"markup.deleted"
+			],
+			"settings": {
+				"background": "#feedef"
+			}
+		},
+		{
+			"name": "Markup: Emphasis",
+			"scope": [
+				"markup.italic"
+			],
+			"settings": {
+				"fontStyle": "italic"
+			}
+		},
+		{
+			"name": "Markup: Error",
+			"scope": [
+				"markup.error"
+			],
+			"settings": {
+				"background": "#96000014",
+				"foreground": "#660000"
+			}
+		},
+		{
+			"name": "Markup: Insertion",
+			"scope": [
+				"markup.inserted"
+			],
+			"settings": {
+				"background": "#e4f6d4"
+			}
+		},
+		{
+			"name": "Markup: Link",
+			"scope": [
+				"meta.link",
+				"meta.image.inline"
+			],
+			"settings": {
+				"foreground": "#4b83cd"
+			}
+		},
+		{
+			"name": "Markup: Output",
+			"scope": [
+				"markup.output",
+				"markup.raw"
+			],
+			"settings": {
+				"foreground": "#777777"
+			}
+		},
+		{
+			"name": "Markup: Prompt",
+			"scope": [
+				"markup.prompt"
+			],
+			"settings": {
+				"foreground": "#777777"
+			}
+		},
+		{
+			"name": "Markup: Heading",
+			"scope": [
+				"markup.heading"
+			],
+			"settings": {
+				"foreground": "#333333",
+				"fontStyle": " bold"
+			}
+		},
+		{
+			"name": "Markup: Strong",
+			"scope": [
+				"markup.bold"
+			],
+			"settings": {
+				"fontStyle": "bold",
+				"foreground": ""
+			}
+		},
+		{
+			"name": "Markup: Traceback",
+			"scope": [
+				"markup.traceback"
+			],
+			"settings": {
+				"foreground": "#660000"
+			}
+		},
+		{
+			"name": "Markup: Underline",
+			"scope": [
+				"markup.underline"
+			],
+			"settings": {
+				"fontStyle": "underline"
+			}
+		},
+		{
+			"name": "Markup Inline",
+			"scope": [
+				"markup.inline.raw"
+			],
+			"settings": {
+				"foreground": "#777777"
+			}
+		},
+		{
+			"name": "Markdown: Punctuation",
+			"scope": [
+				"markdown.punctuation",
+				"markdown.link punctuation",
+				"punctuation.definition.raw.markdown",
+				"punctuation.definition.heading.markdown",
+				"beginning.punctuation.definition.list.markdown",
+				"beginning.punctuation.definition.quote.markdown",
+				"punctuation.definition.bold.markdown",
+				"punctuation.definition.italic.markdown",
+				"punctuation.definition.metadata.markdown"
+			],
+			"settings": {
+				"foreground": "#448c27"
+			}
+		},
+		{
+			"name": "Markdown: Link title",
+			"scope": [
+				"string.other.link.description.markdown",
+				"string.other.link.title.markdown"
+			],
+			"settings": {
+				"foreground": "#7a3e9d"
+			}
+		},
+		{
+			"name": "Extra: Diff Range",
+			"scope": [
+				"meta.diff.range",
+				"meta.diff.index",
+				"meta.separator"
+			],
+			"settings": {
+				"background": "#fffab7"
+			}
+		},
+		{
+			"name": "Extra: Diff From",
+			"scope": [
+				"meta.diff.header.from-file"
+			],
+			"settings": {
+				"background": "#feedef"
+			}
+		},
+		{
+			"name": "Extra: Diff To",
+			"scope": [
+				"meta.diff.header.to-file"
+			],
+			"settings": {
+				"background": "#e4f6d4"
+			}
+		}
+	],
+	"colors": {
+		"editor.background": "#f5f5f5",
+		"editor.foreground": "#333",
+		"editorCursor.foreground": "#aaa",
+		"editorWhitespace.foreground": "#ebebeb",
+		"editorRuler.foreground": "#ebebeb",
+		"editorIndentGuide.background": "#ebebeb",
+		"editorIndentGuide.activeBackground": "#dcdcdc",
+		"editor.lineHighlightBackground": "#e4f6d4",
+		"activityBar.background": "#e0e9f6",
+		"activityBar.foreground": "#4b83cd",
+		"activityBarBadge.background": "#448c27",
+		"badge.background": "#448c27",
+		"badge.foreground": "#fff",
+		"sideBar.background": "#f2f2f2",
+		"sideBarSectionHeader.background": "#e0e9f6",
+		"editorLineNumber.activeForeground": "#333",
+		"editorLineNumber.foreground": "#aaa",
+		"statusBar.background": "#4b83cd",
+		"statusBar.debuggingBackground": "#aa3731",
+		"statusBar.noFolderBackground": "#aa3731",
+		"button.background": "#4b83cd",
+		"dropdown.background": "#f5f5f5",
+		"errorForeground": "#600",
+		"editor.selectionBackground": "#c1f5b0",
+		"editor.selectionHighlightBackground": "#c1f5b044",
+		"editor.selectionHighlightBorder": "#c1f5b0",
+		"editor.inactiveSelectionBackground": "#dcdcdcaa",
+		"editor.findMatchBackground": "#fef935",
+		"editor.findMatchHighlightBackground": "#fef93533",
+		"editor.findRangeHighlightBackground": "#dcdcdc55",
+		"editorLink.activeForeground": "#4b83cd",
+		"selection.background": "#c1f5b0",
+		"editor.wordHighlightBackground": "#c1f5b044",
+		"editor.wordHighlightStrongBackground": "#c1f5b044",
+		"list.activeSelectionBackground": "#4b83cd",
+		"list.activeSelectionForeground": "#fff",
+		"list.inactiveSelectionBackground": "#91b3e0",
+		"list.inactiveSelectionForeground": "#fff",
+		"list.focusBackground": "#91b3e0",
+		"list.inactiveFocusBackground": "#91b3e0",
+		"list.hoverBackground": "#e0e0e0",
+		"list.highlightForeground": "#7a3e9d",
+
+		"editorGroup.dropBackground": "#c9d0d988",
+		"focusBorder": "#a6b39b",
+		"inputOption.activeBorder": "#adafb7",
+		"inputValidation.errorBackground": "#ffeaea",
+		"inputValidation.errorBorder": "#f1897f",
+		"inputValidation.infoBackground": "#f2fcff",
+		"inputValidation.infoBorder": "#4ec1e5",
+		"inputValidation.warningBackground": "#fffee2",
+		"inputValidation.warningBorder": "#ffe055",
+		"panel.background": "#f5f5f5",
+		"peekView.border": "#705697",
+		"peekViewEditor.background": "#f2f8fc",
+		"peekViewEditor.matchHighlightBackground": "#c2dfe3",
+		"peekViewResult.background": "#f2f8fc",
+		"peekViewResult.matchHighlightBackground": "#93c6d6",
+		"peekViewTitle.background": "#f2f8fc",
+		"pickerGroup.border": "#749351",
+		"pickerGroup.foreground": "#a6b39b",
+		"progressBar.background": "#705697",
+		"tab.modifiedBorder": "#f1897f",
+		"titleBar.activeBackground": "#c4b7d7",
+		"walkThrough.embeddedEditorBackground": "#00000014"
+	}
+}

+ 2 - 0
src/extensions/index.ts

@@ -1,6 +1,7 @@
 import { IExtension } from '@dtinsight/molecule/esm/model';
 import { FirstExtension } from './theFirstExtension';
 import { OneDarkPro } from './oneDarkPro';
+import {QuietLight} from "@/extensions/QuietLight";
 import { SettingsExtension } from './settings';
 import { MenuBarExtension } from './menubar';
 import { ActionExtension } from './action';
@@ -14,6 +15,7 @@ const extensions: IExtension[] = [
     new ActionExtension(),
     GoToGitlabExtension,
     OneDarkPro,
+    QuietLight,
     new InitializeExtension(),
 ];
 

+ 5 - 5
src/extensions/theFirstExtension/editorController.tsx

@@ -1,7 +1,7 @@
 import molecule from "@dtinsight/molecule";
 import Welcome from "../../pages/welcome";
 import {store} from "@/redux/store";
-import {loadQuestion} from "@/redux/action/action";
+import {loadCurrentQuestion, loadQuestion} from "@/redux/action/action";
 import * as monaco from '@dtinsight/molecule/esm/monaco';
 import {
     CloseAction,
@@ -30,10 +30,10 @@ export function activateEditCallback() {
                 if (prevFileValue !== nextFileValue) {
                     node.data.value = nextFileValue
                     molecule.folderTree.update(node)
-                    const question = store.getState().loadQuestion
-                    if (question.codeList && question.codeList[0].editable && location) {
-                        question.codeList[0].editable[location] = nextFileValue
-                        store.dispatch(loadQuestion(question))
+                    const question = store.getState().loadCurrentQuestion
+                    if (question && question.editable && location) {
+                        question.editable[location] = nextFileValue
+                        store.dispatch(loadCurrentQuestion(question))
                     }
                     if (location != null) {
                         const el = window.document.querySelector(`div[data-key='${node.id}'].mo-tree__treenode span.mo-tree__treenode__title`) as HTMLElement | null;

+ 7 - 6
src/pages/index.tsx

@@ -12,6 +12,7 @@ import {getCookie, getQuestion, getQuestionList, goToLogin, setCookie} from "@/u
 import Result from "@/pages/seec/result";
 import {IExplorerPanelItem} from "@dtinsight/molecule/esm/model";
 import {IActionBarItemProps} from "@dtinsight/molecule/esm/components";
+import {store} from "@/redux/store";
 
 const moInstance = create({
     extensions,
@@ -60,15 +61,15 @@ export default function HomePage() {
         }
         if (history.location.query?.id_token) {
             setCookie('token', history.location.query?.id_token as string)
-            if (history.location.query?.examId && history.location.query?.questionId) {
+            if (history.location.query?.examId) {
                 getQuestionList(history.location.query?.examId as unknown as number)
-                getQuestion(history.location.query?.examId as string, history.location.query?.questionId as string)
+                getQuestion(history.location.query?.examId as string, history.location.query?.studentId as string)
             }
             history.push('/')
         }
-        else if (history.location.query?.examId && history.location.query?.questionId) {
+        else if (history.location.query?.examId) {
             getQuestionList(history.location.query?.examId as unknown as number)
-            getQuestion(history.location.query?.examId as string, history.location.query?.questionId as string)
+            getQuestion(history.location.query?.examId as string, history.location.query?.studentId as string)
             history.push('/')
         }
         const unlisten = history.listen((route) => {
@@ -77,9 +78,9 @@ export default function HomePage() {
             }
             if (history.location.query?.id_token) {
                 setCookie('token', history.location.query?.id_token as string)
-                if (history.location.query?.examId && history.location.query?.questionId) {
+                if (history.location.query?.examId) {
                     getQuestionList(history.location.query?.examId as unknown as number)
-                    getQuestion(history.location.query?.examId as string, history.location.query?.questionId as string)
+                    getQuestion(history.location.query?.examId as string, history.location.query?.studentId as string)
                 }
                 history.push('/')
             }

+ 10 - 1
src/redux/action/action.ts

@@ -1,4 +1,4 @@
-import {CodeSerializer, ProblemSerializer, UserSerializer} from "@/api";
+import {CodeSerializer, NestedCodeItemVO, ProblemSerializer, UserSerializer} from "@/api";
 
 export const LOADING_PROJECT = "LOADING_PROJECT"
 
@@ -12,6 +12,8 @@ export const LOAD_QUESTION_LIST = "LOAD_QUESTION_LIST"
 
 export const LOAD_QUESTION = "LOAD_QUESTION"
 
+export const LOAD_CURRENT_QUESTION = "LOAD_CURRENT_QUESTION"
+
 export function loadingProject(projectInfo: {
     nameScope: string,
     path: string,
@@ -57,3 +59,10 @@ export function loadQuestion(questionInfo: CodeSerializer) {
     }
 }
 
+export function loadCurrentQuestion(current: NestedCodeItemVO) {
+    return {
+        type: LOAD_CURRENT_QUESTION,
+        current
+    }
+}
+

+ 20 - 4
src/redux/reducer/reducer.ts

@@ -1,12 +1,12 @@
 import { combineReducers } from 'redux'
 import {
     LOAD_ERROR,
-    LOAD_QUESTION, LOAD_QUESTION_LIST,
+    LOAD_QUESTION, LOAD_QUESTION_LIST, LOAD_CURRENT_QUESTION,
     LOAD_SUCCESS,
     LOAD_USER,
     LOADING_PROJECT,
 } from "../action/action";
-import {CodeSerializer, ProblemSerializer, UserSerializer} from "@/api";
+import {CodeSerializer, NestedCodeItemVO, ProblemSerializer, UserSerializer} from "@/api";
 export type IState = {
     isLoading: boolean,
     isValid: boolean,
@@ -93,17 +93,33 @@ function loadQuestion(state: CodeSerializer = {}, action: {
     }
 }
 
+function loadCurrentQuestion(state: NestedCodeItemVO= {}, action: {
+    type: string,
+    current :NestedCodeItemVO
+}) {
+    switch (action.type) {
+        case LOAD_CURRENT_QUESTION:
+            return Object.assign({}, state, {
+                ...action.current
+            })
+        default:
+            return state
+    }
+}
+
 const rootReducer = combineReducers({
         loadProject,
         loadUser,
         loadQuestion,
-        loadQuestionList
+        loadQuestionList,
+        loadCurrentQuestion
     }
 )
 
 export interface IStoreState {
     loadUser: UserSerializer,
     loadQuestion: CodeSerializer,
-    loadQuestionList:  ProblemSerializer[]
+    loadQuestionList:  ProblemSerializer[],
+    loadCurrentQuestion: NestedCodeItemVO
 }
 export default rootReducer

+ 86 - 52
src/utils/index.ts

@@ -1,6 +1,6 @@
-import Api, {ExamSerializer, ReceivedData} from "@/api";
+import Api, {ExamSerializer, NestedCodeItemVO, ReceivedData} from "@/api";
 import {store} from "@/redux/store";
-import {loadQuestion, loadQuestionList, loadUser} from "@/redux/action/action";
+import {loadCurrentQuestion, loadQuestion, loadQuestionList, loadUser} from "@/redux/action/action";
 import {history} from "@@/core/history";
 import notification from "@/components/notification";
 import {IActivityMenuItemProps, IFolderTreeNodeProps} from "@dtinsight/molecule/esm/model";
@@ -90,7 +90,7 @@ export function getQuestionList(examId: number) {
     if (examId === store.getState().loadQuestion.examId) {
         return store.getState().loadQuestionList
     } else {
-        Api.getByExamId(examId).then((res: ReceivedData<ExamSerializer>) => {
+        Api.getExamTest(examId).then((res: ReceivedData<ExamSerializer>) => {
             if (res.err === 0) {
                 const exam = res.res
                 if (exam && exam.problems) {
@@ -122,6 +122,39 @@ const extToLang: { [prop: string]: string } = {
 }
 let id = 1
 
+export function submitQuestion() {
+    const examId = store.getState().loadQuestion.examId
+    if (!examId) message.error("Please select an exam")
+    else {
+        const question = store.getState().loadQuestion
+        const current = store.getState().loadCurrentQuestion
+        const questionId = current.questionId
+        if (question && question.codeList) {
+            for (let i = 0; i < question.codeList.length; i++){
+                if (question.codeList[i].questionId === current.questionId) {
+                    question.codeList[i] = current
+                    store.dispatch(loadQuestion(question))
+                }
+            }
+        }
+        api.updateOnlineCodeByExamIdAndQuestionId(examId!, questionId!, {
+            code: store.getState().loadCurrentQuestion.editable!
+        }).then(r => {
+            if (r.err === 0) {
+                const elList = window.document.querySelectorAll("div.mo-tree__treenode span.mo-tree__treenode__title")
+                elList.forEach((el) => {
+                    const span = el as HTMLElement
+                    span.style.color = ''
+                })
+                message.success("Success")
+            }
+            else {
+                message.error("Failure")
+                notification.error({key: "SubmitError", message: r.msg})
+            }
+        }).catch(r => message.error("Failure"))
+    }
+}
 function generateFileNodes(
     nodes: IFolderTreeNodeProps[],
     pathList: string[],
@@ -177,67 +210,68 @@ function generateFileNodes(
     }
 }
 
-export function submitQuestion() {
-    const examId = store.getState().loadQuestion.examId
-    if (!examId) message.error("Please select an exam")
-    else {
-        const questionId = store.getState().loadQuestion.codeList![0].questionId
-        api.updateOnlineCodeByExamIdAndQuestionId(examId!, questionId!, {
-            code: store.getState().loadQuestion.codeList![0].editable!
-        }).then(r => {
-            if (r.err === 0) {
-                const elList = window.document.querySelectorAll("div.mo-tree__treenode span.mo-tree__treenode__title")
-                elList.forEach((el) => {
-                    const span = el as HTMLElement
-                    span.style.color = ''
-                })
-                message.success("Success")
+function generateFileTree(question: NestedCodeItemVO) {
+    const editableFiles = [...Object.keys(question.editable!)]
+    const editable = editableFiles.reduce<IFolderTreeNodeProps[]>((nodes, filename) => {
+        const filePathList = filename
+            .split('/')
+            .filter((name) => name.length > 0)
+        return generateFileNodes(nodes, filePathList, filename, false, question.editable!)
+    }, [])
+    const unEditableFiles = [...Object.keys(question.uneditable!)]
+    const unEditable = unEditableFiles.reduce<IFolderTreeNodeProps[]>((nodes, filename) => {
+        const filePathList = filename
+            .split('/')
+            .filter((name) => name.length > 0)
+        return generateFileNodes(nodes, filePathList, filename, true, question.uneditable!)
+    }, [])
+    const files: IFolderTreeNodeProps = {
+        id: 0,
+        readOnly: false,
+        name: question.projectName,
+        fileType: "RootFolder",
+        location: question.projectName,
+        isLeaf: false,
+        data: "",
+        children: [...editable, ...unEditable]
+    }
+    molecule.folderTree.reset()
+    molecule.folderTree.add(files)
+    message.success('Loading is Complete')
+}
+
+export function changeQuestion(questionId: number) {
+    const question = store.getState().loadQuestion
+    const current = store.getState().loadCurrentQuestion
+    let next
+    if (question && question.codeList) {
+        for (let i = 0; i < question.codeList.length; i++){
+            if (question.codeList[i].questionId === current.questionId) {
+                question.codeList[i] = current
+                store.dispatch(loadQuestion(question))
             }
-            else {
-                message.error("Failure")
-                notification.error({key: "SubmitError", message: r.msg})
+            if (question.codeList[i].questionId === questionId) {
+                next = question.codeList[i]
             }
-        }).catch(r => message.error("Failure"))
+        }
+        generateFileTree(next? next : {})
     }
 }
 
-export function getQuestion(examId: string, questionId: string) {
+export function getQuestion(examId: string, studentId: string) {
     const hide = message.loading("Loading...", 0)
     const regPos = /^[0-9]+/;
-    if (regPos.test(examId) && regPos.test(questionId)) {
-        Api.getQuestion(examId as unknown as number, questionId as unknown as number).then(
+    if (regPos.test(examId)) {
+        Api.test(examId as unknown as number, studentId as unknown as number).then(
             response => {
                 hide()
                 if (response.err === 0) {
                     store.dispatch(loadQuestion(response.res))
-                    const question = response.res.codeList[0]
-                    const editableFiles = [...Object.keys(question.editable)]
-                    const editable = editableFiles.reduce<IFolderTreeNodeProps[]>((nodes, filename) => {
-                        const filePathList = filename
-                            .split('/')
-                            .filter((name) => name.length > 0)
-                        return generateFileNodes(nodes, filePathList, filename, false, question.editable)
-                    }, [])
-                    const unEditableFiles = [...Object.keys(question.uneditable)]
-                    const unEditable = unEditableFiles.reduce<IFolderTreeNodeProps[]>((nodes, filename) => {
-                        const filePathList = filename
-                            .split('/')
-                            .filter((name) => name.length > 0)
-                        return generateFileNodes(nodes, filePathList, filename, true, question.uneditable)
-                    }, [])
-                    const files: IFolderTreeNodeProps = {
-                        id: 0,
-                        readOnly: false,
-                        name: question.projectName,
-                        fileType: "RootFolder",
-                        location: question.projectName,
-                        isLeaf: false,
-                        data: "",
-                        children: [...editable, ...unEditable]
+                    const current = store.getState().loadCurrentQuestion
+                    if (Object.keys(current).length === 0) {
+                        store.dispatch(loadCurrentQuestion(response.res.codeList[0]))
+                        generateFileTree(response.res.codeList[0])
                     }
-                    molecule.folderTree.reset()
-                    molecule.folderTree.add(files)
-                    message.success('Loading is Complete')
                 }
                 return response;
             }).then(response => {