11일차
2024. 8. 2. 19:15ㆍFCB2O4
어제 만든 리액트 코드에 엔터키로 입력되도록 하는 코드 작성
const enterKey = (e) => {
if(e.key === 'Enter'){
e.preventDefault();
sendMessage();
}
}
<input
type="text"
value={message}
onChange={(e) => setMessage(e.target.value)}
disabled={!connected}
onKeyDown={enterKey}
/>
이모지 파일을 LiveChat 파일과 연동
//Emoji.js
import React from 'react';
import '../css/Streaming.css';
const emojiList = [
// 중략
];
function Emoji({onSelect}) {
return (
<div className="emoji-list">
<div className="emoji-picker">
{emojiList.map((emoji, index) => (
<span
key={index}
onClick={() => onSelect(emoji)}
className="emoji"
>
{emoji}
</span>
))}
</div>
</div>
);
}
export default Emoji;
//LiveChat.js
// 중략..
const [emojiPick, setEmojiPick] = useState(false);
// 중략...
const emojiPicker = () => {
setEmojiPick(!emojiPick);
}
const emojiMessage = (emoji) => {
setMessage((prevMessages) => prevMessages + emoji);
}
// 중략...
<div className='chat-box'>
<div className='input-container'>
{emojiPick && <Emoji onSelect={emojiMessage} />}
<input
type="text"
value={message}
onChange={(e) => setMessage(e.target.value)}
disabled={!connected}
onKeyDown={enterKey}
className='message-input'
/>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
fill="currentColor"
className="bi bi-emoji-smile emoji-icon"
viewBox="0 0 16 16"
onClick={emojiPicker} // 아이콘 클릭 시 이모지 리스트 보이기
>
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16"/>
<path d="M4.285 9.567a.5.5 0 0 1 .683.183A3.5 3.5 0 0 0 8 11.5a3.5 3.5 0 0 0 3.032-1.75.5.5 0 1 1 .866.5A4.5 4.5 0 0 1 8 12.5a4.5 4.5 0 0 1-3.898-2.25.5.5 0 0 1 .183-.683M7 6.5C7 7.328 6.552 8 6 8s-1-.672-1-1.5S5.448 5 6 5s1 .672 1 1.5m4 0c0 .828-.448 1.5-1 1.5s-1-.672-1-1.5S9.448 5 10 5s1 .672 1 1.5"/>
</svg>
</div>
</div>
스트리밍 화면과 채팅창을 2:1 비율로 나누기 위해 전체 컨테이너에 flex 지정
.streaming-container {
display: flex;
}
채팅창 정리 및 이모지 아이콘을 input창 안에 넣기
.chat-container {
display: flex;
flex-direction: column;
height: 700px;
width: 400px;
margin: 10px;
border: 1px solid #ccc;
}
.messages {
flex: 1;
overflow-y: auto;
padding: 10px;
}
.chat-box {
display: flex;
align-items: center;
padding: 10px;
border-top: 1px solid #ccc;
background: #fff;
}
.input-container {
position: relative; /* 이모지 아이콘을 입력창 안에 위치시키기 */
flex: 1;
}
.message-input {
width: 100%;
padding: 10px;
padding-right: 40px;
box-sizing: border-box;
}
이모지 아이콘 위치 설정
.emoji-icon {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%); /* 대상을 y축(수직) 이동. -50% : 자신의 높이의 절반만큼 위로 이동 */
cursor: pointer;
width: 24px;
height: 24px;
}
이모지 리스트 위치 및 크기 지정
.emoji-list {
font-family: sans-serif;
text-align: center;
padding: 1rem;
width: 400px;
height: 200px;
border: 1px solid #ccc;
background: #fff;
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%); /* 대상을 x축(수평) 이동. -50% : 자신의 너비의 절반만큼 왼쪽로 이동 */
z-index: 1000;
}
.emoji-picker {
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: 1rem;
max-height: 100%;
overflow-y: auto; /* 스크롤바 생성 */
padding-right: 10px;
}
.emoji {
cursor: pointer;
font-size: 1rem;
}
자동 스크롤 구현
const messagesEndRef = useRef(null);
// 중략...
useEffect(() => {
// 메시지가 업데이트될 때마다 자동으로 스크롤을 아래로 이동
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
}, [messages]);
// 중략
<div className='chat-container'>
<div className='messages'>
{messages.map((msg, index) => (
<div key={index}>
<strong>{msg.sender}</strong>: {msg.content}
</div>
))}
<div ref={messagesEndRef} />
</div>