Skip to content

Multiplayer v1 #97

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 154 commits into from
May 28, 2025
Merged

Multiplayer v1 #97

merged 154 commits into from
May 28, 2025

Conversation

cyclotruc
Copy link
Member

@cyclotruc cyclotruc commented May 28, 2025

🚀 Major Architecture Overhaul: Real-time Collaboration

Overview

This is a comprehensive rewrite of pad.ws that allows real-time collaborative whiteboard experience

You can right click on your tabs to change their sharing status, then copy their url in the form:
https://pad.ws/pad/f8467ed7-0af1-45b4-bae6-9c92d3882e6d
image

image

🎯 Key Features Added

🔄 Real-time Collaboration

  • WebSocket-based collaboration with pointer tracking and live cursors
  • Multi-user scene synchronization with conflict resolution
  • Connected user indicators showing who's actively working on each pad
  • Public/private pad sharing with public URL

📝 Multi-Pad Management

  • Tabbed interface for managing multiple pads simultaneously
  • Pad sharing controls (private, public, whitelist)
  • Smart tab indicators showing collaboration status
  • Contextual pad operations (rename, delete, share, copy URL)

🏗️ Architecture Modernization

  • Domain-driven design with separated business logic
  • Redis-based caching for improved performance
  • Background workers for canvas state processing
  • Simplified database schema removing unused backup system

🎨 Enhanced UI/UX

  • Improved authentication flow with proper refresh mechanism (tabs will stay logged in more reliably)
  • Public pad visual indicators with animated borders

🔧 Technical Improvements

Backend Refactoring

  • Eliminated repository/service layer separation in favor of domain entities
  • Consolidated database models (UserStore, PadStore with embedded methods)
  • WebSocket implementation for real-time features using Pydantic validation
  • Canvas worker system for processing scene updates in background
  • Redis session management replacing complex token handling

Frontend Modernization

  • React Query for all API calls replacing custom hooks
  • Domain-specific hooks (usePadTabs, useAuthStatus, useWorkspace)
  • WebSocket collaboration client with automatic reconnection
  • Improved error boundaries and loading states
  • Modern component patterns with better separation of concerns

🗑️ Removed Features

  • Backup system - simplified to focus on real-time collaboration
  • Template system - reduced complexity, single default template
  • Build versioning - simplified deployment process

🔄 How to update

We recommand exporting your pads manually before reseting your postgres DB, then importing your pads manually from the frontend (you can also ctrl c + v any selection without exporting)

This is because the structure of the data has changed within the data JSONB field of the previous
At this early stage of the project, we believe this manual migration will be more time effective compared to offering an update script that would work for any version
Feel free to reach out if you have any trouble doing this manual update in your deployment

Roadmap notes:

This milestone is the first of three steps in order to achieve the modern IDE experience we envision
After we spend a bit of time polishing this update as we receive the first feedbacks, the next 2 steps will be:

  • Allow VM collaboration/sharing with modularised cloud dev environments
  • Integrate 3rd party AI agents (starting with terminal based ones like Claude Code)
    We're always looking for cool builders to ship this ambitious software with us, you can find us on discord if you're interested in this journey

From @atyrode and @cyclotruc
(Special thanks to Glaude 3.7, you will be missed)

atyrode added 30 commits May 12, 2025 15:43
- Updated the version of @atyrode/excalidraw in package.json and yarn.lock to ensure compatibility with the latest features and fixes.
- Adjusted the integrity hash in yarn.lock to reflect the new version.
- Deleted the frontend-backend communication documentation as it is no longer relevant.
- Removed BuildVersionCheck, apiUtils, configService, and hooks files to streamline the codebase.
- Refactored AuthGate and related components to simplify authentication logic, setting isAuthenticated to a static value for now.
- Updated ExcalidrawWrapper and App components to reflect changes in authentication handling and removed unnecessary imports.
- Cleaned up various UI components by removing references to deleted hooks and API calls, ensuring a more maintainable code structure.
- Removed the ExcalidrawWrapper component to streamline the integration of Excalidraw directly within the App component.
- Updated the App component to handle Excalidraw rendering and state management, enhancing clarity and maintainability.
- Cleaned up index.html by removing unnecessary script imports related to Excalidraw.
- Adjusted authentication handling and UI elements to reflect the new structure, ensuring a more cohesive user experience.
- Removed the custom build-info plugin from vite.config.mts to simplify the configuration.
- Commented out analytics capture calls in ActionButton.tsx and SettingsDialog.tsx for future implementation consideration.
- Streamlined the codebase by eliminating unused imports and enhancing maintainability.
- Updated the authentication router to include a new `/api/auth/status` endpoint for checking user authentication status.
- Modified the logout functionality to clear the session cookie upon successful logout.
- Refactored the frontend to utilize the new authentication status hook, improving user experience by dynamically managing authentication state.
- Adjusted the main application routing to reflect the new API structure, ensuring a consistent and organized API design.
…ponents

