addEventListener('rpc-new', ({detail}) => { const {uid, kind} = detail.value if(kind === 'screen') { const sender = ScreenShare.isSource && ScreenShare.stream const receiver = !ScreenShare.isSource && ScreenShare.stream signal({kind: 'rpc-setup', value: {uid, sender, receiver}}) } }) const ScreenShareConfig = { view() { if (ScreenShare.isOff) { const onclick = ScreenShare.getStream return m('button', {onclick}, 'start screen sharing') } else { const onclick = () => wire({kind: 'screen-stop'}) return m('button', {onclick}, 'stop screen sharing') } } } const ScreenShare = { isSource: false, stream: new MediaStream(), get isOff() { return ScreenShare.stream.getTracks().length === 0 }, async getStream() { await navigator.mediaDevices .getDisplayMedia({}) .then(stream => stream .getTracks() .forEach(tr => ScreenShare.stream.addTrack(tr, stream)) ) ScreenShare.isSource = true State.others.forEach(target => { signal({kind: 'rpc-needed', value: {kind: 'screen', target}}) }) m.redraw() }, async stopStream() { ScreenShare.stream.getTracks().forEach(tr => tr.stop()) ScreenShare.stream = new MediaStream() ScreenShare.isSource = false m.redraw() }, view() { const style = { overflow: 'scroll', backgroundColor: 'gray', color: 'white', fontFamily: 'monospace', position: 'relative', } return ScreenShare.isOff ? [] : m('.screen-share', {style}, m('video[playsinline][autoplay]', {srcObject: ScreenShare.stream}) ) }, } addEventListener('screen-stop', () => { ScreenShare.stopStream() }) addEventListener('join', ({detail: {value: user}}) => { if(ScreenShare.isSource) { signal({kind: 'rpc-needed', value: {kind: 'screen', target: user}}) } }) addEventListener('load', () => { doNotLog.add('screen-stop') Headers.push([ScreenShareConfig]) Apps.push([ScreenShare, {key: 'screen-share-container'}]) })