import React, { useState, useCallback, useEffect, } from 'react' import * as Y from 'yjs' import { useEditor, EditorContent } from '@tiptap/react' import StarterKit from '@tiptap/starter-kit' import TaskList from '@tiptap/extension-task-list' import TaskItem from '@tiptap/extension-task-item' import Highlight from '@tiptap/extension-highlight' import CharacterCount from '@tiptap/extension-character-count' import Collaboration from '@tiptap/extension-collaboration' import CollaborationCursor from '@tiptap/extension-collaboration-cursor' import { HocuspocusProvider } from '@hocuspocus/provider' import MenuBar from './MenuBar' import './styles.scss' const colors = ['#958DF1', '#F98181', '#FBBC88', '#FAF594', '#70CFF8', '#94FADB', '#B9F18D'] const rooms = ['rooms.30', 'rooms.31', 'rooms.32'] const names = [ 'Lea Thompson', 'Cyndi Lauper', 'Tom Cruise', 'Madonna', 'Jerry Hall', 'Joan Collins', 'Winona Ryder', 'Christina Applegate', 'Alyssa Milano', 'Molly Ringwald', 'Ally Sheedy', 'Debbie Harry', 'Olivia Newton-John', 'Elton John', 'Michael J. Fox', 'Axl Rose', 'Emilio Estevez', 'Ralph Macchio', 'Rob Lowe', 'Jennifer Grey', 'Mickey Rourke', 'John Cusack', 'Matthew Broderick', 'Justine Bateman', 'Lisa Bonet', ] const getRandomElement = list => list[Math.floor(Math.random() * list.length)] const getRandomRoom = () => getRandomElement(rooms) const getRandomColor = () => getRandomElement(colors) const getRandomName = () => getRandomElement(names) const room = getRandomRoom() const ydoc = new Y.Doc() const websocketProvider = new HocuspocusProvider({ url: 'wss://connect.gethocuspocus.com', parameters: { key: 'write_bqgvQ3Zwl34V4Nxt43zR', }, name: room, document: ydoc, }) const getInitialUser = () => { return JSON.parse(localStorage.getItem('currentUser')) || { name: getRandomName(), color: getRandomColor(), } } export default () => { const [status, setStatus] = useState('connecting') const [currentUser, setCurrentUser] = useState(getInitialUser) const editor = useEditor({ extensions: [ StarterKit.configure({ history: false, }), Highlight, TaskList, TaskItem, CharacterCount.configure({ limit: 10000, }), Collaboration.configure({ document: ydoc, }), CollaborationCursor.configure({ provider: websocketProvider, }), ], }) useEffect(() => { // Update status changes websocketProvider.on('status', event => { setStatus(event.status) }) }, []) // Save current user to localStorage and emit to editor useEffect(() => { if (editor && currentUser) { localStorage.setItem('currentUser', JSON.stringify(currentUser)) editor.chain().focus().updateUser(currentUser).run() } }, [editor, currentUser]) const setName = useCallback(() => { const name = (window.prompt('Name') || '').trim().substring(0, 32) if (name) { return setCurrentUser({ ...currentUser, name }) } }, [currentUser]) return (