Chat.js 8.38 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) {
JeongYeonwoo's avatar
JeongYeonwoo committed
17

Soo Hyun Kim's avatar
soo0115    
Soo Hyun Kim committed
18
  const [inner, setInner] = useState([''])
Choi Ga Young's avatar
   
Choi Ga Young committed
19
20
  const [chat, setChat] = useState([INIT_CHAT])  
  
21
22
23
24
  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
25
26
27
28
  const [disabled, setDisabled] = useState(true)
  const [user, setUser] = useState('')
  const [error, setError] = useState('');

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

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

Choi Ga Young's avatar
Choi Ga Young committed
33
34
35
36
37
38
39
40
  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
41

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

    console.log(props.leftInfo)
48
49
50
  }

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

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

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

64
65
66
67
68
69
70
71
72
73
74
75
76
  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)
    }

77
  }
Choi Ga Young's avatar
Choi Ga Young committed
78

Choi Ga Young's avatar
Choi Ga Young committed
79
  function handleClick() {
Soo Hyun Kim's avatar
Soo Hyun Kim committed
80
    props.closeChatRoom(props.roomCode)
Choi Ga Young's avatar
Choi Ga Young committed
81
    props.setRecievedMsg('')
Choi Ga Young's avatar
Choi Ga Young committed
82
    props.handleChatc()
JeongYeonwoo's avatar
JeongYeonwoo committed
83
    setChat([''])
84
    recordEntryLog()
85
    props.setRoomCode('')
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
  }

  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
107
108
109
110
111

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

Choi Ga Young's avatar
Choi Ga Young committed
117
  async function exitAndCloseRoom() {
Soo Hyun Kim's avatar
Soo Hyun Kim committed
118
119
120
121
    props.exitRoom(props.roomCode)
    setExit(false)
    props.handleChatc()
  }
Choi Ga Young's avatar
Choi Ga Young committed
122

JeongYeonwoo's avatar
yeonwoo    
JeongYeonwoo committed
123
124
125
  useEffect(() => {
    getProfile(userId)
  }, [userId])
126

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

Soo Hyun Kim's avatar
Soo Hyun Kim committed
131
  useEffect(() => {
JeongYeonwoo's avatar
JeongYeonwoo committed
132
    setChat([...chat, { msg: props.recievedMsg, sender: props.recievedUser, img: props.recievedImg, time: props.recievedTime }])
Soo Hyun Kim's avatar
Soo Hyun Kim committed
133
134
  }, [props.recievedMsg])

135
136
137
138
139
  useEffect(() => {
    getPreviousChat()
  }, [props.roomCode])


우지원's avatar
ul    
우지원 committed
140
  return (
Soo Hyun Kim's avatar
Soo Hyun Kim committed
141
    <div id="chat" style={{ display: "flex", flexDirection: "column", borderStyle: "solid", borderRadius: "5px", borderColor: "#4A5D7E", backgroundColor: "#FFFFFF", padding: '15px', width: "100%", height: "90vh", position: "relative" }}>
Soo Hyun Kim's avatar
Soo Hyun Kim committed
142
      <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
143
        <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
144
        <div style={{ justifyContent: "center" }}>
Soo Hyun Kim's avatar
Soo Hyun Kim committed
145
146
          <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
147
        </div>
Choi Ga Young's avatar
Choi Ga Young committed
148
        <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
149
150
151
152
      </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
153
154
          <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
155
156
        </div>
        : null}
Soo Hyun Kim's avatar
Soo Hyun Kim committed
157
      <div id="chat-body" style={{ overflow: 'auto', padding: '15px', width: "100%", height: "75%", margin: "1%", background: '' }}>
