diff --git a/apps/web/src/shared/components/Header.vue b/apps/web/src/shared/components/Header.vue index 6a4dea5..d6901fe 100644 --- a/apps/web/src/shared/components/Header.vue +++ b/apps/web/src/shared/components/Header.vue @@ -40,6 +40,18 @@ const router = useRouter() const { isMobile, isDesktop } = useBreakpoints() const { learnStep } = useLearnProgress() +/** + * 课堂求助的入口收进姓名下拉里了,顶栏只留姓名按钮上的角标 —— 老师不用展开 + * 菜单也能看见有没有人举手。桌面端限定,教师端接单后要在弹框里替学生写代码。 + */ +const showHelpRequests = ref(false) +const hasHelpEntry = computed( + () => isDesktop.value && userStore.isTeacherOrAbove, +) +const pendingHelpCount = computed(() => + hasHelpEntry.value ? collabStore.pendingCount : 0, +) + const isDark = useDark() /** @@ -241,6 +253,17 @@ const menus = computed(() => [ ]) const options = computed>(() => [ + { + label: pendingHelpCount.value + ? `课堂求助(${pendingHelpCount.value})` + : "课堂求助", + key: "help", + show: hasHelpEntry.value, + icon: renderIcon("streamline-emojis:raising-hands-2"), + props: { + onClick: () => (showHelpRequests.value = true), + }, + }, { label: "我的主页", key: "home", @@ -348,15 +371,16 @@ function handleMenuSelect(key: string) { > {{ screenMode }} -
- - - - {{ userStore.user!.username }} - - + + + + + {{ userStore.user!.username }} + + + + diff --git a/apps/web/src/shared/components/HelpRequestList.vue b/apps/web/src/shared/components/HelpRequestList.vue index 7b318bf..2180110 100644 --- a/apps/web/src/shared/components/HelpRequestList.vue +++ b/apps/web/src/shared/components/HelpRequestList.vue @@ -2,18 +2,35 @@ import { Icon } from "@iconify/vue" import { useCollabStore } from "shared/store/collab" +/** 由顶栏的姓名下拉菜单打开 */ +const show = defineModel("show", { default: false }) + const collabStore = useCollabStore() -// 等待时长要每秒走一格,所以自己转一个 now +// 等待时长要每秒走一格,所以自己转一个 now。 +// 只在弹框开着时转 —— 这个组件跟着顶栏常驻,关着的时候没人看这个数。 const now = ref(Date.now()) let timer: number | null = null -onMounted(() => { - timer = window.setInterval(() => (now.value = Date.now()), 1000) -}) -onUnmounted(() => { - if (timer !== null) window.clearInterval(timer) + +function stopTimer() { + if (timer === null) return + window.clearInterval(timer) + timer = null +} + +watch(show, (opened) => { + if (!opened) { + stopTimer() + return + } + now.value = Date.now() + if (timer === null) { + timer = window.setInterval(() => (now.value = Date.now()), 1000) + } }) +onUnmounted(stopTimer) + const waited = (createdAt: number) => { const seconds = Math.max(0, Math.floor((now.value - createdAt) / 1000)) const m = Math.floor(seconds / 60) @@ -25,21 +42,19 @@ const handleAccept = (studentId: number, status: string) => { // 已被别的老师接走的不能点 if (status === "active") return collabStore.accept(studentId) + // 接单后马上要弹 CollabModal,这个列表得让位 + show.value = false }