Project/sendbird를 활용한 웹 채팅
[Sendbird를 활용한 웹 채팅] 9. 채팅 페이지 - 메세지 송수신, UI, 파일 다운로드
반응형
1. 채팅 메세지 불러오는 프로세스
채팅 페이지(Pages/Chatting.js)는
- 채팅 리스트에서 하나의 채팅 방을 클릭하면 이동하는 페이지이다.
- 페이지의 도메인은 유니크하며
채팅 url(url)
과오픈채팅여부(isopen)
의 정보가 담겨있다.
프로세스
- 페이지 주소를 통해 채팅
url
과 오픈 채팅 여부를 판단 getChannel
호출- 채널 정보 저장
getMessageList
호출- 오픈 채팅인 경우
enter
, 그룹 채팅인 경우markAsRead
이벤트 수행
getMessageList
호출- 메세지 리스트 저장
scrollToBottom
호출
메세지 수신 이벤트
채팅 페이지에 들어와 있을 때 도착하는 메세지에 대한 이벤트 설정
->채팅방에 있을 때 새로고침없이 전달된 채팅 출력
sb.onMessageReceivedHandler({
handler: (channel, message) => {
if (chatUrl === message.channelUrl) {
setMessageList([...messageList, message]);
scrollToBottom();
if (!isOpenChannel) sb.markAsRead(channel);
}
},
});
채팅 창 스크롤 제어
scrollToBottom
const scrollToBottom = useCallback(() => {
const msgWrapEl = document.getElementById("message-wrap");
msgWrapEl.scrollTop = msgWrapEl.scrollHeight;
}, []);
2. 메세지 보내기
텍스트 메세지
const onChangemessage = (e) => {
setMessage(e.target.value);
};
const onClickSubmit = () => {
setMessage("");
sb.sendUserMessage({
channel,
message,
handler: (message, error) => {
if (error) return;
if (chatUrl === message.channelUrl) {
setMessageList([...messageList, message]);
scrollToBottom();
}
},
});
};
파일 메세지
const onChangeFile = (e) => {
const file = e.target.files[0];
const thumbnailSizes = [{ maxWidth: 100, maxHeight: 100 }];
sb.sendFileMessage({
channel,
file,
thumbnailSizes,
handler: (message, error) => {
if (error) return;
if (chatUrl === message.channelUrl) {
setMessageList([...messageList, message]);
scrollToBottom();
}
},
});
};
[시행착오]
🔒문제
오픈 채팅 페이지에서 sendUserMessage
메서드를 통해 메세지 보내기 시도 → not a member
에러 발생
🔑해결
메세지를 보내기 전에 해당 채널에 입장을 해야한다. 입장을 우선해야 메세지를 보낼 수 있다!
즉, 오픈 채팅에서 메세지를 보내는 방법은,
- getChannel
- enter
- sendUserMessage
cf. 그룹 채팅에서는 해당하지 않는다.
3. 채팅 UI 구성하기
Flex Box 안에서 아래로 정렬하는 방법
Body(빨간부분)
안에서 MessageWrap(파란부분)
을 아래쪽으로 정렬하는 방법
<Body>
<MessageWrap>
<MessageDate>2021.07.10</MessageDate>
<MessageList messageList={messageList} />
</MessageWrap>
</Body>
const Body = styled.div`
display: flex;
flex-direction: column;
justify-content: flex-end;
height: 500px;
border: 2px solid red;
`;
const MessageWrap = styled.div`
display: flex;
flex-direction: column;
border: 2px solid blue;
`;
-> justify-content: flex-end
를 사용하면 부모 영역을 기준으로 자식을 끝으로 정렬시킬 수 있다.
텍스트 사이즈 조절
🔒 문제
텍스트가 div 안에 있지 않고 밖으로 나가는 문제 발생
🔑 해결
해당 div의 style에 아래 설정을 추가해준다.
word-break: break-all;
Timestamps (feat. Unix Time)
센드버드에서 넘어오는 날짜의 데이터의 값은 우리가 일상적으로 보는 날짜와 형식이 다르다. 아래 링크를 참고해 원하는 포멧으로 변경해주면 된다.
- 패키지 설치 ->
moment 2.29.1
- format 참고 -> https://momentjscom.readthedocs.io/en/latest/moment/04-displaying/01-format/
최종 UI
<Layout history={history} title={channel.name}>
<Body>
<MessageWrap id="message-wrap">
<MessageList messageList={messageList} />
</MessageWrap>
</Body>
<FooterWrap>
<Footer>
<FileWrap>
<Label htmlFor="file">
<img src={AddIcon} alt="addFile" />
</Label>
<FileInput id="file" type="file" onChange={onChangeFile} />
</FileWrap>
<Message
id="message"
type="text"
value={message}
placeholder="메세지를 입력하세요"
onChange={onChangemessage}
onKeyPress={onKeyPress}
/>
<Btn onClick={onClickSubmit}></Btn>
</Footer>
</FooterWrap>
</Layout>
4. 파일 다운로드
const onClickDownload = async () => {
const image = await fetch(message.url);
const imageBlob = await image.blob();
const imageUrl = URL.createObjectURL(imageBlob);
const link = document.createElement("a");
link.href = imageUrl;
link.download = `${message.name}`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
Reference
반응형
'Project > sendbird를 활용한 웹 채팅' 카테고리의 다른 글
[Sendbird를 활용한 웹 채팅] 11. CRA 프로젝트 Electron으로 패키징하기 (0) | 2021.09.21 |
---|---|
[Sendbird를 활용한 웹 채팅] 10. 채팅 페이지2 - scrollToBottom, 관리자 공지, Push 알림 (0) | 2021.09.20 |
[Sendbird를 활용한 웹 채팅] 8. 채팅 리스트 불러오기 (0) | 2021.09.16 |
[Sendbird를 활용한 웹 채팅] 7. sendbird connect (레이아웃) (0) | 2021.09.13 |
[Sendbird를 활용한 웹 채팅] 6. 로그인 시행착오 (CORS, Failed to load resource: the server responed with a status of 404 (Not Found)) (0) | 2021.09.13 |