split editor.
This commit is contained in:
@@ -2,115 +2,40 @@
|
||||
import { SOURCES } from "utils/constants"
|
||||
import { Problem } from "utils/types"
|
||||
import Monaco from "~/shared/Monaco.vue"
|
||||
import Submit from "./Submit.vue"
|
||||
import { code } from "oj/composables/code"
|
||||
import { isDesktop, isMobile } from "~/shared/composables/breakpoints"
|
||||
import { DropdownOption } from "naive-ui"
|
||||
import { isDesktop } from "~/shared/composables/breakpoints"
|
||||
import Form from "./Form.vue"
|
||||
|
||||
interface Props {
|
||||
problem: Problem
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
code.language = props.problem.languages[0] || "C"
|
||||
code.value = props.problem.template[code.language] || SOURCES[code.language]
|
||||
|
||||
watch(() => code.language, reset)
|
||||
|
||||
function reset() {
|
||||
code.value = props.problem.template[code.language] || SOURCES[code.language]
|
||||
}
|
||||
|
||||
function change(value: string) {
|
||||
code.value = value
|
||||
}
|
||||
|
||||
function goSubmissions() {
|
||||
const name = !!route.params.contestID ? "contest submissions" : "submissions"
|
||||
router.push({ name, query: { problem: props.problem._id } })
|
||||
}
|
||||
const options: DropdownOption[] = props.problem.languages.map((it) => ({
|
||||
label: () => [
|
||||
h("img", {
|
||||
src: `/${it}.svg`,
|
||||
style: {
|
||||
width: "16px",
|
||||
height: "16px",
|
||||
marginRight: "8px",
|
||||
transform: "translateY(3px)",
|
||||
},
|
||||
}),
|
||||
it,
|
||||
],
|
||||
value: it,
|
||||
}))
|
||||
|
||||
const menu: DropdownOption[] = [
|
||||
{ label: "重置", key: "reset" },
|
||||
{ label: "提交信息", key: "submissions" },
|
||||
]
|
||||
|
||||
function select(key: string) {
|
||||
switch (key) {
|
||||
case "reset":
|
||||
reset()
|
||||
break
|
||||
case "submissions":
|
||||
goSubmissions()
|
||||
break
|
||||
}
|
||||
}
|
||||
const editorHeight = computed(() =>
|
||||
isDesktop.value ? "calc(100vh - 150px)" : "calc(100vh - 200px)"
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n-form inline label-placement="left">
|
||||
<n-form-item :label="isDesktop ? '语言' : ''">
|
||||
<n-select
|
||||
class="language"
|
||||
v-model:value="code.language"
|
||||
:options="options"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item>
|
||||
<Submit />
|
||||
</n-form-item>
|
||||
<n-dropdown
|
||||
v-if="isMobile"
|
||||
trigger="click"
|
||||
:options="menu"
|
||||
@select="select"
|
||||
>
|
||||
<n-button>
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<i-ep-more-filled />
|
||||
</n-icon>
|
||||
</template>
|
||||
</n-button>
|
||||
</n-dropdown>
|
||||
<n-form-item v-if="isDesktop">
|
||||
<n-space>
|
||||
<n-button @click="reset">重置</n-button>
|
||||
<n-button @click="goSubmissions">提交信息</n-button>
|
||||
</n-space>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
<Form :problem="props.problem" />
|
||||
<Monaco
|
||||
class="editor"
|
||||
:language="code.language"
|
||||
:value="code.value"
|
||||
@change="change"
|
||||
height="calc(100vh - 200px)"
|
||||
:height="editorHeight"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.language {
|
||||
width: 140px;
|
||||
}
|
||||
.editor {
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
100
src/oj/problem/components/Form.vue
Normal file
100
src/oj/problem/components/Form.vue
Normal file
@@ -0,0 +1,100 @@
|
||||
<script setup lang="ts">
|
||||
import { DropdownOption } from "naive-ui"
|
||||
import { SOURCES } from "utils/constants"
|
||||
import { Problem } from "utils/types"
|
||||
import { code } from "oj/composables/code"
|
||||
import { isDesktop, isMobile } from "~/shared/composables/breakpoints"
|
||||
import Submit from "./Submit.vue"
|
||||
|
||||
interface Props {
|
||||
problem: Problem
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
watch(() => code.language, reset)
|
||||
|
||||
function reset() {
|
||||
code.value = props.problem.template[code.language] || SOURCES[code.language]
|
||||
}
|
||||
|
||||
function goSubmissions() {
|
||||
const name = !!route.params.contestID ? "contest submissions" : "submissions"
|
||||
router.push({ name, query: { problem: props.problem._id } })
|
||||
}
|
||||
|
||||
const menu: DropdownOption[] = [
|
||||
{ label: "重置", key: "reset" },
|
||||
{ label: "提交信息", key: "submissions" },
|
||||
]
|
||||
|
||||
const options: DropdownOption[] = props.problem.languages.map((it) => ({
|
||||
label: () => [
|
||||
h("img", {
|
||||
src: `/${it}.svg`,
|
||||
style: {
|
||||
width: "16px",
|
||||
height: "16px",
|
||||
marginRight: "8px",
|
||||
transform: "translateY(3px)",
|
||||
},
|
||||
}),
|
||||
it,
|
||||
],
|
||||
value: it,
|
||||
}))
|
||||
|
||||
function select(key: string) {
|
||||
switch (key) {
|
||||
case "reset":
|
||||
reset()
|
||||
break
|
||||
case "submissions":
|
||||
goSubmissions()
|
||||
break
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n-form inline label-placement="left">
|
||||
<n-form-item>
|
||||
<n-select
|
||||
class="language"
|
||||
v-model:value="code.language"
|
||||
:options="options"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item>
|
||||
<Submit />
|
||||
</n-form-item>
|
||||
<n-dropdown
|
||||
v-if="isMobile"
|
||||
trigger="click"
|
||||
:options="menu"
|
||||
@select="select"
|
||||
>
|
||||
<n-button>
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<i-ep-more-filled />
|
||||
</n-icon>
|
||||
</template>
|
||||
</n-button>
|
||||
</n-dropdown>
|
||||
<n-form-item v-if="isDesktop">
|
||||
<n-space>
|
||||
<n-button @click="reset">重置</n-button>
|
||||
<n-button @click="goSubmissions">提交信息</n-button>
|
||||
</n-space>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.language {
|
||||
width: 140px;
|
||||
}
|
||||
</style>
|
||||
@@ -32,14 +32,21 @@ provide("problem", readonly(problem))
|
||||
<template>
|
||||
<n-grid v-if="problem" x-gap="16" :cols="2">
|
||||
<n-gi :span="isDesktop ? 1 : 2">
|
||||
<n-scrollbar v-if="isDesktop" style="max-height: calc(100vh - 92px)">
|
||||
<n-tabs default-value="content">
|
||||
<n-tab-pane name="content" tab="题目描述">
|
||||
<n-scrollbar v-if="isDesktop" style="max-height: calc(100vh - 136px)">
|
||||
<ProblemContent :problem="problem" />
|
||||
</n-scrollbar>
|
||||
<ProblemContent v-else :problem="problem" />
|
||||
</n-tab-pane>
|
||||
<n-tab-pane v-if="isMobile" name="editor" tab="代码编辑">
|
||||
<n-tab-pane name="info" tab="题目信息">
|
||||
<ProblemInfo :problem="problem" />
|
||||
</n-tab-pane>
|
||||
</n-tabs>
|
||||
</n-scrollbar>
|
||||
<n-tabs v-else default-value="content">
|
||||
<n-tab-pane name="content" tab="题目描述">
|
||||
<ProblemContent :problem="problem" />
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="editor" tab="代码编辑">
|
||||
<Editor :problem="problem" />
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="info" tab="题目信息">
|
||||
|
||||
@@ -45,7 +45,7 @@ onMounted(async () => {
|
||||
lineNumbersMinChars: 2,
|
||||
automaticLayout: true, // 自适应布局
|
||||
tabSize: 4,
|
||||
fontSize: isMobile.value ? 20 : 24, // 字体大小
|
||||
fontSize: isMobile.value ? 20 : 22, // 字体大小
|
||||
scrollBeyondLastLine: false,
|
||||
lineDecorationsWidth: 0,
|
||||
scrollBeyondLastColumn: 0,
|
||||
|
||||
Reference in New Issue
Block a user