Deploy / deploy (build, debian, 22) (push) Canceled after 0s
- 挑战列表改成独立页面(ChallengeHome):每题一行,完成状态、分值、出题人,可按未做 / 已交筛选; 教程面板只放教程 - 教程每一节的代码各存一份(和挑战同一个按任务的 key),切回来时还在,第一次才放示例代码; 提交列表“复制到编辑器”对教程也写入该任务的代码 - 教程 / 挑战出题页合并为 TaskEditor:“提交”改为“保存”,保存后停在当前项,删除前说明会连带删除学生提交; admin 也能在列表里切换挑战是否公开(保存时本来就能设) - 用户管理:初始密码默认隐藏,封号前确认,批量新建说明用户名规则 - 整站暗色:顶栏切换跟随系统 / 亮色 / 暗色;Naive 暗色主题、markdown 和代码高亮的暗色覆盖 (styles/dark-content.css 由 GitHub 暗色样式生成)、CodeMirror One Dark 配色、md-editor 暗色; 组件里剩下的硬编码颜色全部换成配色变量 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
78 lines
2.1 KiB
Vue
78 lines
2.1 KiB
Vue
<script lang="ts" setup>
|
|
import { EditorView } from "@codemirror/view"
|
|
import { Codemirror } from "vue-codemirror"
|
|
import { css } from "@codemirror/lang-css"
|
|
import { javascript } from "@codemirror/lang-javascript"
|
|
import { html } from "@codemirror/lang-html"
|
|
import { computed } from "vue"
|
|
import { syntaxHighlighting } from "@codemirror/language"
|
|
import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark"
|
|
import { isDark } from "../../store/theme"
|
|
|
|
const styleTheme = EditorView.baseTheme({
|
|
"& .cm-scroller": {
|
|
"font-family": "var(--wp-font-mono)",
|
|
},
|
|
"&.cm-editor.cm-focused": {
|
|
outline: "none",
|
|
},
|
|
"&.cm-editor .cm-tooltip.cm-tooltip-autocomplete ul": {
|
|
"font-family": "var(--wp-font-mono)",
|
|
},
|
|
})
|
|
|
|
const bgColors: Record<string, string> = {
|
|
html: "var(--wp-html-soft)",
|
|
css: "var(--wp-css-soft)",
|
|
js: "var(--wp-js-soft)",
|
|
}
|
|
|
|
interface Props {
|
|
language?: "html" | "css" | "js"
|
|
fontSize?: number
|
|
}
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
language: "html",
|
|
fontSize: 16,
|
|
})
|
|
|
|
const code = defineModel<string>("value")
|
|
|
|
const lang = computed(() => {
|
|
if (props.language === "html") return html()
|
|
if (props.language === "css") return css()
|
|
return javascript()
|
|
})
|
|
|
|
const bgTheme = computed(() => {
|
|
const bg = bgColors[props.language] ?? "var(--wp-surface)"
|
|
return EditorView.theme(
|
|
{
|
|
"&": { backgroundColor: bg, color: "var(--wp-ink)" },
|
|
".cm-gutters": { backgroundColor: bg, color: "var(--wp-faint)", borderColor: "var(--wp-line)" },
|
|
".cm-activeLine, .cm-activeLineGutter": { backgroundColor: "rgba(127, 127, 127, 0.08)" },
|
|
".cm-cursor": { borderLeftColor: "var(--wp-ink)" },
|
|
},
|
|
{ dark: isDark.value },
|
|
)
|
|
})
|
|
|
|
// 暗色时换成 One Dark 的语法配色(默认配色是给浅色背景设计的)
|
|
const extensions = computed(() => [
|
|
styleTheme,
|
|
bgTheme.value,
|
|
...(isDark.value ? [syntaxHighlighting(oneDarkHighlightStyle)] : []),
|
|
lang.value,
|
|
])
|
|
</script>
|
|
<template>
|
|
<Codemirror
|
|
v-model="code"
|
|
indentWithTab
|
|
:extensions="extensions"
|
|
:tabSize="4"
|
|
:style="{ height: '100%', fontSize: props.fontSize + 'px' }"
|
|
/>
|
|
</template>
|