realtimecursor
Version:
Real-time collaboration system with cursor tracking and approval workflow
119 lines (104 loc) • 3.73 kB
JSX
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;