Skip to content

Commit

Permalink
Merge pull request #71 from SWM-FIRE/FIRE-359-fe-video-소켓과-연결
Browse files Browse the repository at this point in the history
FIRE-359-fe-video-소켓과-연결
  • Loading branch information
071yoon authored Jul 26, 2022
2 parents d63c54b + cf1fe05 commit 2cde9df
Show file tree
Hide file tree
Showing 14 changed files with 312 additions and 25 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ REACT_APP_SOCKET_URL=https://xn--hq1br4kwqt.com/socket/room
REACT_APP_ROOM=http://172.16.101.93:8282/room
REACT_APP_SEND_USER_INFORMATION_URL=https://모도코.com/api/v1/users
REACT_APP_SOCKET_CHAT_URL=https://모도코.com/socket/chat
REACT_APP_SOCKET_VIDEO_URL=https://모도코.com/socket/video
REACT_APP_GET_USER_INFO=https://모도코.com/api/v1/users/
130 changes: 130 additions & 0 deletions src/components/room/LocalScreen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import React, { useEffect, useRef } from 'react';
import styled from 'styled-components';
import MyAvatar from '../../assets/avatar/MyAvatar';
import controlModal from '../../stores/controlModal';
import { useCreateMediaStream } from '../rtc/hooks/useCreateLocalStream';

export default function LocalScreen({ nickname, avatar, uid }) {
const { userMediaStream, createMediaStream } = useCreateMediaStream();
useEffect(() => {
createMediaStream();
}, []);
const { toggleModal, setNickname, setAvatar, setUid } = controlModal();
const videoRef = useRef<HTMLVideoElement>(null);
const OpenModal = () => {
setNickname(nickname);
setAvatar(avatar);
setUid(uid);
toggleModal();
};

useEffect(() => {
if (videoRef.current) {
videoRef.current.srcObject = userMediaStream;
}
}, [videoRef, userMediaStream]);

return (
<Container onClick={OpenModal}>
<Video ref={videoRef} autoPlay playsInline muted />
<ControlBar>
<ChatContainer>
<ChatInner>
<Chats>Lorem ipsum dolor sit amet,</Chats>
<Chats>Vestibulum sit amet tellus suscipit</Chats>
</ChatInner>
</ChatContainer>
<AvatarPosition>
<MyAvatar num={Number(avatar)} />
<NameContainer>{nickname}</NameContainer>
</AvatarPosition>
</ControlBar>
</Container>
);
}

const Container = styled.div`
position: relative;
cursor: pointer;
@media (max-width: 900px) {
width: 60%;
height: 0;
padding-bottom: 38%;
}
width: 36%;
height: 0;
padding-bottom: 22%;
border-radius: 1rem;
position: relative;
`;

const ControlBar = styled.div`
z-index: 1;
position: absolute;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
`;

const ChatInner = styled.div`
display: flex;
flex-direction: column;
align-items: center;
position: absolute;
bottom: 0;
gap: 1rem;
`;

const ChatContainer = styled.div`
width: calc(100% - 3rem);
height: calc(95% - 3rem);
position: absolute;
bottom: calc(5% + 3rem);
overflow: hidden;
margin-left: 1.2rem;
`;

const Chats = styled.div`
align-self: flex-start;
padding: 1.6rem;
background-color: rgba(53, 69, 122, 0.8);
font-family: IBMPlexSansKRRegular;
font-weight: 400;
border-radius: 0.8rem;
font-size: 15px;
line-height: 22px;
color: #ffffff;
`;

const NameContainer = styled.div`
padding: 1%;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.6rem;
font-family: IBMPlexSansKRRegular;
color: #f9fafb;
`;

const AvatarPosition = styled.div`
bottom: calc(-5% - 4rem);
height: calc(10% + 6rem);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
svg {
height: 100%;
}
position: absolute;
`;

const Video = styled.video`
z-index: 0;
width: 100%;
height: 100%;
border-radius: 1rem;
position: absolute;
`;
11 changes: 6 additions & 5 deletions src/components/room/Participants.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import styled from 'styled-components';
import mockPeople from '../../mockPoeple.json';
import SingleParticipant from './SingleParticipant';
import connectedUsersStore from '../../stores/connectedUsersStore';

