Team Ai
Apppublic

Harsh-jain/codecollab-vs-code-meets-google-docs

sourceHugging Faceupdated 11mo agoView on Hugging Face
0likes
script.js129 linesDownload Raw Back to root
1 2// Initialize real-time collaboration socket3const socket = io();4 5// Initialize components6customElements.define('collaborator-list', CollaboratorList);7customElements.define('collab-navbar', CollabNavbar);8customElements.define('collab-sidebar', CollabSidebar);9// Project state10let projectId = null;11let projectName = 'Untitled Project';12let projectCode = '';13let isHost = false;14 15// Track active collaborators16const collaborators = new Map();17 18// Handle incoming cursor positions19socket.on('cursor-position', (data) => {20    const { position, userId } = data;21    22    // Create or update cursor element23    let cursor = document.getElementById(`cursor-${userId}`);24    if (!cursor) {25        cursor = document.createElement('div');26        cursor.id = `cursor-${userId}`;27        cursor.className = 'absolute w-px h-6 bg-green-400 cursor-pulse';28        cursor.style.pointerEvents = 'none';29        cursor.style.zIndex = '10';30        document.getElementById('editor-container').appendChild(cursor);31        32        // Add collaborator name label33        const label = document.createElement('div');34        label.className = 'absolute text-xs text-white bg-green-600 px-1 rounded -translate-y-full';35        label.textContent = `User ${userId.substr(5, 3)}`;36        cursor.appendChild(label);37    }38    39    // Position the cursor (this would be mapped to editor coordinates)40    // In a real implementation, we'd use Monaco's API to position decorations41    cursor.style.left = `${position.column * 8}px`;42    cursor.style.top = `${position.lineNumber * 20}px`;43});44 45// Handle collaborator disconnections46socket.on('user-disconnected', (userId) => {47    const cursor = document.getElementById(`cursor-${userId}`);48    if (cursor) {49        cursor.remove();50    }51    collaborators.delete(userId);52});53// Generate a random project ID54function generateProjectId() {55    return 'project-' + Math.random().toString(36).substr(2, 9);56}57 58// Create a new project59function createProject() {60    projectId = generateProjectId();61    isHost = true;62    socket.emit('create-project', { projectId });63    updateShareLink();64}65 66// Join an existing project67function joinProject(id) {68    projectId = id;69    isHost = false;70    socket.emit('join-project', { projectId });71}72 73// Update the share link UI74function updateShareLink() {75    const shareLink = `${window.location.origin}?project=${projectId}`;76    const shareBtn = document.querySelector('#share-btn');77    if (shareBtn) {78        shareBtn.textContent = 'Copy Share Link';79        shareBtn.onclick = () => {80            navigator.clipboard.writeText(shareLink);81            shareBtn.textContent = 'Copied!';82            setTimeout(() => shareBtn.textContent = 'Copy Share Link', 2000);83        };84    }85}86 87// Handle incoming project data88socket.on('project-data', (data) => {89    projectCode = data.code;90    if (window.monacoEditor) {91        window.monacoEditor.setValue(projectCode);92    }93});94 95// Handle project creation success96socket.on('project-created', (data) => {97    projectId = data.projectId;98    updateShareLink();99});100 101// Check URL for project ID on load102function checkUrlForProject() {103    const urlParams = new URLSearchParams(window.location.search);104    const projectParam = urlParams.get('project');105    if (projectParam) {106        joinProject(projectParam);107    } else {108        createProject();109    }110}111 112// File system operations would be handled here113document.addEventListener('DOMContentLoaded', () => {114    checkUrlForProject();115// Handle file selection in sidebar116    document.addEventListener('click', (e) => {117        if (e.target.closest('.file-item')) {118            const fileItems = document.querySelectorAll('.file-item');119            fileItems.forEach(item => item.classList.remove('active'));120            e.target.closest('.file-item').classList.add('active');121            122            // In a real app, we'd load the file content here123            // and update the editor124        }125    });126    127    // Initialize tooltips128    feather.replace();129});