import { useState, useEffect } from 'react'; import AgoraRTC, { ClientConfig, ConnectionDisconnectedReason, IAgoraRTCRemoteUser, NetworkQuality } from 'agora-rtc-sdk-ng'; import { DeviceTypeEnum } from '../context/enum/DeviceTypeEnum'; import { DeviceT } from '../context/type/DeviceT'; import { Context } from '../context/Context'; import { InitAction } from '../action/InitAction'; import { Determinants } from "../context/determinants/Determinants"; import { useSelector, useDispatch } from 'react-redux'; import { setContext } from '../store/slices/context'; import { Resources } from '../context/resources/Resources'; import action, { setAction, deleteActionById, increaseIntent, clearAction } from '../store/slices/action'; import { IntervalWorker } from '../worker/IntervalWorker'; import { IAction } from '../action/interface/IAction'; import { WSTransport } from '../transport/WSTransport'; import { InitActionParams } from '../action/type/InitActionParams'; import { RegionChangeActionParams } from '../action/type/RegionChangeActionParams'; import { RegionChangeAction } from '../action/RegionChangeAction'; import { ConnectionStatesEnum } from '../context/enum/ConnectionStates'; import { ActiveProxyAction } from '../action/ActiveProxyAction'; import { ActiveProxyActionParams } from '../action/type/ActiveProxyActionParams'; import { RoleUserEnum } from '../context/enum/RoleUserEnum'; import { DisconnectAction } from '../action/DisconnectAction'; import { DisconnectParams } from '../action/type/DisconnectParams'; import { ToggleVoiceActionParams } from '../action/type/ToggleVoiceActionParams'; import { ToggleVoiceAction } from '../action/ToggleVoiceAction'; import { ChangeDeviceActionParams } from '../action/type/ChangeDeviceActionParams'; import { ChangeDeviceAction } from '../action/ChangeDeviceAction'; import { SubscribeAction } from '../action/SubscribeAction'; import { SubscribeActionParams } from '../action/type/SubscribeActionParams'; import { MediaTypeEnum } from '../context/enum/MediaTypeEnum'; import { UnsubscribeActionParams } from '../action/type/UnsubscribeActionParams'; import { UnsubscribeAction } from '../action/UnsubscribeAction'; import { ShareCameraActionParams } from '../action/type/ShareCameraActionParams'; import { ShareCameraAction } from '../action/ShareCameraAction'; import { ShareScreenActionParams } from '../action/type/ShareScreenActionParams'; import { ShareScreenAction } from '../action/ShareScreenAction'; import { IWorker } from '../worker/interface/IWorker'; import { ChangeRoleParams } from '../action/type/ChangeRoleParams'; import { ChangeRoleAction } from '../action/ChangeRoleAction'; import { ChangeModuleConfigParams } from '../action/type/ChangeModuleConfigParams'; import { ChangeModuleConfigAction } from '../action/ChangeModuleConfigAction'; import { EActionPriorityType } from '../action/enum/EActionPriorityType'; import { EActionType } from '../action/enum/EActionType'; export function ActionsHook() : { Init: Function, RegionChange: Function, ReJoin: Function, ActiveProxy: Function, Disconnect: Function, ToggleVoice: Function, ChangeDevice: Function, ShareCamera: Function, ShareScreen: Function, ChangeRole: Function, ChangeModuleConfig: Function, AgoraContext: Context, Worker: IWorker, setLoggerExpose: Function, setTransportExpose: Function, setVolumenExpose: Function, microphones: Array, cameras: Array, speakers: Array, contextUpdating: number, cameraSharing: boolean, screenSharing: boolean, initiated: boolean } { const reintenTimeProxyFailBack = 3000; const dispatch = useDispatch(); const AgoraContext: Context = useSelector((state: any) => state.context).context const actions: Array = useSelector((state: any) => state.action).action const [contextUpdating, setContextUpdating] = useState(0); const [cameraSharing, setCameraSharing] = useState(false); const [screenSharing, setScreenSharing] = useState(false); const [determinants, setDeterminants] = useState(); const [actionDeleteId, setActionDeleteId] = useState(); const [actionReintentId, setActionReintentId] = useState(); const [resources, setResources] = useState(); const [Worker, setWorker] = useState(new IntervalWorker(AgoraContext)); const [microphones, setMicrophones] = useState(new Array()); const [cameras, setCameras] = useState(new Array()); const [speakers, setSpeakers] = useState(new Array()); const [handlerErrorProxy, setHandlerErrorProxy] = useState(false); const [initiated, setInitiated] = useState(false); AgoraRTC.onMicrophoneChanged = async (changedDevice) => { getDevices(); } /* DELETE ACTIONS BY WORKER*/ useEffect(() => { if (actionDeleteId) { let id = actionDeleteId.split(":"); dispatch(deleteActionById({ id: id[0] })); } }, [actionDeleteId]); /* DELETE REINTENT BY WORKER*/ useEffect(() => { if (actionReintentId) { let id = actionReintentId.split(":"); dispatch(increaseIntent({ id: id[0] })); } }, [actionReintentId]); /* SETUP DEVICES*/ useEffect(() => { getDevices(); }, []); /* SETUP DISPATCH ACTIONS*/ useEffect(() => { AgoraContext.getDeterminants().setActionDispatch(dispatch); }, []); /* SETUP and RUN WORKER*/ useEffect(() => { Worker.setReintentActionCallback(setActionReintentId); Worker.setDeleteActionCallback(setActionDeleteId); Worker.run(); }, []); /* UPDATE ACTION TO WORKER*/ useEffect(() => { Worker.setActions(actions); }, [actions]); /* SETUP CALLBACKS TO UPDATE CONTEXT*/ useEffect(() => { AgoraContext.getDeterminants().setDeterminantsCallback(setDeterminants); AgoraContext.getResources().setResourcesCallback(setResources); dispatch(setContext({ context: AgoraContext })); }, [AgoraContext]); /* UPDATE CONTEXT-DETERMINANTS IN REDUX*/ useEffect(() => { if (determinants) { let newDeterminants = new Determinants(determinants); AgoraContext.setDeterminants(newDeterminants); Worker.setContext(AgoraContext); dispatch(setContext({ context: AgoraContext })); setContextUpdating(Date.now()); if (AgoraContext.getDeterminants().getHasCamera()) setCameraSharing(true); else setCameraSharing(false); if (AgoraContext.getDeterminants().getHasScreen()) setScreenSharing(true); else setScreenSharing(false); if (AgoraContext.getDeterminants().getInit()) setInitiated(true); else setInitiated(false); } }, [determinants]); /* UPDATE CONTEXT-RESOURCES IN REDUX*/ useEffect(() => { if (resources) { let newResources = new Resources(resources); AgoraContext.setResources(newResources); if (AgoraContext.getResources().getListeners() && !AgoraContext.getResources().getListeners().isReadyCallbacks()) { AgoraContext.getResources().getListeners().connectionState(contectionState); AgoraContext.getResources().getListeners().userJoined(userJoined); AgoraContext.getResources().getListeners().userLeft(userLeft); AgoraContext.getResources().getListeners().userPublished(userPublished); AgoraContext.getResources().getListeners().userUnpublished(userUnpublished); AgoraContext.getResources().getListeners().joinFallbackToProxy(joinFallbackToProxy); AgoraContext.getResources().getListeners().networkQuality(networkQuality); AgoraContext.getResources().getListeners().setReadyCallbacks(true); } Worker.setContext(AgoraContext); dispatch(setContext({ context: AgoraContext })); setContextUpdating(Date.now()); } }, [resources]); /* * CALLBACKS AGORA LISTENERS */ const contectionState = (curState: ConnectionStatesEnum, revState: ConnectionStatesEnum, reason: ConnectionDisconnectedReason | undefined) => { AgoraContext.getDeterminants().setConnectionState({ curState: curState, revState: revState, reason: reason }) } const userJoined = (user: IAgoraRTCRemoteUser) => { } const userLeft = (user: IAgoraRTCRemoteUser, reason: string) => { } const userPublished = (user: IAgoraRTCRemoteUser, mediaType: string) => { let mediaTypeValue: MediaTypeEnum = mediaType == MediaTypeEnum.AUDIO ? MediaTypeEnum.AUDIO : MediaTypeEnum.VIDEO; let params: SubscribeActionParams = { remoteUser: user, mediaType: mediaTypeValue, uid: user.uid }; let action = new SubscribeAction(params); console.log("[AgoraModule] - push SubscribeAction ", action); dispatch(setAction({ action: action })); } const userUnpublished = (user: IAgoraRTCRemoteUser, mediaType: string) => { let mediaTypeValue: MediaTypeEnum = mediaType == MediaTypeEnum.AUDIO ? MediaTypeEnum.AUDIO : MediaTypeEnum.VIDEO; let params: UnsubscribeActionParams = { remoteUser: user, mediaType: mediaTypeValue, uid: user.uid }; let action = new UnsubscribeAction(params); console.log("[AgoraModule] - push UnsubscribeAction ", action); dispatch(setAction({ action: action })); } const joinFallbackToProxy = (proxyServer: string) => { if (!handlerErrorProxy) { setTimeout(() => { if (AgoraContext.getDeterminants().getConnectionState().curState == ConnectionStatesEnum.CONNECTING) { Disconnect(EActionPriorityType.SUPER_LIFO); ActiveProxy(); setHandlerErrorProxy(false); } }, reintenTimeProxyFailBack); setHandlerErrorProxy(true); } } const networkQuality = (NetworkQuality: NetworkQuality) => { AgoraContext.getDeterminants().setNetworkQuality(NetworkQuality); } /* * ACTIONS TO EXPOSE */ function Init() { let params: InitActionParams = { init: true }; let action = new InitAction(params); console.log("[AgoraModule] - push InitAction ", action); dispatch(setAction({ action: action })); } function RegionChange(channel: string, role: RoleUserEnum, requiredConfirm?: boolean, keepTracks?: boolean) { let params: RegionChangeActionParams = { channel: channel, role: role }; if (keepTracks != undefined || keepTracks != null) { params.keepTracks = keepTracks; } else { params.keepTracks = false; } if (requiredConfirm != undefined || requiredConfirm != null) { params.requiredConfirm = requiredConfirm; } else { params.requiredConfirm = false }; let action = new RegionChangeAction(params); console.log("[AgoraModule] - push RegionChangeAction ", action); dispatch(setAction({ action: action })); } function ReJoin(channel?: string, role?: RoleUserEnum) { dispatch(clearAction()); setTimeout(() => { Disconnect(EActionPriorityType.SUPER_LIFO); if (channel && role) { RegionChange(channel, role, true, true); } else { RegionChange(AgoraContext.getDeterminants().ChannelIncoming, AgoraContext.getDeterminants().RoleIncoming, true, true); } }, 300); } function ActiveProxy() { let params: ActiveProxyActionParams = { type: 3 }; let action = new ActiveProxyAction(params); console.log("[AgoraModule] - push ActiveProxyAction ", action); dispatch(setAction({ action: action })); } function Disconnect(priority?: EActionPriorityType) { let params: DisconnectParams = { datetime: Date.now(), priority: priority ? priority : EActionPriorityType.SUPER_LIFO }; let action = new DisconnectAction(params); console.log("[AgoraModule] - push DisconnectAction ", action); dispatch(setAction({ action: action })); } function ToggleVoice(mute?: boolean) { let params: ToggleVoiceActionParams = { action: mute != undefined ? mute : !AgoraContext.getDeterminants().getMuted() }; let action = new ToggleVoiceAction(params); console.log("[AgoraModule] - push ToggleVoiceAction ", action); dispatch(setAction({ action: action })); } function ChangeDevice(type: DeviceTypeEnum, device: DeviceT) { let params: ChangeDeviceActionParams = { device: device, type: type }; let action = new ChangeDeviceAction(params); console.log("[AgoraModule] - push ChangeDeviceAction ", action); dispatch(setAction({ action: action })); } function ShareCamera(active?: boolean) { let params: ShareCameraActionParams = { active: active != undefined ? active : !AgoraContext.getDeterminants().getHasCamera() }; let action = new ShareCameraAction(params); console.log("[AgoraModule] - push ShareCameraAction ", action); dispatch(setAction({ action: action })); } function ShareScreen(active?: boolean) { let params: ShareScreenActionParams = { active: active != undefined ? active : !AgoraContext.getDeterminants().getHasScreen() }; let action = new ShareScreenAction(params); console.log("[AgoraModule] - push ShareScreenAction ", action); dispatch(setAction({ action: action })); } function ChangeRole(role: RoleUserEnum) { let params: ChangeRoleParams = { role: role }; let action = new ChangeRoleAction(params); console.log("[AgoraModule] - push ChangeRoleAction ", action); dispatch(setAction({ action: action })); } function ChangeModuleConfig(app_id?: string, uid?: number | string, user?: any, client_config?: ClientConfig) { let params: ChangeModuleConfigParams = {}; if (app_id) params.app_id = app_id; if (uid) params.uid = uid; if (user) params.user = user; if (client_config) params.client_config = client_config; let action = new ChangeModuleConfigAction(params); console.log("[AgoraModule] - push ChangeModuleConfigAction ", action); dispatch(setAction({ action: action })); } /*TO SETUP CALLBACK LOGGER VIEW*/ function setLoggerExpose(value: Function) { AgoraContext.getDeterminants().setLoggerViewCallback(value); dispatch(setContext({ context: AgoraContext })); } /*TO SETUP INSTANCE TRANSPORT*/ function setTransportExpose(value: Function) { AgoraContext.getDeterminants().setTranport(new WSTransport(value)); } /*TO SETUP CALLBACK VOLUMEN*/ function setVolumenExpose(value: Function) { AgoraContext.getDeterminants().setVolumenCallback(value); dispatch(setContext({ context: AgoraContext })); } async function getDevices() { if (AgoraContext.getResources()) { const microphones = await AgoraContext.getResources().getMicrophones(); const cameras = await AgoraContext.getResources().getCameras(); const speakers = await AgoraContext.getResources().getSpeakers(); setMicrophones(microphones); setCameras(cameras); setSpeakers(speakers); } } return { Init, RegionChange, ReJoin, ActiveProxy, Disconnect, ToggleVoice, ChangeDevice, ShareCamera, ShareScreen, ChangeRole, ChangeModuleConfig, AgoraContext, Worker, setLoggerExpose, setTransportExpose, setVolumenExpose, microphones, cameras, speakers, contextUpdating, cameraSharing, screenSharing, initiated }; }