Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | 'use client' import { useCallback, useEffect, useRef, useState } from 'react' import type { Socket } from 'socket.io-client' import { createSocket } from '@/lib/socket' import type { SkillTutorialControlAction, SkillTutorialControlEvent, } from '@/lib/classroom/socket-events' interface UseTutorialControlResult { /** Whether connected to the socket */ isConnected: boolean /** Send a control action to the student */ sendControl: (action: SkillTutorialControlAction) => void } /** * Hook for teachers to send control events to a student's skill tutorial * * @param classroomId - The classroom ID (used for the socket channel) * @param playerId - The student's player ID * @param enabled - Whether control is enabled (default: true) */ export function useTutorialControl( classroomId: string | undefined, playerId: string | undefined, enabled = true ): UseTutorialControlResult { const socketRef = useRef<Socket | null>(null) const [isConnected, setIsConnected] = useState(false) // Connect to socket and join classroom channel useEffect(() => { if (!classroomId || !playerId || !enabled) { if (socketRef.current) { socketRef.current.disconnect() socketRef.current = null setIsConnected(false) } return } // Create socket connection const socket = createSocket({ reconnection: true, reconnectionDelay: 1000, reconnectionAttempts: 5, }) socketRef.current = socket socket.on('connect', () => { console.log('[TutorialControl] Connected, joining classroom channel:', classroomId) setIsConnected(true) // Join the classroom channel to send control events socket.emit('join-classroom', { classroomId }) }) socket.on('disconnect', () => { console.log('[TutorialControl] Disconnected') setIsConnected(false) }) return () => { console.log('[TutorialControl] Cleaning up socket connection') socket.emit('leave-classroom', { classroomId }) socket.disconnect() socketRef.current = null setIsConnected(false) } }, [classroomId, playerId, enabled]) // Send control action to student const sendControl = useCallback( (action: SkillTutorialControlAction) => { if (!socketRef.current || !isConnected || !playerId) { console.warn('[TutorialControl] Cannot send control - not connected or no playerId') return } const event: SkillTutorialControlEvent = { playerId, action, } socketRef.current.emit('skill-tutorial-control', event) console.log('[TutorialControl] Sent control:', action) }, [isConnected, playerId] ) return { isConnected, sendControl, } } |