split editor.
This commit is contained in:
@@ -2,115 +2,40 @@
|
|||||||
import { SOURCES } from "utils/constants"
|
import { SOURCES } from "utils/constants"
|
||||||
import { Problem } from "utils/types"
|
import { Problem } from "utils/types"
|
||||||
import Monaco from "~/shared/Monaco.vue"
|
import Monaco from "~/shared/Monaco.vue"
|
||||||
import Submit from "./Submit.vue"
|
|
||||||
import { code } from "oj/composables/code"
|
import { code } from "oj/composables/code"
|
||||||
import { isDesktop, isMobile } from "~/shared/composables/breakpoints"
|
import { isDesktop } from "~/shared/composables/breakpoints"
|
||||||
import { DropdownOption } from "naive-ui"
|
import Form from "./Form.vue"
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
problem: Problem
|
problem: Problem
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<Props>()
|
const props = defineProps<Props>()
|
||||||
const route = useRoute()
|
|
||||||
const router = useRouter()
|
|
||||||
|
|
||||||
code.language = props.problem.languages[0] || "C"
|
code.language = props.problem.languages[0] || "C"
|
||||||
code.value = props.problem.template[code.language] || SOURCES[code.language]
|
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) {
|
function change(value: string) {
|
||||||
code.value = value
|
code.value = value
|
||||||
}
|
}
|
||||||
|
|
||||||
function goSubmissions() {
|
const editorHeight = computed(() =>
|
||||||
const name = !!route.params.contestID ? "contest submissions" : "submissions"
|
isDesktop.value ? "calc(100vh - 150px)" : "calc(100vh - 200px)"
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<n-form inline label-placement="left">
|
<Form :problem="props.problem" />
|
||||||
<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>
|
|
||||||
<Monaco
|
<Monaco
|
||||||
class="editor"
|
class="editor"
|
||||||
:language="code.language"
|
:language="code.language"
|
||||||
:value="code.value"
|
:value="code.value"
|
||||||
@change="change"
|
@change="change"
|
||||||
height="calc(100vh - 200px)"
|
:height="editorHeight"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.language {
|
|
||||||
width: 140px;
|
|
||||||
}
|
|
||||||
.editor {
|
.editor {
|
||||||
min-height: 200px;
|
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>
|
<template>
|
||||||
<n-grid v-if="problem" x-gap="16" :cols="2">
|
<n-grid v-if="problem" x-gap="16" :cols="2">
|
||||||
<n-gi :span="isDesktop ? 1 : 2">
|
<n-gi :span="isDesktop ? 1 : 2">
|
||||||
<n-tabs default-value="content">
|
<n-scrollbar v-if="isDesktop" style="max-height: calc(100vh - 92px)">
|
||||||
<n-tab-pane name="content" tab="题目描述">
|
<n-tabs default-value="content">
|
||||||
<n-scrollbar v-if="isDesktop" style="max-height: calc(100vh - 136px)">
|
<n-tab-pane name="content" tab="题目描述">
|
||||||
<ProblemContent :problem="problem" />
|
<ProblemContent :problem="problem" />
|
||||||
</n-scrollbar>
|
</n-tab-pane>
|
||||||
<ProblemContent v-else :problem="problem" />
|
<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>
|
||||||
<n-tab-pane v-if="isMobile" name="editor" tab="代码编辑">
|
<n-tab-pane name="editor" tab="代码编辑">
|
||||||
<Editor :problem="problem" />
|
<Editor :problem="problem" />
|
||||||
</n-tab-pane>
|
</n-tab-pane>
|
||||||
<n-tab-pane name="info" tab="题目信息">
|
<n-tab-pane name="info" tab="题目信息">
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ onMounted(async () => {
|
|||||||
lineNumbersMinChars: 2,
|
lineNumbersMinChars: 2,
|
||||||
automaticLayout: true, // 自适应布局
|
automaticLayout: true, // 自适应布局
|
||||||
tabSize: 4,
|
tabSize: 4,
|
||||||
fontSize: isMobile.value ? 20 : 24, // 字体大小
|
fontSize: isMobile.value ? 20 : 22, // 字体大小
|
||||||
scrollBeyondLastLine: false,
|
scrollBeyondLastLine: false,
|
||||||
lineDecorationsWidth: 0,
|
lineDecorationsWidth: 0,
|
||||||
scrollBeyondLastColumn: 0,
|
scrollBeyondLastColumn: 0,
|
||||||
|
|||||||
Reference in New Issue
Block a user