daddy/client/src/hooks/useConference.tsx

84 lines
2.2 KiB
TypeScript

import * as Y from 'yjs'
import { WebrtcProvider, } from 'y-webrtc'
import { useEffect, useRef, useState } from 'react'
import { uuidV4 } from '../util/uuid';
const uuid = uuidV4();
export function useConference() {
const docRef = useRef(new Y.Doc());
const [ state, setState ] = useState({
data: {
emails: {},
nicknames: {},
statuses: {},
peers: {},
},
uuid,
});
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 peers = doc.getMap('peers');
peers.observe(evt => setData('peers', 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.destroy();
docRef.current.destroy();
};
}, []);
return {
data: state.data,
uuid: state.uuid,
setStatus: (status: string) => {
const doc = docRef.current;
const statuses = doc.getMap('statuses');
statuses.set(state.uuid, status);
},
ping: () => {
const doc = docRef.current;
const peers = doc.getMap('peers');
peers.set(state.uuid, (new Date()).toJSON());
},
setNickname: (nickname: string) => {
console.log('setNickname', nickname);
const doc = docRef.current;
const nicknames = doc.getMap('nicknames');
nicknames.set(state.uuid, nickname);
},
setEmail: (email: string) => {
console.log('setEmail', email);
const doc = docRef.current;
const emails = doc.getMap('emails');
emails.set(state.uuid, email);
},
forget: (uuid: string) => {
const doc = docRef.current;
const peers = doc.getMap('peers');
peers.delete(uuid);
},
};
}