import { atom , DefaultValue , selector } from 'recoil' ; import { Socket , io } from 'socket.io-client' ; import { SERVER_URL } from 'config.keys' ; export const createSocket = ( ) : Socket => { const socket = io ( SERVER_URL ) ; return socket ; } ; export const socketState = atom < Socket > ( { key : 'socketState' , default : createSocket ( ) , } ) ; export interface Room { id ? : string ; created_by ? : string ; name ? : string ; opts ? : { maxPeople ? : string ; } ; } export const roomState = atom < Room | null > ( { key : 'roomState' , default : null , } ) ; export interface RemoteStream { stream : MediaStream ; partnerId : string ; partnerName ? : string ; isDisplay ? : boolean ; } export const remoteStreamsState = atom < RemoteStream [ ] > ( { key : 'remoteStreamsState' , default : [ ] , } ) ; export const addRemoteStreamsSelector = selector < RemoteStream [ ] > ( { key : 'addRemoteStreamsSelector' , get : ( { get } ) => get ( remoteStreamsState ) , set : ( { get , set } , newVal ) => { if ( newVal instanceof DefaultValue ) { throw Error ( 'What were you thinking dude' ) ; } const [ user , display ] = newVal as ( RemoteStream | undefined ) [ ] ; const remoteStreams = get ( remoteStreamsState ) ; let rStreams = remoteStreams ; if ( user && ! remoteStreams . find ( ( r ) => ! r . isDisplay && r . partnerId === user . partnerId ) ) { rStreams = rStreams . concat ( user ) ; } if ( display && ! remoteStreams . find ( ( r ) => r . isDisplay && r . partnerId === display . partnerId && r . stream . getVideoTracks ( ) [ 0 ] . id === display ?. stream . getVideoTracks ( ) [ 0 ] . id ) ) { rStreams = rStreams . filter ( ( { isDisplay , stream , partnerId } ) => { if ( isDisplay && partnerId === display . partnerId ) { stream . getTracks ( ) . forEach ( ( t ) => { t . stop ( ) ; stream . removeTrack ( t ) ; } ) ; return false ; } return true ; } ) ; rStreams = rStreams . concat ( display ) ; } if ( ! display ) { rStreams = rStreams . filter ( ( { isDisplay , stream , partnerId } ) => { if ( isDisplay && partnerId === user ?. partnerId ) { stream . getTracks ( ) . forEach ( ( t ) => { t . stop ( ) ; stream . removeTrack ( t ) ; } ) ; return false ; } return true ; } ) ; } set ( remoteStreamsState , rStreams ) ; } , } ) ; export interface Connection { partnerId : string ; initiator : boolean ; partnerName ? : string ; } export const connectionsState = atom < Connection [ ] > ( { key : 'connectionsState' , default : [ ] , } ) ; export const addConnectionsSelector = selector < Connection [ ] > ( { key : 'addConnectionsSelector' , get : ( { get } ) => get ( connectionsState ) , set : ( { get , set } , newVal ) => { if ( newVal instanceof DefaultValue ) { throw Error ( 'What were you thinking dude' ) ; } const connections = get ( connectionsState ) ; const toAdd = [ ] ; newVal . forEach ( ( val ) => { if ( ! connections . find ( ( c ) => c . partnerId === val . partnerId ) ) { toAdd . push ( val ) ; } } ) ; if ( toAdd . length ) set ( connectionsState , connections . concat ( toAdd ) ) ; } , } ) ; export const removeConnectionsSelector = selector < Connection [ ] > ( { key : 'removeConnectionsSelector' , get : ( { get } ) => get ( connectionsState ) , set : ( { get , set } , newVal ) => { if ( newVal instanceof DefaultValue ) { throw Error ( 'What were you thinking dude' ) ; } const remoteStreams = get ( remoteStreamsState ) ; set ( remoteStreamsState , remoteStreams . filter ( ( r ) => ! newVal . find ( ( v ) => v . partnerId === r . partnerId ) ) ) ; const connections = get ( connectionsState ) ; set ( connectionsState , connections . filter ( ( c ) => ! newVal . find ( ( v ) => v . partnerId === c . partnerId ) ) ) ; if ( window . vitaPeers ) { window . vitaPeers = window . vitaPeers . filter ( ( p ) => ! newVal . find ( ( v ) => v . partnerId === p . partnerId ) ) ; } } , } ) ;