Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5주차] 김채림 미션 제출합니다. #16

Open
wants to merge 33 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
558c64f
typescript setting
chaaerim May 2, 2022
68e5196
add : set user, message data
chaaerim May 2, 2022
f88e8a3
feat : add MessengerBox
chaaerim May 3, 2022
1fa59cb
feat : add UserNav
chaaerim May 3, 2022
d8ab759
feat : add MessengerInput
chaaerim May 3, 2022
d93bcfb
feat : add MessengerList, SingleMessage
chaaerim May 5, 2022
853c304
fix : add userName to messageInput
chaaerim May 5, 2022
fb7863e
chore : change textList to chatList
chaaerim May 5, 2022
d3b98dd
chore : add time to message
chaaerim May 5, 2022
a4bc798
refactor : set interface
chaaerim May 5, 2022
654d846
feat : add useInput hook
chaaerim May 5, 2022
45e884a
style : add style
chaaerim May 5, 2022
9f3b7c7
feat : add custom-scrollbar
chaaerim May 6, 2022
930c318
style : set styled-components
chaaerim May 6, 2022
2a30610
chore : delete console.log
chaaerim May 6, 2022
7f400ef
refactor : refactor code
chaaerim May 7, 2022
a232d32
refactor : delete onScrollFrame
chaaerim May 7, 2022
bb1dd5f
feat : add FriendList page
chaaerim May 10, 2022
f502ab8
feat : add Setting page
chaaerim May 10, 2022
0197867
feat : add add UnderNavBar
chaaerim May 10, 2022
eff40d7
chore : update message.json
chaaerim May 11, 2022
a76d7e6
feat : add ChatList page
chaaerim May 11, 2022
ebefc6d
feat : update MessengerBox
chaaerim May 12, 2022
b2ad9f5
feat : add SearchUser
chaaerim May 12, 2022
007f422
style : update style component
chaaerim May 13, 2022
293bf5a
chore : add icon to Header
chaaerim May 13, 2022
56d3826
chore : delete console.log
chaaerim May 13, 2022
c237ae2
refactor : apply type
chaaerim May 13, 2022
7a7c2a4
refactor : change scrollToBottom
chaaerim May 13, 2022
d9a926a
refactor : apply React.memo to SingleMessage
chaaerim May 14, 2022
98cc50d
refactor : apply useCallback to handleInputChange
chaaerim May 14, 2022
c4ee182
refactor : apply useCallback to handleInputSubmit
chaaerim May 14, 2022
9456954
:bug: fix: input 입력 업데이트
chaaerim Oct 16, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"singleQuote": true
}
492 changes: 492 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.1.1",
"@testing-library/user-event": "^13.5.0",
"@types/react-custom-scrollbars": "^4.0.10",
"react": "^18.1.0",
"react-custom-scrollbars": "^4.2.1",
"react-dom": "^18.1.0",
"react-icons": "^4.3.1",
"react-router-dom": "^6.3.0",
"react-scripts": "5.0.1",
"recoil": "^0.7.3-alpha.2",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

시도의 흔적

"styled-components": "^5.3.5",
"web-vitals": "^2.1.4"
},
"scripts": {
Expand All @@ -34,5 +40,8 @@
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@types/styled-components": "^5.1.25"
}
}
Binary file added public/assets/user0.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/user1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/user2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/user3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/user4.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/user5.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 0 additions & 5 deletions src/App.js

This file was deleted.

36 changes: 36 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Route, Routes } from 'react-router-dom';
import GlobalStyle from './Globalstyle';
import styled from 'styled-components';
import FriendList from './routes/FriendList';
import ChatList from './routes/ChatList';
import Setting from './routes/Setting';
Comment on lines +4 to +6
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

페이지와 관련된 컴포넌트들은 보통 pages 폴더에 작성합니다!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 !! 수정해보겠습니다!!!

import MessengerBox from './components/Message/MessengerBox';

const App = () => {
return (
<>
<GlobalStyle />
<MessengerContainer>
<Routes>
<Route path="/" element={<FriendList />} />
<Route path="/chatlist" element={<ChatList />} />
<Route path="/messengerbox/:userName" element={<MessengerBox />} />
<Route path="/setting" element={<Setting />} />
</Routes>
</MessengerContainer>
</>
);
};
export default App;

const MessengerContainer = styled.div`
/* 너비 | 스타일 | 색 */
border: 0.08rem solid #c2bbbb;
margin: 0 auto;
margin-top: 5rem;
background: white;
border-radius: 0.5rem;
height: 43rem;
width: 26rem;
justify-content: flex-start;
`;
29 changes: 29 additions & 0 deletions src/Globalstyle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { createGlobalStyle } from 'styled-components';

