UNPKG

realtimecursor

Version:

Real-time collaboration system with cursor tracking and approval workflow

119 lines (104 loc) 3.73 kB
import React, { useState, useRef, useEffect } from 'react'; import { useRealtimeCursor, CursorOverlay } from 'realtimecursor-sdk'; import 'realtimecursor-sdk/dist/cursor.css'; function CollaborativeEditor() { const [content, setContent] = useState('Welcome to RealtimeCursor React Example!\n\nTry opening this in multiple windows to see real-time collaboration.'); const editorRef = useRef(null); // Generate random user const userId = useRef(`user_${Math.random().toString(36).substring(2, 10)}`); const userName = useRef(`User ${Math.floor(Math.random() * 1000)}`); const colors = ['#3b82f6', '#ef4444', '#10b981', '#f59e0b', '#8b5cf6']; const userColor = useRef(colors[Math.floor(Math.random() * colors.length)]); // Initialize RealtimeCursor const { cursors, updateCursor, updateContent, collaborators, setTyping, connect, disconnect } = useRealtimeCursor({ apiUrl: 'http://localhost:3000', // Change to your server URL projectId: 'react-example', user: { id: userId.current, name: userName.current, color: userColor.current } }); // Connect on mount useEffect(() => { connect(); return () => disconnect(); }, [connect, disconnect]); // Handle mouse movement const handleMouseMove = (e) => { if (!editorRef.current) return; const rect = editorRef.current.getBoundingClientRect(); const relativeX = e.clientX - rect.left; const relativeY = e.clientY - rect.top; updateCursor({ x: e.clientX, y: e.clientY, textPosition: editorRef.current.selectionStart }); }; // Handle content changes const handleChange = (e) => { const newContent = e.target.value; setContent(newContent); updateContent(newContent, e.target.selectionStart); }; // Handle typing indicator let typingTimeoutRef = useRef(null); const handleKeyDown = () => { setTyping(true); clearTimeout(typingTimeoutRef.current); typingTimeoutRef.current = setTimeout(() => { setTyping(false); }, 1000); }; return ( <div className="collaborative-editor"> <h2>RealtimeCursor React Example</h2> {/* Collaborators list */} <div className="collaborators"> {collaborators.map(user => ( user.id !== userId.current && ( <div key={user.id} className="collaborator" style={{ backgroundColor: '#f0f9ff', padding: '8px 12px', borderRadius: '20px', display: 'flex', alignItems: 'center', marginRight: '10px' }}> <div style={{ width: '24px', height: '24px', borderRadius: '50%', backgroundColor: user.color, color: 'white', display: 'flex', alignItems: 'center', justifyContent: 'center', marginRight: '8px', fontWeight: 'bold' }}> {user.name.charAt(0)} </div> <span>{user.name}</span> {user.isTyping && <span style={{ marginLeft: '5px' }}>...</span>} </div> ) ))} </div> {/* Editor */} <div style={{ position: 'relative', marginTop: '20px' }}> <textarea ref={editorRef} value={content} onChange={handleChange} onMouseMove={handleMouseMove} onKeyDown={handleKeyDown} style={{ width: '100%', height: '300px', padding: '16px', fontFamily: 'monospace', fontSize: '16px', lineHeight: 1.5, border: '1px solid #ccc', borderRadius: '8px' }} /> {/* Cursor overlay */} <CursorOverlay cursors={cursors} /> </div> </div> ); } export default CollaborativeEditor;