Merge branch 'develop' into dist/ubuntu/bionic/develop
This commit is contained in:
commit
d177e2dc3f
|
@ -13,22 +13,23 @@ const StatusThumbsUp = 'thumbs-up';
|
||||||
const StatusThumbsDown = 'thumbs-down';
|
const StatusThumbsDown = 'thumbs-down';
|
||||||
const StatusNoVote = 'no-vote';
|
const StatusNoVote = 'no-vote';
|
||||||
|
|
||||||
|
const HeartbeatInterval = 5000;
|
||||||
|
|
||||||
export const ConferencePage:FunctionComponent<ConferencePageProps> = () => {
|
export const ConferencePage:FunctionComponent<ConferencePageProps> = () => {
|
||||||
const { user } = useUserProfile();
|
const { user } = useUserProfile();
|
||||||
const { id, data, peers, setNickname, setEmail, ping, setStatus } = useConference();
|
const { uuid, data, setNickname, setEmail, ping, setStatus, forget } = useConference();
|
||||||
|
|
||||||
const currentStatus = data.statuses[id];
|
const currentStatus = data.statuses[uuid];
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (peers.length === 0) return;
|
if (!user.name && !user.email) return;
|
||||||
if (!id || (!user.name && !user.email)) return;
|
|
||||||
setNickname(user.name || user.email.split('@')[0]);
|
setNickname(user.name || user.email.split('@')[0]);
|
||||||
setEmail(user.email);
|
setEmail(user.email);
|
||||||
}, [user.name, user.email, peers.length]);
|
}, [user.name, user.email]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
ping();
|
ping();
|
||||||
const intervalId = setInterval(() => ping(), 30000);
|
const intervalId = setInterval(() => ping(), HeartbeatInterval);
|
||||||
return () => clearInterval(intervalId);
|
return () => clearInterval(intervalId);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
@ -78,11 +79,21 @@ export const ConferencePage:FunctionComponent<ConferencePageProps> = () => {
|
||||||
<h3 className="is-size-3">Assemblée</h3>
|
<h3 className="is-size-3">Assemblée</h3>
|
||||||
<div className="columns mt-1">
|
<div className="columns mt-1">
|
||||||
<UserCard className="column is-narrow"
|
<UserCard className="column is-narrow"
|
||||||
nickname={data.nicknames[id]}
|
nickname={data.nicknames[uuid]}
|
||||||
status={currentStatus}
|
status={currentStatus}
|
||||||
email={user.email} />
|
email={user.email} />
|
||||||
{
|
{
|
||||||
peers.map(p => {
|
Object.keys(data.peers).map(p => {
|
||||||
|
const now = new Date();
|
||||||
|
const lastHeartBeat = new Date(data.peers[p]);
|
||||||
|
|
||||||
|
if (p === uuid) return null;
|
||||||
|
|
||||||
|
if (now.getTime() > lastHeartBeat.getTime() + HeartbeatInterval) {
|
||||||
|
forget(p);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const nickname = data.nicknames[p] || '???';
|
const nickname = data.nicknames[p] || '???';
|
||||||
const email = data.emails[p] || '';
|
const email = data.emails[p] || '';
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,19 +1,21 @@
|
||||||
import * as Y from 'yjs'
|
import * as Y from 'yjs'
|
||||||
import { WebrtcProvider, } from 'y-webrtc'
|
import { WebrtcProvider, } from 'y-webrtc'
|
||||||
import { useEffect, useRef, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
|
import { uuidV4 } from '../util/uuid';
|
||||||
|
|
||||||
|
const uuid = uuidV4();
|
||||||
|
|
||||||
export function useConference() {
|
export function useConference() {
|
||||||
const docRef = useRef(new Y.Doc());
|
const docRef = useRef(new Y.Doc());
|
||||||
|
|
||||||
const [ state, setState ] = useState({
|
const [ state, setState ] = useState({
|
||||||
data: {
|
data: {
|
||||||
heartbeats: {},
|
|
||||||
emails: {},
|
emails: {},
|
||||||
nicknames: {},
|
nicknames: {},
|
||||||
statuses: {},
|
statuses: {},
|
||||||
|
peers: {},
|
||||||
},
|
},
|
||||||
peers: [],
|
uuid,
|
||||||
id: null,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const setData = (key: string, value: any) => {
|
const setData = (key: string, value: any) => {
|
||||||
|
@ -25,17 +27,8 @@ export function useConference() {
|
||||||
const roomName = `${window.location.protocol}//${window.location.host}/daddy/conference`;
|
const roomName = `${window.location.protocol}//${window.location.host}/daddy/conference`;
|
||||||
const provider = new WebrtcProvider(roomName, docRef.current);
|
const provider = new WebrtcProvider(roomName, docRef.current);
|
||||||
|
|
||||||
const onPeers = (evt) => {
|
const peers = doc.getMap('peers');
|
||||||
let peers = [...state.peers];
|
peers.observe(evt => setData('peers', evt.currentTarget.toJSON()));
|
||||||
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');
|
const nicknames = doc.getMap('nicknames');
|
||||||
nicknames.observe(evt => setData('nicknames', evt.currentTarget.toJSON()));
|
nicknames.observe(evt => setData('nicknames', evt.currentTarget.toJSON()));
|
||||||
|
@ -47,7 +40,6 @@ export function useConference() {
|
||||||
statuses.observe(evt => setData('statuses', evt.currentTarget.toJSON()));
|
statuses.observe(evt => setData('statuses', evt.currentTarget.toJSON()));
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
provider.off('peers', onPeers);
|
|
||||||
provider.destroy();
|
provider.destroy();
|
||||||
docRef.current.destroy();
|
docRef.current.destroy();
|
||||||
};
|
};
|
||||||
|
@ -55,31 +47,38 @@ export function useConference() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data: state.data,
|
data: state.data,
|
||||||
peers: state.peers,
|
uuid: state.uuid,
|
||||||
id: state.id,
|
|
||||||
|
|
||||||
setStatus: (status: string) => {
|
setStatus: (status: string) => {
|
||||||
const doc = docRef.current;
|
const doc = docRef.current;
|
||||||
const statuses = doc.getMap('statuses');
|
const statuses = doc.getMap('statuses');
|
||||||
statuses.set(state.id, status);
|
statuses.set(state.uuid, status);
|
||||||
},
|
},
|
||||||
|
|
||||||
ping: () => {
|
ping: () => {
|
||||||
const doc = docRef.current;
|
const doc = docRef.current;
|
||||||
const heartbeats = doc.getMap('heartbeats');
|
const peers = doc.getMap('peers');
|
||||||
heartbeats.set(state.id, (new Date()).toJSON());
|
peers.set(state.uuid, (new Date()).toJSON());
|
||||||
},
|
},
|
||||||
|
|
||||||
setNickname: (nickname: string) => {
|
setNickname: (nickname: string) => {
|
||||||
|
console.log('setNickname', nickname);
|
||||||
const doc = docRef.current;
|
const doc = docRef.current;
|
||||||
const nicknames = doc.getMap('nicknames');
|
const nicknames = doc.getMap('nicknames');
|
||||||
nicknames.set(state.id, nickname);
|
nicknames.set(state.uuid, nickname);
|
||||||
},
|
},
|
||||||
|
|
||||||
setEmail: (email: string) => {
|
setEmail: (email: string) => {
|
||||||
|
console.log('setEmail', email);
|
||||||
const doc = docRef.current;
|
const doc = docRef.current;
|
||||||
const emails = doc.getMap('emails');
|
const emails = doc.getMap('emails');
|
||||||
emails.set(state.id, email);
|
emails.set(state.uuid, email);
|
||||||
|
},
|
||||||
|
|
||||||
|
forget: (uuid: string) => {
|
||||||
|
const doc = docRef.current;
|
||||||
|
const peers = doc.getMap('peers');
|
||||||
|
peers.delete(uuid);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
Loading…
Reference in New Issue