- Simplified the authentication completion process in the popup by storing the completion timestamp in localStorage and directly closing the window.
- Removed the message event listener for auth completion, transitioning to a localStorage-based approach for better performance and reliability.
- Enhanced the AuthDialog component by dynamically loading the GitHub buttons script and adding a GitHub Star button for improved user engagement.
- Updated the MainMenu component to reset the Excalidraw scene upon logout, ensuring a clean state for the user experience.
- Updated the refresh_token function to use 'refresh_expires_in' for token expiry.
- Added a new endpoint for refreshing the session, improving user experience by allowing seamless token renewal.
- Refactored the auth_status endpoint to utilize user session data directly, enhancing clarity and maintainability.
- Improved the useAuthStatus hook to handle session expiration and refresh logic, ensuring timely updates to authentication state.
- Enhanced error handling in the logout process for better debugging and user feedback.
…dling

- Removed unnecessary print statement for missing session ID in the authentication callback.
- Simplified the auth_status endpoint by removing the request parameter, enhancing clarity.
- Updated error logging in the useLogout hook to provide more context in case of JSON parsing failures.
- Removed unused redis import from config.py to streamline dependencies.
- Simplified the import statements in dependencies.py for clarity.
- Updated the condition for rendering the AuthDialog in App.tsx to explicitly check for false authentication state.
- Adjusted the useAuthStatus hook to return undefined for isAuthenticated when data is not available, enhancing state management.
- Introduced a new padding configuration in the default initial data for better layout control.
- Increased the iframe load timeout from 2 seconds to 5 seconds to enhance reliability in loading external content.
- Added a new custom hook, useAppConfig, to fetch and manage application configuration.
- Integrated PostHog initialization in the App component based on the fetched configuration.
- Updated AuthGate to utilize app configuration for OIDC priming and improved error handling for configuration loading.
- Enhanced PostHog initialization logic to prevent multiple initializations and handle errors gracefully.
atyrode and others added 10 commits May 25, 2025 22:16
- Replaced static authentication state with dynamic state management using the `useAuthStatus` hook in `AuthGate` component.
- Updated effect dependencies to include loading state from `useAuthStatus`, ensuring proper handling of authentication status and configuration loading.
- Added a debounced function to manage app state updates, reducing unnecessary broadcasts.
- Integrated lodash's debounce and isEqual for efficient state comparison and broadcasting.
- Updated handleSceneChange to utilize the new debounced function for app state updates.
- Enhanced Portal class with a method to broadcast app state updates over WebSocket.
…nd Portal components

- Eliminated the viewport bounds throttling and related methods from the Collab component to streamline functionality.
- Removed follow/unfollow request methods from the Portal class, simplifying the collaboration logic.
- Cleaned up the Collab component by removing unused event listeners and state management related to user following.
- Deleted the developer onboarding guide and frontend collaboration documentation as they are no longer relevant to the current project structure and workflow.
- This cleanup helps streamline the documentation repository and reduces confusion for new contributors.
… canvas data on pad initialization

- Added `elements` and `files` properties to `INITIAL_APP_DATA` for better state management.
- Updated the `usePad` hook to normalize canvas data before updating the scene, enhancing data consistency.
- Replaced manual scene update with a reference to INITIAL_APP_DATA for cleaner state management.
- This change enhances maintainability and ensures consistency with the initialized app data structure.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants