feat(举手与协作): 老师能在看板上直接打开学生正在写的代码,同一道题好几个人举手能「讲完了,都放下」,举手面板写着每人错在哪
学生编辑器报「在写哪道题」,看板接口带 editing;新增 peek / dismiss 两条协作消息, 求助记录带这道题最后一次提交(判完新的一次会刷新)。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5c9d0ca501
commit
573a0f967f
5 files changed
+306
-43
No files matched your search
@@ -39,13 +39,28 @@ export function normalizeCollabLanguage(value: unknown): CollabLanguage {
|
||||
: "C"
|
||||
}
|
||||
|
||||
/**
|
||||
* 学生这道题最后一次代码提交,老师的举手面板按它写错法(和课堂看板的格子同一份形状,
|
||||
* 前端用同一个 errorKind 归类)。只带归类要用的几样,不带代码
|
||||
*/
|
||||
export interface CollabLatest {
|
||||
submissionId: string
|
||||
result: number
|
||||
runtimeError?: unknown
|
||||
sampleCheck?: unknown
|
||||
}
|
||||
|
||||
export interface HelpRequest {
|
||||
studentId: number
|
||||
studentName: string
|
||||
className: string | null
|
||||
/** 题目的展示号(problem._id 列,前端一路用的都是它),不是自增主键 */
|
||||
problemId: string
|
||||
/** problem.id,查他最后一次提交用 */
|
||||
problemPk: number
|
||||
problemTitle: string
|
||||
/** 他这道题最后一次代码提交;没交过为 null。判完新的一次会刷新(refreshRequestLatest) */
|
||||
latest: CollabLatest | null
|
||||
/**
|
||||
* 学生编辑器当前的语言。决定教师端弹框用哪套高亮和补全 —— 求助时带上,
|
||||
* 协作期间学生切语言会用 help_language 更新这里
|
||||
@@ -111,6 +126,11 @@ export function teacherSockets() {
|
||||
export interface Room {
|
||||
/** 房主 = 学生。房间以学生为键,因为学生的代码是内容源 */
|
||||
studentId: number
|
||||
/**
|
||||
* help = 学生举了手、老师接的;peek = 老师在看板上主动打开的(学生没举手)。
|
||||
* 两边看到的字不一样(「在帮你」/「在看你的代码」),peek 没有求助记录要清
|
||||
*/
|
||||
mode: "help" | "peek"
|
||||
teacherId: number
|
||||
studentSocket: CollabSocket
|
||||
teacherSocket: CollabSocket
|
||||
@@ -138,3 +158,29 @@ export function roomOf(ws: CollabSocket) {
|
||||
const ownerId = ws.data.roomOwnerId
|
||||
return ownerId === undefined ? undefined : rooms.get(ownerId)
|
||||
}
|
||||
|
||||
/**
|
||||
* 学生此刻开着哪道题的代码编辑器(题目页,非比赛)。老师在看板上「在写」那一列看它、
|
||||
* 点它主动打开 —— 不用等学生举手。学生端编辑器挂上 / 换题 / 卸载时上报,
|
||||
* 连接断了就清掉。同一账号开了两个标签页时,后报的算
|
||||
*/
|
||||
export interface Presence {
|
||||
problemId: string
|
||||
language: CollabLanguage
|
||||
socket: CollabSocket
|
||||
}
|
||||
|
||||
const presences = new Map<number, Presence>()
|
||||
|
||||
export function setPresence(userId: number, presence: Presence) {
|
||||
presences.set(userId, presence)
|
||||
}
|
||||
|
||||
/** 只清这条连接报的:同账号另一个标签页报的那份不能被这边关页面顺手清掉 */
|
||||
export function clearPresence(userId: number, ws: CollabSocket) {
|
||||
if (presences.get(userId)?.socket === ws) presences.delete(userId)
|
||||
}
|
||||
|
||||
export function presenceOf(userId: number) {
|
||||
return presences.get(userId)
|
||||
}
|
||||
Reference in new issue
Block a user