인프런 커뮤니티 질문&답변

Min Uk Jo님의 프로필 이미지
Min Uk Jo

작성한 질문수

Slack 클론 코딩[실시간 채팅 with React]

DM 페이지 만들기

chat box가 위에 고정되어 있습니다.

작성

·

425

0

DirectMessage

import React, { useCallback, useState } from 'react';
import gravatar from 'gravatar';
import { Container } from 'semantic-ui-react';
import { Header } from './styles';
import useSWR from 'swr';
import { useParams } from 'react-router';
import fetcher from '@utils/fetcher';
import ChatBox from '@components/ChatBox';
import useInput from '@hooks/useinput';
import axios from 'axios';
import { IDM } from '@typings/db';
import ChatList from '@components/ChatList';

const DirectMessage = () => {
  const { workspace, id } = useParams<{ workspace: string; id: string }>();

  const { data: userData } = useSWR(`/api/workspaces/${workspace}/users/${id}`, fetcher);

  const { data: myData } = useSWR('/api/users', fetcher);

  const {
    data: chatData,
    mutate: mutateChat,
    revalidate,
  } = useSWR<IDM[]>(`/api/workspace/${workspace}/dms/${id}/chats?perPage=20&page=1`, fetcher);

  const [chat, onChangeChat, setChat] = useInput('');

  const onSubmitForm = useCallback(
    (e) => {
      e.preventDefault();
      console.log('chat');
      if (chat?.trim()) {
        axios
          .post(`/api/workspaces/${workspace}/dms/${id}/chats`, {
            content: chat,
          })
          .then(() => {
            revalidate();
            setChat('');
          })
          .catch(console.error);
      }
    },
    [chat],
  );

  if (!userData || !myData) {
    return null;
  }

  return (
    <Container>
      <Header>
        <img src={gravatar.url(userData.email, { s: '24px', d: 'retro' })} alt={userData.nicknam} />
        <span>{userData.nickname}</span>
      </Header>
      <ChatList chatData={chatData} />
      <ChatBox chat={chat} onChangeChat={onChangeChat} onSubmitForm={onSubmitForm} />
    </Container>
  );
};

export default DirectMessage;

ChatList

import React, { VFC } from 'react';
import { ChatZone, Section } from './styles';
import { IDM } from '@typings/db';
import Chat from '@components/Chat';

interface Props {
  chatData?: IDM[];
}

const ChatList: VFC<Props> = ({ chatData }) => {
  return (
    <ChatZone>
    {chatData?.map((chat) => {
        <Chat key={chat.id} data={chat} />;
      })} 
    </ChatZone>
  );
};

export default ChatList;

 

보여드린 코드처럼 chatbox 중간에 chatlist를 넣게 되면 자동으로 아래로 내려갈 수 있게 했습니다.

말씀대로 chatlist를 만들고 directmessage사이에 chatlist를 import 했습니다. 그런데 아래로 내려오지 않고 상단으로 그대로 고정되어 있어서 아무리 찾아보려고 해도 답이 안나오는거 같아 질문 남겨드립니다 ㅠ

 

 

 

답변 1

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

이해가 잘 안되는데요. 스크린샷 보여주세요.

Min Uk Jo님의 프로필 이미지
Min Uk Jo
질문자

스크린샷 2023-05-05 125401.png이러한 상황으로 dm 채팅박스가 밑으로 내려오질 않고 있습니다..ㅠ

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

이건 챗리스트랑 챗박스 css 부분 봐야할 것 같습니다. 그리고 이 둘의 부모가 height 100%를 차지하고있는지도 궁금하네요.

Min Uk Jo님의 프로필 이미지
Min Uk Jo
질문자

말씀 하신대로 우선 쳇리스트와 쳇박스 CSS는 깃허브에 올려져 있는 내용 그대로 가지도 온 상태이구요 그리고 이 둘의 부모인 DirectMessage또한 깃에서 그대로 복붙 한 상태입니다..

