-
Notifications
You must be signed in to change notification settings - Fork 12
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
[4주차] 김선영 미션 제출합니다. #20
Open
seondal
wants to merge
42
commits into
CEOS-Developers:master
Choose a base branch
from
seondal:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
42 commits
Select commit
Hold shift + click to select a range
8d8b7b1
[Set] styled-components 설치 및 적용
seondal fa18c7d
[Feat] InputForm으로 사용자 입력값 받기
seondal 33bc4f5
[Feat] 입력받은 값들 ChatList에서 보여주기
seondal eb2a4da
[Feat] UserList 구현
seondal 6bc5c72
[Feat] 채팅에 유저 정보 포함시키기
seondal a1eb122
[Style] UserItem 디자인 적용
seondal fca94cf
[Style] ChatItem 디자인 적용중...
seondal c8b2bcf
[Feat] 각 채팅에 date 속성 추가
seondal 8df779e
[Feat] 각 채팅에 전송자(유저) 정보 추가
seondal da075cf
[Style] UserList
seondal 5196769
[Style] ChatList
seondal e380432
[Style] 현재유저의 말풍선만 스타일 다르게
seondal 432a440
[Style] 전체적인 사이즈 변경
seondal 8b7a67e
[Style] 말풍선 텍스트 줄바꿈 처리
seondal 9c3a3e3
[Style] InputForm
seondal cd549c0
[Feat] 메세지 전송할때마다 맨 밑으로 스크롤 자동 이동
seondal ccacc5e
[Style] 스크롤바 커스텀
seondal c35a0ad
[Feat] 엔터로 전송, shift+엔터로 줄바꿈
seondal ed5dfeb
[Fix] 버튼으로 submit 할 시 새로고침되는 현상 수정
seondal 571e82b
[Refact] 샘플 데이터 json 파일로 관리하기
seondal 7a81211
[Fix] 한글 중복 입력 오류를 고치자 ! (기여 : @yjoonjang)
seondal 570cb4e
Merge branch 'CEOS-Developers:master' into master
seondal ff0ac89
[Refact] Routing 설정
seondal 6ace85b
[Del] 사용안하는 파일 삭제
seondal 0a894b5
[Foldering] 라우팅을 위한 폴더링
seondal 48b8e4f
[Feat] 라우팅을 이용한 페이지 이동 구현
seondal 7b342fb
[Style] Layout NavLink
seondal bf1e6ad
[Add] ChatData 확장 및 유저데이터 추가
seondal 0831d21
[Feat] 경로에 따라 해당 채팅방 보여지게하기
seondal b820b80
[Fix] 채팅방에 참여하는 유저만이 아닌 전체 유저가 보이는 오류 수정
seondal e590aac
[Feat] ChatroomPage 채팅방 리스트 띄우기
seondal 32be316
[Feat] FriendPage 유저 리스트 띄우기
seondal f37cd87
[Feat] getRoomMembers: 채팅방에 참여하는 멤버들의 유저정보를 반환해주는 custom hooks
seondal 79b63bb
[Feat] SettingPage
seondal 23ea56e
💄 style : layout
seondal e55c5e8
💄 style : 친구 페이지
seondal 1bef60c
🏗 folder : 폴더링
seondal 9936ddb
💄 style : 채팅 페이지
seondal 5ba033e
💄 style : 채팅방 디자인
seondal 87fa56a
✨ feat : 채팅방 연속 챗 프로필 안보이게
seondal c9c8adb
✂️ edit : 더보기
seondal 2f41407
🛠 fix : 빌드에러
seondal File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,24 @@ | ||
function App() { | ||
return <div>화이팅!!</div>; | ||
} | ||
import { Route, Routes } from "react-router-dom"; | ||
|
||
import Layout from "./components/Layout"; | ||
import FriendPage from "./pages/FriendPage"; | ||
import ChatroomPage from "./pages/ChatroomPage"; | ||
import SettingPage from "./pages/SettingPage"; | ||
import Chatroom from "./pages/Chatroom"; | ||
|
||
const App = () => { | ||
return ( | ||
<> | ||
<Routes> | ||
<Route element={<Layout />}> | ||
<Route path="/" element={<FriendPage />} /> | ||
<Route path="/chatrooms" element={<ChatroomPage />} /> | ||
<Route path="/setting" element={<SettingPage />} /> | ||
</Route> | ||
<Route path="/chatrooms/:id" element={<Chatroom />} /> | ||
</Routes> | ||
</> | ||
); | ||
}; | ||
|
||
export default App; |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import person from "./person.svg"; | ||
import chat from "./chat.svg"; | ||
import more from "./more.svg"; | ||
|
||
export const ICON = { person, chat, more }; |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { User } from "./interface"; | ||
import chatData from "../data/chatData.json"; | ||
import userData from "../data/userData.json"; | ||
|
||
const chatrooms = chatData.rooms; | ||
const users = userData.users; | ||
|
||
// 해당 채팅방 멤버들의 유저정보를 담은 배열을 반환 | ||
export const getRoomMembers = (roomId: number, includeCurUser: Boolean) => { | ||
const roomMembers: User[] = []; | ||
chatrooms[roomId].users.map((memberId) => roomMembers.push(users[memberId])); | ||
if (!includeCurUser) { | ||
roomMembers.shift(); | ||
} | ||
return roomMembers; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
html{ | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
background-color: whitesmoke; | ||
font-size: 0.8rem; | ||
height: 100vh; | ||
overflow: hidden; | ||
} | ||
|
||
body { | ||
position: relative; | ||
margin: 0; | ||
width: 400px; | ||
height: 90vh; | ||
box-shadow: 0 0 16px lightgray; | ||
background-color: white; | ||
border-radius: 10px; | ||
} | ||
|
||
a { | ||
text-decoration: none; | ||
} | ||
|
||
@media screen and (max-width: 400px) { | ||
body { | ||
width: 100%; | ||
height: 100%; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
export interface User { | ||
id: number; | ||
name: string; | ||
profileImage: string; | ||
message: string; | ||
} | ||
|
||
export interface Chat { | ||
id: number; | ||
senderId: number; | ||
text: string; | ||
date: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import styled from "styled-components"; | ||
|
||
export const Item = styled.div` | ||
display: flex; | ||
align-items: center; | ||
padding: 8px 20px; | ||
gap: 8px; | ||
|
||
:hover { | ||
background-color: whitesmoke; | ||
} | ||
|
||
.title { | ||
color: black; | ||
} | ||
|
||
.content { | ||
color: gray; | ||
font-size: 0.8rem; | ||
} | ||
`; | ||
|
||
export const ProfileImage = styled.img<{ | ||
noImage?: boolean; | ||
selected?: boolean; | ||
}>` | ||
width: 40px; | ||
height: 40px; | ||
border-radius: 15px; | ||
object-fit: cover; | ||
outline: ${({ selected }: { selected?: boolean }) => | ||
selected ? "1px solid black" : "none"}; | ||
opacity: ${(props) => (props.noImage ? 0 : 1)}; | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { NavLink, Outlet, useLocation } from "react-router-dom"; | ||
import styled from "styled-components"; | ||
import { ICON } from "../asset/icon"; | ||
|
||
const MENUS = [ | ||
{ text: "친구", path: "/", icon: ICON.person }, | ||
{ text: "채팅", path: "/chatrooms", icon: ICON.chat }, | ||
{ text: "더보기", path: "/setting", icon: ICON.more }, | ||
]; | ||
|
||
export default function Layout() { | ||
const { pathname } = useLocation(); | ||
|
||
return ( | ||
<Wrapper> | ||
<Navigation> | ||
{MENUS.map((menu) => ( | ||
<NavLink | ||
key={menu.text} | ||
to={menu.path} | ||
style={({ isActive }) => | ||
isActive ? { opacity: 1.0 } : { opacity: 0.3 } | ||
}> | ||
<img src={menu.icon} alt="" /> | ||
</NavLink> | ||
))} | ||
</Navigation> | ||
<Container> | ||
<h2>{MENUS.find((menu) => menu.path === pathname)?.text}</h2> | ||
<Outlet /> | ||
</Container> | ||
</Wrapper> | ||
); | ||
} | ||
|
||
const Wrapper = styled.div` | ||
display: flex; | ||
position: absolute; | ||
top: 0; | ||
left: 0; | ||
right: 0; | ||
bottom: 0; | ||
`; | ||
|
||
const Navigation = styled.div` | ||
display: flex; | ||
align-items: center; | ||
flex-direction: column; | ||
gap: 20px; | ||
background-color: #e6e6e6; | ||
padding: 20px; | ||
border-bottom-left-radius: 10px; | ||
border-top-left-radius: 10px; | ||
`; | ||
|
||
const Container = styled.div` | ||
display: flex; | ||
flex: 1; | ||
flex-direction: column; | ||
|
||
h2 { | ||
margin: 0px; | ||
padding: 20px; | ||
} | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import styled from "styled-components"; | ||
import { Chat, User } from "../../common/interface"; | ||
import { ProfileImage } from "../Item"; | ||
|
||
interface ChatItemProps { | ||
chat: Chat; | ||
isCurUser: boolean; | ||
noProfile: boolean; | ||
sender: User; | ||
} | ||
|
||
const ChatItem = ({ chat, isCurUser, sender, noProfile }: ChatItemProps) => { | ||
const time = String(new Date(chat.date).getHours()).padStart(2, "0"); | ||
const minute = String(new Date(chat.date).getMinutes()).padStart(2, "0"); | ||
|
||
return ( | ||
<Wrapper isCurUser={isCurUser} isMargin={!noProfile}> | ||
{isCurUser ? ( | ||
<> | ||
<ChatWrapper> | ||
<div className="time"> | ||
{time}:{minute} | ||
</div> | ||
<ChatBalloon isCurUser={true}>{chat.text}</ChatBalloon> | ||
</ChatWrapper> | ||
</> | ||
) : ( | ||
<> | ||
{noProfile ? ( | ||
<ProfileImage src={sender.profileImage} noImage={true} /> | ||
) : ( | ||
<ProfileImage src={sender.profileImage} /> | ||
)} | ||
<ContentWrapper> | ||
{!noProfile && <div className="name">{sender.name}</div>} | ||
<ChatWrapper> | ||
<ChatBalloon isCurUser={false}>{chat.text}</ChatBalloon> | ||
<div className="time"> | ||
{time}:{minute} | ||
</div> | ||
</ChatWrapper> | ||
</ContentWrapper> | ||
</> | ||
)} | ||
</Wrapper> | ||
); | ||
}; | ||
|
||
const Wrapper = styled.div<{ isCurUser: boolean; isMargin: boolean }>` | ||
display: flex; | ||
gap: 10px; | ||
justify-content: ${({ isCurUser }: { isCurUser: boolean }) => | ||
isCurUser ? "flex-end" : "flex-start"}; | ||
width: 100%; | ||
margin-top: ${({ isMargin }: { isMargin: boolean }) => | ||
isMargin ? "20px" : "0px"}; | ||
`; | ||
|
||
const ContentWrapper = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
gap: 5px; | ||
`; | ||
const ChatWrapper = styled.div` | ||
display: flex; | ||
align-items: flex-end; | ||
gap: 5px; | ||
.time { | ||
font-size: 8px; | ||
color: grey; | ||
} | ||
`; | ||
const ChatBalloon = styled.div` | ||
background-color: ${({ isCurUser }: { isCurUser: boolean }) => | ||
isCurUser ? "yellow" : "white"}; | ||
padding: 10px; | ||
border-radius: 5px; | ||
word-break: break-all; | ||
`; | ||
|
||
export default ChatItem; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { useEffect, useRef } from "react"; | ||
import styled from "styled-components"; | ||
import { Chat, User } from "../../common/interface"; | ||
import ChatItem from "./ChatItem"; | ||
|
||
interface ChatListProps { | ||
curUser: number; | ||
chats: Chat[]; | ||
users: User[]; | ||
} | ||
|
||
const ChatList = ({ curUser, chats, users }: ChatListProps) => { | ||
// 채팅이 업데이트될 때마다 아래로 스크롤 | ||
const chatListRef = useRef<HTMLDivElement>(null); | ||
useEffect(() => { | ||
chatListRef.current?.scrollTo(0, chatListRef.current.scrollHeight); | ||
console.log("스크롤!"); | ||
}, [chats]); | ||
|
||
return ( | ||
<Wrapper ref={chatListRef}> | ||
{chats.map((chat, idx) => ( | ||
<ChatItem | ||
key={chat.id} | ||
noProfile={idx !== 0 && chats[idx - 1].senderId === chat.senderId} | ||
isCurUser={curUser === chat.senderId} | ||
chat={chat} | ||
sender={users[chat.senderId]} | ||
/> | ||
))} | ||
</Wrapper> | ||
); | ||
}; | ||
|
||
const Wrapper = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
padding: 15px; | ||
gap: 10px; | ||
height: 65%; | ||
overflow: auto; | ||
background-color: powderblue; | ||
|
||
/* 스크롤바 커스텀*/ | ||
::-webkit-scrollbar { | ||
width: 3px; | ||
} | ||
::-webkit-scrollbar-thumb { | ||
background-color: white; | ||
border-radius: 10px; | ||
} | ||
::-webkit-scrollbar-track { | ||
} | ||
`; | ||
|
||
export default ChatList; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interface선언 파일이 따로 있는데 여기다가 인터페이스를 선언한 이유가 따로 있으신가요???