fix submission.

This commit is contained in:
2023-04-07 11:33:15 +08:00
parent 0862b0ff91
commit 9c3038245d
10 changed files with 406 additions and 27 deletions

View File

@@ -430,7 +430,7 @@ watch([fromExistingTags, newTags], (tags) => {
:name="lang"
>
<CodeEditor
v-model:value="template[lang]"
v-model="template[lang]"
:language="lang"
:font-size="16"
height="200px"

View File

@@ -57,7 +57,7 @@ function next() {
</n-scrollbar>
</n-gi>
<n-gi :span="14">
<CodeEditor v-model:value="code" />
<CodeEditor v-model="code" />
</n-gi>
</n-grid>
<div v-else>
@@ -72,7 +72,7 @@ function next() {
</n-button>
</n-space>
</n-scrollbar>
<CodeEditor v-model:value="code" height="calc(50vh - 42px)" />
<CodeEditor v-model="code" height="calc(50vh - 42px)" />
</div>
</template>

View File

@@ -24,7 +24,7 @@ const editorHeight = computed(() =>
<template>
<Form :problem="props.problem" />
<CodeEditor
v-model:value="code.value"
v-model="code.value"
:language="code.language"
:height="editorHeight"
/>

View File

@@ -63,6 +63,22 @@ async function test(sample: Sample, index: number) {
return sample
}
})
const id = setTimeout(() => {
clearTimeout(id)
samples.value = samples.value.map((sample) => {
if (sample.id === index) {
return {
...sample,
msg: res.output,
status: "not_test",
loading: false,
}
} else {
return sample
}
})
}, 2000)
}
function label(status: ProblemStatus, loading: boolean) {
@@ -108,19 +124,14 @@ function type(status: ProblemStatus) {
<div v-for="(sample, index) of samples" :key="index">
<n-space align="center">
<p class="title testcaseTitle" :style="style">测试用例 {{ index + 1 }}</p>
<n-tooltip trigger="hover">
<template #trigger>
<n-button
size="small"
:type="type(sample.status)"
:disabled="disabled"
@click="test(sample, index)"
>
{{ label(sample.status, sample.loading) }}
</n-button>
</template>
点击测试
</n-tooltip>
<n-button
size="small"
:type="type(sample.status)"
:disabled="disabled"
@click="test(sample, index)"
>
{{ label(sample.status, sample.loading) }}
</n-button>
</n-space>
<n-descriptions
bordered
@@ -145,7 +156,7 @@ function type(status: ProblemStatus) {
</template>
<div class="testcase">{{ sample.output }}</div>
</n-descriptions-item>
<n-descriptions-item label="运行结果" v-if="sample.status === 'failed'">
<n-descriptions-item label="运行结果" v-if="sample.msg">
<div class="testcase">{{ sample.msg }}</div>
</n-descriptions-item>
</n-descriptions>

View File

@@ -13,9 +13,9 @@ import { Submission } from "utils/types"
import { adminRejudge, getSubmissions } from "oj/api"
import { isDesktop } from "~/shared/composables/breakpoints"
import { useUserStore } from "~/shared/store/user"
import { useConfigStore } from "~/shared/store/config"
interface Query {
problem: string
username: string
result: string
limit: number
@@ -26,12 +26,12 @@ interface Query {
const route = useRoute()
const router = useRouter()
const userStore = useUserStore()
const configStore = useConfigStore()
const message = useMessage()
const submissions = ref([])
const total = ref(0)
const query = reactive<Query>({
problem: <string>route.query.problem ?? "",
result: <string>route.query.result ?? "",
page: parseInt(<string>route.query.page) || 1,
limit: parseInt(<string>route.query.limit) || 10,
@@ -48,6 +48,7 @@ const options: SelectOption[] = [
]
async function listSubmissions() {
query.problem = <string>route.query.problem ?? ""
query.result = <string>route.query.result ?? ""
query.page = parseInt(<string>route.query.page) || 1
query.limit = parseInt(<string>route.query.limit) || 10

View File

@@ -4,8 +4,11 @@ import { cpp } from "@codemirror/lang-cpp"
import { python } from "@codemirror/lang-python"
import { java } from "@codemirror/lang-java"
import { javascript } from "@codemirror/lang-javascript"
import { LANGUAGE } from "~/utils/types"
import { EditorView } from "@codemirror/view"
import { oneDark } from "./themes/oneDark"
import { smoothy } from "./themes/smoothy"
import { LANGUAGE } from "~/utils/types"
import { isDark } from "./composables/dark"
const styleTheme = EditorView.baseTheme({
"&.cm-editor.cm-focused": {
@@ -14,7 +17,7 @@ const styleTheme = EditorView.baseTheme({
})
interface Props {
value: string
modelValue: string
language?: LANGUAGE
fontSize?: number
height?: string
@@ -26,8 +29,14 @@ const props = withDefaults(defineProps<Props>(), {
height: "100%",
})
const code = ref(props.value)
const emit = defineEmits(["update:value"])
const code = ref(props.modelValue)
watch(
() => props.modelValue,
(v) => {
code.value = v
}
)
const emit = defineEmits(["update:modelValue"])
const lang = computed(() => {
if (props.language === "C" || props.language === "C++") return cpp()
@@ -37,13 +46,13 @@ const lang = computed(() => {
})
function onChange(v: string) {
emit("update:value", v)
emit("update:modelValue", v)
}
</script>
<template>
<Codemirror
v-model="code"
:extensions="[styleTheme, lang]"
:extensions="[styleTheme, lang, isDark ? oneDark : smoothy]"
indentWithTab
:tabSize="4"
@change="onChange"

View File

@@ -0,0 +1,107 @@
import { EditorView } from "@codemirror/view"
import { Extension } from "@codemirror/state"
import {
HighlightStyle,
TagStyle,
syntaxHighlighting,
} from "@codemirror/language"
interface Options {
/**
* Theme variant. Determines which styles CodeMirror will apply by default.
*/
variant: Variant
/**
* Settings to customize the look of the editor, like background, gutter, selection and others.
*/
settings: Settings
/**
* Syntax highlighting styles.
*/
styles: TagStyle[]
}
type Variant = "light" | "dark"
interface Settings {
/**
* Editor background.
*/
background: string
/**
* Default text color.
*/
foreground: string
/**
* Caret color.
*/
caret: string
/**
* Selection background.
*/
selection: string
/**
* Background of highlighted lines.
*/
lineHighlight: string
/**
* Gutter background.
*/
gutterBackground: string
/**
* Text color inside gutter.
*/
gutterForeground: string
}
export const createTheme = ({
variant,
settings,
styles,
}: Options): Extension => {
const theme = EditorView.theme(
{
// eslint-disable-next-line @typescript-eslint/naming-convention
"&": {
backgroundColor: settings.background,
color: settings.foreground,
},
".cm-content": {
caretColor: settings.caret,
},
".cm-cursor, .cm-dropCursor": {
borderLeftColor: settings.caret,
},
"&.cm-focused .cm-selectionBackgroundm .cm-selectionBackground, .cm-content ::selection":
{
backgroundColor: settings.selection,
},
".cm-activeLine": {
backgroundColor: settings.lineHighlight,
},
".cm-gutters": {
backgroundColor: settings.gutterBackground,
color: settings.gutterForeground,
},
".cm-activeLineGutter": {
backgroundColor: settings.lineHighlight,
},
},
{
dark: variant === "dark",
}
)
const highlightStyle = HighlightStyle.define(styles)
const extension = [theme, syntaxHighlighting(highlightStyle)]
return extension
}

View File

@@ -0,0 +1,169 @@
import { EditorView } from "@codemirror/view"
import { Extension } from "@codemirror/state"
import { HighlightStyle, syntaxHighlighting } from "@codemirror/language"
import { tags as t } from "@lezer/highlight"
// Using https://github.com/one-dark/vscode-one-dark-theme/ as reference for the colors
const chalky = "#e5c07b",
coral = "#e06c75",
cyan = "#56b6c2",
invalid = "#ffffff",
ivory = "#abb2bf",
stone = "#7d8799", // Brightened compared to original to increase contrast
malibu = "#61afef",
sage = "#98c379",
whiskey = "#d19a66",
violet = "#c678dd",
darkBackground = "#26262a",
highlightBackground = "#2c313a",
background = "#101014", // naive-ui
tooltipBackground = "#353a42",
selection = "#3E4451",
cursor = "#528bff"
/// The colors used in the theme, as CSS color strings.
const color = {
chalky,
coral,
cyan,
invalid,
ivory,
stone,
malibu,
sage,
whiskey,
violet,
darkBackground,
highlightBackground,
background,
tooltipBackground,
selection,
cursor,
}
/// The editor theme styles for One Dark.
const oneDarkTheme = EditorView.theme(
{
"&": {
color: ivory,
backgroundColor: background,
},
".cm-content": {
caretColor: cursor,
},
".cm-cursor, .cm-dropCursor": { borderLeftColor: cursor },
"&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection":
{ backgroundColor: selection },
".cm-panels": { backgroundColor: darkBackground, color: ivory },
".cm-panels.cm-panels-top": { borderBottom: "2px solid black" },
".cm-panels.cm-panels-bottom": { borderTop: "2px solid black" },
".cm-searchMatch": {
backgroundColor: "#72a1ff59",
outline: "1px solid #457dff",
},
".cm-searchMatch.cm-searchMatch-selected": {
backgroundColor: "#6199ff2f",
},
".cm-activeLine": { backgroundColor: "#6699ff0b" },
".cm-selectionMatch": { backgroundColor: "#aafe661a" },
"&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket": {
backgroundColor: "#bad0f847",
},
".cm-gutters": {
backgroundColor: background,
color: stone,
border: "none",
},
".cm-activeLineGutter": {
backgroundColor: highlightBackground,
},
".cm-foldPlaceholder": {
backgroundColor: "transparent",
border: "none",
color: "#ddd",
},
".cm-tooltip": {
border: "none",
backgroundColor: tooltipBackground,
},
".cm-tooltip .cm-tooltip-arrow:before": {
borderTopColor: "transparent",
borderBottomColor: "transparent",
},
".cm-tooltip .cm-tooltip-arrow:after": {
borderTopColor: tooltipBackground,
borderBottomColor: tooltipBackground,
},
".cm-tooltip-autocomplete": {
"& > ul > li[aria-selected]": {
backgroundColor: highlightBackground,
color: ivory,
},
},
},
{ dark: true }
)
/// The highlighting style for code in the One Dark theme.
const oneDarkHighlightStyle = HighlightStyle.define([
{ tag: t.keyword, color: violet },
{
tag: [t.name, t.deleted, t.character, t.propertyName, t.macroName],
color: coral,
},
{ tag: [t.function(t.variableName), t.labelName], color: malibu },
{ tag: [t.color, t.constant(t.name), t.standard(t.name)], color: whiskey },
{ tag: [t.definition(t.name), t.separator], color: ivory },
{
tag: [
t.typeName,
t.className,
t.number,
t.changed,
t.annotation,
t.modifier,
t.self,
t.namespace,
],
color: chalky,
},
{
tag: [
t.operator,
t.operatorKeyword,
t.url,
t.escape,
t.regexp,
t.link,
t.special(t.string),
],
color: cyan,
},
{ tag: [t.meta, t.comment], color: stone },
{ tag: t.strong, fontWeight: "bold" },
{ tag: t.emphasis, fontStyle: "italic" },
{ tag: t.strikethrough, textDecoration: "line-through" },
{ tag: t.link, color: stone, textDecoration: "underline" },
{ tag: t.heading, fontWeight: "bold", color: coral },
{ tag: [t.atom, t.bool, t.special(t.variableName)], color: whiskey },
{ tag: [t.processingInstruction, t.string, t.inserted], color: sage },
{ tag: t.invalid, color: invalid },
])
/// Extension to enable the One Dark theme (both the editor theme and
/// the highlight style).
export const oneDark: Extension = [
oneDarkTheme,
syntaxHighlighting(oneDarkHighlightStyle),
]

View File

@@ -0,0 +1,82 @@
import { tags as t } from "@lezer/highlight"
import { createTheme } from "./createTheme"
// Author: Kenneth Reitz
export const smoothy = createTheme({
variant: "light",
settings: {
background: "#FFFFFF",
foreground: "#000000",
caret: "#000000",
selection: "#FFFD0054",
gutterBackground: "#FFFFFF",
gutterForeground: "#00000070",
lineHighlight: "#00000008",
},
styles: [
{
tag: t.comment,
color: "#CFCFCF",
},
{
tag: [t.number, t.bool, t.null],
color: "#E66C29",
},
{
tag: [
t.className,
t.definition(t.propertyName),
t.function(t.variableName),
t.labelName,
t.definition(t.typeName),
],
color: "#2EB43B",
},
{
tag: t.keyword,
color: "#D8B229",
},
{
tag: t.operator,
color: "#4EA44E",
fontWeight: "bold",
},
{
tag: [t.definitionKeyword, t.modifier],
color: "#925A47",
},
{
tag: t.string,
color: "#704D3D",
},
{
tag: t.typeName,
color: "#2F8996",
},
{
tag: [t.variableName, t.propertyName],
color: "#77ACB0",
},
{
tag: t.self,
color: "#77ACB0",
fontWeight: "bold",
},
{
tag: t.regexp,
color: "#E3965E",
},
{
tag: [t.tagName, t.angleBracket],
color: "#BAA827",
},
{
tag: t.attributeName,
color: "#B06520",
},
{
tag: t.derefOperator,
color: "#000",
},
],
})

View File

@@ -26,7 +26,7 @@ export default defineConfig({
chart: ["vue-chartjs", "chart.js"],
editor: ["@wangeditor/editor"],
codemirror: [
"vue-codemirror6",
"vue-codemirror",
"codemirror",
"@codemirror/autocomplete",
"@codemirror/commands",