-
Notifications
You must be signed in to change notification settings - Fork 10
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주차] 유세은 미션 제출합니다. #14
base: main
Are you sure you want to change the base?
Changes from all commits
b60720a
147a78b
4bd3d12
3351e51
71de2ca
61334d3
ee6551a
59d9871
81d1133
ee9cbe1
ceb2e4f
ef196a8
cdde61e
85c4860
f45cc54
e102582
adcb063
63facf4
ba7c673
5d2c5fd
a299536
3527a06
bcfb45a
58901e1
de3b6ee
5c052aa
5d9ada8
18c71fb
604b36f
b8b756c
059b643
4a12b35
3ba4cdf
24e3104
ce0fb9c
6146dce
c85821d
f2864d0
cfdb30c
0a7f070
22b7a9f
bc50314
64ca89c
fab4be2
bfef9b1
2bd669e
99ccfed
930a6ac
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
module.exports = { | ||
parser: '@typescript-eslint/parser', | ||
plugins: ['@typescript-eslint', 'react-hooks'], | ||
extends: [ | ||
'airbnb', // or airbnb-base | ||
'plugin:react/recommended', | ||
'plugin:jsx-a11y/recommended', // 설치 한경우 | ||
'plugin:import/errors', // 설치한 경우 | ||
'plugin:import/warnings', // 설치한 경우 | ||
'plugin:@typescript-eslint/recommended', | ||
'plugin:prettier/recommended', | ||
], | ||
rules: { | ||
'prettier/prettier': 0, | ||
}, | ||
settings: { | ||
'import/resolver': { | ||
node: { | ||
extensions: ['.js', '.jsx', '.ts', '.tsx'], | ||
}, | ||
}, | ||
}, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"trailingComma": "es5", | ||
"tabWidth": 2, | ||
"semi": true, | ||
"singleQuote": true | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { Route, Routes } from 'react-router-dom'; | ||
import styled from "styled-components"; | ||
import ChatRoom from "./Pages/ChatRoom"; | ||
import Menu from "./Menu"; | ||
import FriendList from './Pages/FriendList'; | ||
import ChatRoomList from './Pages/ChatRoomList'; | ||
import Home from './Pages/Home'; | ||
import Setting from './Pages/Setting'; | ||
|
||
function App() { | ||
|
||
|
||
const Container = styled.div` | ||
|
||
text-align: center; | ||
width: 400px; | ||
height: 600px; | ||
background-color: white; | ||
display: flex; | ||
|
||
border-left :0px; | ||
border-radius: 9px; | ||
|
||
margin:0 auto; //중앙에 박스 | ||
margin-top: 50px; | ||
box-shadow:3px 3px 3px 3px lightgrey; | ||
|
||
`; | ||
|
||
|
||
return ( | ||
|
||
/* | ||
|
||
App | ||
/ \ | ||
Menu CHatRoom | ||
/ \ \ | ||
InputForm UserProfile Message | ||
|
||
*/ | ||
Comment on lines
+33
to
+41
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 주석으로 이렇게 구조를 표시해주신 점 너무 좋네요..! |
||
<div> | ||
<Container> | ||
<Menu/> | ||
<Routes> | ||
<Route path ="/Home" element ={<Home/>}/> | ||
<Route index element={<FriendList />} /> | ||
<Route path ="/Chatroom/:friendId" element ={<ChatRoom/>}/> | ||
<Route path ="/ChatRoomList" element ={<ChatRoomList/>}/> | ||
<Route path ="/Setting" element ={<Setting/>}/> | ||
</Routes> | ||
</Container> | ||
</div> | ||
); | ||
} | ||
|
||
export default App; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import {MessageItem} from "../../type" | ||
import React from "react"; | ||
import {useCallback} from "react"; | ||
import { Dispatch, SetStateAction} from "react"; | ||
import useInput from "../../hook/useInput"; | ||
import {Input,MessageButton,Form,InputWrapper,Emojimerong} from "./InputformDesign"; | ||
import { useRecoilValue, useSetRecoilState } from "recoil"; | ||
import { messageListState, userState } from "../../recoil"; | ||
|
||
type InputProps = { | ||
messageList : MessageItem[]; | ||
setMessageList : Dispatch<SetStateAction<MessageItem[]>> | ||
}; | ||
|
||
function Inputform ({messageList, setMessageList} : InputProps){ | ||
|
||
const{message, onChange ,setMessage} = useInput(); | ||
const currentUser = useRecoilValue(userState); //currentUser 불러오기 | ||
|
||
//const messageList =useRecoilValue(messageListState); | ||
//const setMessageList = useSetRecoilState(messageListState); | ||
|
||
const submitEmoji = useCallback((event : React.SyntheticEvent) => { | ||
event.preventDefault(); | ||
setMessageList(messageList => [...messageList, | ||
{ | ||
roomId : currentUser, | ||
text: "😛", | ||
userId: currentUser, | ||
}]); | ||
//입력받은 걸 배열에 넣음 | ||
|
||
},[currentUser]); | ||
|
||
const submitInput = useCallback((event : React.SyntheticEvent) => { | ||
event.preventDefault(); | ||
|
||
if (message) { | ||
setMessageList(messageList => [...messageList, | ||
{ | ||
roomId : currentUser, | ||
text: message, | ||
userId: currentUser, | ||
}]); | ||
//입력받은 걸 배열에 넣음 | ||
|
||
} | ||
|
||
else{ | ||
alert("메시지를 입력하세요!"); | ||
} | ||
|
||
setMessage(""); | ||
},[message]); | ||
|
||
return( | ||
<Form onSubmit={submitInput} > | ||
<Emojimerong onClick={submitEmoji}>😛</Emojimerong> | ||
<Input | ||
onChange={onChange} | ||
value={message} | ||
type="text" | ||
placeholder="메시지를 입력하세요" | ||
autoFocus = {true} | ||
spellCheck="false" | ||
|
||
/> | ||
<MessageButton onClick={submitInput}>보내기</MessageButton> | ||
</Form> | ||
); | ||
} | ||
|
||
|
||
export default React.memo(Inputform); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import styled from "styled-components"; | ||
|
||
export const Input = styled.input | ||
` | ||
font-family: 'SuncheonB'; | ||
width: 200px; | ||
height: 50px; | ||
border-radius: 9px; | ||
margin:1rem; | ||
|
||
` | ||
|
||
export const MessageButton = styled.span | ||
` | ||
cursor: pointer; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 커서 모양까지 정해 주신 디테일..! |
||
margin-left : 0.1rem; | ||
font-size: 15px; | ||
` | ||
|
||
export const Form = styled.form | ||
` | ||
margin-bottom: 10px; | ||
|
||
` | ||
; | ||
|
||
export const InputWrapper = styled.div | ||
` | ||
flex:0.3; | ||
`; | ||
export const Emojimerong = styled.span | ||
` | ||
cursor:pointer; | ||
font-size:20px; | ||
`; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { MessageItem, MessageList} from "../../type"; | ||
import {useRef,useEffect} from "react"; | ||
import {Wrapper,ChatMessage,ChatProfile,Chatcontainer,MessageBox,ChatName} from "./MessageDesign"; | ||
import user from "../../data/user.json"; | ||
import React from "react"; | ||
import { useRecoilValue, useSetRecoilState } from "recoil"; | ||
import { messageListState } from "../../recoil"; | ||
import chatting from "../../data/chat.json"; | ||
|
||
type IMessage = { | ||
roomId : number; | ||
} | ||
|
||
function Message({messageList} : MessageList){ | ||
|
||
const messageRef = useRef<HTMLDivElement>(null); | ||
|
||
const ScrollEvent = useEffect(()=>{ | ||
if(messageRef.current) | ||
messageRef.current.scrollTo({ | ||
top: messageRef.current.scrollHeight, | ||
behavior: "smooth", | ||
}) | ||
},[messageList]); //메세지리스트가 변할때만 스크롤에 대한 렌더링 | ||
|
||
|
||
return( | ||
|
||
<Wrapper ref={messageRef}> | ||
{messageList.map((message) => ( | ||
<Chatcontainer key ={message.roomId}> | ||
<ChatProfile src = {user[message.roomId].profile} loading ="lazy"/> | ||
<MessageBox> | ||
<ChatName>{user[message.roomId].name} 님의 말: </ChatName> | ||
<ChatMessage>{message.text}</ChatMessage> | ||
</MessageBox> | ||
</Chatcontainer> | ||
)) | ||
} | ||
|
||
</Wrapper> | ||
|
||
); | ||
|
||
} | ||
|
||
export default React.memo(Message); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import styled from "styled-components"; | ||
export const Wrapper = styled.div | ||
` | ||
flex:1; | ||
overflow: auto; | ||
::-webkit-scrollbar{ | ||
width:8px; | ||
heigth:8px; | ||
background-color: white; | ||
/* 스크롤바 둥글게 설정 */ | ||
border-radius: 10px; | ||
} | ||
::-webkit-scrollbar-track{ | ||
background-color: white; | ||
|
||
`; | ||
|
||
export const ChatName = styled.div | ||
` | ||
text-align:left; | ||
font-size:13px; | ||
margin: 0.5rem; | ||
`; | ||
|
||
export const Chatcontainer = styled.div | ||
` border-radius: 9px | ||
border: 1px solid grey; | ||
display:flex; | ||
margin: 0.5rem; | ||
`; | ||
|
||
export const ChatProfile =styled.img | ||
` | ||
flex:0.1; | ||
width: 30px; | ||
height: 30px; | ||
border-radius: 30px; | ||
margin:0.7rem; | ||
`; | ||
|
||
export const ChatMessage = styled.div | ||
` | ||
text-align:left; | ||
margin-left: 1.3rem; | ||
font-size:13px; | ||
`; | ||
|
||
export const MessageBox = styled.div | ||
` | ||
display:flex; | ||
flex-direction: column; | ||
|
||
`; |
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.
box-shadow: 0 1rem 4rem hsl(0 0% 0% / 15%);
제가 자주 사용하는 자연스러운 Shadowing 방식입니다.. 참고해 보세요!!
근데 이번에 세은 님께서 꾸미신 UI 컨셉에는 세은 님께서 기존에 사용하신 방식이 분위기상 더 어울리네요!!