export default function Participants() {
const { connectedUsers } = connectedUsersStore();
return (
<Component>
<Title>참여자 목록</Title>
Expand All @@ -11,11 +12,11 @@ export default function Participants() {
nickname={localStorage.getItem('nickname')}
avatar={localStorage.getItem('avatar')}
/>
{mockPeople.people.map((person) => (
{connectedUsers.map((user) => (
<SingleParticipant
key={person.nickname}
nickname={person.nickname}
avatar={person.avatar}
key={user.nickname}
nickname={user.nickname}
avatar={user.avatar}
/>
))}
</UserList>
Expand Down
25 changes: 16 additions & 9 deletions src/components/room/ScreenModal.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import React from 'react';
import React, { useRef, useEffect } from 'react';
import styled from 'styled-components';
import ModalPortal from '../atoms/ModalPotal';
import { ReactComponent as LeftArrow } from '../../assets/svg/arrow-left.svg';
import controlModal from '../../stores/controlModal';
import MyAvatar from '../../assets/avatar/MyAvatar';
import { useCreateMediaStream } from '../rtc/hooks/useCreateLocalStream';

export default function ScreenModal() {
const { nickname, avatar, toggleModal } = controlModal();
const videoRef = useRef<HTMLVideoElement>(null);
const { uid, nickname, avatar, toggleModal } = controlModal();
const { userMediaStream } = useCreateMediaStream();
useEffect(() => {
if (uid === localStorage.getItem('uid') && videoRef.current) {
videoRef.current.srcObject = userMediaStream;
}
}, [videoRef, userMediaStream]);

return (
<ModalPortal>
<ModalBackground>
Expand All @@ -18,19 +27,16 @@ export default function ScreenModal() {
<MyAvatar num={Number(avatar)} />
<Nickname>{nickname}</Nickname>
</ModalController>
<Screen />
<ModalVideo ref={videoRef} autoPlay playsInline muted />
</ModalBox>
</ModalBackground>
</ModalPortal>
);
}

const Screen = styled.div`
const ModalVideo = styled.video`
margin-top: 1.6rem;
width: calc(100% - 1.43rem);
height: 0;
padding-bottom: 53%;
background-color: #4a4a4a;
`;

const Nickname = styled.div`
Expand Down Expand Up @@ -60,10 +66,10 @@ const ArrowBox = styled.div`
const ModalBackground = styled.div`
position: fixed;
width: 100%;
height: 100%;
height: 100vh;
justify-content: center;
align-items: center;
top: 0;
top: -7rem;
display: flex;
z-index: 999;
`;
Expand All @@ -79,4 +85,5 @@ const ModalBox = styled.div`
border-radius: 1rem;
display: flex;
flex-direction: column;
overflow: auto;
`;
17 changes: 11 additions & 6 deletions src/components/room/ScreenShare.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
import { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import styled from 'styled-components';
import mockPeople from '../../mockPoeple.json';
import SingleScreen from './SingleScreen';
import LocalScreen from './LocalScreen';
import connectedUsersStore from '../../stores/connectedUsersStore';

export default function ScreenShare() {
const navigate = useNavigate();
const { connectedUsers } = connectedUsersStore();
useEffect(() => {
if (!localStorage.getItem('uid') || !localStorage.getItem('nickname')) {
alert('로그인 후 이용해주세요');
navigate('/main');
}
}, []);

return (
<Container>
<ScreenWrapper>
<SingleScreen
<LocalScreen
nickname={localStorage.getItem('nickname')}
avatar={localStorage.getItem('avatar')}
uid={localStorage.getItem('uid')}
/>
{mockPeople.people.map((person) => (
{connectedUsers.map((user) => (
<SingleScreen
key={person.nickname}
nickname={person.nickname}
avatar={person.avatar}
key={user.nickname}
nickname={user.nickname}
avatar={user.avatar}
uid={user.uid}
/>
))}
</ScreenWrapper>
Expand Down
5 changes: 4 additions & 1 deletion src/components/room/SingleScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ import controlModal from '../../stores/controlModal';
export default function SingleScreen({
nickname,
avatar,
uid,
}: {
nickname: string;
avatar: string;
uid: string;
}) {
const { toggleModal, setNickname, setAvatar } = controlModal();
const { toggleModal, setNickname, setAvatar, setUid } = controlModal();
const OpenModal = () => {
setNickname(nickname);
setAvatar(avatar);
setUid(uid);
toggleModal();
};
return (
Expand Down
28 changes: 28 additions & 0 deletions src/components/rtc/hooks/useCreateLocalStream.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import UserMediaStreamStore from '../../../stores/userMediaStreamStore';

export const useCreateMediaStream = () => {
const { userMediaStream, setUserMediaStream } = UserMediaStreamStore();

const stopMediaStream = () => {
if (userMediaStream) {
userMediaStream.getTracks().forEach((track) => track.stop());
}
setUserMediaStream(null);
};

const createMediaStream = async () => {
if (!userMediaStream?.active) {
try {
const stream = await navigator.mediaDevices.getDisplayMedia({
video: true,
audio: true,
});
setUserMediaStream(stream);
} catch (error) {
console.log(error);
}
}
};

return { userMediaStream, createMediaStream, stopMediaStream };
};
13 changes: 13 additions & 0 deletions src/hooks/useUserInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { useQuery } from 'react-query';
import axios from 'axios';

const getUser = async (senderUid) => {
const { data } = await axios.get(
(process.env.REACT_APP_GET_USER_INFO as string) + senderUid,
);
return data;
};

export default function useUserInfo(senderUid) {
return useQuery(['userData', 'getOne'], () => getUser(senderUid));
}
4 changes: 2 additions & 2 deletions src/interface/user.interface.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export default interface User {
uid: string;
nickname: string;
avatar: string;
nickname: string;
uid: string;
}
6 changes: 4 additions & 2 deletions src/mockPoeple.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
"people": [
{
"nickname": "groot",
"avatar": "10"
"avatar": "10",
"uid": "391230df8123f8hdsk"
},
{
"nickname": "halang",
"avatar": "27"
"avatar": "27",
"uid": "zgd8u9szsg8d09uz"
}
]
}
Loading

1 comment on commit 2cde9df

@vercel
Copy link

@vercel vercel bot commented on 2cde9df Jul 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.