import { desktopCapturer , DesktopCapturerSource , ipcRenderer , SourcesOptions , } from 'electron' ; import { apiCmds , apiName , NOTIFICATION_WINDOW_TITLE , } from '../common/api-interface' ; import { isWindowsOS } from '../common/env' ; const includes = [ '' ] . includes ; let nextId = 0 ; let isScreenShareEnabled = false ; let screenShareArgv ; export interface ICustomSourcesOptions extends SourcesOptions { requestId ? : number ; } export interface ICustomDesktopCapturerSource extends DesktopCapturerSource { requestId : number | undefined ; } export interface IScreenSourceError { name : string ; message : string ; requestId : number | undefined ; } export type CallbackType = ( error : IScreenSourceError | null , source ? : ICustomDesktopCapturerSource ) => void ; const getNextId = ( ) => ++ nextId ; param options returns { boolean } const isValid = ( options ) => { return ( ( options !== null ? options . types : undefined ) !== null && Array . isArray ( options . types ) ) ; } ; param options { SourcesOptions } param callback { CallbackType } returns { * } export const getSource = async ( options , callback ) => { let captureWindow ; let captureScreen ; let id ; const sourcesOpts = [ ] ; const { requestId , ... updatedOptions } = options ; if ( ! isValid ( options ) ) { callback ( { name : 'Invalid options' , message : 'Invalid options' , requestId , } ) ; return ; } captureWindow = includes . call ( options . types , 'window' ) ; captureScreen = includes . call ( options . types , 'screen' ) ; if ( ! updatedOptions . thumbnailSize ) { updatedOptions . thumbnailSize = { height : 150 , width : 150 , } ; } if ( isWindowsOS && captureWindow ) { type { boolean } captureWindow = await ipcRenderer . invoke ( apiName . symphonyApi , { cmd : apiCmds . isAeroGlassEnabled , } ) ; } if ( captureWindow ) { sourcesOpts . push ( 'window' ) ; } if ( captureScreen ) { sourcesOpts . push ( 'screen' ) ; } if ( ! isScreenShareEnabled ) { await ipcRenderer . invoke ( apiName . symphonyApi , { cmd : apiCmds . showScreenSharePermissionDialog , } ) ; callback ( { name : 'Permission Denied' , message : 'Permission Denied' , requestId , } ) ; return ; } id = getNextId ( ) ; const sources = await desktopCapturer . getSources ( { types : sourcesOpts , thumbnailSize : updatedOptions . thumbnailSize , } ) ; if ( screenShareArgv ) { const title = screenShareArgv . substr ( screenShareArgv . indexOf ( '=' ) + 1 ) ; const filteredSource = sources . filter ( ( source ) => source . name === title ) ; if ( Array . isArray ( filteredSource ) && filteredSource . length > 0 ) { const source = { ... filteredSource [ 0 ] , requestId } ; return callback ( null , source ) ; } if ( sources . length > 0 ) { const firstSource = { ... sources [ 0 ] , requestId } ; return callback ( null , firstSource ) ; } } const updatedSources = sources . filter ( ( source ) => source . name !== NOTIFICATION_WINDOW_TITLE ) . map ( ( source ) => { return { ... source , ... { thumbnail : source . thumbnail . toDataURL ( ) , } , } ; } ) ; ipcRenderer . send ( apiName . symphonyApi , { cmd : apiCmds . openScreenPickerWindow , id , sources : updatedSources , } ) ; const successCallback = ( _e , source ) => { if ( ! source ) { ipcRenderer . removeListener ( 'start-share' + id , successCallback ) ; return callback ( { name : 'User Cancelled' , message : 'User Cancelled' , requestId , } ) ; } return callback ( null , { ... source , ... { requestId } } ) ; } ; ipcRenderer . once ( 'start-share' + id , successCallback ) ; return null ; } ; ipcRenderer . once ( 'screen-share-argv' , ( _event , arg ) => { if ( typeof arg === 'string' ) { screenShareArgv = arg ; } } ) ; ipcRenderer . on ( 'is-screen-share-enabled' , ( _event , canShareScreen ) => { if ( typeof canShareScreen === 'boolean' && canShareScreen ) { isScreenShareEnabled = canShareScreen ; } } ) ;