|  |  | @@ -3,10 +3,8 @@ const datachannels = {} | 
		
	
		
			
			|  |  |  | const streams = {} | 
		
	
		
			
			|  |  |  | const screen = {} | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | function setTracks({source, tracks}) { | 
		
	
		
			
			|  |  |  | streams[source] = streams[source] || new MediaStream() | 
		
	
		
			
			|  |  |  | streams[source].getTracks().forEach(t => streams[source].removeTrack(t)) | 
		
	
		
			
			|  |  |  | tracks.forEach(track => streams[source].addTrack(track)) | 
		
	
		
			
			|  |  |  | function setStream({source, stream}) { | 
		
	
		
			
			|  |  |  | streams[source] = stream | 
		
	
		
			
			|  |  |  | m.redraw() | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(source === State.username) { | 
		
	
	
		
			
			|  |  | @@ -16,19 +14,14 @@ function setTracks({source, tracks}) { | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | function reloadAllStreams() { | 
		
	
		
			
			|  |  |  | State.online.forEach(username => { | 
		
	
		
			
			|  |  |  | const rpc = connections[username] | 
		
	
		
			
			|  |  |  | if(rpc) { | 
		
	
		
			
			|  |  |  | rpc.getSenders().map(s => rpc.removeTrack(s)) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | signal({kind: 'rpc', value: {type: 'request'}, source: username}) | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | function getOwnTracks() { | 
		
	
		
			
			|  |  |  | if(streams[State.username]) { | 
		
	
		
			
			|  |  |  | return streams[State.username].getTracks() | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | else { | 
		
	
		
			
			|  |  |  | return [] | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | function createConnection(target) { | 
		
	
		
			
			|  |  |  | const rpc = new RTCPeerConnection(rpcConfig) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
			|  |  | @@ -38,9 +31,8 @@ function createConnection(target) { | 
		
	
		
			
			|  |  |  | wire({kind: 'rpc', value, target}) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | rpc.ontrack = () => { | 
		
	
		
			
			|  |  |  | const tracks = rpc.getReceivers().map(t => t.track) | 
		
	
		
			
			|  |  |  | setTracks({source: target, tracks: tracks}) | 
		
	
		
			
			|  |  |  | rpc.ontrack = ({streams: [stream]}) => { | 
		
	
		
			
			|  |  |  | setStream({source: target, stream}) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | rpc.onconnectionstatechange = () => { | 
		
	
		
			
			|  |  |  | if(rpc.connectionState === 'failed') { | 
		
	
	
		
			
			|  |  | @@ -73,10 +65,13 @@ async function handlePeerInfo({source: target, value}) { | 
		
	
		
			
			|  |  |  | return | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | const olds = rpc.getSenders().map(t => t.track) | 
		
	
		
			
			|  |  |  | const news = getOwnTracks() | 
		
	
		
			
			|  |  |  | rpc.getSenders().filter(s => !news.includes(s.track)).forEach(s => rpc.removeTrack(s)) | 
		
	
		
			
			|  |  |  | news.filter(track => !olds.includes(track)).forEach(t => t && rpc.addTrack(t)) | 
		
	
		
			
			|  |  |  | const stream = streams[State.username] | 
		
	
		
			
			|  |  |  | if(stream) { | 
		
	
		
			
			|  |  |  | stream.getTracks().forEach(track => { | 
		
	
		
			
			|  |  |  | try {rpc.addTrack(track, stream) } | 
		
	
		
			
			|  |  |  | catch { } | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if(value.type === 'request') { | 
		
	
		
			
			|  |  |  | const localOffer = await rpc.createOffer() | 
		
	
	
		
			
			|  |  | @@ -116,8 +111,17 @@ function destroyConnection(username) { | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | addEventListener('tracks', (e) => setTracks(e.detail.value)) | 
		
	
		
			
			|  |  |  | function destroyAll() { | 
		
	
		
			
			|  |  |  | const people = new Set() | 
		
	
		
			
			|  |  |  | const collect = [connections, datachannels, streams, screen] | 
		
	
		
			
			|  |  |  | .map(collection => Object.keys(collection)) | 
		
	
		
			
			|  |  |  | .forEach(keys => keys.forEach(key => people.add(key))) | 
		
	
		
			
			|  |  |  | people.forEach(destroyConnection) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | addEventListener('stream', (e) => setStream(e.detail.value)) | 
		
	
		
			
			|  |  |  | addEventListener('rpc', (e) => handlePeerInfo(e.detail)) | 
		
	
		
			
			|  |  |  | addEventListener('join', (e) => createConnection(e.detail.value)) | 
		
	
		
			
			|  |  |  | addEventListener('leave', (e) => destroyConnection(e.detail.value)) | 
		
	
		
			
			|  |  |  | addEventListener('logout', () => destroyAll()) | 
		
	
		
			
			|  |  |  | addEventListener('load', () => doNotLog.add('rpc')) |