DirectMessage.tsx

import styled from '@emotion/styled';

export const Container = styled.div`
  display: flex;
  flex-wrap: wrap;
  height: calc(100vh - 38px);
  flex-flow: column;
  position: relative;
`;

export const Header = styled.header`
  height: 64px;
  display: flex;
  width: 100%;
  --saf-0: rgba(var(--sk_foreground_low, 29, 28, 29), 0.13);
  box-shadow: 0 1px 0 var(--saf-0);
  padding: 20px 16px 20px 20px;
  font-weight: bold;
  align-items: center;
  & img {
    margin-right: 5px;
  }
`;

export const DragOver = styled.div`
  position: absolute;
  top: 64px;
  left: 0;
  width: 100%;
  height: calc(100% - 64px);
  background: white;
  opacity: 0.7;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 40px;
`;

chatBox/styles.tsx

import styled from '@emotion/styled';
// import { MentionsInput } from 'react-mentions';

export const ChatArea = styled.div`
  display: flex;
  width: 100%;
  padding: 20px;
  padding-top: 0;
`;

export const Form = styled.form`
  color: rgb(29, 28, 29);
  font-size: 15px;
  width: 100%;
  border-radius: 4px;
  border: 1px solid rgb(29, 28, 29);
`;

export const MentionsTextarea = styled.textarea`
  font-family: Slack-Lato, appleLogo, sans-serif;
  font-size: 15px;
  padding: 8px 9px;
  width: 100%;
  & strong {
    background: skyblue;
  }
  & textarea {
    height: 44px;
    padding: 9px 10px !important;
    outline: none !important;
    border-radius: 4px !important;
    resize: none !important;
    line-height: 22px;
    border: none;
  }
  & ul {
    border: 1px solid lightgray;
    max-height: 200px;
    overflow-y: auto;
    padding: 9px 10px;
    background: white;
    border-radius: 4px;
    width: 150px;
  }
`;

export const Toolbox = styled.div`
  position: relative;
  background: rgb(248, 248, 248);
  height: 41px;
  display: flex;
  border-top: 1px solid rgb(221, 221, 221);
  align-items: center;
  border-bottom-left-radius: 4px;
  border-bottom-right-radius: 4px;
`;

export const SendButton = styled.button`
  position: absolute;
  right: 5px;
  top: 5px;
`;

export const EachMention = styled.button<{ focus: boolean }>`
  padding: 4px 20px;
  background: transparent;
  border: none;
  display: flex;
  align-items: center;
  color: rgb(28, 29, 28);
  width: 100%;
  & img {
    margin-right: 5px;
  }
  ${({ focus }) =>
    focus &&
    `
    background: #1264a3;
    color: white;
  `};
`;

chatList / Styles.tsx

import styled from '@emotion/styled';

export const ChatZone = styled.div`
  width: 100%;
  display: flex;
  flex: 1;
`;

export const Section = styled.section`
  margin-top: 20px;
  border-top: 1px solid #eee;
`;

export const StickyHeader = styled.div`
  display: flex;
  justify-content: center;
  flex: 1;
  width: 100%;
  position: sticky;
  top: 14px;
  & button {
    font-weight: bold;
    font-size: 13px;
    height: 28px;
    line-height: 27px;
    padding: 0 16px;
    z-index: 2;
    --saf-0: rgba(var(--sk_foreground_low, 29, 28, 29), 0.13);
    box-shadow: 0 0 0 1px var(--saf-0), 0 1px 3px 0 rgba(0, 0, 0, 0.08);
    border-radius: 24px;
    position: relative;
    top: -13px;
    background: white;
    border: none;
    outline: none;
  }
`;
제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

Container를 엉뚱한 곳에서 임포트하셨네요.

Min Uk Jo님의 프로필 이미지
Min Uk Jo
질문자

하..이런 실수를 ㅠㅠ 감사합니다!!

Min Uk Jo님의 프로필 이미지
Min Uk Jo

작성한 질문수

질문하기