85 lines
2.3 KiB
TypeScript
85 lines
2.3 KiB
TypeScript
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);
|
|
},
|
|
};
|
|
} |