Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
530e1a3d5d
commit
195069450f
480 files changed
+15507
-24650
No files matched your search
@@ -9,15 +9,15 @@ export interface ExplainPerson {
|
||||
</script>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Icon } from "@iconify/vue"
|
||||
import { onKeyStroke } from "@vueuse/core"
|
||||
import { useThemeVars } from "naive-ui"
|
||||
import SubmissionView from "oj/submission/components/SubmissionView.vue"
|
||||
import UserName from "shared/components/UserName.vue"
|
||||
import { useBackClose } from "shared/composables/backClose"
|
||||
import { useBreakpoints } from "shared/composables/breakpoints"
|
||||
import type { ClassBoardProblem } from "utils/types"
|
||||
import ProblemBrief from "./ProblemBrief.vue"
|
||||
import { Icon } from '@iconify/vue'
|
||||
import { onKeyStroke } from '@vueuse/core'
|
||||
import { useThemeVars } from 'naive-ui'
|
||||
import SubmissionView from 'oj/submission/components/SubmissionView.vue'
|
||||
import UserName from 'shared/components/UserName.vue'
|
||||
import { useBackClose } from 'shared/composables/backClose'
|
||||
import { useBreakpoints } from 'shared/composables/breakpoints'
|
||||
import type { ClassBoardProblem } from 'utils/types'
|
||||
import ProblemBrief from './ProblemBrief.vue'
|
||||
|
||||
/**
|
||||
* 课堂看板「讲错误」(设计稿 BdOpen):点一个红格子或错法堆里的名字打开。老师在讲台上
|
||||
@@ -34,8 +34,8 @@ const props = defineProps<{
|
||||
problem: ClassBoardProblem | null
|
||||
people: ExplainPerson[]
|
||||
}>()
|
||||
const show = defineModel<boolean>("show", { required: true })
|
||||
const index = defineModel<number>("index", { required: true })
|
||||
const show = defineModel<boolean>('show', { required: true })
|
||||
const index = defineModel<number>('index', { required: true })
|
||||
|
||||
const theme = useThemeVars()
|
||||
const { isMobile } = useBreakpoints()
|
||||
@@ -46,26 +46,24 @@ useBackClose(show, isMobile)
|
||||
* v-bind 的变量挂在组件根上,传不过去(弹层底色整个透明)
|
||||
*/
|
||||
const vars = computed(() => ({
|
||||
"--card": theme.value.cardColor,
|
||||
"--text1": theme.value.textColor1,
|
||||
"--text2": theme.value.textColor2,
|
||||
"--text3": theme.value.textColor3,
|
||||
"--divider": theme.value.dividerColor,
|
||||
"--border": theme.value.borderColor,
|
||||
"--success": theme.value.successColor,
|
||||
"--hover": theme.value.hoverColor,
|
||||
'--card': theme.value.cardColor,
|
||||
'--text1': theme.value.textColor1,
|
||||
'--text2': theme.value.textColor2,
|
||||
'--text3': theme.value.textColor3,
|
||||
'--divider': theme.value.dividerColor,
|
||||
'--border': theme.value.borderColor,
|
||||
'--success': theme.value.successColor,
|
||||
'--hover': theme.value.hoverColor,
|
||||
}))
|
||||
const current = computed(() => props.people[index.value] ?? null)
|
||||
const showProblem = useStorage("oj_explain_show_problem", false)
|
||||
const showProblem = useStorage('oj_explain_show_problem', false)
|
||||
|
||||
/** 一排人横着滑的时候,换到的人要滑进来(← → 换人、或者点开的就是排在后面的) */
|
||||
const peopleRef = ref<HTMLElement | null>(null)
|
||||
watch([index, show], async () => {
|
||||
if (!show.value) return
|
||||
await nextTick()
|
||||
peopleRef.value
|
||||
?.querySelector<HTMLElement>(".person.on")
|
||||
?.scrollIntoView({ block: "nearest", inline: "nearest" })
|
||||
peopleRef.value?.querySelector<HTMLElement>('.person.on')?.scrollIntoView({ block: 'nearest', inline: 'nearest' })
|
||||
})
|
||||
|
||||
function step(delta: -1 | 1) {
|
||||
@@ -73,45 +71,30 @@ function step(delta: -1 | 1) {
|
||||
if (next >= 0 && next < props.people.length) index.value = next
|
||||
}
|
||||
|
||||
onKeyStroke(["ArrowLeft", "ArrowRight"], (event) => {
|
||||
onKeyStroke(['ArrowLeft', 'ArrowRight'], (event) => {
|
||||
if (!show.value || props.people.length < 2) return
|
||||
if (event.altKey || event.ctrlKey || event.metaKey) return
|
||||
event.preventDefault()
|
||||
step(event.key === "ArrowLeft" ? -1 : 1)
|
||||
step(event.key === 'ArrowLeft' ? -1 : 1)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<n-modal v-model:show="show" :auto-focus="false">
|
||||
<!-- 无 preset 的 n-modal 直接子节点要是普通元素 -->
|
||||
<div
|
||||
class="sheet"
|
||||
:class="{ narrow: isMobile }"
|
||||
:style="vars"
|
||||
role="dialog"
|
||||
:aria-label="problem ? `讲 ${problem.problemDisplayId} 的错误` : '讲错误'"
|
||||
>
|
||||
<div class="sheet" :class="{ narrow: isMobile }" :style="vars" role="dialog" :aria-label="problem ? `讲 ${problem.problemDisplayId} 的错误` : '讲错误'">
|
||||
<div class="top">
|
||||
<span v-if="problem" class="problem">
|
||||
<b>{{ problem.problemDisplayId }}</b> {{ problem.title }}
|
||||
<template v-if="people.length > 1"> · 错着的</template>
|
||||
</span>
|
||||
<div ref="peopleRef" class="people">
|
||||
<button
|
||||
v-for="(person, i) in people"
|
||||
:key="person.userId"
|
||||
type="button"
|
||||
class="person"
|
||||
:class="{ on: i === index }"
|
||||
@click="index = i"
|
||||
>
|
||||
<button v-for="(person, i) in people" :key="person.userId" type="button" class="person" :class="{ on: i === index }" @click="index = i">
|
||||
<UserName :username="person.username" />
|
||||
<span class="kind">{{ person.label }}</span>
|
||||
</button>
|
||||
</div>
|
||||
<span v-if="people.length > 1 && !isMobile" class="keys"
|
||||
><kbd>←</kbd><kbd>→</kbd> 换人</span
|
||||
>
|
||||
<span v-if="people.length > 1 && !isMobile" class="keys"><kbd>←</kbd><kbd>→</kbd> 换人</span>
|
||||
<div class="spacer"></div>
|
||||
<div class="buttons">
|
||||
<n-button
|
||||
@@ -123,13 +106,7 @@ onKeyStroke(["ArrowLeft", "ArrowRight"], (event) => {
|
||||
>
|
||||
题目
|
||||
</n-button>
|
||||
<n-button
|
||||
v-if="current"
|
||||
:size="isMobile ? 'small' : 'medium'"
|
||||
tag="a"
|
||||
:href="'/submission/' + current.submissionId"
|
||||
target="_blank"
|
||||
>
|
||||
<n-button v-if="current" :size="isMobile ? 'small' : 'medium'" tag="a" :href="'/submission/' + current.submissionId" target="_blank">
|
||||
在新页面打开
|
||||
</n-button>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import type { ClassBoardStudent } from "utils/types"
|
||||
import type { ClassBoardStudent } from 'utils/types'
|
||||
|
||||
/**
|
||||
* 看板的「请假」框:勾今天不在的人。规则在看板那边(只有今天还没交过的人能算请假、
|
||||
@@ -12,7 +12,7 @@ const props = defineProps<{
|
||||
current: string[]
|
||||
}>()
|
||||
const emit = defineEmits<{ save: [usernames: string[]] }>()
|
||||
const show = defineModel<boolean>("show", { required: true })
|
||||
const show = defineModel<boolean>('show', { required: true })
|
||||
|
||||
const selected = ref<string[]>([])
|
||||
watch(show, (open) => {
|
||||
@@ -28,9 +28,9 @@ const unseen = (student: ClassBoardStudent | undefined) => !!student && !student
|
||||
/** 今天没上过线的分在前面一堆:请假的人基本在这里面,剩下的是和同桌共用电脑的 */
|
||||
const sections = computed(() =>
|
||||
[
|
||||
{ label: "今天没上线", students: props.candidates.filter(unseen) },
|
||||
{ label: '今天没上线', students: props.candidates.filter(unseen) },
|
||||
{
|
||||
label: "今天上过线",
|
||||
label: '今天上过线',
|
||||
students: props.candidates.filter((student) => !unseen(student)),
|
||||
},
|
||||
].filter((section) => section.students.length),
|
||||
@@ -41,7 +41,7 @@ function selectAll(list: ClassBoardStudent[]) {
|
||||
}
|
||||
|
||||
function save() {
|
||||
emit("save", selected.value)
|
||||
emit('save', selected.value)
|
||||
show.value = false
|
||||
}
|
||||
</script>
|
||||
@@ -50,11 +50,7 @@ function save() {
|
||||
<n-modal
|
||||
v-model:show="show"
|
||||
preset="card"
|
||||
:title="
|
||||
candidates.length
|
||||
? `今天还没交过的 ${candidates.length} 人里,谁请假了?`
|
||||
: '今天全班都交过题了'
|
||||
"
|
||||
:title="candidates.length ? `今天还没交过的 ${candidates.length} 人里,谁请假了?` : '今天全班都交过题了'"
|
||||
style="width: 640px; max-width: calc(100vw - 32px)"
|
||||
>
|
||||
<n-checkbox-group v-if="candidates.length" v-model:value="selected">
|
||||
@@ -72,22 +68,14 @@ function save() {
|
||||
</n-button>
|
||||
</div>
|
||||
<div class="leave-grid">
|
||||
<n-checkbox
|
||||
v-for="student in section.students"
|
||||
:key="student.userId"
|
||||
:value="student.username"
|
||||
:label="student.username"
|
||||
class="leave-option"
|
||||
/>
|
||||
<n-checkbox v-for="student in section.students" :key="student.userId" :value="student.username" :label="student.username" class="leave-option" />
|
||||
</div>
|
||||
</div>
|
||||
</n-checkbox-group>
|
||||
<n-text v-else depth="3">请假的人一定是没交过题的,现在没有人可以标。</n-text>
|
||||
<template #footer>
|
||||
<n-flex align="center" :wrap="false">
|
||||
<n-text depth="3" class="meta" style="flex-grow: 1">
|
||||
已选 {{ selected.length }} 人 · 只记在这台电脑上,今天有效
|
||||
</n-text>
|
||||
<n-text depth="3" class="meta" style="flex-grow: 1"> 已选 {{ selected.length }} 人 · 只记在这台电脑上,今天有效 </n-text>
|
||||
<n-button :disabled="!selected.length" @click="selected = []">全部取消</n-button>
|
||||
<n-button @click="show = false">取消</n-button>
|
||||
<n-button type="primary" @click="save">确定</n-button>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import type { LessonLanguage } from "@oj2/contract"
|
||||
import { setClassLesson } from "oj/api"
|
||||
import { errorMessage } from "utils/api"
|
||||
import { LANGUAGE_SHOW_VALUE } from "utils/constants"
|
||||
import type { ClassBoard } from "utils/types"
|
||||
import type { LessonLanguage } from '@oj2/contract'
|
||||
import { setClassLesson } from 'oj/api'
|
||||
import { errorMessage } from 'utils/api'
|
||||
import { LANGUAGE_SHOW_VALUE } from 'utils/constants'
|
||||
import type { ClassBoard } from 'utils/types'
|
||||
|
||||
/**
|
||||
* 看板上布置「这节课的题」:题号是上课时当场填的。两种样子 ——
|
||||
@@ -13,7 +13,7 @@ import type { ClassBoard } from "utils/types"
|
||||
const props = defineProps<{
|
||||
board: ClassBoard
|
||||
className: string
|
||||
variant: "inline" | "start"
|
||||
variant: 'inline' | 'start'
|
||||
}>()
|
||||
const emit = defineEmits<{ saved: []; cancel: [] }>()
|
||||
const message = useMessage()
|
||||
@@ -22,27 +22,24 @@ const message = useMessage()
|
||||
* 这份作业用什么语言做,跟着这一次布置走(用户定的:不是给班级定死的设置)。默认是这个班
|
||||
* 上一次布置时选的;选了之后看板和学生那边的「做完」都只认这个语言交对的
|
||||
*/
|
||||
const lessonLanguage = ref<LessonLanguage>("Python")
|
||||
const LESSON_LANGUAGES: LessonLanguage[] = ["Python", "C", "C++", "SQL"]
|
||||
const lessonLanguage = ref<LessonLanguage>('Python')
|
||||
const LESSON_LANGUAGES: LessonLanguage[] = ['Python', 'C', 'C++', 'SQL']
|
||||
const languageOptions = LESSON_LANGUAGES.map((value) => ({
|
||||
label: LANGUAGE_SHOW_VALUE[value],
|
||||
value,
|
||||
}))
|
||||
const lessonInput = ref("")
|
||||
const lessonInput = ref('')
|
||||
const saving = ref(false)
|
||||
|
||||
function resetLessonInput() {
|
||||
lessonInput.value =
|
||||
props.board.source === "teacher"
|
||||
? props.board.problems.map((problem) => problem.problemDisplayId).join(" ")
|
||||
: ""
|
||||
lessonLanguage.value = props.board.language ?? props.board.lastLanguage ?? "Python"
|
||||
lessonInput.value = props.board.source === 'teacher' ? props.board.problems.map((problem) => problem.problemDisplayId).join(' ') : ''
|
||||
lessonLanguage.value = props.board.language ?? props.board.lastLanguage ?? 'Python'
|
||||
}
|
||||
|
||||
resetLessonInput()
|
||||
// 推断出来的题也带进框里,老师多半只是确认一下
|
||||
if (props.variant === "inline" && !lessonInput.value && props.board.problems.length) {
|
||||
lessonInput.value = props.board.problems.map((problem) => problem.problemDisplayId).join(" ")
|
||||
if (props.variant === 'inline' && !lessonInput.value && props.board.problems.length) {
|
||||
lessonInput.value = props.board.problems.map((problem) => problem.problemDisplayId).join(' ')
|
||||
}
|
||||
// 换了班要把输入框换成那个班今天布置的题、布置时选的语言(15 秒一次的刷新不动它们)。
|
||||
// 必须写成两个来源:一个 getter 返回数组的话,每次刷新整个 board 换新,数组也是新的,
|
||||
@@ -54,8 +51,8 @@ async function saveLesson() {
|
||||
saving.value = true
|
||||
try {
|
||||
await setClassLesson(props.className, ids, ids.length ? lessonLanguage.value : null)
|
||||
message.success(ids.length ? "已布置,学生首页会显示这几道题" : "已清掉")
|
||||
emit("saved")
|
||||
message.success(ids.length ? '已布置,学生首页会显示这几道题' : '已清掉')
|
||||
emit('saved')
|
||||
} catch (error) {
|
||||
message.error(errorMessage(error))
|
||||
} finally {
|
||||
@@ -66,37 +63,14 @@ async function saveLesson() {
|
||||
|
||||
<template>
|
||||
<div v-if="variant === 'inline'">
|
||||
<n-select
|
||||
v-model:value="lessonLanguage"
|
||||
:options="languageOptions"
|
||||
aria-label="用什么语言做"
|
||||
class="lang-select"
|
||||
/>
|
||||
<n-input
|
||||
v-model:value="lessonInput"
|
||||
placeholder="这节课的题号,用空格隔开"
|
||||
clearable
|
||||
autofocus
|
||||
@keyup.enter="saveLesson"
|
||||
/>
|
||||
<n-select v-model:value="lessonLanguage" :options="languageOptions" aria-label="用什么语言做" class="lang-select" />
|
||||
<n-input v-model:value="lessonInput" placeholder="这节课的题号,用空格隔开" clearable autofocus @keyup.enter="saveLesson" />
|
||||
<n-button type="primary" :loading="saving" @click="saveLesson">布置</n-button>
|
||||
<n-button @click="emit('cancel')">取消</n-button>
|
||||
</div>
|
||||
<div v-else>
|
||||
<n-select
|
||||
v-model:value="lessonLanguage"
|
||||
:options="languageOptions"
|
||||
aria-label="用什么语言做"
|
||||
size="large"
|
||||
class="lang-select"
|
||||
/>
|
||||
<n-input
|
||||
v-model:value="lessonInput"
|
||||
size="large"
|
||||
placeholder="输入题号,用空格隔开"
|
||||
class="start-input"
|
||||
@keyup.enter="saveLesson"
|
||||
/>
|
||||
<n-select v-model:value="lessonLanguage" :options="languageOptions" aria-label="用什么语言做" size="large" class="lang-select" />
|
||||
<n-input v-model:value="lessonInput" size="large" placeholder="输入题号,用空格隔开" class="start-input" @keyup.enter="saveLesson" />
|
||||
<n-button type="primary" size="large" :loading="saving" @click="saveLesson">布置</n-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { isSqlProblem } from "@oj2/contract"
|
||||
import { getProblem } from "oj/api"
|
||||
import { errorMessage } from "utils/api"
|
||||
import type { ProblemDetail } from "utils/types"
|
||||
import { isSqlProblem } from '@oj2/contract'
|
||||
import { getProblem } from 'oj/api'
|
||||
import { errorMessage } from 'utils/api'
|
||||
import type { ProblemDetail } from 'utils/types'
|
||||
|
||||
// Markdown 连着整套代码高亮(两百多 KB),这里要等点开 / AI 写完才用得上,别让它拖慢页面
|
||||
const Markdown = defineAsyncComponent(() => import("shared/components/Markdown.vue"))
|
||||
const Markdown = defineAsyncComponent(() => import('shared/components/Markdown.vue'))
|
||||
|
||||
/**
|
||||
* 「讲错误」弹层左边的题目(用户要的:演示学生的错误时题目和代码要并排)。
|
||||
@@ -14,14 +14,14 @@ const Markdown = defineAsyncComponent(() => import("shared/components/Markdown.v
|
||||
const props = defineProps<{ displayId: string }>()
|
||||
|
||||
const problem = ref<ProblemDetail | null>(null)
|
||||
const failed = ref("")
|
||||
const failed = ref('')
|
||||
|
||||
// 同一道题 ← → 换人不重拉:弹层开着时一直是这道题
|
||||
const cache = new Map<string, ProblemDetail>()
|
||||
watch(
|
||||
() => props.displayId,
|
||||
async (id) => {
|
||||
failed.value = ""
|
||||
failed.value = ''
|
||||
const hit = cache.get(id)
|
||||
if (hit) {
|
||||
problem.value = hit
|
||||
@@ -29,7 +29,7 @@ watch(
|
||||
}
|
||||
problem.value = null
|
||||
try {
|
||||
const data = await getProblem(id, "")
|
||||
const data = await getProblem(id, '')
|
||||
cache.set(id, data)
|
||||
if (props.displayId === id) problem.value = data
|
||||
} catch (error) {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { Icon } from "@iconify/vue"
|
||||
import { useThemeVars } from "naive-ui"
|
||||
import { useTone } from "shared/composables/tone"
|
||||
import UserName from "shared/components/UserName.vue"
|
||||
import { attemptTone, cachedSubmission } from "oj/statistics/attempts"
|
||||
import { JUDGE_STATUS, LANGUAGE_FORMAT_VALUE } from "utils/constants"
|
||||
import { parseTime } from "utils/functions"
|
||||
import type { ClassBoardCell, ClassBoardProblem, Submission } from "utils/types"
|
||||
import { Icon } from '@iconify/vue'
|
||||
import { useThemeVars } from 'naive-ui'
|
||||
import { useTone } from 'shared/composables/tone'
|
||||
import UserName from 'shared/components/UserName.vue'
|
||||
import { attemptTone, cachedSubmission } from 'oj/statistics/attempts'
|
||||
import { JUDGE_STATUS, LANGUAGE_FORMAT_VALUE } from 'utils/constants'
|
||||
import { parseTime } from 'utils/functions'
|
||||
import type { ClassBoardCell, ClassBoardProblem, Submission } from 'utils/types'
|
||||
|
||||
/**
|
||||
* 点开一个做对了的格子:他这道题今天交的每一次,一格一次、从早到晚,下面是停着的那一次的代码
|
||||
@@ -28,30 +28,26 @@ defineEmits<{ close: [] }>()
|
||||
const tone = useTone()
|
||||
const theme = useThemeVars()
|
||||
|
||||
const picked = ref(
|
||||
props.cell.acceptedTry
|
||||
? Math.max(props.cell.acceptedTry - 2, 0)
|
||||
: Math.max(props.cell.trail.length - 1, 0),
|
||||
)
|
||||
const picked = ref(props.cell.acceptedTry ? Math.max(props.cell.acceptedTry - 2, 0) : Math.max(props.cell.trail.length - 1, 0))
|
||||
const item = computed(() => props.cell.trail[picked.value] ?? props.cell.trail.at(-1))
|
||||
|
||||
const code = reactive<Record<string, Submission | "loading" | "failed">>({})
|
||||
const code = reactive<Record<string, Submission | 'loading' | 'failed'>>({})
|
||||
watch(
|
||||
() => item.value?.id,
|
||||
async (id) => {
|
||||
if (!id || (code[id] && code[id] !== "failed")) return
|
||||
code[id] = "loading"
|
||||
if (!id || (code[id] && code[id] !== 'failed')) return
|
||||
code[id] = 'loading'
|
||||
try {
|
||||
code[id] = await cachedSubmission(id)
|
||||
} catch {
|
||||
code[id] = "failed"
|
||||
code[id] = 'failed'
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
const shown = computed(() => {
|
||||
const value = item.value && code[item.value.id]
|
||||
return typeof value === "object" ? value : null
|
||||
return typeof value === 'object' ? value : null
|
||||
})
|
||||
|
||||
const squares = computed(() =>
|
||||
@@ -98,17 +94,9 @@ const squares = computed(() =>
|
||||
<b :style="{ color: tone(attemptTone(item.result)).color }">
|
||||
{{ JUDGE_STATUS[item.result]?.name }}
|
||||
</b>
|
||||
<span class="muted"
|
||||
>{{ parseTime(item.createTime, "HH:mm") }} · 第 {{ picked + 1 }} 次</span
|
||||
>
|
||||
<span class="muted">{{ parseTime(item.createTime, 'HH:mm') }} · 第 {{ picked + 1 }} 次</span>
|
||||
</div>
|
||||
<n-code
|
||||
v-if="shown"
|
||||
class="code-body"
|
||||
:code="shown.code"
|
||||
:language="LANGUAGE_FORMAT_VALUE[shown.language]"
|
||||
show-line-numbers
|
||||
/>
|
||||
<n-code v-if="shown" class="code-body" :code="shown.code" :language="LANGUAGE_FORMAT_VALUE[shown.language]" show-line-numbers />
|
||||
<span v-else-if="code[item.id] === 'failed'" class="muted">代码没拉下来,点下面打开看</span>
|
||||
<span v-else class="muted">代码加载中…</span>
|
||||
</div>
|
||||
@@ -177,14 +165,14 @@ const squares = computed(() =>
|
||||
|
||||
.square.on {
|
||||
box-shadow:
|
||||
0 0 0 2px v-bind("theme.cardColor"),
|
||||
0 0 0 4px v-bind("theme.textColor1");
|
||||
0 0 0 2px v-bind('theme.cardColor'),
|
||||
0 0 0 4px v-bind('theme.textColor1');
|
||||
}
|
||||
|
||||
.summary {
|
||||
white-space: nowrap;
|
||||
font-variant-numeric: tabular-nums;
|
||||
color: v-bind("theme.textColor2");
|
||||
color: v-bind('theme.textColor2');
|
||||
}
|
||||
|
||||
.code {
|
||||
@@ -193,7 +181,7 @@ const squares = computed(() =>
|
||||
gap: 6px;
|
||||
padding: 10px 12px;
|
||||
border-radius: 6px;
|
||||
background: v-bind("theme.actionColor");
|
||||
background: v-bind('theme.actionColor');
|
||||
}
|
||||
|
||||
.code-head {
|
||||
@@ -214,7 +202,7 @@ const squares = computed(() =>
|
||||
}
|
||||
|
||||
.links a {
|
||||
color: v-bind("theme.primaryColor");
|
||||
color: v-bind('theme.primaryColor');
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@@ -223,6 +211,6 @@ const squares = computed(() =>
|
||||
}
|
||||
|
||||
.muted {
|
||||
color: v-bind("theme.textColor3");
|
||||
color: v-bind('theme.textColor3');
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user