We have designed and implemented an online real-time collaborative text editor. This type of software enables multiple users on different machines to edit the same document simultaneously, similar to popular tools like Google Docs.
- User Registration and Authentication: Register and login to user accounts.
- File Management: Create, open, rename, and delete files.
- Access Control: Share documents with permissions (viewer or editor); ensure security with owner-only file deletion.
- List Documents: View owned and shared documents.
- Support File Editing: Edit document text with bold and italic formatting.
- Support Concurrent Edits: Enable multiple users to edit simultaneously; manage conflicts effectively.
- Real-time Updates: Track edits in real-time; see other users' cursors and active sessions.
- Simple UI: Includes login, sign up, intuitive file management (create, list, delete, rename, share, open), and text editing capabilities.
- Backend:
- Java
- Spring Boot
- Spring Security
- STOMP Web Sockets
- SQL Database
- Frontend:
- React.js
- Quilljs
- Clone the repository using:
git clone https://github.com/SalahAbotaleb/Online-Collaborative-Text-Editor.git
- Redirect to the backend folder:
cd Online-Collaborative-Text-Editor/backend - Build the
gradle.buildfile:./gradlew build
- Run the Spring Boot app on localhost:
./gradlew bootRun
- Redirect to the frontend folder:
cd ../frontend - Install the dependencies:
npm i
- Run the development server:
npm run dev
- Open a web browser and go to the host link.
DemoAPT.mp4
The general idea of the algorithm is very similar to a doubly linked list. Each node contains:
- Node ID
- ID of the left node
- ID of the right node
- Character
- Bold
- Italic
- Deleted
The ID of any node consists of the operation number of the user, "@" and the username. For example, if user Moaaz adds the letter 'b' as his fourth operation, the ID of the node is "3@moaaz".
Inserting is done using the left and right IDs as if they are pointers (since there are no pointers in JS, we use a hashmap that contains the node with access by ID of the element).
We use the username as a tiebreaker. Lexicographically higher numbers mean higher priority. The higher priority nodes are placed to the left.
- For delete, the operation is simply to set the item as deleted.
- For showing an item, we search for the first item to its left that was not deleted.
- For italic and bold, in normal insertion items are set as bold and italic.
- For selecting multiple elements then bolding or italicizing, the loop goes through all the IDs and sets the
isBoldorisItalicor both. - Conflicts are resolved using CRDT data structure.