//페이지 전체에 적용될 style
const GlobalStyle = createGlobalStyle`

button {
&:hover{
cursor: pointer;
}
Comment on lines +6 to +9

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

버튼까지 전역으로 스타일링 좋네요

border: none;
background: none;
font-size: 17px;
}

::-webkit-scrollbar {
width: 0.9rem;
margin: 0;
}

::-webkit-scrollbar-thumb {
height: 17%;
background-color: #c2bbbb;
border-radius: 10px;
background-clip: padding-box;
border: 0.3rem solid transparent;
}
`;

export default GlobalStyle;
34 changes: 34 additions & 0 deletions src/components/ChatList/Chattings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import styled from 'styled-components';
import { IChattingsProps } from '../../interface/interface';
import {
LinkToChat,
ListItem,
ProfileImg,
UserName,
} from '../layout/CommonStyle';
const Chattings = ({ userId, userName, message }: IChattingsProps) => {
return (
<ChattingRooms>
<LinkToChat to={`/messengerbox/${userName}`}>
<ProfileImg src={`/assets/${userId}.jpg`} />
<ListItem>
<UserName>{userName}</UserName>
<LastMessage>{message}</LastMessage>
</ListItem>
</LinkToChat>
</ChattingRooms>
Comment on lines +12 to +19

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이런 방식이라면 확실히 리코일 없이 데이터가 관리가 편했겠네요.
저도 지난 주에는 이런 식으로 했었는데 편했는데 이번주에 리코일로 관리를 해봤거든요
전역으로 다룰 수 있어서 좋았습니다. 리덕스보다 훨씬 편리해서 추천드려용

);
};

export default Chattings;

const ChattingRooms = styled.div`
display: flex;
padding-left: 1rem;
margin: 0.5rem;
`;

const LastMessage = styled.div`
font-weight: lighter;
font-size: 14px;
`;
34 changes: 34 additions & 0 deletions src/components/FriendList/Friends.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import styled from 'styled-components';
import { IFriendsProps } from '../../interface/interface';
import {
LinkToChat,
ListItem,
ProfileImg,
UserName,
} from '../layout/CommonStyle';
const Friends = ({ userProfile, userName, userStatus }: IFriendsProps) => {
return (
<FriendList>
<LinkToChat to={`/messengerbox/${userName}`}>
<ProfileImg src={`/assets/${userProfile}`} />
<ListItem>
<UserName>{userName}</UserName>
<UserStatus>{userStatus}</UserStatus>
</ListItem>
</LinkToChat>
</FriendList>
Comment on lines +11 to +19
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Friends 컴포넌트와 Chattings 컴포넌트의 구조가 비슷하니 중복을 줄여보는 것도 좋을 것 같아요

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이제와서 보니 정말 구조가 비슷하네요 컴포넌트를 재사용해봐야겠어요 반영해서 수정해보겠습니당

);
};

export default Friends;

const FriendList = styled.div`
display: flex;
padding-left: 1rem;
margin: 0.5rem;
`;

const UserStatus = styled.div`
font-weight: lighter;
font-size: 14px;
`;
43 changes: 43 additions & 0 deletions src/components/FriendList/SearchUser.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import styled from 'styled-components';
import { BsSearch } from 'react-icons/bs';

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

꿀팁 배워갑니다

import useInput from '../../hooks/useInput';
import { useEffect } from 'react';
import { IFilteredUser } from '../../interface/interface';

const SearchUser = ({ filteredUser }: IFilteredUser) => {
const { textinput, handleInputChange } = useInput('');

useEffect(() => filteredUser(textinput), [filteredUser, textinput]);
return (
<SearchContainer>
<BsSearch size={18} className="searchLogo" />
<SearchInput
placeholder="Search . . . "
value={textinput}
type="text"
onChange={handleInputChange}
/>
</SearchContainer>
);
};
export default SearchUser;

const SearchInput = styled.input`
margin-left: 1rem;
width: 16rem;
height: 1.5rem;
border-radius: 0.5rem;
border: 0.08rem solid #c2bbbb;
padding-left: 1rem;
`;
const SearchContainer = styled.div`
padding: 1rem;
height: 2rem;
text-align: center;

.searchLogo {
line-height: 3rem;
position: relative;
top: 0.3rem;
}
`;
37 changes: 37 additions & 0 deletions src/components/Message/MessageList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useEffect, useRef } from 'react';
import styled from 'styled-components';
import SingleMessage from './SingleMessage';
import { IMessageData } from '../../interface/interface';

