import * as Y from 'yjs' import { WebrtcProvider, } from 'y-webrtc' import { useEffect, useRef, useState } from 'react' export function useConference() { const docRef = useRef(new Y.Doc()); const [ state, setState ] = useState({ data: { heartbeats: {}, emails: {}, nicknames: {}, statuses: {}, }, peers: [], id: null, }); const setData = (key: string, value: any) => { setState(state => ({...state, data: { ...state.data, [key]: value }})); } useEffect(() => { const doc = docRef.current; const roomName = `${window.location.protocol}//${window.location.host}/daddy/conference`; const provider = new WebrtcProvider(roomName, docRef.current); const onPeers = (evt) => { let peers = [...state.peers]; peers = peers.filter(p => evt.removed.indexOf(p) === -1); peers.push(...evt.added); setState(state => ({ ...state, id: provider.room.peerId, peers })); }; provider.on('peers', onPeers); const heartbeats = doc.getMap('heartbeats'); heartbeats.observe(evt => setData('heartbeats', evt.currentTarget.toJSON())); const nicknames = doc.getMap('nicknames'); nicknames.observe(evt => setData('nicknames', evt.currentTarget.toJSON())); const emails = doc.getMap('emails'); emails.observe(evt => setData('emails', evt.currentTarget.toJSON())); const statuses = doc.getMap('statuses'); statuses.observe(evt => setData('statuses', evt.currentTarget.toJSON())); return () => { provider.off('peers', onPeers); provider.destroy(); docRef.current.destroy(); }; }, []); return { data: state.data, peers: state.peers, id: state.id, setStatus: (status: string) => { const doc = docRef.current; const statuses = doc.getMap('statuses'); statuses.set(state.id, status); }, ping: () => { const doc = docRef.current; const heartbeats = doc.getMap('heartbeats'); heartbeats.set(state.id, (new Date()).toJSON()); }, setNickname: (nickname: string) => { const doc = docRef.current; const nicknames = doc.getMap('nicknames'); nicknames.set(state.id, nickname); }, setEmail: (email: string) => { const doc = docRef.current; const emails = doc.getMap('emails'); emails.set(state.id, email); }, }; }