All files / src/pages/spacePage Space.tsx

0% Statements 0/54
0% Branches 0/28
0% Functions 0/11
0% Lines 0/52

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172                                                                                                                                                                                                                                                                                                                                                       
import React, {useEffect, useRef, useState} from 'react';
import {RouteComponentProps} from 'react-router-dom';
import io from 'socket.io-client';
import PeerManager, {AudioAnalyser, Me, Vec2} from '../../utils/RTCGameUtils';
import Navigation from '../../components/Navigation';
import SpaceCanvas from '../../components/SpaceCanvas';
import './space.css';
import {message} from 'antd';
import RTCSignalingHelper from '../../utils/RTCSignalingHelper';
import {iceConfig} from '../../utils/IceServerList';
import SpaceLoading from '../../components/SpaceLoading';
 
const qs = require('query-string');
 
interface SpaceQuery {
  roomId: string;
  nickname: string;
  avatarIdx: number;
  speakerDeviceID: string;
  micDeviceID: string;
}
 
export interface LoadingInfo {
  needToLoad: number;
  finishLoad: number;
}
 
function setNewPeerManager(
  spaceMainContainer: HTMLDivElement,
  audioContainer: HTMLDivElement,
  query: SpaceQuery,
  initialCenterPos: Vec2,
  successCallBack: (arg0: PeerManager) => void,
  failCallBack: () => void,
): void {
  navigator.mediaDevices
    .getUserMedia({video: false, audio: {deviceId: query.micDeviceID}}) // 오디오 연결
    .then((stream: MediaStream) => {
      const socket = io(`${process.env.REACT_APP_SOCKET_URL}`, {
        reconnection: false,
      });
      if (!socket) {
        failCallBack();
        return;
      }
      socket.on('connect', () => {
        const signalingHelper = new RTCSignalingHelper(socket);
        const audioAnalyser = new AudioAnalyser(stream);
        const nicknameDiv = document.createElement('div') as HTMLDivElement;
        nicknameDiv.className = 'canvasOverlay';
        spaceMainContainer.appendChild(nicknameDiv);
 
        const textMessageDiv = document.createElement('div') as HTMLDivElement;
        textMessageDiv.className = 'canvasOverlay';
        spaceMainContainer.appendChild(textMessageDiv);
 
        const me = new Me(
          nicknameDiv,
          textMessageDiv,
          audioAnalyser,
          initialCenterPos,
          query.nickname,
          '',
          Number(query.avatarIdx),
        );
 
        const peerManager = new PeerManager(
          signalingHelper,
          stream,
          audioContainer,
          spaceMainContainer,
          iceConfig,
          query.roomId,
          me,
          query.speakerDeviceID,
          query.micDeviceID,
        );
        successCallBack(peerManager);
        console.log('socket connected');
      });
    })
    .catch(() => {
      failCallBack();
    });
 
  return;
}
 
function isQueryValid(query: SpaceQuery) {
  if (!query.nickname || query.nickname === '') {
    return false;
  }
  if (!query.avatarIdx) {
    return false;
  }
  if (!query.micDeviceID) {
    query.micDeviceID = 'default';
  }
  if (!query.speakerDeviceID) {
    query.speakerDeviceID = 'default';
  }
  return true;
}
 
function Space(props: RouteComponentProps): JSX.Element {
  //state
  const [peerManager, setPeerManager] = useState<PeerManager | null>(null);
  //query validate part
  const query = qs.parse(props.location.search) as SpaceQuery; // URL에서 쿼리 부분 파싱하여 roomId, nickname, avatarIdx 를 가진 SpaceMainQuery 객체에 저장
  if (!query.roomId || query.roomId === '') {
    message.info('올바르지 않은 접근입니다. roomId를 확인해 주세요.');
    props.history.push('/');
  }
  if (!isQueryValid(query)) {
    props.history.push(`/setting?roomId=${query.roomId}`);
  }
  //ref
  const spaceMainContainerRef = useRef<HTMLDivElement>(null);
  const audioContainerRef = useRef<HTMLDivElement>(null);
 
  //useEffect onMounted
  useEffect(() => {
    if (!isQueryValid(query)) return;
    if (!spaceMainContainerRef.current || !audioContainerRef.current) {
      console.error('can not find div,audio Container error');
      return;
    }
    setNewPeerManager(
      spaceMainContainerRef.current,
      audioContainerRef.current,
      query,
      {x: 150, y: 150},
      (peerManager: PeerManager) => {
        setPeerManager(peerManager);
      },
      () => {
        console.error('setNewPeerManager error');
      },
    );
    return () => {
      if (peerManager) peerManager.close();
    };
  }, []);
 
  const goToHome = () => {
    props.history.push('/');
  };
 
  return (
    <div id="spaceMainContainer" ref={spaceMainContainerRef}>
      {peerManager ? (
        <>
          <SpaceCanvas peerManager={peerManager} />
          <Navigation peerManager={peerManager} goToHome={goToHome} />
        </>
      ) : (
        <SpaceLoading
          loadingPercentage={0}
          message="오디오를 가져오고 서버와 연결 중"
        ></SpaceLoading>
      )}
      <div
        id="audioContainer"
        ref={audioContainerRef}
        style={{width: '0', height: '0'}}
      ></div>
    </div>
  );
}
 
export default Space;