diff --git a/apps/web/src/oj/problem/components/CollabBar.vue b/apps/web/src/oj/problem/components/CollabBar.vue index 3330b0b..9df01fb 100644 --- a/apps/web/src/oj/problem/components/CollabBar.vue +++ b/apps/web/src/oj/problem/components/CollabBar.vue @@ -31,47 +31,85 @@ function openHisSubmissions() { diff --git a/apps/web/src/oj/problem/components/ContextBar.vue b/apps/web/src/oj/problem/components/ContextBar.vue index 424afa0..dc08969 100644 --- a/apps/web/src/oj/problem/components/ContextBar.vue +++ b/apps/web/src/oj/problem/components/ContextBar.vue @@ -7,6 +7,8 @@ import { isFlowchartPass, useFlowchartStore } from "oj/store/flowchart" import { useLessonStore } from "oj/store/lesson" import { useProblemStore } from "oj/store/problem" import { useUserStore } from "shared/store/user" +import { useBreakpoints } from "shared/composables/breakpoints" +import { useThemeVars } from "naive-ui" import type { ProblemSet, ProblemSetProblem } from "utils/types" import { useProblemPageContext } from "../composables/problemPageContext" import ProblemChips, { type ChipItem } from "./ProblemChips.vue" @@ -27,6 +29,20 @@ import ProblemChips, { type ChipItem } from "./ProblemChips.vue" const CHIPS_FIT = 5 const ctx = useProblemPageContext() +const { isMobile } = useBreakpoints() +const theme = useThemeVars() +const isDark = useDark() + +/** + * 三种入口各一种底色(设计稿「上下文条与协作状态」):课堂浅绿、题单浅蓝、比赛浅黄。 + * 字色在暗色下换成浅一档的,深绿、深蓝、深黄放在暗底上看不清 + */ +const tone = computed(() => ({ + lessonText: isDark.value ? theme.value.primaryColor : theme.value.primaryColorPressed, + setText: isDark.value ? "#8fb4ee" : "#1d4f9c", + setBar: isDark.value ? "#6f9be0" : "#2f6bc4", + contestText: isDark.value ? "#f2c97d" : "#8a5200", +})) const userStore = useUserStore() const { problem } = storeToRefs(useProblemStore()) const currentId = computed(() => problem.value?._id ?? "") @@ -85,6 +101,7 @@ const lesson = computed(() => { chips, done: list.filter((item) => item.myStatus === "accepted").length, total: list.length, + position: index + 1, previous: chips[index - 1]?.to ?? null, next: chips[index + 1]?.to ?? null, } @@ -211,115 +228,274 @@ onSolvedHere(() => { diff --git a/apps/web/src/oj/problem/components/EditorToolbar.vue b/apps/web/src/oj/problem/components/EditorToolbar.vue index 6179c03..ed7a330 100644 --- a/apps/web/src/oj/problem/components/EditorToolbar.vue +++ b/apps/web/src/oj/problem/components/EditorToolbar.vue @@ -10,7 +10,7 @@ import { useUserStore } from "shared/store/user" import storage from "utils/storage" import type { LANGUAGE } from "utils/types" import { Icon } from "@iconify/vue" -import { NFlex } from "naive-ui" +import { NFlex, useThemeVars } from "naive-ui" import SubmitCode from "./SubmitCode.vue" import { useProblemPageContext } from "../composables/problemPageContext" import { statisticsOpen, useEditorMenu } from "../composables/editorMenu" @@ -44,6 +44,7 @@ const mode = computed({ }) const { isDesktop } = useBreakpoints() +const theme = useThemeVars() /** * 「运行例子」:用题目里的例子试跑(Judge0),结果在左栏「结果」页签。顶替原来题面里 @@ -119,8 +120,8 @@ const toggleHelp = () => { * 所以次要的按钮收进「更多」、「写代码 / 画流程图」缩短一点(设计文档 5.4)。语言下拉不收: * 窄于 120px 时图标和「Python」会被挤成两行 */ -const toolbarRef = useTemplateRef<{ $el: HTMLElement }>("toolbarRef") -const { width: toolbarWidth } = useElementSize(() => toolbarRef.value?.$el) +const toolbarRef = useTemplateRef("toolbarRef") +const { width: toolbarWidth } = useElementSize(toolbarRef) const narrow = computed(() => isDesktop.value && toolbarWidth.value > 0 && toolbarWidth.value < 600) /** 「课堂统计」常驻在工具栏上:桌面、而且放得下 */ const statisticsInline = computed(() => isDesktop.value && !narrow.value) @@ -152,7 +153,8 @@ const changeLanguage = (v: LANGUAGE) => { + + diff --git a/apps/web/src/oj/problem/components/LessonNext.vue b/apps/web/src/oj/problem/components/LessonNext.vue index 0b328e0..c3a903e 100644 --- a/apps/web/src/oj/problem/components/LessonNext.vue +++ b/apps/web/src/oj/problem/components/LessonNext.vue @@ -1,4 +1,5 @@ diff --git a/apps/web/src/oj/problem/components/ProblemChips.vue b/apps/web/src/oj/problem/components/ProblemChips.vue index 8888d99..3f6f7d5 100644 --- a/apps/web/src/oj/problem/components/ProblemChips.vue +++ b/apps/web/src/oj/problem/components/ProblemChips.vue @@ -5,8 +5,9 @@ import type { RouteLocationRaw } from "vue-router" /** * 上下文条里的一排题号(课堂、比赛共用)。只放题号,题目名在鼠标停上去时给。 * - * 状态用图标区分,不只靠颜色:✓ 做完(实心绿)/ ! 做过没对(橙)/ 灰底 没做;当前题描边。 - * 一节课一般 5 道以内,一行放得下;多了(比赛、老师一次布置了一长串)就横向滚动, + * 状态用图标区分,不只靠颜色:✓ 做完(实心绿)/ 做过没对(课堂是橙色 !,比赛是红色 ✕)/ + * 灰底 没做;当前题描边,做完了的当前题实心绿再套一圈。课堂是圆角胶囊、比赛是方角 + * (设计稿「上下文条与协作状态」)。一节课一般 5 道以内,一行放得下;多了就横向滚动, * 当前题保持在视野里。 */ export interface ChipItem { @@ -19,17 +20,22 @@ export interface ChipItem { const props = defineProps<{ items: ChipItem[] current: string + variant: "lesson" | "contest" }>() const theme = useThemeVars() -/** - * 「做完」的实心绿上用什么字色。暗色主题的成功色是浅薄荷绿,白字几乎看不见 —— - * 和 Naive 自己的主按钮一样,暗色下换深色字 - */ +/** 「做完」的实心绿上用什么字色:暗色主题的成功色是浅薄荷绿,白字几乎看不见 */ const isDark = useDark() const doneText = computed(() => (isDark.value ? "rgba(0, 0, 0, 0.85)" : "#fff")) -const STATUS_TEXT = { done: "做完了", tried: "做过,还没对", none: "还没做" } as const +const STATUS_TEXT = computed( + () => + ({ + done: "做完了", + tried: props.variant === "contest" ? "交过,还没对" : "做过,还没对", + none: "还没做", + }) as const, +) const isCurrent = (item: ChipItem) => item.displayId.toLowerCase() === props.current.toLowerCase() @@ -49,7 +55,8 @@ watch(