feat(点评): 点评轮盘换成一排大按钮,选之前不显示人数,选完看大家怎么选、直接去下一题
- 七个选项不变,排成 4 + 3 的大按钮(表情 + 15px 的字)。原来的轮盘要把鼠标移到扇区上 才看得清,每块的字只有 12px 左右;还用了 Chrome 111 才有的 color-mix(),机房 105 那档 渲染不出扇区底色 - 选之前不显示「N 人选择」,免得跟风;选完换成横条图,标出自己选的那一项 - 防误触:弹出后 600ms 内点不了,强制弹窗里不响应 Enter / 空格,也不预选任何一项 - 选完弹窗不马上关,下面只有一个按钮、焦点就在上面:这节课的「下一题」,或者刚才被拦下 的换题「继续」,都没有就是「好的」 - 标题从「恭喜你成功提交」改成「做对了!」:交上去不等于做对 - 提交失败留在弹窗里提示「没记上,再点一次」;没做对的人在抽屉里只看到一句说明 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
116b0a2c95
commit
c64b0a402b
5 files changed
+304
-550
No files matched your search
@@ -5,7 +5,7 @@ import { getReaction } from "oj/api"
|
||||
import { useProblemStore } from "oj/store/problem"
|
||||
import { useSubmissionStore } from "oj/store/submission"
|
||||
import { useFireworks } from "oj/problem/composables/useFireworks"
|
||||
import { useBreakpoints } from "shared/composables/breakpoints"
|
||||
import { useLessonStore } from "oj/store/lesson"
|
||||
import { SubmissionStatus } from "utils/constants"
|
||||
import { useProblemPageContext } from "../composables/problemPageContext"
|
||||
|
||||
@@ -28,10 +28,9 @@ const { submission } = storeToRefs(submissionStore)
|
||||
const router = useRouter()
|
||||
const ctx = useProblemPageContext()
|
||||
|
||||
const { isDesktop } = useBreakpoints()
|
||||
const { celebrate } = useFireworks()
|
||||
|
||||
// ==================== AC 后弹出点评轮盘 ====================
|
||||
// ==================== AC 后弹出点评 ====================
|
||||
// 只对已经能评价、且还没评过的人弹:后端要求先有 AC 才收评价,这里刚 AC 完正好;
|
||||
// mine 非 null 说明早就评过了,别再打扰。
|
||||
//
|
||||
@@ -50,6 +49,7 @@ async function openReview() {
|
||||
try {
|
||||
const res = await getReaction(problem.value!.id)
|
||||
if (res.mine === null) {
|
||||
reviewed.value = false
|
||||
commentPanel.value = true
|
||||
return
|
||||
}
|
||||
@@ -76,6 +76,46 @@ function closeCommentPanel() {
|
||||
settleReview()
|
||||
}
|
||||
|
||||
/**
|
||||
* 评完不马上关:弹窗里换成大家怎么选的,下面只有一个按钮,焦点落在它上面。
|
||||
* 按钮去哪:刚才点「下一题」之类被拦下的,就接着去那里;否则是这节课的下一题
|
||||
* (和结果页签里 LessonNext 同一个算法);都没有就是「好的」,关掉回到结果页签。
|
||||
*/
|
||||
const reviewed = ref(false)
|
||||
const continueButton = useTemplateRef<{ $el: HTMLElement }>("continueButton")
|
||||
const lessonStore = useLessonStore()
|
||||
|
||||
// navigationAfterReview 是普通变量(守卫里改,不需要触发渲染),按钮文案要一个响应式的影子
|
||||
const navigationAfterReviewShown = ref(false)
|
||||
|
||||
/** 题目名中位 7 字、最长 33 字,按钮里放不下那么长的 */
|
||||
const shortTitle = (title: string) => (title.length > 14 ? `${title.slice(0, 13)}…` : title)
|
||||
|
||||
const continueAction = computed(() => {
|
||||
if (navigationAfterReviewShown.value) return { label: "继续", target: null }
|
||||
const lesson = problem.value ? lessonStore.nextAfter(problem.value._id) : null
|
||||
const next = ctx.value.lessonNext ? lesson?.next : null
|
||||
if (next)
|
||||
return {
|
||||
label: `下一题:${next.problemDisplayId} ${shortTitle(next.title)}`,
|
||||
target: `/problem/${next.problemDisplayId}`,
|
||||
}
|
||||
return { label: "好的", target: null }
|
||||
})
|
||||
|
||||
async function onReviewed() {
|
||||
reviewed.value = true
|
||||
navigationAfterReviewShown.value = navigationAfterReview !== null
|
||||
await nextTick()
|
||||
continueButton.value?.$el.focus()
|
||||
}
|
||||
|
||||
function continueAfterReview() {
|
||||
const target = continueAction.value.target
|
||||
if (target && !navigationAfterReview) navigationAfterReview = target
|
||||
closeCommentPanel()
|
||||
}
|
||||
|
||||
const { start: showCommentPanelDelayed, stop: cancelCommentPanel } = useTimeoutFn(
|
||||
openReview,
|
||||
1500,
|
||||
@@ -188,15 +228,25 @@ watch(
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- 原来的标题是「恭喜你成功提交」:交上去不等于做对。auto-focus 关掉:不预选任何一项 -->
|
||||
<n-modal
|
||||
v-model:show="commentPanel"
|
||||
preset="card"
|
||||
title="恭喜你成功提交,说说你对这道题的感受吧"
|
||||
:title="reviewed ? '大家是这样觉得的' : '做对了!说说你对这道题的感受吧'"
|
||||
:mask-closable="false"
|
||||
:closable="false"
|
||||
:close-on-esc="false"
|
||||
:style="{ maxWidth: isDesktop && '50vw', maxHeight: '80vh' }"
|
||||
v-model:show="commentPanel"
|
||||
:auto-focus="false"
|
||||
style="width: min(600px, calc(100vw - 32px))"
|
||||
>
|
||||
<ProblemReaction @submitted="closeCommentPanel" />
|
||||
<ProblemReaction guard @submitted="onReviewed">
|
||||
<template #after>
|
||||
<n-flex justify="end">
|
||||
<n-button ref="continueButton" type="primary" @click="continueAfterReview">
|
||||
{{ continueAction.label }}
|
||||
</n-button>
|
||||
</n-flex>
|
||||
</template>
|
||||
</ProblemReaction>
|
||||
</n-modal>
|
||||
</template>
|
||||
Reference in new issue
Block a user