从答案正确到点评弹窗出来有 1.5 秒(外加查一次评过没有),而换题会取消弹窗的 定时器 ——「下一题」在通过的那一刻就出现,学生手快就绕过了强制点评。 现在这段时间里离开这道题的导航(下一题、题号直达、顶栏导航、相似题……)先拦下: 立刻弹点评,选完再去原来要去的地方。只改 query(左栏切页签)不拦;弹窗已经开着时 也不拦,免得点评接口一直失败时把学生关在这一页。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
85fadd237e
commit
0daa74651d
1 file changed
+57
-5
@@ -9,6 +9,7 @@ import { useFireworks } from "oj/problem/composables/useFireworks"
|
||||
import { useSubmissionMonitor } from "oj/problem/composables/useSubmissionMonitor"
|
||||
import { LANGUAGE_FORMAT_VALUE, SubmissionStatus } from "utils/constants"
|
||||
import type { SubmitCodePayload } from "utils/types"
|
||||
import type { RouteLocationNormalized } from "vue-router"
|
||||
import { getSubmitButtonState } from "./submitButtonState"
|
||||
import { useBreakpoints } from "shared/composables/breakpoints"
|
||||
import { useUserStore } from "shared/store/user"
|
||||
@@ -40,6 +41,7 @@ function closeCommentPanel() {
|
||||
// 点评价弹窗时,结果面板会当成「点了外面」收起来 —— 而「下一题」就在面板里
|
||||
// (LessonNext),评价完得把它重新打开
|
||||
showResult.value = true
|
||||
settleReview()
|
||||
}
|
||||
|
||||
const { isDesktop } = useBreakpoints()
|
||||
@@ -79,17 +81,63 @@ const { start: startCooldown, isPending: isCooldown } = useTimeout(5000, {
|
||||
// ==================== AC 后弹出点评轮盘 ====================
|
||||
// 只对已经能评价、且还没评过的人弹:后端要求先有 AC 才收评价,这里刚 AC 完正好;
|
||||
// mine 非 null 说明早就评过了,别再打扰。
|
||||
const { start: showCommentPanelDelayed, stop: cancelCommentPanel } = useTimeoutFn(
|
||||
async () => {
|
||||
//
|
||||
// 点评是强制的,但从 AC 到弹窗出来有 1.5 秒(加上查一次「评过没有」),而换题会把
|
||||
// 定时器取消(见下面换题的 watch)—— 「下一题」在通过的那一刻就出现了,学生手快点
|
||||
// 下去,点评就跳过了。所以这段时间里欠着一次点评(reviewOwed),离开这道题的导航
|
||||
// 先拦下来:立刻弹点评,选完再去原来要去的地方。
|
||||
const reviewOwed = ref(false)
|
||||
let reviewChecking = false
|
||||
let navigationAfterReview: string | null = null
|
||||
|
||||
async function openReview() {
|
||||
if (reviewChecking) return
|
||||
reviewChecking = true
|
||||
try {
|
||||
const res = await getReaction(problem.value!.id)
|
||||
if (res.mine === null) {
|
||||
commentPanel.value = true
|
||||
return
|
||||
}
|
||||
},
|
||||
} catch {
|
||||
// 查不到就不拦:宁可少一条点评,也不能把学生卡在这道题上
|
||||
} finally {
|
||||
reviewChecking = false
|
||||
}
|
||||
settleReview()
|
||||
}
|
||||
|
||||
/** 这次点评了结(评完了、原来就评过、或者查不到),接着去刚才被拦下的地方 */
|
||||
function settleReview() {
|
||||
reviewOwed.value = false
|
||||
const target = navigationAfterReview
|
||||
navigationAfterReview = null
|
||||
if (target) router.push(target)
|
||||
}
|
||||
|
||||
const { start: showCommentPanelDelayed, stop: cancelCommentPanel } = useTimeoutFn(
|
||||
openReview,
|
||||
1500,
|
||||
{ immediate: false },
|
||||
)
|
||||
|
||||
/**
|
||||
* 只拦「离开这道题」:换 query(左栏切页签会改 `?tab=`)不算。弹窗已经开着的时候
|
||||
* 不拦 —— 那时页面被遮罩盖住,还能走的只有浏览器后退,拦下来就等于把人关在这一页,
|
||||
* 点评接口一直失败时连退路都没有。
|
||||
*/
|
||||
function holdForReview(to: RouteLocationNormalized, from: RouteLocationNormalized) {
|
||||
if (!reviewOwed.value || commentPanel.value) return true
|
||||
if (to.name === from.name && to.params.problemID === from.params.problemID) return true
|
||||
navigationAfterReview = to.fullPath
|
||||
cancelCommentPanel()
|
||||
openReview()
|
||||
return false
|
||||
}
|
||||
|
||||
onBeforeRouteUpdate(holdForReview)
|
||||
onBeforeRouteLeave(holdForReview)
|
||||
|
||||
const { start: goToProblemSetDelayed, stop: cancelGoToProblemSet } = useTimeoutFn(
|
||||
() => {
|
||||
router.push({
|
||||
@@ -105,8 +153,9 @@ const { start: goToProblemSetDelayed, stop: cancelGoToProblemSet } = useTimeoutF
|
||||
|
||||
/**
|
||||
* 换题时把上一道题的东西全收掉:结果面板、提交前的语法错误、还在跟的那条提交,以及
|
||||
* 通过之后那两个 1.5 秒的定时器 —— 评价弹窗是按**当前**题目去查、去弹的,学生通过后
|
||||
* 马上点了「下一题」,不取消的话就会给一道还没做的题弹评价。
|
||||
* 通过之后那两个 1.5 秒的定时器 —— 评价弹窗是按**当前**题目去查、去弹的,不取消的话
|
||||
* 就会给一道还没做的题弹评价。欠着的点评走不到这里:离开这道题的导航已经被
|
||||
* holdForReview 拦下、评完才放行;还能走到这里的只有弹窗开着时按了浏览器后退。
|
||||
*
|
||||
* 题目页换题是同一个组件复用(只换路由参数),以前几乎只有退回列表再点进来这一条路,
|
||||
* 有了顶栏题号直达和结果面板里的「下一题」之后,这成了常规操作。
|
||||
@@ -119,6 +168,8 @@ watch(
|
||||
syntaxErrorInfo.value = ""
|
||||
commentPanel.value = false
|
||||
cancelCommentPanel()
|
||||
reviewOwed.value = false
|
||||
navigationAfterReview = null
|
||||
cancelGoToProblemSet()
|
||||
resetSubmission()
|
||||
},
|
||||
@@ -246,6 +297,7 @@ watch(
|
||||
|
||||
// 4. 弹出评价框。比赛里不打扰;题单里 1.5 秒后要跳回题单页,弹了也会被冲掉
|
||||
if (!contestID && !problemSetId) {
|
||||
reviewOwed.value = true
|
||||
showCommentPanelDelayed()
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user