feat: 채팅 유저 이름 표시 추가

This commit is contained in:
jhynsoo 2024-07-26 12:57:10 +09:00
parent 06ef530edd
commit 7963ece5bb
3 changed files with 72 additions and 25 deletions

View File

@ -3,6 +3,7 @@ import styles from './ChatRoom.module.css';
import { chatClient } from '../../utils/chat/chatClient';
import { useParams } from 'react-router-dom';
import SendIcon from '/src/assets/icons/send.svg?react';
import useBoundStore from '../../store';
const USER_ID = crypto.getRandomValues(new Uint32Array(1))[0];
@ -11,6 +12,7 @@ export default function ChatRoom() {
const { lectureId } = useParams();
const client = chatClient;
const [messages, setMessages] = useState([]);
const userName = useBoundStore((state) => state.userName) ?? '익명';
const inputRef = useRef(null);
const handleSubmit = (e) => {
e.preventDefault();
@ -24,7 +26,7 @@ export default function ChatRoom() {
destination: `/pub/message/${lectureId}`,
body: JSON.stringify({
userId: USER_ID,
name: '홍길동',
name: userName,
content: text,
}),
});
@ -35,8 +37,8 @@ export default function ChatRoom() {
client.onConnect = () => {
client.subscribe(`/sub/channel/${lectureId}`, (response) => {
const data = JSON.parse(response.body);
const message = data.content;
setMessages((prev) => [...prev, { id: prev.length, text: message, isMine: USER_ID === data.userId }]);
const { content: message, name } = data;
setMessages((prev) => [...prev, { id: prev.length, text: message, isMine: USER_ID === data.userId, name }]);
});
};
client.activate();
@ -49,13 +51,14 @@ export default function ChatRoom() {
return (
<section className={styles.room}>
<h2 className={styles.title}>채팅</h2>
<ol className={styles.bubbles}>
<ol className={styles.messageList}>
{messages.map((message) => (
<li
key={message.id}
className={message.isMine ? styles.my : styles.your}
>
{message.text}
<span className={styles.name}>{message.name}</span>
<span className={styles.bubble}>{message.text}</span>
</li>
))}
</ol>

View File

@ -6,7 +6,6 @@
height: 100%;
border: 1px solid var(--border-color);
border-radius: 16px;
box-sizing: border-box;
overflow: hidden;
}
@ -21,65 +20,105 @@
backdrop-filter: blur(16px); */
}
.bubbles {
.messageList {
display: flex;
flex-direction: column;
justify-content: end;
align-items: start;
gap: 8px;
gap: 12px;
list-style: none;
height: 100%;
margin: 0;
padding: 0 16px;
box-sizing: border-box;
overflow-y: auto;
white-space: nowrap;
}
@keyframes show {
from {
opacity: 0;
transform: scale(0.9);
}
to {
opacity: 1;
transform: scale(1);
}
}
.your,
.my {
display: flex;
padding: 12px 16px;
border-radius: 8px;
background-color: var(--background-secondary);
color: var(--text-color);
font-size: 16px;
line-height: 1.4;
font-weight: 500;
white-space: pre-wrap;
flex-direction: column;
animation: show 0.25s cubic-bezier(0.175, 0.885, 0.32, 1.275);
transform-origin: left bottom;
& > .bubble {
padding: 8px 16px;
border-radius: 20px;
background-color: var(--background-secondary);
color: var(--text-color);
font-size: 16px;
line-height: 1.4;
font-weight: 500;
white-space: pre-wrap;
}
}
.my {
align-self: end;
background-color: var(--primary-color);
color: var(--on-primary);
align-items: end;
transform-origin: right bottom;
& > .name {
display: none;
}
& > .bubble {
background-color: var(--primary-color);
color: var(--on-primary);
}
}
.name {
padding: 0 4px;
color: var(--text-color-secondary);
font-size: 12px;
line-height: 1.4;
font-weight: 500;
}
.form {
display: flex;
gap: 16px;
padding: 16px;
align-items: center;
gap: 8px;
margin: 16px;
background-color: var(--background);
border: 1px solid var(--border-color);
border-radius: 12px;
box-shadow: var(--shadow);
overflow: hidden;
& > input[type='text'] {
flex-grow: 1;
padding: 8px;
flex: 1;
padding: 16px;
width: 100%;
height: 100%;
border: none;
border-radius: 6px;
border-radius: 12px;
color: var(--text-color);
font-size: 16px;
line-height: 1.4;
font-weight: 400;
outline: none;
}
& > button {
display: flex;
justify-content: center;
align-items: center;
padding: 8px;
width: 48px;
height: 48px;
padding: 0;
border: none;
border-radius: 6px;
font-size: 16px;

View File

@ -0,0 +1,5 @@
export const userNameSlice = (set) => ({
userName: null,
setUserName: (userName) => set({ userName }),
isAnonymous: () => set.userName === null,
});