본문 바로가기

Project/sendbird를 활용한 웹 채팅

[Sendbird를 활용한 웹 채팅] 8. 채팅 리스트 불러오기

반응형

1. 오픈 채팅 리스트 불러오기

Pages/OpenChat.js

const OpenChat = ({ history }) => {
  const sb = useMemo(() => new SendBirdAction(), []);
  const [openChatList, setOpenChatList] = useState([]);

  const getOpenChannels = useCallback(
    (isInit = false) => {
      sb.getOpenChannelList(isInit).then((list) => {
        setOpenChatList(list);
      });
    },
    [sb]
  );

  //하나의 채팅 클릭 시 새로운 창으로 채팅 방이 열린다.
  const onClickBtn = (chat) => {
    window.open(`/chatting/${chat.url}/${true}`, chat.url, `repace=true`);
  };

  return (
    <Layout
      history={history}
      title="오픈 채팅"
      callBack={getOpenChannels}
      isNav={true}
    >
        <ChatList chatList={openChatList} onClickBtn={onClickBtn} />
    </Layout>
  );
};

export default OpenChat;

 

오픈 채팅 리스트 UI

 

2. 그룹 채팅 리스트 불러오기

Pages/GroupChat.js

  const sb = useMemo(() => new SendBirdAction(), []);
  const [groupChatList, setGroupChatList] = useState([]);

  const getGroupChannels = useCallback(
    (isInit = false) => {
      sb.getGroupChannelList(isInit).then((list) => {
        setGroupChatList(list);
      });
    },
    [sb]
  );

메세지 이벤트 핸들러 적용 -> 채팅 리스트 페이지에 머물 때 메세지가 오면 새로 고침 없이 숫자가 화면에 표시되도록 설정한다.

  sb.onMessageReceivedHandler({
    handler: (channel, message) => {
      const list = groupChatList.filter((chat) => chat.url !== channel.url);
      setGroupChatList([channel, ...list]);
    },
  });

- 모든 메세지 확인한 상태                                             - 읽지 않은 메세지 표시

그룹 채팅 리스트 UI

 

3. 채팅 컴포넌트

API를 통해 가져온 채팅 리스트를 담을 ChatList 컴포넌트와 각각의 채팅 하나를 구성할 ChatItem 컴포넌트이다.오픈 채팅과 그룹채팅가 가져오는 데이터에 차이가 있기 때문에 각각을 구성하는 UI도 다르다. 즉, 동일한 컴포넌트를 사용하지만 채팅 타입을 구분해 UI를 구성한다.

 

Components/ChatList.js

const ChatList = ({ chatList, onClickBtn }) => {
  return (
    <Container>
      {chatList &&
        chatList.map((chat) => (
          <ChatItem
            key={chat.url || chat.id}
            chat={chat}
            coverUrl={chat.coverUrl}
            name={chat.name}
            memberCount={chat.memberCount || chat.participantCount}
            lastMessage={chat.lastMessage}
            info={chat.info}
            unreadMessageCount={chat.unreadMessageCount}
            onClickBtn={onClickBtn}
          />
        ))}
    </Container>
  );
};

ChatList.prototype = {
  chatList: PropTypes.array.isRequired,
};

ChatList.defaultProps = {
  chatList: [],
};

export default ChatList;

const Container = styled.div`
  height: 85vh;
`;

 

Components/ChatItem.js

const ChatItem = ({
  chat,
  coverUrl,
  name,
  memberCount,
  lastMessage,
  info,
  unreadMessageCount,
  onClickBtn,
}) => {
  let message = "";
  let isAll = false;
  if (info) {
    message = info;
    isAll = true;
  } else {
    if (lastMessage.messageType === "file") message = lastMessage.name;
    else message = lastMessage.message;
  }

  return (
    <>
      <Container isAll={isAll} onClick={() => onClickBtn(chat)}>
        <Left>
          <CoverImg src={coverUrl || defaultImg} alt="profile" />
          <Mid>
            <MidUp>
              <Name>{name}</Name>
              <Count>{memberCount || ""}</Count>
            </MidUp>
            {Object.keys(lastMessage).length !== 0 && (
              <Message>
                {message.length > 30
                  ? `${message.substring(0, 30)}...`
                  : message}
              </Message>
            )}
          </Mid>
        </Left>
        <Right>
          {isAll ? (
            <Register to="/register" />
          ) : (
            <>
              <Time>
                {Object.keys(lastMessage).length !== 0 &&
                  timestampToTime(lastMessage.createdAt)}
              </Time>
              {unreadMessageCount !== 0 && (
                <UnRead>{unreadMessageCount}</UnRead>
              )}
            </>
          )}
        </Right>
      </Container>
    </>
  );
};

export default ChatItem;

//PropTypes 과 Style 생략
반응형