Chat.js 8.51 KB
Newer Older
JeongYeonwoo's avatar
yeonwoo    
JeongYeonwoo committed
1
import axios from 'axios';
Soo Hyun Kim's avatar
soo0115    
Soo Hyun Kim committed
2
import React, { useState, useEffect } from 'react';
JeongYeonwoo's avatar
yeonwoo    
JeongYeonwoo committed
3
4
5
import { Form, Button, Row, Image, Col, Container } from 'react-bootstrap';
import { isAuthenticated } from '../utils/auth';
import catchErrors from '../utils/catchErrors';
Soo Hyun Kim's avatar
Soo Hyun Kim committed
6
7
import { BsCaretLeftFill, BsList, BsExclamationCircleFill, BsCheck, BsX } from "react-icons/bs";
import { FiSend } from "react-icons/fi";
JeongYeonwoo's avatar
JeongYeonwoo committed
8
9
10
11
12
13
14

const INIT_CHAT = {
  msg: '',
  sender: '',
  img: '',
  time: ''
}
15

우지원's avatar
ul    
우지원 committed
16
function Chat(props) {
Choi Ga Young's avatar
Choi Ga Young committed
17
  //const [sender, setSender] = useState([])
JeongYeonwoo's avatar
JeongYeonwoo committed
18

Choi Ga Young's avatar
Choi Ga Young committed
19
  //const [roomName, setRoomName] = useState('')
Soo Hyun Kim's avatar
soo0115    
Soo Hyun Kim committed
20
  const [inner, setInner] = useState([''])
JeongYeonwoo's avatar
JeongYeonwoo committed
21
  const [chat, setChat] = useState([INIT_CHAT])   //object로 key는 보낸사람 value는 메세지
JeongYeonwoo's avatar
JeongYeonwoo committed
22

23
24
25
26
  const simpleTime = new Date().toLocaleTimeString()
  const usualTime = simpleTime.substring(0, simpleTime.length - 3)
  const realTime = new Date().toISOString()

Choi Ga Young's avatar
Choi Ga Young committed
27
28
29
30
  const [disabled, setDisabled] = useState(true)
  const [user, setUser] = useState('')
  const [error, setError] = useState('');

Soo Hyun Kim's avatar
Soo Hyun Kim committed
31
  const [exit, setExit] = useState(false);
Choi Ga Young's avatar
Choi Ga Young committed
32
33

  const userId = isAuthenticated()
Soo Hyun Kim's avatar
Soo Hyun Kim committed
34

Choi Ga Young's avatar
Choi Ga Young committed
35
36
37
38
39
40
41
42
  async function getProfile(userId) {
    try {
      const response = await axios.get(`/users/${userId}`)
      setUser(response.data)
    } catch (error) {
      catchErrors(error, setError)
    }
  }
Soo Hyun Kim's avatar
soo0115    
Soo Hyun Kim committed
43

44
45
  function handleChange(e) {
    e.preventDefault()
Soo Hyun Kim's avatar
soo0115    
Soo Hyun Kim committed
46
    setInner(e.target.value)
JeongYeonwoo's avatar
yeonwoo    
JeongYeonwoo committed
47
    setDisabled(false)
48
49

    console.log(props.leftInfo)
50
51
52
  }

  function sendMsgCH(e) {
Soo Hyun Kim's avatar
soo0115    
Soo Hyun Kim committed
53
    e.preventDefault()
JeongYeonwoo's avatar
JeongYeonwoo committed
54

55
    props.setSingleTime(usualTime)
JeongYeonwoo's avatar
JeongYeonwoo committed
56
57
    props.setSingleImg(user.profileimg)
    props.setSingleUser(user.nickname)
Soo Hyun Kim's avatar
soo0115    
Soo Hyun Kim committed
58
    props.setSingleChat(inner)
59
    props.sendMsg(e)
Soo Hyun Kim's avatar
soo0115    
Soo Hyun Kim committed
60
    setInner('')
JeongYeonwoo's avatar
yeonwoo    
JeongYeonwoo committed
61
    setDisabled(true)
62
63

    recordEntryLog()  //그냥 새로고침해도 최신화
64
  }
Choi Ga Young's avatar
Choi Ga Young committed
65

66
67
68
69
70
71
72
73
74
75
76
77
78
79

  async function recordEntryLog() {
    const leaveInfo = { userId: userId, roomCode: props.roomCode, leaveTime: realTime }
    try {
      const check = await axios.get('/room/entrylog', { params: leaveInfo })
      if (check.data) {       //있으면 put으로
        await axios.put('/room/entrylog', leaveInfo)
      } else {        //없으면 post
        await axios.post('/room/entrylog', leaveInfo)
      }
    } catch (error) {
      catchErrors(error, setError)
    }

80
  }
Choi Ga Young's avatar
Choi Ga Young committed
81

82

Choi Ga Young's avatar
Choi Ga Young committed
83
  function handleClick() {
Soo Hyun Kim's avatar
Soo Hyun Kim committed
84
    props.closeChatRoom(props.roomCode)
Choi Ga Young's avatar
Choi Ga Young committed
85
    props.setRecievedMsg('')
Choi Ga Young's avatar
Choi Ga Young committed
86
    props.handleChatc()
JeongYeonwoo's avatar
JeongYeonwoo committed
87
    setChat([''])
88
    props.setLeaveInfo([...props.leaveInfo, { roomName: props.roomCode, leaveTime: realTime }])
89
    recordEntryLog()
90
    props.setRoomCode('')
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
  }

  function settingtime(hour) {
    let newhour = parseInt(hour) + 9
    if (newhour >= 24) {
      newhour -= 24
    }
    if (newhour >= 13) {
      newhour -= 12
      newhour = '오후 ' + newhour
    } else {
      newhour = '오전 ' + newhour
    }
    return newhour
  }

  //이전 채팅 내용에 대한 것 불러오기
  //프사 닉네임 메세지가 각각의 배열로 들어가서 띄워지는 방식
  async function getPreviousChat() {
    const respond = await axios.get('/room/getChatInfo', { params: { 'roomCode': props.roomCode } })
    const info = respond.data
JeongYeonwoo's avatar
JeongYeonwoo committed
112
113
114
115
116

    let intochat = []
    for (let prop in info) {
      let hour = info[prop].createdAt.split('T')[1].split(':')
      hour = settingtime(hour[0]) + ':' + hour[1]
117
      intochat.push({ msg: info[prop].message, sender: info[prop].username, img: info[prop].profileimg, time: hour })
118
    }
JeongYeonwoo's avatar
JeongYeonwoo committed
119
    setChat(intochat)
Choi Ga Young's avatar
Choi Ga Young committed
120
121
  }

Choi Ga Young's avatar
Choi Ga Young committed
122
  async function exitAndCloseRoom() {
Soo Hyun Kim's avatar
Soo Hyun Kim committed
123
124
125
126
    props.exitRoom(props.roomCode)
    setExit(false)
    props.handleChatc()
  }
Choi Ga Young's avatar
Choi Ga Young committed
127

JeongYeonwoo's avatar
yeonwoo    
JeongYeonwoo committed
128
129
130
  useEffect(() => {
    getProfile(userId)
  }, [userId])
131

Soo Hyun Kim's avatar
soo0115    
Soo Hyun Kim committed
132
  useEffect(() => {
JeongYeonwoo's avatar
JeongYeonwoo committed
133
    setChat([...chat, { msg: props.singleChat, sender: props.singleUser, img: props.singleImg, time: props.singleTime }])
Soo Hyun Kim's avatar
soo0115    
Soo Hyun Kim committed
134
  }, [props.singleChat])
JeongYeonwoo's avatar
yeonwoo    
JeongYeonwoo committed
135

Soo Hyun Kim's avatar
Soo Hyun Kim committed
136
  useEffect(() => {
JeongYeonwoo's avatar
JeongYeonwoo committed
137
    setChat([...chat, { msg: props.recievedMsg, sender: props.recievedUser, img: props.recievedImg, time: props.recievedTime }])
Soo Hyun Kim's avatar
Soo Hyun Kim committed
138
139
  }, [props.recievedMsg])

140
141
142
143
144
  useEffect(() => {
    getPreviousChat()
  }, [props.roomCode])


우지원's avatar
ul    
우지원 committed
145
  return (
Soo Hyun Kim's avatar
Soo Hyun Kim committed
146
147
    <div id="chat" style={{ display: "flex", flexDirection: "column", borderStyle: "solid", borderRadius: "5px", borderColor: "#4A5D7E", backgroundColor: "#FFFFFF", padding: '15px', width: "100%", height: "580px", position: "relative" }}>
      <div id="chat-head" style={{ display: "flex", flexDirection: "row", justifyContent: "space-between", alignItems: "center", width: "100%", height: "80px" }}>
Choi Ga Young's avatar
Choi Ga Young committed
148
        <a href="#;" onClick={handleClick} style={{ margin: "0px 0px 0px 15px" }}><BsCaretLeftFill size="20" color="#333333" /></a>
Soo Hyun Kim's avatar
Soo Hyun Kim committed
149
        <div style={{ justifyContent: "center" }}>
Soo Hyun Kim's avatar
Soo Hyun Kim committed
150
151
          <p style={{ color: "#333333", fontWeight: "bold", fontSize: "1.6em", textAlign: "center", margin: "0px 0px 0.5px 0px" }}> {props.roomName} </p>
          <p style={{ color: "#333333", fontSize: "0.8em", textAlign: "center", margin: "0.5px 0px 0px 0px" }}> {props.roomCode} </p>
Soo Hyun Kim's avatar
Soo Hyun Kim committed
152
        </div>
Choi Ga Young's avatar
Choi Ga Young committed
153
        <a href="#;" onClick={() => setExit(!exit)} style={{ margin: "0px 15px 0px 0px" }}><BsList size="20" color="#333333" /></a>
Soo Hyun Kim's avatar
Soo Hyun Kim committed
154
155
156
157
      </div>
      {exit ?
        <div id="chat-exit-check" style={{ display: "flex", flexDirection: "row", justifyContent: "space-evenly", alignItems: "center", margin: "1%", backgroundColor: "#30284D", borderRadius: "5px", height: "50px" }}>
          <p style={{ width: "70%", color: "#FAFAFA", fontSize: "1em", margin: "0px 10px 0px 20px" }}><BsExclamationCircleFill size="1em" color="#F2D788" />  퇴장하시겠습니까?</p>
Choi Ga Young's avatar
Choi Ga Young committed
158
159
          <a href="#;" onClick={exitAndCloseRoom}><BsCheck size="1em" color="#F2D788" /></a>
          <a href="#;" onClick={() => setExit(!exit)}><BsX size="1em" color="#F2D788" /></a>
Soo Hyun Kim's avatar
Soo Hyun Kim committed
160
161
        </div>
        : null}
Soo Hyun Kim's avatar
Soo Hyun Kim committed
162
      <div id="chat-body" style={{ overflow: 'auto', padding: '15px', width: "100%", height: "400px", margin: "1%", background: '' }}>
JeongYeonwoo's avatar
JeongYeonwoo committed
163
        {chat.map((value, index) => {
164
          if (!(value.msg === '')) {
Choi Ga Young's avatar
Choi Ga Young committed
165
166
            if (value.sender === "system") {
              return (
Choi Ga Young's avatar
Choi Ga Young committed
167
                <Row style={{ background: "#F5F5F5", border: "none", justifyContent: "center" }}>
Choi Ga Young's avatar
Choi Ga Young committed
168
169
170
171
                  {value.msg}
                </Row>
              )
            } else if (!(value.sender === user.nickname)) {
JeongYeonwoo's avatar
JeongYeonwoo committed
172
173
174
              return (
                <Row key={index} className='m-1' >
                  <Col xs={2}>
JeongYeonwoo's avatar
JeongYeonwoo committed
175
                    <Image src={value.img && `/images/${value.img}`} style={{ width: "50px", height: "50px" }} roundedCircle />
JeongYeonwoo's avatar
JeongYeonwoo committed
176
177
                  </Col>
                  <Col xs={8}>
JeongYeonwoo's avatar
JeongYeonwoo committed
178
                    <Row><strong>{value.sender}</strong></Row>
JeongYeonwoo's avatar
JeongYeonwoo committed
179
                    <Row className='d-flex flex-wrap-nowrap'>
180
                      <Row className='border' style={{ width: 'max-content', maxWidth: '300px', height: 'auto', paddingLeft: '15px', paddingRight: '15px', background: '#f1ebf7', borderRadius: '5px', fontSize: 'x-large' }}>{value.msg}</Row>
JeongYeonwoo's avatar
JeongYeonwoo committed
181
                      <Col className='ml-1'>{value.time}</Col>
JeongYeonwoo's avatar
JeongYeonwoo committed
182
183
                    </Row>
                  </Col>
184
                </Row>
JeongYeonwoo's avatar
JeongYeonwoo committed
185
              )
Choi Ga Young's avatar
xxxxx    
Choi Ga Young committed
186
187
            } else {
              return ( //내가 보낸 메시지
JeongYeonwoo's avatar
JeongYeonwoo committed
188
189
                <Row key={index} className='m-1 justify-content-end'>
                  <Row className='d-flex flex-wrap-nowrap' >
JeongYeonwoo's avatar
JeongYeonwoo committed
190
                    <Col className='mr-1'>{value.time}</Col>
Soo Hyun Kim's avatar
Soo Hyun Kim committed
191
                    <Row className='mr-2' name='msg' style={{ width: 'max-content', maxWidth: '300px', height: 'auto', paddingLeft: '15px', paddingRight: '15px', background: "#d6c8e3", borderRadius: 'px', fontSize: 'x-large' }}>{value.msg}</Row>
JeongYeonwoo's avatar
JeongYeonwoo committed
192
                  </Row>
193
                </Row>
JeongYeonwoo's avatar
JeongYeonwoo committed
194
195
196
197
              )
            }
          } else {
            return null
JeongYeonwoo's avatar
JeongYeonwoo committed
198
          }
JeongYeonwoo's avatar
JeongYeonwoo committed
199
        })
200
        }
Soo Hyun Kim's avatar
Soo Hyun Kim committed
201
202
203
204
205
206
207
      </div>
      <div id="chat-low-side" style={{ width: "95%", height: "60px", position: "absolute", bottom: "0", padding: "10px 5px 5px 10px" }}>
        <div id="chat-form" style={{ width: "100%", height: "100%", borderStyle: "solid", borderWidth: "2px", borderColor: "#C1C1C1", borderRadius: "25px", padding: "3px 2px 2px 3px" }}>
          <Form onSubmit={sendMsgCH}>
            <Form.Group style={{ display: "flex", flexDirection: "row", justifyContent: "space-evenly" }}>
              <Form.Control name='chat' type="text" value={inner} onChange={handleChange} style={{ width: "80%", height: "90%", borderColor: "#FFFFFF" }} />
              <Button type="submit" disabled={disabled} style={{ justifyContent: "center", width: "10%", height: "90%", borderRadius: "20px", backgroundColor: "#C1C1C1", borderColor: "#FFFFFF" }}>
우지원's avatar
오픈    
우지원 committed
208
                <FiSend size="16px" color="#FAFAFA" />
Soo Hyun Kim's avatar
Soo Hyun Kim committed
209
210
211
212
213
              </Button>
            </Form.Group>
          </Form>
        </div>
      </div>
Soo Hyun Kim's avatar
Soo Hyun Kim committed
214
    </div>
우지원's avatar
ul    
우지원 committed
215
216
217
  );
}

Soo Hyun Kim's avatar
Soo Hyun Kim committed
218

우지원's avatar
ul    
우지원 committed
219
export default Chat;
JeongYeonwoo's avatar
JeongYeonwoo committed
220