JeongYeonwoo's avatar
JeongYeonwoo committed
158
        {chat.map((value, index) => {
159
          if (!(value.msg === '')) {
Choi Ga Young's avatar
Choi Ga Young committed
160
161
            if (value.sender === "system") {
              return (
Choi Ga Young's avatar
Choi Ga Young committed
162
                <Row style={{ background: "#F5F5F5", border: "none", justifyContent: "center" }}>
Choi Ga Young's avatar
Choi Ga Young committed
163
164
165
166
                  {value.msg}
                </Row>
              )
            } else if (!(value.sender === user.nickname)) {
JeongYeonwoo's avatar
JeongYeonwoo committed
167
              return (
우지원's avatar
chat    
우지원 committed
168
                <Row key={index} className='d-flex flex-wrap-nowrap mt-2' style={{ width: "95%", maxWidth: '95%' }}>
우지원's avatar
우지원 committed
169
                  <Col xs="auto">
우지원's avatar
chat    
우지원 committed
170
                    <Image src={value.img && `/images/${value.img}`} style={{ width: "55px", height: "55px" }} roundedCircle />
JeongYeonwoo's avatar
JeongYeonwoo committed
171
                  </Col>
우지원's avatar
chat    
우지원 committed
172
                  <Col className="ml-2">
JeongYeonwoo's avatar
JeongYeonwoo committed
173
                    <Row><strong>{value.sender}</strong></Row>
우지원's avatar
chat    
우지원 committed
174
                    <Row xs="auto" className='d-flex flex-wrap-nowrap'>
Soo Hyun Kim's avatar
Soo Hyun Kim committed
175
                      <Row style={{ width: 'max-content', maxWidth: '300px', height: 'auto', paddingLeft: '15px', paddingRight: '15px', background: '#f1ebf7', borderRadius: '5px', fontSize: 'x-large' }}>{value.msg}</Row>
우지원's avatar
chat    
우지원 committed
176
                      <Col className="ml-1">{value.time}</Col>
JeongYeonwoo's avatar
JeongYeonwoo committed
177
178
                    </Row>
                  </Col>
179
                </Row>
JeongYeonwoo's avatar
JeongYeonwoo committed
180
              )
Choi Ga Young's avatar
xxxxx    
Choi Ga Young committed
181
182
            } else {
              return ( //내가 보낸 메시지
우지원's avatar
chat    
우지원 committed
183
                <Row key={index} className='mt-2 justify-content-end' style={{ width: "100%" }}>
JeongYeonwoo's avatar
JeongYeonwoo committed
184
                  <Row className='d-flex flex-wrap-nowrap' >
우지원's avatar
우지원 committed
185
                    <Col xs="auto" className="ml-3">{value.time}</Col>
우지원's avatar
chat    
우지원 committed
186
                    <Col className='mr-1' name='msg' style={{ width: 'max-content', maxWidth: '300px', height: 'auto', paddingLeft: '15px', paddingRight: '15px', background: "#d6c8e3", borderRadius: '5px', fontSize: 'x-large' }}>{value.msg}</Col>
JeongYeonwoo's avatar
JeongYeonwoo committed
187
                  </Row>
188
                </Row>
JeongYeonwoo's avatar
JeongYeonwoo committed
189
190
191
192
              )
            }
          } else {
            return null
JeongYeonwoo's avatar
JeongYeonwoo committed
193
          }
JeongYeonwoo's avatar
JeongYeonwoo committed
194
        })
195
        }
Soo Hyun Kim's avatar
Soo Hyun Kim committed
196
197
198
199
200
201
202
      </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
203
                <FiSend size="16px" color="#FAFAFA" />
Soo Hyun Kim's avatar
Soo Hyun Kim committed
204
205
206
207
208
              </Button>
            </Form.Group>
          </Form>
        </div>
      </div>
Soo Hyun Kim's avatar
Soo Hyun Kim committed
209
    </div>
우지원's avatar
ul    
우지원 committed
210
211
212
  );
}

Soo Hyun Kim's avatar
Soo Hyun Kim committed
213

우지원's avatar
ul    
우지원 committed
214
export default Chat;
JeongYeonwoo's avatar
JeongYeonwoo committed
215