|
|
88b695d34f
|
feat(课堂求助): 教师端接单直接跳题目页协作,删掉 CollabModal
Deploy / deploy (push) Has been cancelled
点求助列表里的一条 = 跳到 /problem/:id,在页面自带的那个编辑器里和学生同步。
原来是弹一个 CollabModal(弹框里再挂一个 CodeMirror + 一份只读题面):
- 按一下 Esc 弹框就关、协作跟着结束(`show` 的 setter 里 leave 是唯一的关闭语义,
Esc 和点遮罩都走它),上课太容易误触;
- 弹框里那份题面不能跑测试、不能提交,老师还是得另开标签页对照。
现在结束协作只有两条明确的路:工具栏的「结束协作」按钮、离开这一页。教师端也少了
一个 CodeMirror 实例 —— setBinaryHandler 那个单例槽位只剩 SyncCodeEditor 一个使用者。
改造中撞出两个真问题,根因是同一个:`/problem/1002` → `/problem/1001` 是同一条路由
换 params,**组件被复用、不卸载**。
- 老师在别的题上接单跳过来,`@ready` 不会再触发,而 room 早在导航前就 open 了 ——
老师停在一个空编辑器上干等。watch 的源从 room 一个变成 [room, roomIsHere] 两个。
- 反过来老师协作中切去别的题,onUnmounted 不触发 → 不发 leave,学生一直挂着
「老师正在帮你」而老师的字一个也过不去。加 `bound` 标记区分「房间从我这儿挪走了」
(补发 leave)和「房间在别处开起来了」(跟我无关,接单那一瞬间就是这种)。
`leave` 分两种语义(协议加 reason):
| 前端 | 求助记录 | 对面看到 |
|---|---|---|
| leave("done") 点「结束协作」 | 删除 | 老师已结束这次帮忙 |
| leave("left") 离开这道题的页面 | 教师走→退回排队;学生走→删除 | 老师暂时离开,已重新排队 |
"left" 复用的是老师掉线那条路(requeueAfterTeacherGone),两件事语义相同。原来两者
都按 done 处理 —— 老师点一下「提交信息」,学生就得重新举手,而他看到的是
「协作已结束」,会以为被处理完了。发起方收到的 reason 单独一份(self_left/done),
不然学生自己切走了却看到「老师已结束这次帮忙」。
其余为这套交互补的闸:
- 学生排队期间离开那道题 → 自动取消求助。那条求助说的是「我卡在这道题」,人走了
就不成立;原来它会一直挂在队列里,老师接进来时学生的编辑器不在这道题上、根本
不会绑,老师对着空编辑器敲字,两边都没提示。
- 协作中**教师的语言选择跟着 room.language 走**(写 codeStore,不只是改高亮),
结束后还原。只改高亮的话老师会拿自己那档语言提交学生的代码(学生写 C、老师选的
是 Python,当场 CE),工具栏还可能显示「提交流程图」。学生端一个字不动 ——
服务端的 room_language 只发给教师,学生本地那份停在建房那一刻。
- 协作中不给「重置代码」:v-model 一写回就顺着 Yjs 同步过去,等于一键清空学生的作业。
- 协作中「提交信息」走新标签 —— 那是教师工具栏上唯一会跳路由的按钮。
- 接单时 resetScreenMode():分屏在「题目」「自测」两档时右侧编辑器根本没挂出来,
停在同一道题上接单会落进一个没有编辑器的页面(跳到别的题时 detail.vue 的 init()
会重置,同页不会)。
- 老师已在一个房间里时前端也拦住接下一单(服务端本来就拦),不拦的话前端已经跳到
新题目上,等于把手上那场协作断掉。
- 文案:协议层那四条英文(Invalid problemId 之类)会被原样弹成 toast,改成中文;
「请先退出当前协作」统一成「结束」;room_closed 的提示按 reason × 角色展开。
验证:本机起 api + web,三个账号两两组合实跑 —— 跨题接单 / 同页接单、双向编辑、
连按 Esc、结束协作、老师跳走后再接、学生跳走、学生排队中切题、学生协作中切语言、
分屏在「题目」档接单、协作中重复接单,以及上面每一句提示的实际文案。
api typecheck / check:routes、前端 type-check / build、fmt 全过。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-09-16 19:13:42 -06:00 |
|
|
|
3559ae4d6f
|
chore(前端): 浏览器基线从 Chrome < 94 提到 105,删掉 mermaid@9 那套 fallback
机房只有部分电脑还是 Chrome 105,其余更新,按最低那档定基线。
- legacy 插件留着:vite 8 的默认 build.target 是 chrome111,比机房高。
modernTargets 不写,用插件自带的 chrome>=105 基线,正好是这一档。
- polyfill 清单按 105 重新探测,63 → 50 项,仍然写死:自动探测要对每个产物
跑 Babel 扫描,构建 3s → 12s。写死后产出的 polyfills chunk 与自动探测同尺寸。
- 删 mermaid-legacy(mermaid@9)、useMermaid 里按 UA 分叉的 v9 回调式 render、
为它存在的 cytoscape UMD→ESM 别名 —— 105 直接用 mermaid 11。
- View Transitions 要 111,darkTransition 的降级分支保留,注释改成 105。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-09-16 07:43:21 -06:00 |
|
|
|
ec35400249
|
perf(首页): 协作弹框改异步加载,首屏 JS 少三分之一
Deploy / deploy (push) Has been cancelled
CollabHost 静态 import CollabModal,把整套 CodeMirror(view / state /
language / autocomplete / lang-*)拖进了入口 chunk,而那个组件是
v-if="isTeacher" 的——学生根本不渲染,字节却人人下、人人解析。改成
defineAsyncComponent 之后:
入口 eager JS 1355 KB → 717 KB(gzip 447 → 234)
首页 JS 总量 1923 KB → 1285 KB(gzip 642 → 428)
机房那批 Chrome 91 省下的不只是下载,还有六百多 KB 的解析。老师端代价
是第一次接单时多一次 chunk 请求。
顺带修掉题目列表的重复请求:onMounted 拉一次,profile 回来时那个
watch 又拉一次。但请求本来就带 cookie(withCredentials),后端
optionalAuth 认的也是 cookie,首屏那一份的状态列本来就是全的。watcher
改成拿 storage 里的登录态做基线,只在登录态真的变了才补拉。
这条在本机复现不了(/api/me 1ms 就回,路由 chunk 还没挂载完),给
preview 代理的 /api/me 加 300ms 延迟、用 production 构建验证:改前
/problems 发两遍,改后一遍且状态列有值,登录/退出两个切换仍各触发
一次重拉。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tj3959yNB2srvc1oL3PaZH
|
2026-09-01 00:49:56 -06:00 |
|
|
|
e62f41f6c7
|
refactor(web): Header 只管顶栏,全局的东西挂回 App
Header 一直兼着「全局挂载点」:课堂求助的提示、新求助 toast、求助列表和
教师端协作弹框都寄生在里面,只因为顶栏是全局的。它其实不是 ——
/admin/* 走的是 admin.vue,没有 Header,老师一进后台这四个消费者全部
卸载:求助照收,提示、角标、弹框一个都不出现,正好是 collab.ts 里写的
「老师可能正在后台改题时收到求助」那个场景。
这些东西跟着连接走,而连接在 App.vue 按登录态开关,所以搬进 CollabHost
挂在同一层。Header 因此不必再是单根组件,default.vue 那个靠 class 传
居中样式的写法也换成外层 div,连带删掉「必须挂在根 n-flex 内部」那段
补丁注释。
顺带:
- 圆环扩散的暗黑切换抽成 useDarkTransition
- 求助的角标/toast/列表不再限桌面端 —— 老师缩窗口也得知道有人在等;
接单确实要在电脑上写代码,那道闸挪进 HelpRequestList
- 站名改 text 按钮,能 tab 到、回车能按
- logout 的两步收进 userStore.signOut()
- 清掉死代码:handleMenuSelect 只认一个不存在的 key、active 里
["user","setting"] 永远不生效的排除、两个 show:false 的菜单项
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QqqZwxtXLo2GTqMi51C94D
|
2026-08-31 07:36:14 -06:00 |
|