const MessageList = ({ messageData }: { messageData: Array<IMessageData> }) => {
const scrollbarRef = useRef<HTMLDivElement>(null);

const scrollToBottom = () => {
if (scrollbarRef.current) {
scrollbarRef.current.scrollTop = scrollbarRef.current.scrollHeight;
}
};
useEffect(() => {
scrollToBottom();
}, [messageData]);
Comment on lines +9 to +16
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scrollToBottom 함수를 useEffect 밖에 작성하여 보기 깔끔하네요! 👍🏻


return (
<ListContainer ref={scrollbarRef}>
<ShowList>
{messageData.map((chat: IMessageData) => (
<SingleMessage chat={chat} key={chat.userId} />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

userId를 key값으로 주면 동일한 값으로 들어가게 되네요. 데이터에 chatId와 같은 값을 추가하는게 좋을것 같습니다.

))}
</ShowList>
</ListContainer>
);
};

export default MessageList;

const ListContainer = styled.div`
height: 26rem;
padding: 1rem;
overflow-y: auto;
overflow-x: hidden;
`;
const ShowList = styled.div``;
37 changes: 37 additions & 0 deletions src/components/Message/MessengerBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import UserNav from '../layout/UserNav';
import { useState } from 'react';
import user from '../../data/user.json';
import message from '../../data/message.json';
import MessengerInput from './MessengerInput';
import MessageList from './MessageList';
import { useParams } from 'react-router-dom';

const MessengerBox = () => {
// 사용자 나부터 시작
const otherUser = useParams();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

userName 같은 변수명을 사용하는 게 더 좋을 것 같아요~

const userindex = message.findIndex(
(message) => message.userName === otherUser.userName
);
const userMessageData = message[userindex];

const [currentUser, setCurrentUser] = useState(user[0]);
const [messageData, setMessageData] = useState(userMessageData.messages);
return (
<>
<UserNav
currentUser={currentUser}
setCurrentUser={setCurrentUser}
otherUser={otherUser}
/>
<MessageList messageData={messageData} />

<MessengerInput
currentUser={currentUser}
messageData={messageData}
setChatList={setMessageData}
/>
</>
);
};

export default MessengerBox;
86 changes: 86 additions & 0 deletions src/components/Message/MessengerInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { useCallback } from 'react';
import styled from 'styled-components';
import useInput from '../../hooks/useInput';
import { IMessengerInputProps } from '../../interface/interface';
const MessengerInput = ({ currentUser, messageData, setChatList }: any) => {
const { textinput, handleInputChange, handleInputInitialize } = useInput('');

const handleInputSubmit = useCallback(
(e: React.FormEvent<HTMLFormElement>) => {
//공백이 아닐 때에만 send 가능
if (textinput.replace(/\s+/g, '')) {
const date = new Date();
const hours = String(date.getHours()).padStart(2, '0');
const minutes = String(date.getMinutes()).padStart(2, '0');
const messageObject = {
userId: currentUser.userId,
userName: currentUser.userName,
text: textinput,
time: `${hours}:${minutes}`,
};

setChatList([...messageData, messageObject]);

//공백일 경우 alert
} else {
alert('메세지를 입력하세요 ! ');
}

handleInputInitialize();

//새로고침 방지
e.preventDefault();
},
[messageData]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[messageData,textinput]
textinput 을 추가안해주면 입력값이 공백으로 되네요
setState 가 비동기적으로 동작해서 생기는 문제 같아요

);

return (
<SubmitForm onSubmit={handleInputSubmit}>
<InputBoxWrapper>
<InputBox
value={textinput}
onChange={handleInputChange}
placeholder="Send Message . . ."
type="text"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

required 속성을 추가해줘도 편하더라구요

/>
</InputBoxWrapper>

<SendButton>🕸</SendButton>
</SubmitForm>
);
};

export default MessengerInput;

const SubmitForm = styled.form`
align-items: center;
border-top-style: solid;
border-color: #c2bbbb;
border-width: 0.08rem;
padding: 0;
height: 6rem;
display: flex;
justify-content: space-evenly;
`;

const InputBoxWrapper = styled.div`
padding-left: 2rem;
`;

const InputBox = styled.input`
padding-left: 1rem;
line-height: 5.5rem;
border-color: #c2bbbb;
border-width: 0.08rem;
border-style: solid;
Comment on lines +78 to +80
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 세 줄을 border: 0.08rem solid #c2bbbb; 로 한 번에 쓸 수 있습니다!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저번에 효정님이 짚어주셨는데 또 이런짓을 했군요 수정하겠습니다 ㅠ ㅠ

border-radius: 0.5rem;
width: 18rem;
height: 2.3rem;
margin: 0;
line-height: 6rem;
`;
const SendButton = styled.button`
line-height: 6rem;
background-color: transparent;
font-size: 1.5rem;
`;
Loading