From ad25c812ca6fee1a51cef3f745cb9a4b791a7c4c Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Wed, 25 Sep 2024 14:50:53 +0900 Subject: [PATCH 01/54] =?UTF-8?q?Feat:=20=ED=94=84=EB=A1=9C=EC=A0=9D?= =?UTF-8?q?=ED=8A=B8=20=EA=B8=B0=EB=B3=B8=20=ED=8F=B4=EB=8D=94=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 11 +++++++---- package.json | 3 +++ src/App.tsx | 8 ++++++-- src/components/ChatRoomPage/ChatBar.tsx | 6 ++++++ src/components/ChatRoomPage/Header.tsx | 6 ++++++ src/components/ChatRoomPage/TopBar.tsx | 10 ++++++++++ src/index.css | 14 +++++++++----- src/pages/ChatRoomPage.tsx | 10 ++++++++++ tailwind.config.js | 23 +++++++++++++++++++++++ 9 files changed, 80 insertions(+), 11 deletions(-) create mode 100644 src/components/ChatRoomPage/ChatBar.tsx create mode 100644 src/components/ChatRoomPage/Header.tsx create mode 100644 src/components/ChatRoomPage/TopBar.tsx create mode 100644 src/pages/ChatRoomPage.tsx create mode 100644 tailwind.config.js diff --git a/package-lock.json b/package-lock.json index c27bbe4..3f2ef34 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,9 @@ "react-scripts": "5.0.1", "typescript": "^4.9.5", "web-vitals": "^2.1.4" + }, + "devDependencies": { + "tailwindcss": "^3.4.13" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -16491,9 +16494,9 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, "node_modules/tailwindcss": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.1.tgz", - "integrity": "sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==", + "version": "3.4.13", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.13.tgz", + "integrity": "sha512-KqjHOJKogOUt5Bs752ykCeiwvi0fKVkr5oqsFNt/8px/tA8scFPIlkygsf6jXrfCqGHz7VflA6+yytWuM+XhFw==", "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -16503,7 +16506,7 @@ "fast-glob": "^3.3.0", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", - "jiti": "^1.19.1", + "jiti": "^1.21.0", "lilconfig": "^2.1.0", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", diff --git a/package.json b/package.json index ea335d3..15d6dce 100644 --- a/package.json +++ b/package.json @@ -39,5 +39,8 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "devDependencies": { + "tailwindcss": "^3.4.13" } } diff --git a/src/App.tsx b/src/App.tsx index 5381007..20113da 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,7 +1,11 @@ +import ChatRoomPage from './pages/ChatRoomPage'; + function App() { return ( -
-

20기 프론트엔드 파이팅!!! 디자인과 사이좋게 지내요~~~

+
+
+ +
); } diff --git a/src/components/ChatRoomPage/ChatBar.tsx b/src/components/ChatRoomPage/ChatBar.tsx new file mode 100644 index 0000000..53b3107 --- /dev/null +++ b/src/components/ChatRoomPage/ChatBar.tsx @@ -0,0 +1,6 @@ +const ChatBar = () => { + + return ; +} + +export default ChatBar; \ No newline at end of file diff --git a/src/components/ChatRoomPage/Header.tsx b/src/components/ChatRoomPage/Header.tsx new file mode 100644 index 0000000..5d827c3 --- /dev/null +++ b/src/components/ChatRoomPage/Header.tsx @@ -0,0 +1,6 @@ +const Header = () => { + + return ; +} + +export default Header; \ No newline at end of file diff --git a/src/components/ChatRoomPage/TopBar.tsx b/src/components/ChatRoomPage/TopBar.tsx new file mode 100644 index 0000000..6da2c6e --- /dev/null +++ b/src/components/ChatRoomPage/TopBar.tsx @@ -0,0 +1,10 @@ +import React from 'react'; + +const TopBar = () => { + return ( +
+
+ ); +} + +export default TopBar; diff --git a/src/index.css b/src/index.css index ec2585e..b8d7ec8 100644 --- a/src/index.css +++ b/src/index.css @@ -1,13 +1,17 @@ -body { +@tailwind base; +@tailwind components; +@tailwind utilities; + +/* body { margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', - 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", + "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } code { - font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', + font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace; -} +} */ diff --git a/src/pages/ChatRoomPage.tsx b/src/pages/ChatRoomPage.tsx new file mode 100644 index 0000000..1f3e745 --- /dev/null +++ b/src/pages/ChatRoomPage.tsx @@ -0,0 +1,10 @@ +import TopBar from '../components/ChatRoomPage/TopBar'; + +const ChatRoomPage = () => { + + return ( + + ); +} + +export default ChatRoomPage; \ No newline at end of file diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..f35c19e --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,23 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ "./src/**/*.{js,jsx,ts,tsx}", ], + theme: { + colors: { + 'Purple/3': '#D3B8FF', + 'White': '#FFFFFF', + + }, + extend: { + width: { + 'width': '375px', + }, + height: { + 'height': '812px', + 'topBarHeight': '52px', + }, + } + }, + plugins: [], +} + + From ff8f351d93945674b8d3ad5d15f8b0c006e2995a Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Wed, 25 Sep 2024 15:25:31 +0900 Subject: [PATCH 02/54] =?UTF-8?q?Feat:=20=EC=83=81=EB=8B=A8=EB=B0=94=20?= =?UTF-8?q?=EC=8B=9C=EA=B0=84=20=EB=B0=8F=20=EC=95=84=EC=9D=B4=EC=BD=98=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/TopBar/Battery.svg | 7 ++++++ src/assets/TopBar/CellularConnection.svg | 3 +++ src/assets/TopBar/Wifi.svg | 3 +++ src/components/ChatRoomPage/TopBar.tsx | 28 ++++++++++++++++++++++-- src/custom.d.ts | 4 ++++ src/utils/ClockUtils.tsx | 8 +++++++ tsconfig.json | 3 ++- 7 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 src/assets/TopBar/Battery.svg create mode 100644 src/assets/TopBar/CellularConnection.svg create mode 100644 src/assets/TopBar/Wifi.svg create mode 100644 src/custom.d.ts create mode 100644 src/utils/ClockUtils.tsx diff --git a/src/assets/TopBar/Battery.svg b/src/assets/TopBar/Battery.svg new file mode 100644 index 0000000..2096fbf --- /dev/null +++ b/src/assets/TopBar/Battery.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/assets/TopBar/CellularConnection.svg b/src/assets/TopBar/CellularConnection.svg new file mode 100644 index 0000000..71c8333 --- /dev/null +++ b/src/assets/TopBar/CellularConnection.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/TopBar/Wifi.svg b/src/assets/TopBar/Wifi.svg new file mode 100644 index 0000000..8fb9f26 --- /dev/null +++ b/src/assets/TopBar/Wifi.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/ChatRoomPage/TopBar.tsx b/src/components/ChatRoomPage/TopBar.tsx index 6da2c6e..7bea561 100644 --- a/src/components/ChatRoomPage/TopBar.tsx +++ b/src/components/ChatRoomPage/TopBar.tsx @@ -1,8 +1,32 @@ -import React from 'react'; +import React, { useState, useEffect } from 'react'; +import { currentTime } from '../../utils/ClockUtils'; +import BatteryIcon from '../../assets/TopBar/Battery.svg'; +import WifiIcon from '../../assets/TopBar/Wifi.svg'; +import NetworkIcon from '../../assets/TopBar/CellularConnection.svg'; const TopBar = () => { + const [time, setTime] = useState(currentTime()); + + useEffect(() => { + const interval = setInterval(() => { + setTime(currentTime()); + }, 1000); + + return () => clearInterval(interval); + }, []); + return ( -
+
+ {/* 현재 시간 표시 */} +
+ {time} +
+ {/* 상단바 아이콘 */} +
+ Network + Wi-Fi + Battery +
); } diff --git a/src/custom.d.ts b/src/custom.d.ts new file mode 100644 index 0000000..4ec4690 --- /dev/null +++ b/src/custom.d.ts @@ -0,0 +1,4 @@ +declare module '*.svg' { + const content: any; + export default content; +} \ No newline at end of file diff --git a/src/utils/ClockUtils.tsx b/src/utils/ClockUtils.tsx new file mode 100644 index 0000000..d317276 --- /dev/null +++ b/src/utils/ClockUtils.tsx @@ -0,0 +1,8 @@ +// 시간 포맷 +export const currentTime = () => { + return new Date().toLocaleTimeString('ko-KR', { + hour: '2-digit', + minute: '2-digit', + hour12: false, + }); +}; \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index a273b0c..1152a63 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -21,6 +21,7 @@ "jsx": "react-jsx" }, "include": [ - "src" + "src", + "src/custom.d.ts", ] } From bdf3cfae028c7fb32336021ae9c5e49c8b22ec65 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Wed, 25 Sep 2024 16:51:49 +0900 Subject: [PATCH 03/54] =?UTF-8?q?Feat:=20=EC=B1=84=ED=8C=85=EC=B0=BD=20?= =?UTF-8?q?=ED=97=A4=EB=8D=94=20=EC=9A=94=EC=86=8C=20=EB=B0=B0=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/ChatRoom/back.svg | 7 +++++++ src/assets/ChatRoom/menu.svg | 7 +++++++ src/assets/ChatRoom/search.svg | 8 ++++++++ src/components/ChatRoomPage/Header.tsx | 18 +++++++++++++++++- src/index.css | 8 ++++++++ src/pages/ChatRoomPage.tsx | 6 +++++- tailwind.config.js | 3 ++- 7 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 src/assets/ChatRoom/back.svg create mode 100644 src/assets/ChatRoom/menu.svg create mode 100644 src/assets/ChatRoom/search.svg diff --git a/src/assets/ChatRoom/back.svg b/src/assets/ChatRoom/back.svg new file mode 100644 index 0000000..18eacf2 --- /dev/null +++ b/src/assets/ChatRoom/back.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/assets/ChatRoom/menu.svg b/src/assets/ChatRoom/menu.svg new file mode 100644 index 0000000..674a0c6 --- /dev/null +++ b/src/assets/ChatRoom/menu.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/assets/ChatRoom/search.svg b/src/assets/ChatRoom/search.svg new file mode 100644 index 0000000..7fe66cc --- /dev/null +++ b/src/assets/ChatRoom/search.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/components/ChatRoomPage/Header.tsx b/src/components/ChatRoomPage/Header.tsx index 5d827c3..54c888d 100644 --- a/src/components/ChatRoomPage/Header.tsx +++ b/src/components/ChatRoomPage/Header.tsx @@ -1,6 +1,22 @@ +import backIcon from "../../assets/ChatRoom/back.svg"; +import searchIcon from "../../assets/ChatRoom/search.svg"; +import menuIcon from "../../assets/ChatRoom/menu.svg"; + const Header = () => { - return ; + return ( +
+
+ GoBack +

이가빈

+
+ +
+ Search + Menu +
+
+ ); } export default Header; \ No newline at end of file diff --git a/src/index.css b/src/index.css index b8d7ec8..b155dce 100644 --- a/src/index.css +++ b/src/index.css @@ -2,6 +2,14 @@ @tailwind components; @tailwind utilities; +@font-face { + font-family: "Pretendard-Regular"; + src: url("https://fastly.jsdelivr.net/gh/Project-Noonnu/noonfonts_2107@1.1/Pretendard-Regular.woff") + format("woff"); + font-weight: 400; + font-style: normal; +} + /* body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", diff --git a/src/pages/ChatRoomPage.tsx b/src/pages/ChatRoomPage.tsx index 1f3e745..303a6f6 100644 --- a/src/pages/ChatRoomPage.tsx +++ b/src/pages/ChatRoomPage.tsx @@ -1,9 +1,13 @@ +import Header from '../components/ChatRoomPage/Header'; import TopBar from '../components/ChatRoomPage/TopBar'; const ChatRoomPage = () => { return ( - +
+ +
+
); } diff --git a/tailwind.config.js b/tailwind.config.js index f35c19e..52c7333 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -5,7 +5,7 @@ module.exports = { colors: { 'Purple/3': '#D3B8FF', 'White': '#FFFFFF', - + 'Gray/2': '#666666', }, extend: { width: { @@ -14,6 +14,7 @@ module.exports = { height: { 'height': '812px', 'topBarHeight': '52px', + 'headerHeight': '48px', }, } }, From 3b94bbd5f3248d5eea0ca4f5eb8a471794e44776 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Wed, 25 Sep 2024 17:35:09 +0900 Subject: [PATCH 04/54] =?UTF-8?q?Feat:=20IOS=20=ED=99=88=20=EC=9D=B8?= =?UTF-8?q?=EB=94=94=EC=BC=80=EC=9D=B4=ED=84=B0=20=EB=B0=B0=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 6 +++--- src/assets/Common/HomeIndicator.svg | 3 +++ src/components/common/HomeIndicatior.tsx | 13 +++++++++++++ src/components/{ChatRoomPage => common}/TopBar.tsx | 0 src/pages/ChatRoomPage.tsx | 8 ++++++-- tailwind.config.js | 3 +++ 6 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 src/assets/Common/HomeIndicator.svg create mode 100644 src/components/common/HomeIndicatior.tsx rename src/components/{ChatRoomPage => common}/TopBar.tsx (100%) diff --git a/src/App.tsx b/src/App.tsx index 20113da..2cfd3c5 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,9 +2,9 @@ import ChatRoomPage from './pages/ChatRoomPage'; function App() { return ( -
-
- +
+
+
); diff --git a/src/assets/Common/HomeIndicator.svg b/src/assets/Common/HomeIndicator.svg new file mode 100644 index 0000000..039e582 --- /dev/null +++ b/src/assets/Common/HomeIndicator.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/common/HomeIndicatior.tsx b/src/components/common/HomeIndicatior.tsx new file mode 100644 index 0000000..73a1bdf --- /dev/null +++ b/src/components/common/HomeIndicatior.tsx @@ -0,0 +1,13 @@ +import indicator from "../../assets/Common/HomeIndicator.svg"; + +const HomeIndicator = () => { + return ( +
+
+ indicator +
+
+ ); +} + +export default HomeIndicator; diff --git a/src/components/ChatRoomPage/TopBar.tsx b/src/components/common/TopBar.tsx similarity index 100% rename from src/components/ChatRoomPage/TopBar.tsx rename to src/components/common/TopBar.tsx diff --git a/src/pages/ChatRoomPage.tsx b/src/pages/ChatRoomPage.tsx index 303a6f6..4ec2980 100644 --- a/src/pages/ChatRoomPage.tsx +++ b/src/pages/ChatRoomPage.tsx @@ -1,12 +1,16 @@ import Header from '../components/ChatRoomPage/Header'; -import TopBar from '../components/ChatRoomPage/TopBar'; +import HomeIndicator from '../components/common/HomeIndicatior'; +import TopBar from '../components/common/TopBar'; const ChatRoomPage = () => { return ( -
+
+
+ +
); } diff --git a/tailwind.config.js b/tailwind.config.js index 52c7333..f044514 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -3,9 +3,11 @@ module.exports = { content: [ "./src/**/*.{js,jsx,ts,tsx}", ], theme: { colors: { + 'Purple/1': '#AB78FF', 'Purple/3': '#D3B8FF', 'White': '#FFFFFF', 'Gray/2': '#666666', + 'Black': '#000000', }, extend: { width: { @@ -15,6 +17,7 @@ module.exports = { 'height': '812px', 'topBarHeight': '52px', 'headerHeight': '48px', + 'indicatorHeight': '13px', }, } }, From 2ed83e894ca3056fd20bdcc03b01fd45dc0c2c5e Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Wed, 25 Sep 2024 18:52:51 +0900 Subject: [PATCH 05/54] =?UTF-8?q?Feat:=20=EC=B1=84=ED=8C=85=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=EC=B0=BD=20=EA=B5=AC=ED=98=84=20=EB=B0=8F=20=EB=B0=B0?= =?UTF-8?q?=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/ChatRoom/addMedia.svg | 8 ++++++++ src/assets/ChatRoom/emoticonbtn.svg | 10 ++++++++++ src/components/ChatRoomPage/ChatBar.tsx | 26 ++++++++++++++++++++++++- src/pages/ChatRoomPage.tsx | 4 +++- tailwind.config.js | 5 +++++ 5 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 src/assets/ChatRoom/addMedia.svg create mode 100644 src/assets/ChatRoom/emoticonbtn.svg diff --git a/src/assets/ChatRoom/addMedia.svg b/src/assets/ChatRoom/addMedia.svg new file mode 100644 index 0000000..41f4f68 --- /dev/null +++ b/src/assets/ChatRoom/addMedia.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/assets/ChatRoom/emoticonbtn.svg b/src/assets/ChatRoom/emoticonbtn.svg new file mode 100644 index 0000000..ff6969f --- /dev/null +++ b/src/assets/ChatRoom/emoticonbtn.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/components/ChatRoomPage/ChatBar.tsx b/src/components/ChatRoomPage/ChatBar.tsx index 53b3107..29ee2bd 100644 --- a/src/components/ChatRoomPage/ChatBar.tsx +++ b/src/components/ChatRoomPage/ChatBar.tsx @@ -1,6 +1,30 @@ +import addIcon from "../../assets/ChatRoom/addMedia.svg"; +import emoticon from "../../assets/ChatRoom/emoticonbtn.svg"; + const ChatBar = () => { - return ; + return ( +
+ addMedia +
+ + + {/* 이모티콘 버튼 */} + emoticon +
+
+ ); } export default ChatBar; \ No newline at end of file diff --git a/src/pages/ChatRoomPage.tsx b/src/pages/ChatRoomPage.tsx index 4ec2980..a58709e 100644 --- a/src/pages/ChatRoomPage.tsx +++ b/src/pages/ChatRoomPage.tsx @@ -1,3 +1,4 @@ +import ChatBar from '../components/ChatRoomPage/ChatBar'; import Header from '../components/ChatRoomPage/Header'; import HomeIndicator from '../components/common/HomeIndicatior'; import TopBar from '../components/common/TopBar'; @@ -8,7 +9,8 @@ const ChatRoomPage = () => {
-
+
+
diff --git a/tailwind.config.js b/tailwind.config.js index f044514..6da3963 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -7,16 +7,21 @@ module.exports = { 'Purple/3': '#D3B8FF', 'White': '#FFFFFF', 'Gray/2': '#666666', + 'Gray/4' : "#CCCCCC", + 'Gray/5': '#EDEDED', 'Black': '#000000', }, extend: { width: { 'width': '375px', + 'inputWidth':'308px', }, height: { 'height': '812px', 'topBarHeight': '52px', 'headerHeight': '48px', + 'chatBarHeight': '68px', + 'inputHeight': '40px', 'indicatorHeight': '13px', }, } From 80c6cdcccbcbde35316cafdf10efa010148d5bed Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Wed, 25 Sep 2024 22:16:29 +0900 Subject: [PATCH 06/54] =?UTF-8?q?Feat:=20=EC=B1=84=ED=8C=85=20=EC=9E=85?= =?UTF-8?q?=EB=A0=A5=20=EB=82=B4=EC=9A=A9=20=EB=A1=9C=EC=BB=AC=EC=8A=A4?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=EC=A7=80=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ChatRoomPage/ChatBar.tsx | 16 +++++++++++++++- src/components/ChatRoomPage/Header.tsx | 13 ++++++++++++- src/components/ChatRoomPage/MessageList.tsx | 8 ++++++++ src/lib/UserData.tsx | 10 ++++++++++ src/pages/ChatRoomPage.tsx | 18 +++++++++++++++--- tailwind.config.js | 1 + 6 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 src/components/ChatRoomPage/MessageList.tsx create mode 100644 src/lib/UserData.tsx diff --git a/src/components/ChatRoomPage/ChatBar.tsx b/src/components/ChatRoomPage/ChatBar.tsx index 29ee2bd..2ff283c 100644 --- a/src/components/ChatRoomPage/ChatBar.tsx +++ b/src/components/ChatRoomPage/ChatBar.tsx @@ -1,7 +1,18 @@ +import React, { useState } from 'react'; import addIcon from "../../assets/ChatRoom/addMedia.svg"; import emoticon from "../../assets/ChatRoom/emoticonbtn.svg"; -const ChatBar = () => { +const ChatBar = ({ onSendMessage }: { onSendMessage: (message: string) => void }) => { + const [message, setMessage] = useState(''); + + // 엔터로 메시지 전송 + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter' && message.trim() !== '') { + onSendMessage(message); + setMessage(''); + //window.localStorage.clear(); + } + }; return (
{
setMessage(e.target.value)} + onKeyDown={handleKeyDown} placeholder="메시지 입력하기" className="w-full h-full bg-Gray/5 rounded-full placeholder-Gray/4 font-['Pretendard'] pl-[12px]" /> diff --git a/src/components/ChatRoomPage/Header.tsx b/src/components/ChatRoomPage/Header.tsx index 54c888d..3b54d65 100644 --- a/src/components/ChatRoomPage/Header.tsx +++ b/src/components/ChatRoomPage/Header.tsx @@ -1,14 +1,25 @@ import backIcon from "../../assets/ChatRoom/back.svg"; import searchIcon from "../../assets/ChatRoom/search.svg"; import menuIcon from "../../assets/ChatRoom/menu.svg"; +import { UserData } from '../../lib/UserData'; +import { useState } from 'react'; const Header = () => { + const [currentUser, setCurrentUser] = useState(UserData[0]); + + const toggleUser = () => { + setCurrentUser(prevUser => + prevUser.userId === 0 ? UserData[1] : UserData[0] + ); + }; return (
GoBack -

이가빈

+

+ {currentUser.userName} +

diff --git a/src/components/ChatRoomPage/MessageList.tsx b/src/components/ChatRoomPage/MessageList.tsx new file mode 100644 index 0000000..1e64b77 --- /dev/null +++ b/src/components/ChatRoomPage/MessageList.tsx @@ -0,0 +1,8 @@ +const MessageList = () => { + return ( +
+
+ ); +} + +export default MessageList; diff --git a/src/lib/UserData.tsx b/src/lib/UserData.tsx new file mode 100644 index 0000000..228f5a7 --- /dev/null +++ b/src/lib/UserData.tsx @@ -0,0 +1,10 @@ +export const UserData = [ + { + userId: 0, + userName: '이가빈', + }, + { + userId: 1, + userName: '김태양', + }, +]; \ No newline at end of file diff --git a/src/pages/ChatRoomPage.tsx b/src/pages/ChatRoomPage.tsx index a58709e..7a84b4f 100644 --- a/src/pages/ChatRoomPage.tsx +++ b/src/pages/ChatRoomPage.tsx @@ -1,16 +1,28 @@ +import React, { useState } from 'react'; import ChatBar from '../components/ChatRoomPage/ChatBar'; import Header from '../components/ChatRoomPage/Header'; import HomeIndicator from '../components/common/HomeIndicatior'; import TopBar from '../components/common/TopBar'; +import { UserData } from '../lib/UserData'; +import MessageList from '../components/ChatRoomPage/MessageList'; const ChatRoomPage = () => { + const [currentUser, setCurrentUser] = useState(UserData[0]); + const [messages, setMessages] = useState<{ senderId: number, text: string }[]>([]); + + const handleSendMessage = (message: string) => { + setMessages(prevMessages => [...prevMessages, { senderId: currentUser.userId, text: message }]); + }; + + const otherUser = currentUser.userId === 0 ? UserData[1] : UserData[0]; return ( -
+
-
- + +
+
diff --git a/tailwind.config.js b/tailwind.config.js index 6da3963..f7f301d 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -20,6 +20,7 @@ module.exports = { 'height': '812px', 'topBarHeight': '52px', 'headerHeight': '48px', + 'messageAreaHeight':'631px', 'chatBarHeight': '68px', 'inputHeight': '40px', 'indicatorHeight': '13px', From 1e056dbd865ae7e94c892b67b41543055286e04a Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Wed, 25 Sep 2024 22:35:20 +0900 Subject: [PATCH 07/54] =?UTF-8?q?Feat:=20=EB=82=B4=EA=B0=80=20=EB=B3=B4?= =?UTF-8?q?=EB=82=B8=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EB=A0=8C=EB=8D=94?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ChatRoomPage/MessageList.tsx | 23 +++++++++++++++++++-- src/pages/ChatRoomPage.tsx | 2 +- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/components/ChatRoomPage/MessageList.tsx b/src/components/ChatRoomPage/MessageList.tsx index 1e64b77..adf8316 100644 --- a/src/components/ChatRoomPage/MessageList.tsx +++ b/src/components/ChatRoomPage/MessageList.tsx @@ -1,6 +1,25 @@ -const MessageList = () => { +import React from 'react'; + +interface Message { + senderId: number; + text: string; +} + +interface MessageListProps { + messages: Message[]; + currentUserId: number; +} + +const MessageList: React.FC = ({ messages, currentUserId }) => { return ( -
+
+ {messages.map((message, index) => ( +
+

+ {message.text} +

+
+ ))}
); } diff --git a/src/pages/ChatRoomPage.tsx b/src/pages/ChatRoomPage.tsx index 7a84b4f..507aa08 100644 --- a/src/pages/ChatRoomPage.tsx +++ b/src/pages/ChatRoomPage.tsx @@ -20,7 +20,7 @@ const ChatRoomPage = () => {
- +
From de805ece590e367255e8765fd08ae7760b9973c6 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Wed, 25 Sep 2024 22:39:15 +0900 Subject: [PATCH 08/54] =?UTF-8?q?Fix:=20=EB=A9=94=EC=8B=9C=EC=A7=80=20?= =?UTF-8?q?=EB=A0=8C=EB=8D=94=EB=A7=81=20=EC=B0=BD=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A1=A4=EB=B0=94=20=EC=88=A8=EA=B8=B0=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 6 ++++++ package.json | 1 + src/components/ChatRoomPage/MessageList.tsx | 2 +- tailwind.config.js | 2 +- 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3f2ef34..e34dda1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", + "tailwind-scrollbar-hide": "^1.1.7", "typescript": "^4.9.5", "web-vitals": "^2.1.4" }, @@ -16493,6 +16494,11 @@ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" }, + "node_modules/tailwind-scrollbar-hide": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/tailwind-scrollbar-hide/-/tailwind-scrollbar-hide-1.1.7.tgz", + "integrity": "sha512-X324n9OtpTmOMqEgDUEA/RgLrNfBF/jwJdctaPZDzB3mppxJk7TLIDmOreEDm1Bq4R9LSPu4Epf8VSdovNU+iA==" + }, "node_modules/tailwindcss": { "version": "3.4.13", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.13.tgz", diff --git a/package.json b/package.json index 15d6dce..23dccdb 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", + "tailwind-scrollbar-hide": "^1.1.7", "typescript": "^4.9.5", "web-vitals": "^2.1.4" }, diff --git a/src/components/ChatRoomPage/MessageList.tsx b/src/components/ChatRoomPage/MessageList.tsx index adf8316..0018a14 100644 --- a/src/components/ChatRoomPage/MessageList.tsx +++ b/src/components/ChatRoomPage/MessageList.tsx @@ -12,7 +12,7 @@ interface MessageListProps { const MessageList: React.FC = ({ messages, currentUserId }) => { return ( -
+
{messages.map((message, index) => (

diff --git a/tailwind.config.js b/tailwind.config.js index f7f301d..8db2d38 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -27,7 +27,7 @@ module.exports = { }, } }, - plugins: [], + plugins: [require("tailwind-scrollbar-hide")], } From 45d60db69db67de0b11ec9459f2c7005c157d165 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Wed, 25 Sep 2024 22:49:53 +0900 Subject: [PATCH 09/54] =?UTF-8?q?Feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=9D=BC=20=EB=A9=94=EC=8B=9C=EC=A7=80=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98=20=EB=B0=8F=20=EC=8A=A4=ED=83=80=EC=9D=BC=20?= =?UTF-8?q?=EC=A0=84=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ChatRoomPage/Header.tsx | 14 +++++--------- src/pages/ChatRoomPage.tsx | 11 +++++++++-- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/components/ChatRoomPage/Header.tsx b/src/components/ChatRoomPage/Header.tsx index 3b54d65..9b8aa14 100644 --- a/src/components/ChatRoomPage/Header.tsx +++ b/src/components/ChatRoomPage/Header.tsx @@ -1,17 +1,13 @@ import backIcon from "../../assets/ChatRoom/back.svg"; import searchIcon from "../../assets/ChatRoom/search.svg"; import menuIcon from "../../assets/ChatRoom/menu.svg"; -import { UserData } from '../../lib/UserData'; -import { useState } from 'react'; -const Header = () => { - const [currentUser, setCurrentUser] = useState(UserData[0]); +interface HeaderProps { + currentUser: { userId: number, userName: string }; + toggleUser: () => void; +} - const toggleUser = () => { - setCurrentUser(prevUser => - prevUser.userId === 0 ? UserData[1] : UserData[0] - ); - }; +const Header: React.FC = ({ currentUser, toggleUser }) => { return (

diff --git a/src/pages/ChatRoomPage.tsx b/src/pages/ChatRoomPage.tsx index 507aa08..41cdba2 100644 --- a/src/pages/ChatRoomPage.tsx +++ b/src/pages/ChatRoomPage.tsx @@ -3,13 +3,20 @@ import ChatBar from '../components/ChatRoomPage/ChatBar'; import Header from '../components/ChatRoomPage/Header'; import HomeIndicator from '../components/common/HomeIndicatior'; import TopBar from '../components/common/TopBar'; -import { UserData } from '../lib/UserData'; import MessageList from '../components/ChatRoomPage/MessageList'; +import { UserData } from '../lib/UserData'; const ChatRoomPage = () => { const [currentUser, setCurrentUser] = useState(UserData[0]); const [messages, setMessages] = useState<{ senderId: number, text: string }[]>([]); + // 유저 토글 전환 + const toggleUser = () => { + setCurrentUser(prevUser => + prevUser.userId === 0 ? UserData[1] : UserData[0] + ); + }; + const handleSendMessage = (message: string) => { setMessages(prevMessages => [...prevMessages, { senderId: currentUser.userId, text: message }]); }; @@ -19,7 +26,7 @@ const ChatRoomPage = () => { return (
-
+
From 8241b65db175b80bbf20cfa87c2e78517fdc1527 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Wed, 25 Sep 2024 23:00:10 +0900 Subject: [PATCH 10/54] =?UTF-8?q?Chore:=20=EC=95=88=20=EC=93=B0=EB=8A=94?= =?UTF-8?q?=20=EB=B3=80=EC=88=98=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/ChatRoomPage.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pages/ChatRoomPage.tsx b/src/pages/ChatRoomPage.tsx index 41cdba2..06a1fc8 100644 --- a/src/pages/ChatRoomPage.tsx +++ b/src/pages/ChatRoomPage.tsx @@ -21,8 +21,6 @@ const ChatRoomPage = () => { setMessages(prevMessages => [...prevMessages, { senderId: currentUser.userId, text: message }]); }; - const otherUser = currentUser.userId === 0 ? UserData[1] : UserData[0]; - return (
From 8e7eae0088387e67537e08e032654d996b6b3fb0 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Wed, 25 Sep 2024 23:03:57 +0900 Subject: [PATCH 11/54] =?UTF-8?q?Fix:=20=EC=9E=85=EB=A0=A5=EC=B0=BD=20?= =?UTF-8?q?=EC=9D=B4=EB=AA=A8=ED=8B=B0=EC=BD=98=20=EB=B2=84=ED=8A=BC?= =?UTF-8?q?=EA=B3=BC=20=ED=85=8D=EC=8A=A4=ED=8A=B8=20=EA=B2=B9=EC=B9=A8=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ChatRoomPage/ChatBar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ChatRoomPage/ChatBar.tsx b/src/components/ChatRoomPage/ChatBar.tsx index 2ff283c..4ddb2a7 100644 --- a/src/components/ChatRoomPage/ChatBar.tsx +++ b/src/components/ChatRoomPage/ChatBar.tsx @@ -27,7 +27,7 @@ const ChatBar = ({ onSendMessage }: { onSendMessage: (message: string) => void } onChange={(e) => setMessage(e.target.value)} onKeyDown={handleKeyDown} placeholder="메시지 입력하기" - className="w-full h-full bg-Gray/5 rounded-full placeholder-Gray/4 font-['Pretendard'] pl-[12px]" + className="w-full h-full bg-Gray/5 rounded-full placeholder-Gray/4 font-['Pretendard'] pl-[12px] pr-[40px]" /> {/* 이모티콘 버튼 */} From 8a41ef158eb41c8a91358b04bcbcc001a202d1b6 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Thu, 26 Sep 2024 17:05:12 +0900 Subject: [PATCH 12/54] =?UTF-8?q?Feat:=20=EB=A9=94=EC=8B=9C=EC=A7=80=20?= =?UTF-8?q?=ED=83=80=EC=9E=84=EC=8A=A4=ED=83=AC=ED=94=84=20=EB=B0=8F=20?= =?UTF-8?q?=EC=83=81=EB=8C=80=EB=B0=A9=20=ED=94=84=EB=A1=9C=ED=95=84=20?= =?UTF-8?q?=EC=B6=9C=EB=A0=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/ChatRoom/profile.svg | 11 ++++ src/components/ChatRoomPage/MessageList.tsx | 66 +++++++++++++++++++-- src/pages/ChatRoomPage.tsx | 7 ++- 3 files changed, 76 insertions(+), 8 deletions(-) create mode 100644 src/assets/ChatRoom/profile.svg diff --git a/src/assets/ChatRoom/profile.svg b/src/assets/ChatRoom/profile.svg new file mode 100644 index 0000000..33c587a --- /dev/null +++ b/src/assets/ChatRoom/profile.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/components/ChatRoomPage/MessageList.tsx b/src/components/ChatRoomPage/MessageList.tsx index 0018a14..b962b97 100644 --- a/src/components/ChatRoomPage/MessageList.tsx +++ b/src/components/ChatRoomPage/MessageList.tsx @@ -1,8 +1,10 @@ import React from 'react'; +import profileIcon from "../../assets/ChatRoom/profile.svg"; interface Message { senderId: number; text: string; + timestamp: Date; } interface MessageListProps { @@ -10,18 +12,70 @@ interface MessageListProps { currentUserId: number; } +const formatTime = (date: Date) => { + const hours = date.getHours(); + const minutes = date.getMinutes(); + const ampm = hours >= 12 ? '오후' : '오전'; + const formattedHours = hours % 12 === 0 ? 12 : hours % 12; + return `${ampm} ${formattedHours}:${minutes < 10 ? '0' : ''}${minutes}`; +}; + +const groupMessagesByMinute = (messages: Message[]) => { + return messages.reduce((acc, message) => { + // 분 단위로 그룹화 키 생성 + const timeKey = formatTime(message.timestamp); + if (!acc[timeKey]) { + acc[timeKey] = []; + } + acc[timeKey].push(message); + return acc; + }, {} as { [key: string]: Message[] }); +}; + const MessageList: React.FC = ({ messages, currentUserId }) => { + const groupedMessages = groupMessagesByMinute(messages); + return (
- {messages.map((message, index) => ( -
-

- {message.text} -

+ {Object.keys(groupedMessages).map((time, index) => ( +
+ {/* 시간 출력 */} +
{time}
+ + {/* 메시지 그룹 출력 */} + {groupedMessages[time].map((message, idx) => ( +
+ {/* 상대방 메시지 블록 */} + {message.senderId !== currentUserId && idx === 0 && ( +
+ {/* 상대방 프로필 아이콘 및 이름 */} +
+ Profile + 이가빈 +
+ {/* 상대방 메시지 목록 */} + {groupedMessages[time] + .filter((msg) => msg.senderId !== currentUserId) + .map((msg, i) => ( +

+ {msg.text} +

+ ))} +
+ )} + + {/* 현재 사용자 메시지 출력 */} + {message.senderId === currentUserId && ( +

+ {message.text} +

+ )} +
+ ))}
))}
); -} +}; export default MessageList; diff --git a/src/pages/ChatRoomPage.tsx b/src/pages/ChatRoomPage.tsx index 06a1fc8..e94df66 100644 --- a/src/pages/ChatRoomPage.tsx +++ b/src/pages/ChatRoomPage.tsx @@ -8,7 +8,7 @@ import { UserData } from '../lib/UserData'; const ChatRoomPage = () => { const [currentUser, setCurrentUser] = useState(UserData[0]); - const [messages, setMessages] = useState<{ senderId: number, text: string }[]>([]); + const [messages, setMessages] = useState<{ senderId: number, text: string, timestamp: Date }[]>([]); // 유저 토글 전환 const toggleUser = () => { @@ -18,7 +18,10 @@ const ChatRoomPage = () => { }; const handleSendMessage = (message: string) => { - setMessages(prevMessages => [...prevMessages, { senderId: currentUser.userId, text: message }]); + setMessages(prevMessages => [ + ...prevMessages, + { senderId: currentUser.userId, text: message, timestamp: new Date() } // timestamp 추가 + ]); }; return ( From e97c398cf6e264590b4b5c83135467eeaafa7cc9 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Thu, 26 Sep 2024 20:36:16 +0900 Subject: [PATCH 13/54] =?UTF-8?q?Feat:=20=EC=B1=84=ED=8C=85=20=EB=82=B4?= =?UTF-8?q?=EC=9A=A9=20=EB=A1=9C=EC=BB=AC=EC=8A=A4=ED=86=A0=EB=A6=AC?= =?UTF-8?q?=EC=A7=80=20=EC=A0=80=EC=9E=A5=20=EB=B0=8F=20=EB=B6=88=EB=9F=AC?= =?UTF-8?q?=EC=98=A4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ChatRoomPage/ChatBar.tsx | 1 - src/components/ChatRoomPage/Header.tsx | 5 +-- src/components/ChatRoomPage/MessageList.tsx | 34 ++++++++++++------- src/pages/ChatRoomPage.tsx | 36 +++++++++++++++++---- 4 files changed, 54 insertions(+), 22 deletions(-) diff --git a/src/components/ChatRoomPage/ChatBar.tsx b/src/components/ChatRoomPage/ChatBar.tsx index 4ddb2a7..ce57d2f 100644 --- a/src/components/ChatRoomPage/ChatBar.tsx +++ b/src/components/ChatRoomPage/ChatBar.tsx @@ -10,7 +10,6 @@ const ChatBar = ({ onSendMessage }: { onSendMessage: (message: string) => void } if (e.key === 'Enter' && message.trim() !== '') { onSendMessage(message); setMessage(''); - //window.localStorage.clear(); } }; diff --git a/src/components/ChatRoomPage/Header.tsx b/src/components/ChatRoomPage/Header.tsx index 9b8aa14..40cc64b 100644 --- a/src/components/ChatRoomPage/Header.tsx +++ b/src/components/ChatRoomPage/Header.tsx @@ -4,17 +4,18 @@ import menuIcon from "../../assets/ChatRoom/menu.svg"; interface HeaderProps { currentUser: { userId: number, userName: string }; + opponentUser: { userId: number, userName: string }; toggleUser: () => void; } -const Header: React.FC = ({ currentUser, toggleUser }) => { +const Header: React.FC = ({ currentUser, opponentUser, toggleUser }) => { return (
GoBack

- {currentUser.userName} + {opponentUser.userName}

diff --git a/src/components/ChatRoomPage/MessageList.tsx b/src/components/ChatRoomPage/MessageList.tsx index b962b97..5a3af77 100644 --- a/src/components/ChatRoomPage/MessageList.tsx +++ b/src/components/ChatRoomPage/MessageList.tsx @@ -1,6 +1,11 @@ import React from 'react'; import profileIcon from "../../assets/ChatRoom/profile.svg"; +interface User { + userId: number; + userName: string; +} + interface Message { senderId: number; text: string; @@ -10,6 +15,7 @@ interface Message { interface MessageListProps { messages: Message[]; currentUserId: number; + users: User[]; } const formatTime = (date: Date) => { @@ -32,9 +38,15 @@ const groupMessagesByMinute = (messages: Message[]) => { }, {} as { [key: string]: Message[] }); }; -const MessageList: React.FC = ({ messages, currentUserId }) => { +const MessageList: React.FC = ({ messages, currentUserId, users }) => { const groupedMessages = groupMessagesByMinute(messages); + // senderId로 사용자 이름 찾기 + const getUserName = (senderId: number) => { + const user = users.find(user => user.userId === senderId); + return user ? user.userName : '(알 수 없음)'; + }; + return (
{Object.keys(groupedMessages).map((time, index) => ( @@ -46,21 +58,19 @@ const MessageList: React.FC = ({ messages, currentUserId }) => {groupedMessages[time].map((message, idx) => (
{/* 상대방 메시지 블록 */} - {message.senderId !== currentUserId && idx === 0 && ( + {message.senderId !== currentUserId && (
{/* 상대방 프로필 아이콘 및 이름 */}
- Profile - 이가빈 + Profile +

+ {getUserName(message.senderId)} +

- {/* 상대방 메시지 목록 */} - {groupedMessages[time] - .filter((msg) => msg.senderId !== currentUserId) - .map((msg, i) => ( -

- {msg.text} -

- ))} + {/* 상대방 메시지 */} +

+ {message.text} +

)} diff --git a/src/pages/ChatRoomPage.tsx b/src/pages/ChatRoomPage.tsx index e94df66..961fb69 100644 --- a/src/pages/ChatRoomPage.tsx +++ b/src/pages/ChatRoomPage.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import ChatBar from '../components/ChatRoomPage/ChatBar'; import Header from '../components/ChatRoomPage/Header'; import HomeIndicator from '../components/common/HomeIndicatior'; @@ -10,6 +10,23 @@ const ChatRoomPage = () => { const [currentUser, setCurrentUser] = useState(UserData[0]); const [messages, setMessages] = useState<{ senderId: number, text: string, timestamp: Date }[]>([]); + // 상대방 유저 설정 + const opponentUser = currentUser.userId === 0 ? UserData[1] : UserData[0]; + + // 로컬 스토리지에서 메시지 불러오기 + useEffect(() => { + const savedMessages = localStorage.getItem('messages'); + if (savedMessages) { + const parsedMessages = JSON.parse(savedMessages).map((msg: any) => ({ + ...msg, + timestamp: new Date(msg.timestamp), + })); + setMessages(parsedMessages); + //window.localStorage.clear(); + console.log(parsedMessages); + } + }, []); + // 유저 토글 전환 const toggleUser = () => { setCurrentUser(prevUser => @@ -17,18 +34,23 @@ const ChatRoomPage = () => { ); }; + // 메시지 전송 핸들러 const handleSendMessage = (message: string) => { - setMessages(prevMessages => [ - ...prevMessages, - { senderId: currentUser.userId, text: message, timestamp: new Date() } // timestamp 추가 - ]); + const newMessage = { senderId: currentUser.userId, text: message, timestamp: new Date() }; + + setMessages(prevMessages => { + const updatedMessages = [...prevMessages, newMessage]; + // 로컬 스토리지에 저장 + localStorage.setItem('messages', JSON.stringify(updatedMessages)); + return updatedMessages; + }); }; return (
-
- +
+
From b2747189fe18cb6731143e8c5f0afce08201c555 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Thu, 26 Sep 2024 20:46:42 +0900 Subject: [PATCH 14/54] =?UTF-8?q?Fix:=20=EC=83=81=EB=8C=80=EB=B0=A9=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=A4=91=EB=B3=B5=20=EC=B6=9C?= =?UTF-8?q?=EB=A0=A5=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ChatRoomPage/MessageList.tsx | 99 +++++++++++++-------- 1 file changed, 61 insertions(+), 38 deletions(-) diff --git a/src/components/ChatRoomPage/MessageList.tsx b/src/components/ChatRoomPage/MessageList.tsx index 5a3af77..7e0497f 100644 --- a/src/components/ChatRoomPage/MessageList.tsx +++ b/src/components/ChatRoomPage/MessageList.tsx @@ -26,20 +26,26 @@ const formatTime = (date: Date) => { return `${ampm} ${formattedHours}:${minutes < 10 ? '0' : ''}${minutes}`; }; -const groupMessagesByMinute = (messages: Message[]) => { - return messages.reduce((acc, message) => { - // 분 단위로 그룹화 키 생성 +// 사용자와 시간(분 단위)으로 메시지 그룹화 +const groupMessages = (messages: Message[]) => { + return messages.reduce((acc, message, index) => { const timeKey = formatTime(message.timestamp); - if (!acc[timeKey]) { - acc[timeKey] = []; + const prevMessage = messages[index - 1]; + const isSameSender = prevMessage && prevMessage.senderId === message.senderId; + const isSameMinute = prevMessage && formatTime(prevMessage.timestamp) === timeKey; + + if (!isSameSender || !isSameMinute) { + acc.push({ timeKey, senderId: message.senderId, messages: [message] }); + } else { + acc[acc.length - 1].messages.push(message); } - acc[timeKey].push(message); + return acc; - }, {} as { [key: string]: Message[] }); + }, [] as { timeKey: string; senderId: number; messages: Message[] }[]); }; const MessageList: React.FC = ({ messages, currentUserId, users }) => { - const groupedMessages = groupMessagesByMinute(messages); + const groupedMessages = groupMessages(messages); // senderId로 사용자 이름 찾기 const getUserName = (senderId: number) => { @@ -47,43 +53,60 @@ const MessageList: React.FC = ({ messages, currentUserId, user return user ? user.userName : '(알 수 없음)'; }; + // 이전 타임스탬프 저장 + let lastTimeDisplayed: string | null = null; + return (
- {Object.keys(groupedMessages).map((time, index) => ( -
- {/* 시간 출력 */} -
{time}
- - {/* 메시지 그룹 출력 */} - {groupedMessages[time].map((message, idx) => ( -
- {/* 상대방 메시지 블록 */} - {message.senderId !== currentUserId && ( -
- {/* 상대방 프로필 아이콘 및 이름 */} -
- Profile -

- {getUserName(message.senderId)} -

-
+ {groupedMessages.map((group, groupIndex) => { + const shouldDisplayTime = group.timeKey !== lastTimeDisplayed; + lastTimeDisplayed = group.timeKey; + + return ( +
+ {/* 타임스탬프 출력 */} + {shouldDisplayTime && ( +
+ {group.timeKey} +
+ )} + + {/* 메시지 그룹 출력 */} + {group.messages.map((message, idx) => ( +
+ {/* 상대방 메시지 블록 */} + {message.senderId !== currentUserId && ( +
+ {/* 첫 번째 메시지일 경우에만 상대방 프로필 아이콘 및 이름 출력 */} + {idx === 0 && ( +
+ Profile +

+ {getUserName(message.senderId)} +

+
+ )} {/* 상대방 메시지 */}

{message.text}

-
- )} +
+ )} - {/* 현재 사용자 메시지 출력 */} - {message.senderId === currentUserId && ( -

- {message.text} -

- )} -
- ))} -
- ))} + {/* 현재 사용자 메시지 출력 */} + {message.senderId === currentUserId && ( +

+ {message.text} +

+ )} +
+ ))} +
+ ); + })}
); }; From 7bfca7b6e93ecaa263aac4e3c3c0181c689652cf Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Thu, 26 Sep 2024 20:48:31 +0900 Subject: [PATCH 15/54] =?UTF-8?q?Design:=20=ED=83=80=EC=9E=84=EC=8A=A4?= =?UTF-8?q?=ED=83=AC=ED=94=84=20=EC=9C=84=EC=B9=98(=EB=A7=88=EC=A7=84)=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ChatRoomPage/MessageList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ChatRoomPage/MessageList.tsx b/src/components/ChatRoomPage/MessageList.tsx index 7e0497f..c01dadd 100644 --- a/src/components/ChatRoomPage/MessageList.tsx +++ b/src/components/ChatRoomPage/MessageList.tsx @@ -66,7 +66,7 @@ const MessageList: React.FC = ({ messages, currentUserId, user
{/* 타임스탬프 출력 */} {shouldDisplayTime && ( -
+
{group.timeKey}
)} From 4b5ac55fc0a1dc4ef7daee3c2649d8ca3c979948 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Thu, 26 Sep 2024 20:58:08 +0900 Subject: [PATCH 16/54] =?UTF-8?q?Refactor:=20=ED=83=80=EC=9E=84=EC=8A=A4?= =?UTF-8?q?=ED=83=AC=ED=94=84=20=EC=9C=A0=ED=8B=B8=20=ED=95=A8=EC=88=98=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ChatRoomPage/MessageList.tsx | 17 +++++------------ src/utils/ClockUtils.tsx | 11 ++++++++++- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/components/ChatRoomPage/MessageList.tsx b/src/components/ChatRoomPage/MessageList.tsx index c01dadd..4c1af02 100644 --- a/src/components/ChatRoomPage/MessageList.tsx +++ b/src/components/ChatRoomPage/MessageList.tsx @@ -1,5 +1,6 @@ import React from 'react'; import profileIcon from "../../assets/ChatRoom/profile.svg"; +import { formatTime } from '../../utils/ClockUtils'; interface User { userId: number; @@ -18,29 +19,21 @@ interface MessageListProps { users: User[]; } -const formatTime = (date: Date) => { - const hours = date.getHours(); - const minutes = date.getMinutes(); - const ampm = hours >= 12 ? '오후' : '오전'; - const formattedHours = hours % 12 === 0 ? 12 : hours % 12; - return `${ampm} ${formattedHours}:${minutes < 10 ? '0' : ''}${minutes}`; -}; - // 사용자와 시간(분 단위)으로 메시지 그룹화 const groupMessages = (messages: Message[]) => { - return messages.reduce((acc, message, index) => { + return messages.reduce((arr, message, index) => { const timeKey = formatTime(message.timestamp); const prevMessage = messages[index - 1]; const isSameSender = prevMessage && prevMessage.senderId === message.senderId; const isSameMinute = prevMessage && formatTime(prevMessage.timestamp) === timeKey; if (!isSameSender || !isSameMinute) { - acc.push({ timeKey, senderId: message.senderId, messages: [message] }); + arr.push({ timeKey, senderId: message.senderId, messages: [message] }); } else { - acc[acc.length - 1].messages.push(message); + arr[arr.length - 1].messages.push(message); } - return acc; + return arr; }, [] as { timeKey: string; senderId: number; messages: Message[] }[]); }; diff --git a/src/utils/ClockUtils.tsx b/src/utils/ClockUtils.tsx index d317276..058661a 100644 --- a/src/utils/ClockUtils.tsx +++ b/src/utils/ClockUtils.tsx @@ -1,8 +1,17 @@ -// 시간 포맷 +// 현재 시간 포맷 (상단바) export const currentTime = () => { return new Date().toLocaleTimeString('ko-KR', { hour: '2-digit', minute: '2-digit', hour12: false, }); +}; + +// 타임스탬프 포맷 +export const formatTime = (date: Date): string => { + const hours = date.getHours(); + const minutes = date.getMinutes(); + const ampm = hours >= 12 ? '오후' : '오전'; + const formattedHours = hours % 12 === 0 ? 12 : hours % 12; + return `${ampm} ${formattedHours}:${minutes < 10 ? '0' : ''}${minutes}`; }; \ No newline at end of file From 1c496b4b0953ceb97f595d798bb1e7eb604fe69f Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Thu, 26 Sep 2024 21:08:47 +0900 Subject: [PATCH 17/54] =?UTF-8?q?Fix:=20=ED=83=80=EC=9E=84=EC=8A=A4?= =?UTF-8?q?=ED=83=AC=ED=94=84=20=EB=82=A0=EC=A7=9C=20=ED=8F=AC=EB=A7=B7?= =?UTF-8?q?=ED=8C=85=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/ClockUtils.tsx | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/utils/ClockUtils.tsx b/src/utils/ClockUtils.tsx index 058661a..d62f5a6 100644 --- a/src/utils/ClockUtils.tsx +++ b/src/utils/ClockUtils.tsx @@ -9,9 +9,33 @@ export const currentTime = () => { // 타임스탬프 포맷 export const formatTime = (date: Date): string => { + const now = new Date(); + const diffInTime = now.getTime() - date.getTime(); + const diffInDays = Math.floor(diffInTime / (1000 * 60 * 60 * 24)); // 일 단위 차이 계산 + const hours = date.getHours(); const minutes = date.getMinutes(); const ampm = hours >= 12 ? '오후' : '오전'; const formattedHours = hours % 12 === 0 ? 12 : hours % 12; - return `${ampm} ${formattedHours}:${minutes < 10 ? '0' : ''}${minutes}`; + const timeString = `${ampm} ${formattedHours}:${minutes < 10 ? '0' : ''}${minutes}`; + + // 날짜 포맷 + if (diffInDays === 0) { + // 오늘일 경우 시간만 표시 + return timeString; + } else if (diffInDays === 1) { + // 어제일 경우 + return `(어제) ${timeString}`; + } else if (diffInDays === 2) { + // 그저께일 경우 + return `(그저께) ${timeString}`; + } else if (diffInDays <= 3) { + // 3일 전일 경우 + return `(${diffInDays}일 전) ${timeString}`; + } else { + // 3일을 넘는 경우 MM/DD 형식으로 + const month = date.getMonth() + 1; + const day = date.getDate(); + return `(${month}/${day}) ${timeString}`; + } }; \ No newline at end of file From a19c472bc50133d33665ea9bab1b1224aade5598 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Thu, 26 Sep 2024 21:41:17 +0900 Subject: [PATCH 18/54] =?UTF-8?q?Feat:=20=EB=A9=94=EC=8B=9C=EC=A7=80=20?= =?UTF-8?q?=EC=A0=84=EC=86=A1=20=EB=B2=84=ED=8A=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/ChatRoom/sendbtn.svg | 13 ++++++ src/components/ChatRoomPage/ChatBar.tsx | 53 ++++++++++++++++++------- 2 files changed, 52 insertions(+), 14 deletions(-) create mode 100644 src/assets/ChatRoom/sendbtn.svg diff --git a/src/assets/ChatRoom/sendbtn.svg b/src/assets/ChatRoom/sendbtn.svg new file mode 100644 index 0000000..03248de --- /dev/null +++ b/src/assets/ChatRoom/sendbtn.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/src/components/ChatRoomPage/ChatBar.tsx b/src/components/ChatRoomPage/ChatBar.tsx index ce57d2f..fab9616 100644 --- a/src/components/ChatRoomPage/ChatBar.tsx +++ b/src/components/ChatRoomPage/ChatBar.tsx @@ -1,15 +1,25 @@ import React, { useState } from 'react'; import addIcon from "../../assets/ChatRoom/addMedia.svg"; import emoticon from "../../assets/ChatRoom/emoticonbtn.svg"; +import sendIcon from "../../assets/ChatRoom/sendbtn.svg"; const ChatBar = ({ onSendMessage }: { onSendMessage: (message: string) => void }) => { const [message, setMessage] = useState(''); + const [isInputFocused, setIsInputFocused] = useState(false); - // 엔터로 메시지 전송 - const handleKeyDown = (e: React.KeyboardEvent) => { - if (e.key === 'Enter' && message.trim() !== '') { + // 메시지 전송 핸들러 + const handleSendMessage = () => { + if (message.trim() !== '') { onSendMessage(message); setMessage(''); + setIsInputFocused(false); + } + }; + + // 엔터로 메시지 전송 + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === 'Enter') { + handleSendMessage(); } }; @@ -17,27 +27,42 @@ const ChatBar = ({ onSendMessage }: { onSendMessage: (message: string) => void }
- addMedia -
+ > + addMedia +
setMessage(e.target.value)} onKeyDown={handleKeyDown} + onFocus={() => setIsInputFocused(true)} + onBlur={() => { + if (!message.trim()) setIsInputFocused(false); + }} placeholder="메시지 입력하기" - className="w-full h-full bg-Gray/5 rounded-full placeholder-Gray/4 font-['Pretendard'] pl-[12px] pr-[40px]" + className={`transition-all duration-300 w-inputWidth h-inputHeight rounded-full placeholder-Gray/4 font-['Pretendard'] pl-[12px] pr-[40px] bg-Gray/5 ${ + isInputFocused ? 'w-[calc(100%-20px)] mr-0' : 'w-inputWidth' + }`} /> - + {/* 이모티콘 버튼 */} - emoticon +
+ emoticon +
+ + {/* 전송 아이콘 */} + {isInputFocused && ( + + )}
); } -export default ChatBar; \ No newline at end of file +export default ChatBar; From 2a0ab9be02a3c151055204046120d0349af3997b Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Thu, 26 Sep 2024 21:56:40 +0900 Subject: [PATCH 19/54] =?UTF-8?q?Feat:=20=EB=A9=94=EC=8B=9C=EC=A7=80?= =?UTF-8?q?=EB=A5=BC=20=EC=A0=84=EC=86=A1=ED=95=98=EB=A9=B4=20=EC=B1=84?= =?UTF-8?q?=ED=8C=85=EB=B0=A9=20=ED=95=98=EB=8B=A8=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=8A=A4=ED=81=AC=EB=A1=A4=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ChatRoomPage/ChatBar.tsx | 2 +- src/components/ChatRoomPage/MessageList.tsx | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/components/ChatRoomPage/ChatBar.tsx b/src/components/ChatRoomPage/ChatBar.tsx index fab9616..9165ada 100644 --- a/src/components/ChatRoomPage/ChatBar.tsx +++ b/src/components/ChatRoomPage/ChatBar.tsx @@ -57,7 +57,7 @@ const ChatBar = ({ onSendMessage }: { onSendMessage: (message: string) => void } {/* 전송 아이콘 */} {isInputFocused && ( - )} diff --git a/src/components/ChatRoomPage/MessageList.tsx b/src/components/ChatRoomPage/MessageList.tsx index 4c1af02..e5bd64b 100644 --- a/src/components/ChatRoomPage/MessageList.tsx +++ b/src/components/ChatRoomPage/MessageList.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useRef, useEffect } from 'react'; import profileIcon from "../../assets/ChatRoom/profile.svg"; import { formatTime } from '../../utils/ClockUtils'; @@ -49,6 +49,15 @@ const MessageList: React.FC = ({ messages, currentUserId, user // 이전 타임스탬프 저장 let lastTimeDisplayed: string | null = null; + const scrollRef = useRef(null); + + // 메시지가 전송될 때마다 하단으로 스크롤 + useEffect(() => { + if (scrollRef.current) { + scrollRef.current.scrollIntoView({ behavior: 'smooth' }); + } + }, [messages]); + return (
{groupedMessages.map((group, groupIndex) => { @@ -83,7 +92,7 @@ const MessageList: React.FC = ({ messages, currentUserId, user
)} {/* 상대방 메시지 */} -

+

{message.text}

@@ -91,7 +100,7 @@ const MessageList: React.FC = ({ messages, currentUserId, user {/* 현재 사용자 메시지 출력 */} {message.senderId === currentUserId && ( -

+

{message.text}

)} @@ -100,6 +109,8 @@ const MessageList: React.FC = ({ messages, currentUserId, user
); })} + {/* 스크롤 위치 유지 */} +
); }; From d86b6b5eefcdc30e78c394ae383625e468b4e813 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Thu, 26 Sep 2024 22:27:14 +0900 Subject: [PATCH 20/54] =?UTF-8?q?Fix:=20=EC=B1=84=ED=8C=85=EB=B0=94=20?= =?UTF-8?q?=EC=9D=B4=EB=AA=A8=ED=8B=B0=EC=BD=98=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/data/messages.json | 12 ++++++++++++ src/components/ChatRoomPage/ChatBar.tsx | 4 ++-- src/components/ChatRoomPage/MessageList.tsx | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 public/data/messages.json diff --git a/public/data/messages.json b/public/data/messages.json new file mode 100644 index 0000000..591c93a --- /dev/null +++ b/public/data/messages.json @@ -0,0 +1,12 @@ +[ + { + "senderId": 0, + "text": "안녕하세요!", + "timestamp": "2024-09-25T12:34:56Z" + }, + { + "senderId": 1, + "text": "네~안녕하세용", + "timestamp": "2024-09-25T12:35:00Z" + } +] \ No newline at end of file diff --git a/src/components/ChatRoomPage/ChatBar.tsx b/src/components/ChatRoomPage/ChatBar.tsx index 9165ada..c8605f9 100644 --- a/src/components/ChatRoomPage/ChatBar.tsx +++ b/src/components/ChatRoomPage/ChatBar.tsx @@ -41,12 +41,12 @@ const ChatBar = ({ onSendMessage }: { onSendMessage: (message: string) => void } }} placeholder="메시지 입력하기" className={`transition-all duration-300 w-inputWidth h-inputHeight rounded-full placeholder-Gray/4 font-['Pretendard'] pl-[12px] pr-[40px] bg-Gray/5 ${ - isInputFocused ? 'w-[calc(100%-20px)] mr-0' : 'w-inputWidth' + isInputFocused ? 'w-[277px]' : 'w-inputWidth' }`} /> {/* 이모티콘 버튼 */} -
+
emoticon = ({ messages, currentUserId, user
); })} - {/* 스크롤 위치 유지 */} + {/* 스크롤 위치 유지*/}
); From 225d003d963fe5b9aa69b03da7c06b614d651961 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Fri, 27 Sep 2024 18:34:02 +0900 Subject: [PATCH 21/54] =?UTF-8?q?Feat:=20initialMessageData=20=EB=B0=8F=20?= =?UTF-8?q?=EB=A1=9C=EC=BB=AC=EC=8A=A4=ED=86=A0=EB=A6=AC=EC=A7=80=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EB=B3=91?= =?UTF-8?q?=ED=95=A9=20=ED=99=9C=EC=9A=A9=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ChatRoomPage/MessageList.tsx | 43 +++++++++++++-------- src/lib/MessageData.tsx | 22 +++++++++++ src/pages/ChatRoomPage.tsx | 17 ++++---- src/utils/ClockUtils.tsx | 17 ++++---- 4 files changed, 65 insertions(+), 34 deletions(-) create mode 100644 src/lib/MessageData.tsx diff --git a/src/components/ChatRoomPage/MessageList.tsx b/src/components/ChatRoomPage/MessageList.tsx index 126284d..5a03937 100644 --- a/src/components/ChatRoomPage/MessageList.tsx +++ b/src/components/ChatRoomPage/MessageList.tsx @@ -1,6 +1,7 @@ -import React, { useRef, useEffect } from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import profileIcon from "../../assets/ChatRoom/profile.svg"; import { formatTime } from '../../utils/ClockUtils'; +import { MessageData } from '../../lib/MessageData'; interface User { userId: number; @@ -19,7 +20,6 @@ interface MessageListProps { users: User[]; } -// 사용자와 시간(분 단위)으로 메시지 그룹화 const groupMessages = (messages: Message[]) => { return messages.reduce((arr, message, index) => { const timeKey = formatTime(message.timestamp); @@ -37,8 +37,9 @@ const groupMessages = (messages: Message[]) => { }, [] as { timeKey: string; senderId: number; messages: Message[] }[]); }; -const MessageList: React.FC = ({ messages, currentUserId, users }) => { - const groupedMessages = groupMessages(messages); +const MessageList: React.FC = ({ currentUserId, users }) => { + const [messages, setMessages] = useState([]); + const scrollRef = useRef(null); // senderId로 사용자 이름 찾기 const getUserName = (senderId: number) => { @@ -46,18 +47,34 @@ const MessageList: React.FC = ({ messages, currentUserId, user return user ? user.userName : '(알 수 없음)'; }; - // 이전 타임스탬프 저장 - let lastTimeDisplayed: string | null = null; - - const scrollRef = useRef(null); + // MessageData와 로컬스토리지 메시지 병합 + useEffect(() => { + // MessageData 메시지 가져오기 + const initialMessages = MessageData.map(msg => ({ + ...msg, + timestamp: new Date(msg.timestamp) + })); + + // 로컬스토리지에서 메시지 가져오기 + const storedMessages = JSON.parse(localStorage.getItem('messages') || '[]').map((msg: any) => ({ + ...msg, + timestamp: new Date(msg.timestamp) + })); + + const combinedMessages = [...initialMessages, ...storedMessages]; + setMessages(combinedMessages); + }, []); - // 메시지가 전송될 때마다 하단으로 스크롤 useEffect(() => { if (scrollRef.current) { scrollRef.current.scrollIntoView({ behavior: 'smooth' }); } }, [messages]); + const groupedMessages = groupMessages(messages); + + let lastTimeDisplayed: string | null = null; + return (
{groupedMessages.map((group, groupIndex) => { @@ -66,23 +83,19 @@ const MessageList: React.FC = ({ messages, currentUserId, user return (
- {/* 타임스탬프 출력 */} {shouldDisplayTime && (
{group.timeKey}
)} - {/* 메시지 그룹 출력 */} {group.messages.map((message, idx) => (
- {/* 상대방 메시지 블록 */} {message.senderId !== currentUserId && (
- {/* 첫 번째 메시지일 경우에만 상대방 프로필 아이콘 및 이름 출력 */} {idx === 0 && (
Profile @@ -91,14 +104,11 @@ const MessageList: React.FC = ({ messages, currentUserId, user

)} - {/* 상대방 메시지 */}

{message.text}

)} - - {/* 현재 사용자 메시지 출력 */} {message.senderId === currentUserId && (

{message.text} @@ -109,7 +119,6 @@ const MessageList: React.FC = ({ messages, currentUserId, user

); })} - {/* 스크롤 위치 유지*/}
); diff --git a/src/lib/MessageData.tsx b/src/lib/MessageData.tsx new file mode 100644 index 0000000..bdebad1 --- /dev/null +++ b/src/lib/MessageData.tsx @@ -0,0 +1,22 @@ +export const MessageData = [ + { + senderId: 0, + text: "안녕하세요!", + timestamp: new Date('2024-09-27T10:30:00'), + }, + { + senderId: 0, + text: "1주차 세션 팀구성이 궁금합니다!", + timestamp: new Date('2024-09-27T10:30:00'), + }, + { + senderId: 1, + text: "안녕하세요!", + timestamp: new Date('2024-09-27T10:35:00'), + }, + { + senderId: 1, + text: "세오스 공개용 노션에 비상관제시어 관련하여 공지 업로드 했습니다. 참고해주세요!", + timestamp: new Date('2024-09-27T10:35:00'), + }, +]; diff --git a/src/pages/ChatRoomPage.tsx b/src/pages/ChatRoomPage.tsx index 961fb69..2e799e4 100644 --- a/src/pages/ChatRoomPage.tsx +++ b/src/pages/ChatRoomPage.tsx @@ -17,13 +17,14 @@ const ChatRoomPage = () => { useEffect(() => { const savedMessages = localStorage.getItem('messages'); if (savedMessages) { - const parsedMessages = JSON.parse(savedMessages).map((msg: any) => ({ - ...msg, - timestamp: new Date(msg.timestamp), - })); + const parsedMessages = JSON.parse(savedMessages).map((msg: any) => { + // timestamp 값을 Date 객체로 변환 + return { + ...msg, + timestamp: new Date(msg.timestamp), + }; + }); setMessages(parsedMessages); - //window.localStorage.clear(); - console.log(parsedMessages); } }, []); @@ -34,7 +35,7 @@ const ChatRoomPage = () => { ); }; - // 메시지 전송 핸들러 + // 메시지 전송 핸들러 const handleSendMessage = (message: string) => { const newMessage = { senderId: currentUser.userId, text: message, timestamp: new Date() }; @@ -59,4 +60,4 @@ const ChatRoomPage = () => { ); } -export default ChatRoomPage; \ No newline at end of file +export default ChatRoomPage; diff --git a/src/utils/ClockUtils.tsx b/src/utils/ClockUtils.tsx index d62f5a6..d107deb 100644 --- a/src/utils/ClockUtils.tsx +++ b/src/utils/ClockUtils.tsx @@ -8,10 +8,15 @@ export const currentTime = () => { }; // 타임스탬프 포맷 -export const formatTime = (date: Date): string => { +export const formatTime = (date: any): string => { + // Date 객체가 아닌 경우 + if (!(date instanceof Date) || isNaN(date.getTime())) { + return 'Invalid date'; + } + const now = new Date(); const diffInTime = now.getTime() - date.getTime(); - const diffInDays = Math.floor(diffInTime / (1000 * 60 * 60 * 24)); // 일 단위 차이 계산 + const diffInDays = Math.floor(diffInTime / (1000 * 60 * 60 * 24)); const hours = date.getHours(); const minutes = date.getMinutes(); @@ -19,23 +24,17 @@ export const formatTime = (date: Date): string => { const formattedHours = hours % 12 === 0 ? 12 : hours % 12; const timeString = `${ampm} ${formattedHours}:${minutes < 10 ? '0' : ''}${minutes}`; - // 날짜 포맷 if (diffInDays === 0) { - // 오늘일 경우 시간만 표시 return timeString; } else if (diffInDays === 1) { - // 어제일 경우 return `(어제) ${timeString}`; } else if (diffInDays === 2) { - // 그저께일 경우 return `(그저께) ${timeString}`; } else if (diffInDays <= 3) { - // 3일 전일 경우 return `(${diffInDays}일 전) ${timeString}`; } else { - // 3일을 넘는 경우 MM/DD 형식으로 const month = date.getMonth() + 1; const day = date.getDate(); return `(${month}/${day}) ${timeString}`; } -}; \ No newline at end of file +}; From 2c7bb6aa826e8bb3fbbb02cc4660cac70a315857 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Fri, 27 Sep 2024 18:35:09 +0900 Subject: [PATCH 22/54] =?UTF-8?q?Chore:=20=EB=A9=94=EC=8B=9C=EC=A7=80=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20=ED=83=80=EC=9E=84=EC=8A=A4?= =?UTF-8?q?=ED=83=AC=ED=94=84=20=EB=82=A0=EC=A7=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib/MessageData.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib/MessageData.tsx b/src/lib/MessageData.tsx index bdebad1..1cc074b 100644 --- a/src/lib/MessageData.tsx +++ b/src/lib/MessageData.tsx @@ -2,21 +2,21 @@ export const MessageData = [ { senderId: 0, text: "안녕하세요!", - timestamp: new Date('2024-09-27T10:30:00'), + timestamp: new Date('2024-09-25T10:30:00'), }, { senderId: 0, text: "1주차 세션 팀구성이 궁금합니다!", - timestamp: new Date('2024-09-27T10:30:00'), + timestamp: new Date('2024-09-25T10:30:00'), }, { senderId: 1, text: "안녕하세요!", - timestamp: new Date('2024-09-27T10:35:00'), + timestamp: new Date('2024-09-25T10:35:00'), }, { senderId: 1, text: "세오스 공개용 노션에 비상관제시어 관련하여 공지 업로드 했습니다. 참고해주세요!", - timestamp: new Date('2024-09-27T10:35:00'), + timestamp: new Date('2024-09-25T10:35:00'), }, ]; From 5e790c1bdeda95215c3a11035bed716dd492d015 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Sun, 29 Sep 2024 16:55:00 +0900 Subject: [PATCH 23/54] =?UTF-8?q?Fix:=20=EC=9E=85=EB=A0=A5=EC=B0=BD=20?= =?UTF-8?q?=ED=81=B4=EB=A6=AD=20=EC=8B=9C=20=EC=A0=84=EC=86=A1=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=EC=9D=B4=20=EB=82=98=ED=83=80=EB=82=98=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ChatRoomPage/ChatBar.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/components/ChatRoomPage/ChatBar.tsx b/src/components/ChatRoomPage/ChatBar.tsx index c8605f9..a125fef 100644 --- a/src/components/ChatRoomPage/ChatBar.tsx +++ b/src/components/ChatRoomPage/ChatBar.tsx @@ -41,7 +41,7 @@ const ChatBar = ({ onSendMessage }: { onSendMessage: (message: string) => void } }} placeholder="메시지 입력하기" className={`transition-all duration-300 w-inputWidth h-inputHeight rounded-full placeholder-Gray/4 font-['Pretendard'] pl-[12px] pr-[40px] bg-Gray/5 ${ - isInputFocused ? 'w-[277px]' : 'w-inputWidth' + isInputFocused ? 'w-[275px]' : 'w-inputWidth' }`} /> @@ -56,11 +56,13 @@ const ChatBar = ({ onSendMessage }: { onSendMessage: (message: string) => void }
{/* 전송 아이콘 */} - {isInputFocused && ( - - )} +
); } From ff42727075538acc2ab4e28efade30ebb9f03f0c Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Sun, 29 Sep 2024 17:06:57 +0900 Subject: [PATCH 24/54] =?UTF-8?q?Fix:=20=EC=A0=84=EC=86=A1=EB=90=9C=20?= =?UTF-8?q?=EC=83=88=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EB=A0=8C=EB=8D=94?= =?UTF-8?q?=EB=A7=81=20=EC=95=88=EB=90=98=EB=8A=94=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ChatRoomPage/MessageList.tsx | 22 +-------------- src/pages/ChatRoomPage.tsx | 30 +++++++++++++-------- 2 files changed, 20 insertions(+), 32 deletions(-) diff --git a/src/components/ChatRoomPage/MessageList.tsx b/src/components/ChatRoomPage/MessageList.tsx index 5a03937..dbc68d5 100644 --- a/src/components/ChatRoomPage/MessageList.tsx +++ b/src/components/ChatRoomPage/MessageList.tsx @@ -1,7 +1,6 @@ import React, { useState, useEffect, useRef } from 'react'; import profileIcon from "../../assets/ChatRoom/profile.svg"; import { formatTime } from '../../utils/ClockUtils'; -import { MessageData } from '../../lib/MessageData'; interface User { userId: number; @@ -37,8 +36,7 @@ const groupMessages = (messages: Message[]) => { }, [] as { timeKey: string; senderId: number; messages: Message[] }[]); }; -const MessageList: React.FC = ({ currentUserId, users }) => { - const [messages, setMessages] = useState([]); +const MessageList: React.FC = ({ currentUserId, messages, users }) => { const scrollRef = useRef(null); // senderId로 사용자 이름 찾기 @@ -47,24 +45,6 @@ const MessageList: React.FC = ({ currentUserId, users }) => { return user ? user.userName : '(알 수 없음)'; }; - // MessageData와 로컬스토리지 메시지 병합 - useEffect(() => { - // MessageData 메시지 가져오기 - const initialMessages = MessageData.map(msg => ({ - ...msg, - timestamp: new Date(msg.timestamp) - })); - - // 로컬스토리지에서 메시지 가져오기 - const storedMessages = JSON.parse(localStorage.getItem('messages') || '[]').map((msg: any) => ({ - ...msg, - timestamp: new Date(msg.timestamp) - })); - - const combinedMessages = [...initialMessages, ...storedMessages]; - setMessages(combinedMessages); - }, []); - useEffect(() => { if (scrollRef.current) { scrollRef.current.scrollIntoView({ behavior: 'smooth' }); diff --git a/src/pages/ChatRoomPage.tsx b/src/pages/ChatRoomPage.tsx index 2e799e4..6853743 100644 --- a/src/pages/ChatRoomPage.tsx +++ b/src/pages/ChatRoomPage.tsx @@ -5,6 +5,7 @@ import HomeIndicator from '../components/common/HomeIndicatior'; import TopBar from '../components/common/TopBar'; import MessageList from '../components/ChatRoomPage/MessageList'; import { UserData } from '../lib/UserData'; +import { MessageData } from '../lib/MessageData'; const ChatRoomPage = () => { const [currentUser, setCurrentUser] = useState(UserData[0]); @@ -13,21 +14,28 @@ const ChatRoomPage = () => { // 상대방 유저 설정 const opponentUser = currentUser.userId === 0 ? UserData[1] : UserData[0]; - // 로컬 스토리지에서 메시지 불러오기 + // 초기 메시지 및 로컬스토리지 메시지 불러오기 useEffect(() => { + // MessageData 초기 메시지 가져오기 + const initialMessages = MessageData.map(msg => ({ + ...msg, + timestamp: new Date(msg.timestamp), // Date 객체로 변환 + })); + + // 로컬스토리지 메시지 불러오기 const savedMessages = localStorage.getItem('messages'); - if (savedMessages) { - const parsedMessages = JSON.parse(savedMessages).map((msg: any) => { - // timestamp 값을 Date 객체로 변환 - return { - ...msg, - timestamp: new Date(msg.timestamp), - }; - }); - setMessages(parsedMessages); - } + const parsedMessages = savedMessages + ? JSON.parse(savedMessages).map((msg: any) => ({ + ...msg, + timestamp: new Date(msg.timestamp), // Date 객체로 변환 + })) + : []; + + // 초기 메시지 + 로컬스토리지 메시지 병합 + setMessages([...initialMessages, ...parsedMessages]); }, []); + // 유저 토글 전환 const toggleUser = () => { setCurrentUser(prevUser => From 91544c77beefd72234ca60aab0466ac12410223a Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Sun, 29 Sep 2024 17:10:39 +0900 Subject: [PATCH 25/54] =?UTF-8?q?Design:=20=EC=9D=B4=EB=AA=A8=ED=8B=B0?= =?UTF-8?q?=EC=BD=98=20=EB=B2=84=ED=8A=BC=20=EC=9C=84=EC=B9=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ChatRoomPage/ChatBar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ChatRoomPage/ChatBar.tsx b/src/components/ChatRoomPage/ChatBar.tsx index a125fef..6cba75c 100644 --- a/src/components/ChatRoomPage/ChatBar.tsx +++ b/src/components/ChatRoomPage/ChatBar.tsx @@ -46,7 +46,7 @@ const ChatBar = ({ onSendMessage }: { onSendMessage: (message: string) => void } /> {/* 이모티콘 버튼 */} -
+
emoticon Date: Sun, 29 Sep 2024 17:32:57 +0900 Subject: [PATCH 26/54] =?UTF-8?q?Fix:=20=EC=B1=84=ED=8C=85=EC=B0=BD=20?= =?UTF-8?q?=EC=A0=84=EC=86=A1=20=EB=B2=84=ED=8A=BC=20css=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ChatRoomPage/ChatBar.tsx | 15 +++++++++------ tailwind.config.js | 7 +++++-- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/components/ChatRoomPage/ChatBar.tsx b/src/components/ChatRoomPage/ChatBar.tsx index 6cba75c..5c5da20 100644 --- a/src/components/ChatRoomPage/ChatBar.tsx +++ b/src/components/ChatRoomPage/ChatBar.tsx @@ -40,13 +40,15 @@ const ChatBar = ({ onSendMessage }: { onSendMessage: (message: string) => void } if (!message.trim()) setIsInputFocused(false); }} placeholder="메시지 입력하기" - className={`transition-all duration-300 w-inputWidth h-inputHeight rounded-full placeholder-Gray/4 font-['Pretendard'] pl-[12px] pr-[40px] bg-Gray/5 ${ - isInputFocused ? 'w-[275px]' : 'w-inputWidth' - }`} + style={{ + transition: 'width 0.3s ease-in-out', + width: isInputFocused ? '284px' : '308px', + }} + className={`transition-all duration-300 w-inputWidth h-inputHeight rounded-full placeholder-Gray/4 font-['Pretendard'] pl-[12px] pr-[40px] bg-Gray/5`} /> {/* 이모티콘 버튼 */} -
+
emoticon void } {/* 전송 아이콘 */} diff --git a/tailwind.config.js b/tailwind.config.js index 8db2d38..7a57f9e 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,6 +1,7 @@ /** @type {import('tailwindcss').Config} */ + module.exports = { - content: [ "./src/**/*.{js,jsx,ts,tsx}", ], + content: [ "./src/**/*.{js,jsx,ts,tsx}", "./public/index.html"], theme: { colors: { 'Purple/1': '#AB78FF', @@ -27,7 +28,9 @@ module.exports = { }, } }, - plugins: [require("tailwind-scrollbar-hide")], + plugins: [ + require("tailwind-scrollbar-hide") + ], } From bec83a34a67a183944217ab8b1f10397ea48ab4f Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Sun, 29 Sep 2024 17:41:02 +0900 Subject: [PATCH 27/54] =?UTF-8?q?Fix:=20=EB=A1=9C=EC=BB=AC=EC=8A=A4?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=EC=A7=80=EC=97=90=20MessageData=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=20=EC=A0=80=EC=9E=A5=ED=95=98=EB=8A=94=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/ChatRoomPage.tsx | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/pages/ChatRoomPage.tsx b/src/pages/ChatRoomPage.tsx index 6853743..71ea3a5 100644 --- a/src/pages/ChatRoomPage.tsx +++ b/src/pages/ChatRoomPage.tsx @@ -16,23 +16,26 @@ const ChatRoomPage = () => { // 초기 메시지 및 로컬스토리지 메시지 불러오기 useEffect(() => { - // MessageData 초기 메시지 가져오기 - const initialMessages = MessageData.map(msg => ({ - ...msg, - timestamp: new Date(msg.timestamp), // Date 객체로 변환 - })); - // 로컬스토리지 메시지 불러오기 const savedMessages = localStorage.getItem('messages'); - const parsedMessages = savedMessages - ? JSON.parse(savedMessages).map((msg: any) => ({ + if (savedMessages) { + // 로컬스토리지에 저장된 메시지가 있으면 해당 데이터만 사용 + const parsedMessages = JSON.parse(savedMessages).map((msg: any) => ({ ...msg, - timestamp: new Date(msg.timestamp), // Date 객체로 변환 - })) - : []; - - // 초기 메시지 + 로컬스토리지 메시지 병합 - setMessages([...initialMessages, ...parsedMessages]); + timestamp: new Date(msg.timestamp), + })); + setMessages(parsedMessages); + } else { + // 로컬스토리지에 데이터가 없을 경우만 MessageData 사용 + const initialMessages = MessageData.map(msg => ({ + ...msg, + timestamp: new Date(msg.timestamp), + })); + setMessages(initialMessages); + + // 초기 메시지 로컬스토리지에 저장 + localStorage.setItem('messages', JSON.stringify(initialMessages)); + } }, []); From 47102a0e2917ebf7fce4e19f5143a7468a2b0abb Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Wed, 23 Oct 2024 15:39:03 +0900 Subject: [PATCH 28/54] =?UTF-8?q?Feat:=20=EC=B1=84=ED=8C=85=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 39 +++++++++++++++++++++ package.json | 1 + src/App.tsx | 7 +++- src/assets/ChatRoomList/chatting_icon.svg | 3 ++ src/assets/ChatRoomList/friend_icon.svg | 4 +++ src/assets/ChatRoomList/more_icon.svg | 5 +++ src/assets/ChatRoomList/newChat_icon.svg | 5 +++ src/assets/ChatRoomList/openedChat_icon.svg | 4 +++ src/assets/ChatRoomList/setting_icon.svg | 11 ++++++ src/assets/ChatRoomList/shopping_icon.svg | 7 ++++ src/components/ChatRoomListPage/Header.tsx | 25 +++++++++++++ src/components/ChatRoomListPage/NavBar.tsx | 16 +++++++++ src/components/common/Line.tsx | 8 +++++ src/index.tsx | 5 ++- src/pages/ChatRoomListPage.tsx | 22 ++++++++++++ tailwind.config.js | 1 + 16 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 src/assets/ChatRoomList/chatting_icon.svg create mode 100644 src/assets/ChatRoomList/friend_icon.svg create mode 100644 src/assets/ChatRoomList/more_icon.svg create mode 100644 src/assets/ChatRoomList/newChat_icon.svg create mode 100644 src/assets/ChatRoomList/openedChat_icon.svg create mode 100644 src/assets/ChatRoomList/setting_icon.svg create mode 100644 src/assets/ChatRoomList/shopping_icon.svg create mode 100644 src/components/ChatRoomListPage/Header.tsx create mode 100644 src/components/ChatRoomListPage/NavBar.tsx create mode 100644 src/components/common/Line.tsx create mode 100644 src/pages/ChatRoomListPage.tsx diff --git a/package-lock.json b/package-lock.json index e34dda1..69b8958 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "@types/react-dom": "^18.2.22", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-router-dom": "^6.27.0", "react-scripts": "5.0.1", "tailwind-scrollbar-hide": "^1.1.7", "typescript": "^4.9.5", @@ -3342,6 +3343,14 @@ } } }, + "node_modules/@remix-run/router": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.20.0.tgz", + "integrity": "sha512-mUnk8rPJBI9loFDZ+YzPGdeniYK+FTmRD1TMCz7ev2SNIozyKKpnGgsxO34u6Z4z/t0ITuu7voi/AshfsGsgFg==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -14868,6 +14877,36 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.27.0.tgz", + "integrity": "sha512-YA+HGZXz4jaAkVoYBE98VQl+nVzI+cVI2Oj/06F5ZM+0u3TgedN9Y9kmMRo2mnkSK2nCpNQn0DVob4HCsY/WLw==", + "dependencies": { + "@remix-run/router": "1.20.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.27.0.tgz", + "integrity": "sha512-+bvtFWMC0DgAFrfKXKG9Fc+BcXWRUO1aJIihbB79xaeq0v5UzfvnM5houGUm1Y461WVRcgAQ+Clh5rdb1eCx4g==", + "dependencies": { + "@remix-run/router": "1.20.0", + "react-router": "6.27.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/react-scripts": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.1.tgz", diff --git a/package.json b/package.json index 23dccdb..543a059 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@types/react-dom": "^18.2.22", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-router-dom": "^6.27.0", "react-scripts": "5.0.1", "tailwind-scrollbar-hide": "^1.1.7", "typescript": "^4.9.5", diff --git a/src/App.tsx b/src/App.tsx index 2cfd3c5..03b5fe5 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,10 +1,15 @@ import ChatRoomPage from './pages/ChatRoomPage'; +import ChatRoomListPage from './pages/ChatRoomListPage'; +import { Route, Routes } from 'react-router-dom'; function App() { return (
- + + }> + }> +
); diff --git a/src/assets/ChatRoomList/chatting_icon.svg b/src/assets/ChatRoomList/chatting_icon.svg new file mode 100644 index 0000000..c625fd0 --- /dev/null +++ b/src/assets/ChatRoomList/chatting_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/ChatRoomList/friend_icon.svg b/src/assets/ChatRoomList/friend_icon.svg new file mode 100644 index 0000000..2aa8f37 --- /dev/null +++ b/src/assets/ChatRoomList/friend_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/ChatRoomList/more_icon.svg b/src/assets/ChatRoomList/more_icon.svg new file mode 100644 index 0000000..85996da --- /dev/null +++ b/src/assets/ChatRoomList/more_icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/ChatRoomList/newChat_icon.svg b/src/assets/ChatRoomList/newChat_icon.svg new file mode 100644 index 0000000..59338f6 --- /dev/null +++ b/src/assets/ChatRoomList/newChat_icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/ChatRoomList/openedChat_icon.svg b/src/assets/ChatRoomList/openedChat_icon.svg new file mode 100644 index 0000000..a0c5a8c --- /dev/null +++ b/src/assets/ChatRoomList/openedChat_icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/ChatRoomList/setting_icon.svg b/src/assets/ChatRoomList/setting_icon.svg new file mode 100644 index 0000000..e0b5409 --- /dev/null +++ b/src/assets/ChatRoomList/setting_icon.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/assets/ChatRoomList/shopping_icon.svg b/src/assets/ChatRoomList/shopping_icon.svg new file mode 100644 index 0000000..0bbcecb --- /dev/null +++ b/src/assets/ChatRoomList/shopping_icon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/components/ChatRoomListPage/Header.tsx b/src/components/ChatRoomListPage/Header.tsx new file mode 100644 index 0000000..26f1ea8 --- /dev/null +++ b/src/components/ChatRoomListPage/Header.tsx @@ -0,0 +1,25 @@ +import searchIcon from "../../assets/ChatRoom/search.svg"; +import menuIcon from "../../assets/ChatRoom/menu.svg"; +import newChatIcon from "../../assets/ChatRoomList/newChat_icon.svg"; +import settingIcon from "../../assets/ChatRoomList/setting_icon.svg"; + +const Header = () => { + + return ( +
+
+

+ 채팅 +

+
+ +
+ Search + NewChat + Setting +
+
+ ); +} + +export default Header; \ No newline at end of file diff --git a/src/components/ChatRoomListPage/NavBar.tsx b/src/components/ChatRoomListPage/NavBar.tsx new file mode 100644 index 0000000..bf0e6c9 --- /dev/null +++ b/src/components/ChatRoomListPage/NavBar.tsx @@ -0,0 +1,16 @@ +import React, { useState } from 'react'; +import addIcon from "../../assets/ChatRoom/addMedia.svg"; +import emoticon from "../../assets/ChatRoom/emoticonbtn.svg"; + +const NavBar = () => { + return ( +
+ addMedia +
+ ); +} + +export default NavBar; diff --git a/src/components/common/Line.tsx b/src/components/common/Line.tsx new file mode 100644 index 0000000..8fdcaf7 --- /dev/null +++ b/src/components/common/Line.tsx @@ -0,0 +1,8 @@ +const Line = () => { + return ( +
+
+ ); +} + +export default Line; diff --git a/src/index.tsx b/src/index.tsx index d10be77..5e97bd5 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -2,12 +2,15 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; +import { BrowserRouter } from 'react-router-dom'; const root = ReactDOM.createRoot( document.getElementById('root') as HTMLElement ); root.render( - + + + ); diff --git a/src/pages/ChatRoomListPage.tsx b/src/pages/ChatRoomListPage.tsx new file mode 100644 index 0000000..5b8c5f6 --- /dev/null +++ b/src/pages/ChatRoomListPage.tsx @@ -0,0 +1,22 @@ +import React, { useState, useEffect } from 'react'; +import HomeIndicator from '../components/common/HomeIndicatior'; +import TopBar from '../components/common/TopBar'; +import NavBar from '../components/ChatRoomListPage/NavBar'; +import Header from '../components/ChatRoomListPage/Header'; +import Line from '../components/common/Line'; + +const ChatRoomListPage = () => { + return ( +
+ +
+ +
+ + +
+
+ ); +} + +export default ChatRoomListPage; diff --git a/tailwind.config.js b/tailwind.config.js index 7a57f9e..f144856 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -25,6 +25,7 @@ module.exports = { 'chatBarHeight': '68px', 'inputHeight': '40px', 'indicatorHeight': '13px', + 'navBarHeight': '54px', }, } }, From 1bf5c919a4411b38bb0048140596feab4e6cca4f Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Wed, 23 Oct 2024 15:59:37 +0900 Subject: [PATCH 29/54] =?UTF-8?q?Feat:=20=EB=84=A4=EB=B9=84=EA=B2=8C?= =?UTF-8?q?=EC=9D=B4=EC=85=98=EB=B0=94=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=ED=8D=BC=EB=B8=94=EB=A6=AC=EC=8B=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ChatRoomListPage/ChatRoomComponent.tsx | 7 ++++++ src/components/ChatRoomListPage/Header.tsx | 2 +- src/components/ChatRoomListPage/NavBar.tsx | 25 ++++++++++++++++--- 3 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 src/components/ChatRoomListPage/ChatRoomComponent.tsx diff --git a/src/components/ChatRoomListPage/ChatRoomComponent.tsx b/src/components/ChatRoomListPage/ChatRoomComponent.tsx new file mode 100644 index 0000000..f7ccdfe --- /dev/null +++ b/src/components/ChatRoomListPage/ChatRoomComponent.tsx @@ -0,0 +1,7 @@ +const ChatRoomComponent = () => { + return ( +
+ ); +} + +export default ChatRoomComponent; \ No newline at end of file diff --git a/src/components/ChatRoomListPage/Header.tsx b/src/components/ChatRoomListPage/Header.tsx index 26f1ea8..7edbc05 100644 --- a/src/components/ChatRoomListPage/Header.tsx +++ b/src/components/ChatRoomListPage/Header.tsx @@ -8,7 +8,7 @@ const Header = () => { return (
-

+

채팅

diff --git a/src/components/ChatRoomListPage/NavBar.tsx b/src/components/ChatRoomListPage/NavBar.tsx index bf0e6c9..9a6037c 100644 --- a/src/components/ChatRoomListPage/NavBar.tsx +++ b/src/components/ChatRoomListPage/NavBar.tsx @@ -1,14 +1,31 @@ import React, { useState } from 'react'; -import addIcon from "../../assets/ChatRoom/addMedia.svg"; -import emoticon from "../../assets/ChatRoom/emoticonbtn.svg"; +import friendIcon from "../../assets/ChatRoomList/friend_icon.svg"; +import chatIcon from "../../assets/ChatRoomList/chatting_icon.svg"; +import openedChatIcon from "../../assets/ChatRoomList/openedChat_icon.svg"; +import shoppingIcon from "../../assets/ChatRoomList/shopping_icon.svg"; +import moreIcon from "../../assets/ChatRoomList/more_icon.svg"; const NavBar = () => { return (
- addMedia +
+ friend 친구 +
+
+ chat 채팅 +
+
+ openedChat 오픈채팅 +
+
+ shopping 쇼핑 +
+
+ more 더보기 +
); } From b331194e2e17511311fb5f20d1efedc996bbac93 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Wed, 23 Oct 2024 17:25:50 +0900 Subject: [PATCH 30/54] =?UTF-8?q?Feat:=20=EB=84=A4=EB=B9=84=EA=B2=8C?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EB=B0=94=20=ED=81=B4=EB=A6=AD=20=EC=8B=9C?= =?UTF-8?q?=20=EC=83=89=EC=83=81=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20?= =?UTF-8?q?=EB=9D=BC=EC=9A=B0=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 3 ++ src/assets/ChatRoomList/chatting_icon.svg | 2 +- src/assets/ChatRoomList/friend_icon.svg | 4 +- src/assets/ChatRoomList/more_icon.svg | 6 +-- src/assets/ChatRoomList/openedChat_icon.svg | 4 +- src/assets/ChatRoomList/shopping_icon.svg | 10 ++-- src/components/ChatRoomListPage/NavBar.tsx | 33 ------------ src/components/common/NavBar.tsx | 58 +++++++++++++++++++++ src/declaration.d.ts | 6 +++ src/pages/ChatRoomListPage.tsx | 2 +- src/pages/FriendListPage.tsx | 21 ++++++++ 11 files changed, 102 insertions(+), 47 deletions(-) delete mode 100644 src/components/ChatRoomListPage/NavBar.tsx create mode 100644 src/components/common/NavBar.tsx create mode 100644 src/declaration.d.ts create mode 100644 src/pages/FriendListPage.tsx diff --git a/src/App.tsx b/src/App.tsx index 03b5fe5..0fabd86 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,6 @@ import ChatRoomPage from './pages/ChatRoomPage'; import ChatRoomListPage from './pages/ChatRoomListPage'; +import FriendListPage from './pages/FriendListPage'; import { Route, Routes } from 'react-router-dom'; function App() { @@ -9,6 +10,8 @@ function App() { }> }> + + }>
diff --git a/src/assets/ChatRoomList/chatting_icon.svg b/src/assets/ChatRoomList/chatting_icon.svg index c625fd0..4788288 100644 --- a/src/assets/ChatRoomList/chatting_icon.svg +++ b/src/assets/ChatRoomList/chatting_icon.svg @@ -1,3 +1,3 @@ - + diff --git a/src/assets/ChatRoomList/friend_icon.svg b/src/assets/ChatRoomList/friend_icon.svg index 2aa8f37..60f73b5 100644 --- a/src/assets/ChatRoomList/friend_icon.svg +++ b/src/assets/ChatRoomList/friend_icon.svg @@ -1,4 +1,4 @@ - - + + diff --git a/src/assets/ChatRoomList/more_icon.svg b/src/assets/ChatRoomList/more_icon.svg index 85996da..e97e941 100644 --- a/src/assets/ChatRoomList/more_icon.svg +++ b/src/assets/ChatRoomList/more_icon.svg @@ -1,5 +1,5 @@ - - - + + + diff --git a/src/assets/ChatRoomList/openedChat_icon.svg b/src/assets/ChatRoomList/openedChat_icon.svg index a0c5a8c..a43f2f6 100644 --- a/src/assets/ChatRoomList/openedChat_icon.svg +++ b/src/assets/ChatRoomList/openedChat_icon.svg @@ -1,4 +1,4 @@ - - + + diff --git a/src/assets/ChatRoomList/shopping_icon.svg b/src/assets/ChatRoomList/shopping_icon.svg index 0bbcecb..f79754c 100644 --- a/src/assets/ChatRoomList/shopping_icon.svg +++ b/src/assets/ChatRoomList/shopping_icon.svg @@ -1,7 +1,7 @@ - - - - - + + + + + diff --git a/src/components/ChatRoomListPage/NavBar.tsx b/src/components/ChatRoomListPage/NavBar.tsx deleted file mode 100644 index 9a6037c..0000000 --- a/src/components/ChatRoomListPage/NavBar.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import React, { useState } from 'react'; -import friendIcon from "../../assets/ChatRoomList/friend_icon.svg"; -import chatIcon from "../../assets/ChatRoomList/chatting_icon.svg"; -import openedChatIcon from "../../assets/ChatRoomList/openedChat_icon.svg"; -import shoppingIcon from "../../assets/ChatRoomList/shopping_icon.svg"; -import moreIcon from "../../assets/ChatRoomList/more_icon.svg"; - -const NavBar = () => { - return ( -
-
- friend 친구 -
-
- chat 채팅 -
-
- openedChat 오픈채팅 -
-
- shopping 쇼핑 -
-
- more 더보기 -
-
- ); -} - -export default NavBar; diff --git a/src/components/common/NavBar.tsx b/src/components/common/NavBar.tsx new file mode 100644 index 0000000..2e5f60b --- /dev/null +++ b/src/components/common/NavBar.tsx @@ -0,0 +1,58 @@ +import React, { useState, useEffect } from 'react'; +import { useNavigate, useLocation } from 'react-router-dom'; +import { ReactComponent as FriendIcon } from "../../assets/ChatRoomList/friend_icon.svg"; +import { ReactComponent as ChatIcon } from "../../assets/ChatRoomList/chatting_icon.svg"; +import { ReactComponent as OpenedChatIcon } from "../../assets/ChatRoomList/openedChat_icon.svg"; +import { ReactComponent as ShoppingIcon } from "../../assets/ChatRoomList/shopping_icon.svg"; +import { ReactComponent as MoreIcon } from "../../assets/ChatRoomList/more_icon.svg"; + +const NavBar: React.FC = () => { + const basicBtnStyle = "text-Gray/2 text-[9px] font-['Pretendard'] flex flex-col items-center cursor-pointer"; + const navigate = useNavigate(); + const location = useLocation(); + const [activePath, setActivePath] = useState(location.pathname); + + useEffect(() => { + setActivePath(location.pathname); + }, [location]); + + const onBtnClick = (path: string) => { + setActivePath(path); + navigate(path); + } + + const getBtnStyle = (path: string) => { + return activePath === path + ? `text-Purple/1 ${basicBtnStyle}` + : `text-Gray/2 ${basicBtnStyle}`; + } + + const getIconStyle = (path: string) => { + return activePath === path ? "#AB78FF" : "#A3A3A3"; + } + + return ( +
+
onBtnClick("/friends")} className={getBtnStyle("/friends")} style={{color: getIconStyle("/friends")}}> + 친구 +
+
onBtnClick("/chatlist")} className={getBtnStyle("/chatlist")} style={{color: getIconStyle("/chatlist")}}> + 채팅 +
+
onBtnClick("/openedChat")} className={getBtnStyle("/openedChat")} style={{color: getIconStyle("/openedChat")}}> + 오픈채팅 +
+
onBtnClick("/shopping")} className={getBtnStyle("/shopping")} style={{color: getIconStyle("/shopping")}}> + 쇼핑 +
+
onBtnClick("/more")} className={getBtnStyle("/more")} style={{color: getIconStyle("/more")}}> + 더보기 +
+
+ ); +} + +export default NavBar; diff --git a/src/declaration.d.ts b/src/declaration.d.ts new file mode 100644 index 0000000..d7d1bdc --- /dev/null +++ b/src/declaration.d.ts @@ -0,0 +1,6 @@ +declare module "*.svg" { + import * as React from 'react'; + export const ReactComponent: React.FunctionComponent>; + const src: string; + export default src; +} \ No newline at end of file diff --git a/src/pages/ChatRoomListPage.tsx b/src/pages/ChatRoomListPage.tsx index 5b8c5f6..e2f82a5 100644 --- a/src/pages/ChatRoomListPage.tsx +++ b/src/pages/ChatRoomListPage.tsx @@ -1,7 +1,7 @@ import React, { useState, useEffect } from 'react'; import HomeIndicator from '../components/common/HomeIndicatior'; import TopBar from '../components/common/TopBar'; -import NavBar from '../components/ChatRoomListPage/NavBar'; +import NavBar from '../components/common/NavBar'; import Header from '../components/ChatRoomListPage/Header'; import Line from '../components/common/Line'; diff --git a/src/pages/FriendListPage.tsx b/src/pages/FriendListPage.tsx new file mode 100644 index 0000000..41db2ea --- /dev/null +++ b/src/pages/FriendListPage.tsx @@ -0,0 +1,21 @@ +import React, { useState, useEffect } from 'react'; +import HomeIndicator from '../components/common/HomeIndicatior'; +import TopBar from '../components/common/TopBar'; +import NavBar from '../components/common/NavBar'; +import Header from '../components/ChatRoomListPage/Header'; +import Line from '../components/common/Line'; + +const FriendListPage = () => { + return ( +
+ + +
+ + +
+
+ ); +} + +export default FriendListPage; From eca3c887cf817345c8537a04b89098bdcdbdf331 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Wed, 23 Oct 2024 17:30:02 +0900 Subject: [PATCH 31/54] =?UTF-8?q?Design:=20=EB=B2=84=ED=8A=BC=20=EC=83=89?= =?UTF-8?q?=EC=83=81=20=EC=BD=94=EB=93=9C=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/NavBar.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/common/NavBar.tsx b/src/components/common/NavBar.tsx index 2e5f60b..67d1da3 100644 --- a/src/components/common/NavBar.tsx +++ b/src/components/common/NavBar.tsx @@ -7,7 +7,7 @@ import { ReactComponent as ShoppingIcon } from "../../assets/ChatRoomList/shoppi import { ReactComponent as MoreIcon } from "../../assets/ChatRoomList/more_icon.svg"; const NavBar: React.FC = () => { - const basicBtnStyle = "text-Gray/2 text-[9px] font-['Pretendard'] flex flex-col items-center cursor-pointer"; + const basicBtnStyle = "text-[9px] font-['Pretendard'] flex flex-col items-center cursor-pointer"; const navigate = useNavigate(); const location = useLocation(); const [activePath, setActivePath] = useState(location.pathname); @@ -28,7 +28,7 @@ const NavBar: React.FC = () => { } const getIconStyle = (path: string) => { - return activePath === path ? "#AB78FF" : "#A3A3A3"; + return activePath === path ? "#AB78FF" : "#666666"; } return ( From 4245a07c85538eb672c1b0f2c2d5f6eaf84a2d2a Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Wed, 23 Oct 2024 23:41:54 +0900 Subject: [PATCH 32/54] =?UTF-8?q?Feat:=20=EC=B1=84=ED=8C=85=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=B5=9C?= =?UTF-8?q?=EA=B7=BC=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EB=B6=88=EB=9F=AC?= =?UTF-8?q?=EC=98=A4=EA=B8=B0=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 2 +- .../ChatRoomListPage/ChatRoomComponent.tsx | 32 ++++++++++++- src/lib/UserData.tsx | 12 +++++ src/pages/ChatRoomListPage.tsx | 48 ++++++++++++++++++- src/utils/ClockUtils.tsx | 32 +++++++++++++ tailwind.config.js | 3 ++ 6 files changed, 125 insertions(+), 4 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 0fabd86..3b7e8d9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -8,7 +8,7 @@ function App() {
- }> + }> }> }> diff --git a/src/components/ChatRoomListPage/ChatRoomComponent.tsx b/src/components/ChatRoomListPage/ChatRoomComponent.tsx index f7ccdfe..d19779a 100644 --- a/src/components/ChatRoomListPage/ChatRoomComponent.tsx +++ b/src/components/ChatRoomListPage/ChatRoomComponent.tsx @@ -1,6 +1,34 @@ -const ChatRoomComponent = () => { +import React, { useState, useEffect } from 'react'; +import profileIcon from "../../assets/ChatRoom/profile.svg"; +import { UserData } from '../../lib/UserData'; +import { formatTimeForChatList } from '../../utils/ClockUtils'; + +interface LastMessage { + text: string; + timestamp: Date; +} + +interface ComponentProps { + userId: number; + lastMessage?: LastMessage; + onClick: () => void; +} + +const ChatRoomComponent: React.FC = ({ userId, lastMessage, onClick }) => { + const user = UserData.find(user => user.userId === userId); + return ( -
+
+ +
+ {user?.userName || '(알 수 없음)'} + {lastMessage?.text} +
+
+ {lastMessage ? formatTimeForChatList(lastMessage.timestamp) : ''} + 1 +
+
); } diff --git a/src/lib/UserData.tsx b/src/lib/UserData.tsx index 228f5a7..a7bdf1d 100644 --- a/src/lib/UserData.tsx +++ b/src/lib/UserData.tsx @@ -7,4 +7,16 @@ export const UserData = [ userId: 1, userName: '김태양', }, + { + userId: 2, + userName: 'CEOS', + }, + { + userId: 3, + userName: '박연진', + }, + { + userId: 4, + userName: '전재준', + }, ]; \ No newline at end of file diff --git a/src/pages/ChatRoomListPage.tsx b/src/pages/ChatRoomListPage.tsx index e2f82a5..cfdaffe 100644 --- a/src/pages/ChatRoomListPage.tsx +++ b/src/pages/ChatRoomListPage.tsx @@ -1,16 +1,62 @@ import React, { useState, useEffect } from 'react'; +import { useNavigate } from 'react-router-dom'; import HomeIndicator from '../components/common/HomeIndicatior'; import TopBar from '../components/common/TopBar'; import NavBar from '../components/common/NavBar'; import Header from '../components/ChatRoomListPage/Header'; import Line from '../components/common/Line'; +import ChatRoomComponent from '../components/ChatRoomListPage/ChatRoomComponent'; +import { UserData } from '../lib/UserData'; + +interface Message { + senderId: number; + text: string; + timestamp: Date; +} + +const ChatRoomListPage: React.FC = () => { + const navigate = useNavigate(); + const [lastMessages, setLastMessages] = useState<{ [userId: number]: Message | null }>({}); + + useEffect(() => { + const savedMessages = localStorage.getItem('messages'); + if (savedMessages) { + const parsedMessages: Message[] = JSON.parse(savedMessages).map((msg: any) => ({ + ...msg, + timestamp: new Date(msg.timestamp), + })); + + const lastMessagesByUser: { [userId: number]: Message | null } = {}; + UserData.forEach(user => { + // 각 유저의 마지막 메시지 찾기 + const userMessages = parsedMessages.filter(msg => msg.senderId === user.userId); + lastMessagesByUser[user.userId] = userMessages.length > 0 ? userMessages[userMessages.length - 1] : null; + }); + + setLastMessages(lastMessagesByUser); + } + }, []); + + const handleChatRoomClick = (userId: number) => { + // 클릭한 채팅방으로 이동 + navigate(`/chat/${userId}`); + }; -const ChatRoomListPage = () => { return (
+ {UserData.map(user => ( + lastMessages[user.userId] && ( + handleChatRoomClick(user.userId)} + /> + ) + ))}
diff --git a/src/utils/ClockUtils.tsx b/src/utils/ClockUtils.tsx index d107deb..667a939 100644 --- a/src/utils/ClockUtils.tsx +++ b/src/utils/ClockUtils.tsx @@ -38,3 +38,35 @@ export const formatTime = (date: any): string => { return `(${month}/${day}) ${timeString}`; } }; + +// 채팅 리스트용 타임스탬프 +export const formatTimeForChatList = (date: any): string => { + // Date 객체가 아닌 경우 + if (!(date instanceof Date) || isNaN(date.getTime())) { + return 'Invalid date'; + } + + const now = new Date(); + const diffInTime = now.getTime() - date.getTime(); + const diffInDays = Math.floor(diffInTime / (1000 * 60 * 60 * 24)); + + const hours = date.getHours(); + const minutes = date.getMinutes(); + const ampm = hours >= 12 ? '오후' : '오전'; + const formattedHours = hours % 12 === 0 ? 12 : hours % 12; + const timeString = `${ampm} ${formattedHours}:${minutes < 10 ? '0' : ''}${minutes}`; + + if (diffInDays === 0) { + return timeString; + } else if (diffInDays === 1) { + return `어제`; + } else if (diffInDays === 2) { + return `그저께`; + } else if (diffInDays <= 3) { + return `${diffInDays}일 전)`; + } else { + const month = date.getMonth() + 1; + const day = date.getDate(); + return `${month}/${day}`; + } +}; diff --git a/tailwind.config.js b/tailwind.config.js index f144856..69a8130 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -5,9 +5,11 @@ module.exports = { theme: { colors: { 'Purple/1': '#AB78FF', + 'Purple/2': '#B98FFF', 'Purple/3': '#D3B8FF', 'White': '#FFFFFF', 'Gray/2': '#666666', + 'Gray/3': '#999999', 'Gray/4' : "#CCCCCC", 'Gray/5': '#EDEDED', 'Black': '#000000', @@ -26,6 +28,7 @@ module.exports = { 'inputHeight': '40px', 'indicatorHeight': '13px', 'navBarHeight': '54px', + 'ChatRoomComponentHeight': '60px', }, } }, From be81dfcd93682ac0bbf2481e2e667cb750a4eee0 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Wed, 23 Oct 2024 23:44:25 +0900 Subject: [PATCH 33/54] =?UTF-8?q?Fix:=20NavBar=20=EB=B0=8F=20=EC=B1=84?= =?UTF-8?q?=ED=8C=85=EB=B0=A9=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20hei?= =?UTF-8?q?ght=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tailwind.config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tailwind.config.js b/tailwind.config.js index 69a8130..047be21 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -27,8 +27,8 @@ module.exports = { 'chatBarHeight': '68px', 'inputHeight': '40px', 'indicatorHeight': '13px', - 'navBarHeight': '54px', - 'ChatRoomComponentHeight': '60px', + 'navBarHeight': '70px', + 'ChatRoomComponentHeight': '76px', }, } }, From 89335e51f402cbdd30c16fd84b0affe5aeada83c Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Sun, 27 Oct 2024 21:11:55 +0900 Subject: [PATCH 34/54] =?UTF-8?q?Fix:=20=EC=B1=84=ED=8C=85=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=ED=85=8D?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=98=A4=EB=B2=84=ED=94=8C=EB=A1=9C?= =?UTF-8?q?=EC=9A=B0=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 9 +++++++++ package.json | 1 + src/components/ChatRoomListPage/ChatRoomComponent.tsx | 6 +++--- tailwind.config.js | 3 ++- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 69b8958..2f683f5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "react-messenger-19th", "version": "0.1.0", "dependencies": { + "@tailwindcss/line-clamp": "^0.4.4", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", @@ -3669,6 +3670,14 @@ "url": "https://github.com/sponsors/gregberge" } }, + "node_modules/@tailwindcss/line-clamp": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@tailwindcss/line-clamp/-/line-clamp-0.4.4.tgz", + "integrity": "sha512-5U6SY5z8N42VtrCrKlsTAA35gy2VSyYtHWCsg1H87NU1SXnEfekTVlrga9fzUDrrHcGi2Lb5KenUWb4lRQT5/g==", + "peerDependencies": { + "tailwindcss": ">=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1" + } + }, "node_modules/@testing-library/dom": { "version": "9.3.4", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz", diff --git a/package.json b/package.json index 543a059..3776c08 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "0.1.0", "private": true, "dependencies": { + "@tailwindcss/line-clamp": "^0.4.4", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", diff --git a/src/components/ChatRoomListPage/ChatRoomComponent.tsx b/src/components/ChatRoomListPage/ChatRoomComponent.tsx index d19779a..ac80a83 100644 --- a/src/components/ChatRoomListPage/ChatRoomComponent.tsx +++ b/src/components/ChatRoomListPage/ChatRoomComponent.tsx @@ -20,9 +20,9 @@ const ChatRoomComponent: React.FC = ({ userId, lastMessage, onCl return (
-
- {user?.userName || '(알 수 없음)'} - {lastMessage?.text} +
+ {user?.userName || '(알 수 없음)'} + {lastMessage?.text}
{lastMessage ? formatTimeForChatList(lastMessage.timestamp) : ''} diff --git a/tailwind.config.js b/tailwind.config.js index 047be21..b4e62fb 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -33,7 +33,8 @@ module.exports = { } }, plugins: [ - require("tailwind-scrollbar-hide") + require("tailwind-scrollbar-hide"), + require('@tailwindcss/line-clamp'), ], } From 1fff126222b6a580c7d2901dd34277fc0abe3d65 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Sun, 27 Oct 2024 21:18:00 +0900 Subject: [PATCH 35/54] =?UTF-8?q?Feat:=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=ED=97=A4=EB=8D=94=20=EB=92=A4=EB=A1=9C=EA=B0=80=EA=B8=B0=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ChatRoomPage/Header.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/components/ChatRoomPage/Header.tsx b/src/components/ChatRoomPage/Header.tsx index 40cc64b..5baa610 100644 --- a/src/components/ChatRoomPage/Header.tsx +++ b/src/components/ChatRoomPage/Header.tsx @@ -1,3 +1,5 @@ +import React from 'react'; +import { useNavigate } from 'react-router-dom'; import backIcon from "../../assets/ChatRoom/back.svg"; import searchIcon from "../../assets/ChatRoom/search.svg"; import menuIcon from "../../assets/ChatRoom/menu.svg"; @@ -10,10 +12,15 @@ interface HeaderProps { const Header: React.FC = ({ currentUser, opponentUser, toggleUser }) => { + const navigate = useNavigate(); + + const handleBackClick = () => { + navigate(-1); + } return (
- GoBack + GoBack

{opponentUser.userName}

From cc24d2574bddd9be3c07c9a5a01b55a3404cf8b6 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Sun, 27 Oct 2024 21:31:23 +0900 Subject: [PATCH 36/54] =?UTF-8?q?Feat:=20=EB=82=B4=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=ED=97=A4=EB=8D=94=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 2 ++ src/assets/MyProfile/add_friend.svg | 6 +++++ src/assets/MyProfile/music.svg | 5 ++++ src/components/MyProfilePage/Header.tsx | 36 +++++++++++++++++++++++++ src/pages/MyProfilePage.tsx | 22 +++++++++++++++ 5 files changed, 71 insertions(+) create mode 100644 src/assets/MyProfile/add_friend.svg create mode 100644 src/assets/MyProfile/music.svg create mode 100644 src/components/MyProfilePage/Header.tsx create mode 100644 src/pages/MyProfilePage.tsx diff --git a/src/App.tsx b/src/App.tsx index 3b7e8d9..e2c8c5d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,6 +2,7 @@ import ChatRoomPage from './pages/ChatRoomPage'; import ChatRoomListPage from './pages/ChatRoomListPage'; import FriendListPage from './pages/FriendListPage'; import { Route, Routes } from 'react-router-dom'; +import MyProfilePage from './pages/MyProfilePage'; function App() { return ( @@ -12,6 +13,7 @@ function App() { }> }> + }>
diff --git a/src/assets/MyProfile/add_friend.svg b/src/assets/MyProfile/add_friend.svg new file mode 100644 index 0000000..c081114 --- /dev/null +++ b/src/assets/MyProfile/add_friend.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/assets/MyProfile/music.svg b/src/assets/MyProfile/music.svg new file mode 100644 index 0000000..8d0fb6c --- /dev/null +++ b/src/assets/MyProfile/music.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/components/MyProfilePage/Header.tsx b/src/components/MyProfilePage/Header.tsx new file mode 100644 index 0000000..c8b716a --- /dev/null +++ b/src/components/MyProfilePage/Header.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { useNavigate } from 'react-router-dom'; +import backIcon from "../../assets/ChatRoom/back.svg"; +import searchIcon from "../../assets/ChatRoom/search.svg"; +import addIcon from "../../assets/MyProfile/add_friend.svg"; +import musicIcon from "../../assets/MyProfile/music.svg"; +import settingIcon from "../../assets/ChatRoomList/setting_icon.svg"; + +const Header = () => { + + const navigate = useNavigate(); + + const handleBackClick = () => { + navigate(-1); + } + return ( +
+
+ GoBack +

+ 프로필 +

+
+ +
+ Search + AddFriend + Music + Setting + +
+
+ ); +} + +export default Header; \ No newline at end of file diff --git a/src/pages/MyProfilePage.tsx b/src/pages/MyProfilePage.tsx new file mode 100644 index 0000000..48c87d4 --- /dev/null +++ b/src/pages/MyProfilePage.tsx @@ -0,0 +1,22 @@ +import React, { useState, useEffect } from 'react'; +import HomeIndicator from '../components/common/HomeIndicatior'; +import TopBar from '../components/common/TopBar'; +import NavBar from '../components/common/NavBar'; +import Header from '../components/MyProfilePage/Header'; +import Line from '../components/common/Line'; + +const MyProfilePage = () => { + return ( +
+ +
+ +
+ + +
+
+ ); +} + +export default MyProfilePage; From b4dbf8241a0325871b3ad4e7be0737fba8458da3 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Sun, 27 Oct 2024 22:05:56 +0900 Subject: [PATCH 37/54] =?UTF-8?q?Feat:=20=EB=82=B4=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/MyProfile/multiProfile.svg | 6 +++++ src/assets/MyProfile/my_profile.svg | 19 +++++++++++++++ src/assets/MyProfile/right_arrow.svg | 3 +++ src/components/MyProfilePage/ProfileInfo.tsx | 25 ++++++++++++++++++++ src/components/MyProfilePage/UserProfile.tsx | 19 +++++++++++++++ src/pages/MyProfilePage.tsx | 8 ++++++- tailwind.config.js | 1 + 7 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 src/assets/MyProfile/multiProfile.svg create mode 100644 src/assets/MyProfile/my_profile.svg create mode 100644 src/assets/MyProfile/right_arrow.svg create mode 100644 src/components/MyProfilePage/ProfileInfo.tsx create mode 100644 src/components/MyProfilePage/UserProfile.tsx diff --git a/src/assets/MyProfile/multiProfile.svg b/src/assets/MyProfile/multiProfile.svg new file mode 100644 index 0000000..83635ac --- /dev/null +++ b/src/assets/MyProfile/multiProfile.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/assets/MyProfile/my_profile.svg b/src/assets/MyProfile/my_profile.svg new file mode 100644 index 0000000..b8403fe --- /dev/null +++ b/src/assets/MyProfile/my_profile.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/MyProfile/right_arrow.svg b/src/assets/MyProfile/right_arrow.svg new file mode 100644 index 0000000..d84c817 --- /dev/null +++ b/src/assets/MyProfile/right_arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/MyProfilePage/ProfileInfo.tsx b/src/components/MyProfilePage/ProfileInfo.tsx new file mode 100644 index 0000000..d5173ff --- /dev/null +++ b/src/components/MyProfilePage/ProfileInfo.tsx @@ -0,0 +1,25 @@ +import arrowIcon from "../../assets/MyProfile/right_arrow.svg"; + +interface ProfileInfoProps { + title: string; + content: string; +} + +const ProfileInfo: React.FC = ({ title, content }) => { + + return ( +
+
+

+ {title} +

+

+ {content} +

+
+ edit +
+ ); +} + +export default ProfileInfo; \ No newline at end of file diff --git a/src/components/MyProfilePage/UserProfile.tsx b/src/components/MyProfilePage/UserProfile.tsx new file mode 100644 index 0000000..e75a1e1 --- /dev/null +++ b/src/components/MyProfilePage/UserProfile.tsx @@ -0,0 +1,19 @@ +import profileIcon from "../../assets/MyProfile/my_profile.svg"; +import multiProfileIcon from "../../assets/MyProfile/multiProfile.svg"; + +const UserProfile = () => { + + return ( +
+
+ profileImg +

+ 김태양 +

+
+ setMultiProfile +
+ ); +} + +export default UserProfile; \ No newline at end of file diff --git a/src/pages/MyProfilePage.tsx b/src/pages/MyProfilePage.tsx index 48c87d4..685e618 100644 --- a/src/pages/MyProfilePage.tsx +++ b/src/pages/MyProfilePage.tsx @@ -3,14 +3,20 @@ import HomeIndicator from '../components/common/HomeIndicatior'; import TopBar from '../components/common/TopBar'; import NavBar from '../components/common/NavBar'; import Header from '../components/MyProfilePage/Header'; +import UserProfile from '../components/MyProfilePage/UserProfile'; import Line from '../components/common/Line'; +import ProfileInfo from '../components/MyProfilePage/ProfileInfo'; const MyProfilePage = () => { return ( -
+
+ + + +
diff --git a/tailwind.config.js b/tailwind.config.js index b4e62fb..f3a28fe 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -29,6 +29,7 @@ module.exports = { 'indicatorHeight': '13px', 'navBarHeight': '70px', 'ChatRoomComponentHeight': '76px', + 'profileTitleHeight': '86px', }, } }, From 90e11297ffec214d7fde9882313ed349444809af Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Mon, 28 Oct 2024 00:36:55 +0900 Subject: [PATCH 38/54] =?UTF-8?q?Feat:=20=EC=B9=9C=EA=B5=AC=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/FriendList/down_arrow.svg | 3 ++ src/assets/FriendList/make_peong.svg | 5 ++ src/assets/FriendList/peong_bg.svg | 3 ++ src/assets/FriendList/redDot.svg | 3 ++ src/assets/FriendList/up_arrow.svg | 3 ++ src/components/FriendListPage/Birthday.tsx | 17 ++++++ src/components/FriendListPage/FriendList.tsx | 31 +++++++++++ src/components/FriendListPage/Header.tsx | 27 ++++++++++ src/components/FriendListPage/Peong.tsx | 29 +++++++++++ .../FriendListPage/UpdatedProfile.tsx | 52 +++++++++++++++++++ src/pages/FriendListPage.tsx | 18 ++++++- 11 files changed, 189 insertions(+), 2 deletions(-) create mode 100644 src/assets/FriendList/down_arrow.svg create mode 100644 src/assets/FriendList/make_peong.svg create mode 100644 src/assets/FriendList/peong_bg.svg create mode 100644 src/assets/FriendList/redDot.svg create mode 100644 src/assets/FriendList/up_arrow.svg create mode 100644 src/components/FriendListPage/Birthday.tsx create mode 100644 src/components/FriendListPage/FriendList.tsx create mode 100644 src/components/FriendListPage/Header.tsx create mode 100644 src/components/FriendListPage/Peong.tsx create mode 100644 src/components/FriendListPage/UpdatedProfile.tsx diff --git a/src/assets/FriendList/down_arrow.svg b/src/assets/FriendList/down_arrow.svg new file mode 100644 index 0000000..e85132c --- /dev/null +++ b/src/assets/FriendList/down_arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/FriendList/make_peong.svg b/src/assets/FriendList/make_peong.svg new file mode 100644 index 0000000..d19d2f5 --- /dev/null +++ b/src/assets/FriendList/make_peong.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/FriendList/peong_bg.svg b/src/assets/FriendList/peong_bg.svg new file mode 100644 index 0000000..019a36a --- /dev/null +++ b/src/assets/FriendList/peong_bg.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/FriendList/redDot.svg b/src/assets/FriendList/redDot.svg new file mode 100644 index 0000000..f691dab --- /dev/null +++ b/src/assets/FriendList/redDot.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/FriendList/up_arrow.svg b/src/assets/FriendList/up_arrow.svg new file mode 100644 index 0000000..f3d9906 --- /dev/null +++ b/src/assets/FriendList/up_arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/FriendListPage/Birthday.tsx b/src/components/FriendListPage/Birthday.tsx new file mode 100644 index 0000000..f51cde0 --- /dev/null +++ b/src/components/FriendListPage/Birthday.tsx @@ -0,0 +1,17 @@ +import profileIcon from "../../assets/ChatRoom/profile.svg"; +import foldIcon from "../../assets/FriendList/up_arrow.svg"; +import unfoldIcon from "../../assets/FriendList/down_arrow.svg"; + +const Birthday = () => { + + return ( +
+
+

생일인 친구

+ fold +
+
+ ); +} + +export default Birthday; \ No newline at end of file diff --git a/src/components/FriendListPage/FriendList.tsx b/src/components/FriendListPage/FriendList.tsx new file mode 100644 index 0000000..77d016e --- /dev/null +++ b/src/components/FriendListPage/FriendList.tsx @@ -0,0 +1,31 @@ +import profileIcon from "../../assets/ChatRoom/profile.svg"; +import foldIcon from "../../assets/FriendList/up_arrow.svg"; +import unfoldIcon from "../../assets/FriendList/down_arrow.svg"; + +const FriendList = () => { + + return ( +
+
+

친구

+ fold +
+
+
+ profile +

CEOS

+
+
+ profile +

CEOS

+
+
+ profile +

CEOS

+
+
+
+ ); +} + +export default FriendList; \ No newline at end of file diff --git a/src/components/FriendListPage/Header.tsx b/src/components/FriendListPage/Header.tsx new file mode 100644 index 0000000..868d5cd --- /dev/null +++ b/src/components/FriendListPage/Header.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import searchIcon from "../../assets/ChatRoom/search.svg"; +import addIcon from "../../assets/MyProfile/add_friend.svg"; +import musicIcon from "../../assets/MyProfile/music.svg"; +import settingIcon from "../../assets/ChatRoomList/setting_icon.svg"; + +const Header = () => { + return ( +
+
+

+ 친구 +

+
+ +
+ Search + AddFriend + Music + Setting + +
+
+ ); +} + +export default Header; \ No newline at end of file diff --git a/src/components/FriendListPage/Peong.tsx b/src/components/FriendListPage/Peong.tsx new file mode 100644 index 0000000..6866fd5 --- /dev/null +++ b/src/components/FriendListPage/Peong.tsx @@ -0,0 +1,29 @@ +import profileIcon from "../../assets/ChatRoom/profile.svg"; +import foldIcon from "../../assets/FriendList/up_arrow.svg"; +import unfoldIcon from "../../assets/FriendList/down_arrow.svg"; +import makeIcon from "../../assets/FriendList/make_peong.svg"; +import peongIcon from "../../assets/FriendList/peong_bg.svg"; + +const Peong = () => { + + return ( +
+
+

펑 1

+ fold +
+
+
+ makePeong +

만들기

+
+
+ userPeong +

CEOS

+
+
+
+ ); +} + +export default Peong; \ No newline at end of file diff --git a/src/components/FriendListPage/UpdatedProfile.tsx b/src/components/FriendListPage/UpdatedProfile.tsx new file mode 100644 index 0000000..606d951 --- /dev/null +++ b/src/components/FriendListPage/UpdatedProfile.tsx @@ -0,0 +1,52 @@ +import profileIcon from "../../assets/ChatRoom/profile.svg"; +import foldIcon from "../../assets/FriendList/up_arrow.svg"; +import unfoldIcon from "../../assets/FriendList/down_arrow.svg"; +import redDotIcon from "../../assets/FriendList/redDot.svg"; + +const UpdatedProfile = () => { + + return ( +
+
+

업데이트한 프로필 3

+ fold +
+
+
+ newRedDot +
+ profileImg +

CEOS

+
+
+
+ newRedDot +
+ profileImg +

CEOS

+
+
+ newRedDot +
+ profileImg +

CEOS

+
+
+
+ profileImg +

CEOS

+
+
+ profileImg +

CEOS

+
+
+ profileImg +

CEOS

+
+
+
+ ); +} + +export default UpdatedProfile; \ No newline at end of file diff --git a/src/pages/FriendListPage.tsx b/src/pages/FriendListPage.tsx index 41db2ea..8b67b8f 100644 --- a/src/pages/FriendListPage.tsx +++ b/src/pages/FriendListPage.tsx @@ -2,14 +2,28 @@ import React, { useState, useEffect } from 'react'; import HomeIndicator from '../components/common/HomeIndicatior'; import TopBar from '../components/common/TopBar'; import NavBar from '../components/common/NavBar'; -import Header from '../components/ChatRoomListPage/Header'; +import Header from '../components/FriendListPage/Header'; +import UserProfile from '../components/MyProfilePage/UserProfile'; +import UpdatedProfile from '../components/FriendListPage/UpdatedProfile'; +import Peong from '../components/FriendListPage/Peong'; +import Birthday from '../components/FriendListPage/Birthday'; +import FriendList from '../components/FriendListPage/FriendList'; import Line from '../components/common/Line'; const FriendListPage = () => { return ( -
+
+
+ + + + + + + +
From d247207f403115916033f440476a997fb96bce34 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Tue, 29 Oct 2024 15:07:37 +0900 Subject: [PATCH 39/54] =?UTF-8?q?Feat:=20=EC=B9=9C=EA=B5=AC=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=ED=8E=98=EC=9D=B4=EC=A7=80=20UserData=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/FriendListPage/FriendList.tsx | 23 +++++++++----------- src/pages/FriendListPage.tsx | 20 +++++++++-------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/components/FriendListPage/FriendList.tsx b/src/components/FriendListPage/FriendList.tsx index 77d016e..bd8e682 100644 --- a/src/components/FriendListPage/FriendList.tsx +++ b/src/components/FriendListPage/FriendList.tsx @@ -1,6 +1,7 @@ import profileIcon from "../../assets/ChatRoom/profile.svg"; import foldIcon from "../../assets/FriendList/up_arrow.svg"; import unfoldIcon from "../../assets/FriendList/down_arrow.svg"; +import { UserData } from '../../lib/UserData'; const FriendList = () => { @@ -8,21 +9,17 @@ const FriendList = () => {

친구

- fold + fold
-
- profile -

CEOS

-
-
- profile -

CEOS

-
-
- profile -

CEOS

-
+ {UserData.map((user) => ( +
+ profile +

+ {user.userName} +

+
+ ))}
); diff --git a/src/pages/FriendListPage.tsx b/src/pages/FriendListPage.tsx index 8b67b8f..2a57344 100644 --- a/src/pages/FriendListPage.tsx +++ b/src/pages/FriendListPage.tsx @@ -15,15 +15,17 @@ const FriendListPage = () => {
- - - - - - - - - +
+ + + + + + + + + +
From 93b61c494483d9cbab7feb5c8873c0a93cb64d6f Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Tue, 29 Oct 2024 15:39:47 +0900 Subject: [PATCH 40/54] =?UTF-8?q?Feat:=20=EB=82=B4=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=ED=81=B4=EB=A6=AD=20=EC=8B=9C=20=EB=82=B4=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/FriendListPage/FriendList.tsx | 2 +- src/components/FriendListPage/Peong.tsx | 4 ++-- src/components/MyProfilePage/UserProfile.tsx | 11 ++++++++++- src/lib/UserData.tsx | 14 +++++++++++--- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/components/FriendListPage/FriendList.tsx b/src/components/FriendListPage/FriendList.tsx index bd8e682..4ad10ad 100644 --- a/src/components/FriendListPage/FriendList.tsx +++ b/src/components/FriendListPage/FriendList.tsx @@ -13,7 +13,7 @@ const FriendList = () => {
{UserData.map((user) => ( -
+
profile

{user.userName} diff --git a/src/components/FriendListPage/Peong.tsx b/src/components/FriendListPage/Peong.tsx index 6866fd5..5cf39cb 100644 --- a/src/components/FriendListPage/Peong.tsx +++ b/src/components/FriendListPage/Peong.tsx @@ -13,11 +13,11 @@ const Peong = () => { fold

-
+
makePeong

만들기

-
+
userPeong

CEOS

diff --git a/src/components/MyProfilePage/UserProfile.tsx b/src/components/MyProfilePage/UserProfile.tsx index e75a1e1..797aa33 100644 --- a/src/components/MyProfilePage/UserProfile.tsx +++ b/src/components/MyProfilePage/UserProfile.tsx @@ -1,10 +1,19 @@ +import { useNavigate } from 'react-router-dom'; import profileIcon from "../../assets/MyProfile/my_profile.svg"; import multiProfileIcon from "../../assets/MyProfile/multiProfile.svg"; const UserProfile = () => { + const navigate = useNavigate(); + + const handleProfileClick = () => { + navigate('/my'); + }; return ( -
+
profileImg

diff --git a/src/lib/UserData.tsx b/src/lib/UserData.tsx index a7bdf1d..403908c 100644 --- a/src/lib/UserData.tsx +++ b/src/lib/UserData.tsx @@ -9,14 +9,22 @@ export const UserData = [ }, { userId: 2, - userName: 'CEOS', + userName: '김민지', }, { userId: 3, - userName: '박연진', + userName: '팜하니', }, { userId: 4, - userName: '전재준', + userName: '다니엘', + }, + { + userId: 5, + userName: '강해린', + }, + { + userId: 6, + userName: '이혜인', }, ]; \ No newline at end of file From 23971a278e09098dfced763371ea0bee69d23030 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Tue, 29 Oct 2024 16:03:57 +0900 Subject: [PATCH 41/54] =?UTF-8?q?Feat:=20=EC=84=9C=EB=B9=84=EC=8A=A4=20?= =?UTF-8?q?=EC=A4=80=EB=B9=84=EC=A4=91=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 4 ++++ src/assets/Common/shield_warning.svg | 3 +++ src/pages/NotYetPage.tsx | 27 +++++++++++++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 src/assets/Common/shield_warning.svg create mode 100644 src/pages/NotYetPage.tsx diff --git a/src/App.tsx b/src/App.tsx index e2c8c5d..7817e70 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -3,6 +3,7 @@ import ChatRoomListPage from './pages/ChatRoomListPage'; import FriendListPage from './pages/FriendListPage'; import { Route, Routes } from 'react-router-dom'; import MyProfilePage from './pages/MyProfilePage'; +import NotYetPage from './pages/NotYetPage'; function App() { return ( @@ -14,6 +15,9 @@ function App() { }> }> + }> + }> + }>

diff --git a/src/assets/Common/shield_warning.svg b/src/assets/Common/shield_warning.svg new file mode 100644 index 0000000..75bb670 --- /dev/null +++ b/src/assets/Common/shield_warning.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/pages/NotYetPage.tsx b/src/pages/NotYetPage.tsx new file mode 100644 index 0000000..7714aff --- /dev/null +++ b/src/pages/NotYetPage.tsx @@ -0,0 +1,27 @@ +import HomeIndicator from '../components/common/HomeIndicatior'; +import TopBar from '../components/common/TopBar'; +import NavBar from '../components/common/NavBar'; +import Icon from "../assets/Common/shield_warning.svg"; + +const NotYetPage = () => { + return ( +
+ +
+ +

+ 서비스 준비중입니다.

+

+ 보다 나은 서비스 제공을 위하여 페이지 준비중에 있습니다.

+

+ 빠른 시일 내에 준비하여 찾아뵙겠습니다.

+
+
+ + +
+
+ ); +} + +export default NotYetPage; From 21678304bf4886dcf925682f4696efa78627d54f Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Tue, 29 Oct 2024 16:32:16 +0900 Subject: [PATCH 42/54] =?UTF-8?q?Feat:=20=EC=B9=9C=EA=B5=AC=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EC=A0=91=EA=B8=B0=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/FriendListPage/Birthday.tsx | 13 ++++- src/components/FriendListPage/FriendList.tsx | 52 +++++++++++++---- src/components/FriendListPage/Peong.tsx | 33 +++++++---- .../FriendListPage/UpdatedProfile.tsx | 57 ++++++++++++------- 4 files changed, 110 insertions(+), 45 deletions(-) diff --git a/src/components/FriendListPage/Birthday.tsx b/src/components/FriendListPage/Birthday.tsx index f51cde0..f1e371e 100644 --- a/src/components/FriendListPage/Birthday.tsx +++ b/src/components/FriendListPage/Birthday.tsx @@ -1,14 +1,25 @@ +import React, { useState } from 'react'; import profileIcon from "../../assets/ChatRoom/profile.svg"; import foldIcon from "../../assets/FriendList/up_arrow.svg"; import unfoldIcon from "../../assets/FriendList/down_arrow.svg"; const Birthday = () => { + const [isFolded, setIsFolded] = useState(false); + + const toggleFold = () => { + setIsFolded(!isFolded); + }; return (

생일인 친구

- fold + fold
); diff --git a/src/components/FriendListPage/FriendList.tsx b/src/components/FriendListPage/FriendList.tsx index 4ad10ad..286cd34 100644 --- a/src/components/FriendListPage/FriendList.tsx +++ b/src/components/FriendListPage/FriendList.tsx @@ -1,26 +1,54 @@ +import React, { useState } from 'react'; +import { useNavigate } from 'react-router-dom'; import profileIcon from "../../assets/ChatRoom/profile.svg"; import foldIcon from "../../assets/FriendList/up_arrow.svg"; import unfoldIcon from "../../assets/FriendList/down_arrow.svg"; import { UserData } from '../../lib/UserData'; -const FriendList = () => { +interface User { + userId: number; + userName: string; +} + +const FriendList: React.FC = () => { + const [isFolded, setIsFolded] = useState(false); + const navigate = useNavigate(); + + const toggleFold = () => { + setIsFolded(!isFolded); + }; + + const handleProfileClick = (userId: number) => { + navigate(`/chat/${userId}`); + }; return (

친구

- fold -
-
- {UserData.map((user) => ( -
- profile -

- {user.userName} -

-
- ))} + fold
+ {!isFolded && ( +
+ {UserData.map((user) => ( +
handleProfileClick(user.userId)} + > + profile +

+ {user.userName} +

+
+ ))} +
+ )}
); } diff --git a/src/components/FriendListPage/Peong.tsx b/src/components/FriendListPage/Peong.tsx index 5cf39cb..a7b5bc2 100644 --- a/src/components/FriendListPage/Peong.tsx +++ b/src/components/FriendListPage/Peong.tsx @@ -1,3 +1,4 @@ +import React, { useState } from 'react'; import profileIcon from "../../assets/ChatRoom/profile.svg"; import foldIcon from "../../assets/FriendList/up_arrow.svg"; import unfoldIcon from "../../assets/FriendList/down_arrow.svg"; @@ -5,23 +6,35 @@ import makeIcon from "../../assets/FriendList/make_peong.svg"; import peongIcon from "../../assets/FriendList/peong_bg.svg"; const Peong = () => { + const [isFolded, setIsFolded] = useState(false); + + const toggleFold = () => { + setIsFolded(!isFolded); + }; return (

펑 1

- fold + fold
-
-
- makePeong -

만들기

-
-
- userPeong -

CEOS

+ {!isFolded && ( +
+
+ makePeong +

만들기

+
+
+ userPeong +

CEOS

+
-
+ )}
); } diff --git a/src/components/FriendListPage/UpdatedProfile.tsx b/src/components/FriendListPage/UpdatedProfile.tsx index 606d951..157b77a 100644 --- a/src/components/FriendListPage/UpdatedProfile.tsx +++ b/src/components/FriendListPage/UpdatedProfile.tsx @@ -1,50 +1,63 @@ +import React, { useState } from 'react'; import profileIcon from "../../assets/ChatRoom/profile.svg"; import foldIcon from "../../assets/FriendList/up_arrow.svg"; import unfoldIcon from "../../assets/FriendList/down_arrow.svg"; import redDotIcon from "../../assets/FriendList/redDot.svg"; const UpdatedProfile = () => { + const [isFolded, setIsFolded] = useState(false); + + const toggleFold = () => { + setIsFolded(!isFolded); + }; return (

업데이트한 프로필 3

- fold + fold
-
-
- newRedDot + {!isFolded && ( +
+
+ newRedDot +
+ profileImg +

CEOS

+
+
+
+ newRedDot +
+ profileImg +

CEOS

+
+
+ newRedDot +
+ profileImg +

CEOS

+
+
profileImg

CEOS

-
-
- newRedDot
profileImg

CEOS

-
- newRedDot
profileImg

CEOS

-
- profileImg -

CEOS

-
-
- profileImg -

CEOS

-
-
- profileImg -

CEOS

-
-
+ )}
); } From 369611058604c9f2a2d708d5b957ca9c56cf44ea Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Tue, 29 Oct 2024 17:22:00 +0900 Subject: [PATCH 43/54] =?UTF-8?q?Fix:=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=9D=B4=EB=A6=84=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ChatRoomListPage/ChatRoomComponent.tsx | 4 +- src/components/ChatRoomPage/Header.tsx | 6 +- src/lib/UserData.tsx | 4 +- src/pages/ChatRoomListPage.tsx | 32 +++++---- src/pages/ChatRoomPage.tsx | 68 ++++++++++++------- 5 files changed, 66 insertions(+), 48 deletions(-) diff --git a/src/components/ChatRoomListPage/ChatRoomComponent.tsx b/src/components/ChatRoomListPage/ChatRoomComponent.tsx index ac80a83..de26952 100644 --- a/src/components/ChatRoomListPage/ChatRoomComponent.tsx +++ b/src/components/ChatRoomListPage/ChatRoomComponent.tsx @@ -21,8 +21,8 @@ const ChatRoomComponent: React.FC = ({ userId, lastMessage, onCl
- {user?.userName || '(알 수 없음)'} - {lastMessage?.text} + {user?.userName || '(알 수 없음)'} + {lastMessage?.text}
{lastMessage ? formatTimeForChatList(lastMessage.timestamp) : ''} diff --git a/src/components/ChatRoomPage/Header.tsx b/src/components/ChatRoomPage/Header.tsx index 5baa610..6560d0a 100644 --- a/src/components/ChatRoomPage/Header.tsx +++ b/src/components/ChatRoomPage/Header.tsx @@ -5,12 +5,10 @@ import searchIcon from "../../assets/ChatRoom/search.svg"; import menuIcon from "../../assets/ChatRoom/menu.svg"; interface HeaderProps { - currentUser: { userId: number, userName: string }; opponentUser: { userId: number, userName: string }; - toggleUser: () => void; } -const Header: React.FC = ({ currentUser, opponentUser, toggleUser }) => { +const Header: React.FC = ({ opponentUser }) => { const navigate = useNavigate(); @@ -21,7 +19,7 @@ const Header: React.FC = ({ currentUser, opponentUser, toggleUser }
GoBack -

+

{opponentUser.userName}

diff --git a/src/lib/UserData.tsx b/src/lib/UserData.tsx index 403908c..f45f30c 100644 --- a/src/lib/UserData.tsx +++ b/src/lib/UserData.tsx @@ -1,11 +1,11 @@ export const UserData = [ { userId: 0, - userName: '이가빈', + userName: '김태양', }, { userId: 1, - userName: '김태양', + userName: '이가빈', }, { userId: 2, diff --git a/src/pages/ChatRoomListPage.tsx b/src/pages/ChatRoomListPage.tsx index cfdaffe..8b29ffd 100644 --- a/src/pages/ChatRoomListPage.tsx +++ b/src/pages/ChatRoomListPage.tsx @@ -19,22 +19,26 @@ const ChatRoomListPage: React.FC = () => { const [lastMessages, setLastMessages] = useState<{ [userId: number]: Message | null }>({}); useEffect(() => { - const savedMessages = localStorage.getItem('messages'); - if (savedMessages) { - const parsedMessages: Message[] = JSON.parse(savedMessages).map((msg: any) => ({ - ...msg, - timestamp: new Date(msg.timestamp), - })); + const lastMessagesByUser: { [userId: number]: Message | null } = {}; - const lastMessagesByUser: { [userId: number]: Message | null } = {}; - UserData.forEach(user => { - // 각 유저의 마지막 메시지 찾기 - const userMessages = parsedMessages.filter(msg => msg.senderId === user.userId); - lastMessagesByUser[user.userId] = userMessages.length > 0 ? userMessages[userMessages.length - 1] : null; - }); + UserData.forEach(user => { + // 각 유저별 메시지 불러오기 + const savedMessages = localStorage.getItem(`messages_${user.userId}`); + if (savedMessages) { + const parsedMessages: Message[] = JSON.parse(savedMessages).map((msg: any) => ({ + ...msg, + timestamp: new Date(msg.timestamp), + })); - setLastMessages(lastMessagesByUser); - } + // 마지막 메시지 설정 + lastMessagesByUser[user.userId] = parsedMessages.length > 0 ? parsedMessages[parsedMessages.length - 1] : null; + } else { + // 메시지가 없는 경우 null 설정 + lastMessagesByUser[user.userId] = null; + } + }); + + setLastMessages(lastMessagesByUser); }, []); const handleChatRoomClick = (userId: number) => { diff --git a/src/pages/ChatRoomPage.tsx b/src/pages/ChatRoomPage.tsx index 71ea3a5..7716e37 100644 --- a/src/pages/ChatRoomPage.tsx +++ b/src/pages/ChatRoomPage.tsx @@ -1,4 +1,5 @@ import React, { useState, useEffect } from 'react'; +import { useParams } from 'react-router-dom'; import ChatBar from '../components/ChatRoomPage/ChatBar'; import Header from '../components/ChatRoomPage/Header'; import HomeIndicator from '../components/common/HomeIndicatior'; @@ -7,64 +8,79 @@ import MessageList from '../components/ChatRoomPage/MessageList'; import { UserData } from '../lib/UserData'; import { MessageData } from '../lib/MessageData'; -const ChatRoomPage = () => { - const [currentUser, setCurrentUser] = useState(UserData[0]); - const [messages, setMessages] = useState<{ senderId: number, text: string, timestamp: Date }[]>([]); +interface User { + userId: number; + userName: string; +} + +interface Message { + senderId: number; + text: string; + timestamp: Date; +} - // 상대방 유저 설정 - const opponentUser = currentUser.userId === 0 ? UserData[1] : UserData[0]; +const ChatRoomPage: React.FC = () => { + const { userId } = useParams<{ userId: string }>(); + const opponentUser = UserData.find(user => user.userId === parseInt(userId || '')); + const [currentUser] = useState(UserData.find(user => user.userId === 0)); + const [messages, setMessages] = useState([]); // 초기 메시지 및 로컬스토리지 메시지 불러오기 useEffect(() => { - // 로컬스토리지 메시지 불러오기 - const savedMessages = localStorage.getItem('messages'); + if (!opponentUser) return; + + const savedMessages = localStorage.getItem(`messages_${opponentUser.userId}`); if (savedMessages) { - // 로컬스토리지에 저장된 메시지가 있으면 해당 데이터만 사용 - const parsedMessages = JSON.parse(savedMessages).map((msg: any) => ({ + const parsedMessages: Message[] = JSON.parse(savedMessages).map((msg: any) => ({ ...msg, timestamp: new Date(msg.timestamp), })); setMessages(parsedMessages); } else { - // 로컬스토리지에 데이터가 없을 경우만 MessageData 사용 - const initialMessages = MessageData.map(msg => ({ + // 기본 메시지 설정 + const initialMessages: Message[] = MessageData.filter( + msg => msg.senderId === opponentUser.userId || msg.senderId === currentUser?.userId + ).map(msg => ({ ...msg, timestamp: new Date(msg.timestamp), })); setMessages(initialMessages); // 초기 메시지 로컬스토리지에 저장 - localStorage.setItem('messages', JSON.stringify(initialMessages)); + localStorage.setItem(`messages_${opponentUser.userId}`, JSON.stringify(initialMessages)); } - }, []); + }, [opponentUser, currentUser]); - - // 유저 토글 전환 - const toggleUser = () => { - setCurrentUser(prevUser => - prevUser.userId === 0 ? UserData[1] : UserData[0] - ); - }; + // // 유저 토글 전환 + // const toggleUser = () => { + // setCurrentUser(prevUser => + // prevUser.userId === 0 ? UserData[1] : UserData[0] + // ); + // }; // 메시지 전송 핸들러 const handleSendMessage = (message: string) => { - const newMessage = { senderId: currentUser.userId, text: message, timestamp: new Date() }; + const newMessage: Message = { senderId: currentUser?.userId || 0, text: message, timestamp: new Date() }; - setMessages(prevMessages => { + setMessages((prevMessages) => { const updatedMessages = [...prevMessages, newMessage]; // 로컬 스토리지에 저장 - localStorage.setItem('messages', JSON.stringify(updatedMessages)); + if (opponentUser) { + localStorage.setItem(`messages_${opponentUser.userId}`, JSON.stringify(updatedMessages)); + } return updatedMessages; }); }; + if (!opponentUser) return
상대방 정보를 찾을 수 없습니다.
; + return (
-
- +
+
- +
From eb99037ef4392017ceba99203e1b3639ffbca6b4 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Tue, 29 Oct 2024 17:23:00 +0900 Subject: [PATCH 44/54] =?UTF-8?q?Fix:=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=EB=82=B4=20=EB=92=A4=EB=A1=9C=EA=B0=80=EA=B8=B0=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=ED=81=B4=EB=A6=AD=20=EC=8B=9C=20=EB=9D=BC=EC=9A=B0?= =?UTF-8?q?=ED=8C=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ChatRoomPage/Header.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ChatRoomPage/Header.tsx b/src/components/ChatRoomPage/Header.tsx index 6560d0a..2517b25 100644 --- a/src/components/ChatRoomPage/Header.tsx +++ b/src/components/ChatRoomPage/Header.tsx @@ -13,7 +13,7 @@ const Header: React.FC = ({ opponentUser }) => { const navigate = useNavigate(); const handleBackClick = () => { - navigate(-1); + navigate('/chatlist'); } return (
From ec1143816524deafd186af0afcf69b7afe603ffe Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Tue, 29 Oct 2024 18:30:38 +0900 Subject: [PATCH 45/54] =?UTF-8?q?Feat:=20user=20=EC=A0=95=EB=B3=B4=20conte?= =?UTF-8?q?xt=20API=20=EA=B4=80=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 27 +++++----- .../ChatRoomListPage/ChatRoomComponent.tsx | 2 +- src/components/ChatRoomPage/MessageList.tsx | 30 ++++------- src/components/MyProfilePage/UserProfile.tsx | 14 ++++- src/contexts/UserContext.tsx | 54 +++++++++++++++++++ src/lib/UserData.tsx | 23 +++++++- src/pages/ChatRoomListPage.tsx | 28 +++++----- src/pages/ChatRoomPage.tsx | 20 ++----- src/pages/MyProfilePage.tsx | 13 +++-- 9 files changed, 143 insertions(+), 68 deletions(-) create mode 100644 src/contexts/UserContext.tsx diff --git a/src/App.tsx b/src/App.tsx index 7817e70..c74cfd2 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,23 +4,26 @@ import FriendListPage from './pages/FriendListPage'; import { Route, Routes } from 'react-router-dom'; import MyProfilePage from './pages/MyProfilePage'; import NotYetPage from './pages/NotYetPage'; +import { UserProvider } from './contexts/UserContext'; function App() { return ( -
-
- - }> - }> + +
+
+ + }> + }> - }> - }> - }> - }> - }> - + }> + }> + }> + }> + }> + +
-
+ ); } diff --git a/src/components/ChatRoomListPage/ChatRoomComponent.tsx b/src/components/ChatRoomListPage/ChatRoomComponent.tsx index de26952..c103776 100644 --- a/src/components/ChatRoomListPage/ChatRoomComponent.tsx +++ b/src/components/ChatRoomListPage/ChatRoomComponent.tsx @@ -22,7 +22,7 @@ const ChatRoomComponent: React.FC = ({ userId, lastMessage, onCl
{user?.userName || '(알 수 없음)'} - {lastMessage?.text} + {lastMessage?.text}
{lastMessage ? formatTimeForChatList(lastMessage.timestamp) : ''} diff --git a/src/components/ChatRoomPage/MessageList.tsx b/src/components/ChatRoomPage/MessageList.tsx index dbc68d5..0e486be 100644 --- a/src/components/ChatRoomPage/MessageList.tsx +++ b/src/components/ChatRoomPage/MessageList.tsx @@ -1,11 +1,7 @@ -import React, { useState, useEffect, useRef } from 'react'; +import React, { useEffect, useRef } from 'react'; import profileIcon from "../../assets/ChatRoom/profile.svg"; import { formatTime } from '../../utils/ClockUtils'; - -interface User { - userId: number; - userName: string; -} +import { useUser } from '../../contexts/UserContext'; interface Message { senderId: number; @@ -15,10 +11,9 @@ interface Message { interface MessageListProps { messages: Message[]; - currentUserId: number; - users: User[]; } +// 메시지 그룹화 함수 const groupMessages = (messages: Message[]) => { return messages.reduce((arr, message, index) => { const timeKey = formatTime(message.timestamp); @@ -36,15 +31,10 @@ const groupMessages = (messages: Message[]) => { }, [] as { timeKey: string; senderId: number; messages: Message[] }[]); }; -const MessageList: React.FC = ({ currentUserId, messages, users }) => { +const MessageList: React.FC = ({ messages }) => { + const { currentUser, opponentUser } = useUser(); const scrollRef = useRef(null); - // senderId로 사용자 이름 찾기 - const getUserName = (senderId: number) => { - const user = users.find(user => user.userId === senderId); - return user ? user.userName : '(알 수 없음)'; - }; - useEffect(() => { if (scrollRef.current) { scrollRef.current.scrollIntoView({ behavior: 'smooth' }); @@ -72,15 +62,15 @@ const MessageList: React.FC = ({ currentUserId, messages, user {group.messages.map((message, idx) => (
- {message.senderId !== currentUserId && ( + {message.senderId !== currentUser?.userId && (
{idx === 0 && (
Profile

- {getUserName(message.senderId)} + {opponentUser?.userName || '(알 수 없음)'}

)} @@ -89,7 +79,7 @@ const MessageList: React.FC = ({ currentUserId, messages, user

)} - {message.senderId === currentUserId && ( + {message.senderId === currentUser?.userId && (

{message.text}

@@ -104,4 +94,4 @@ const MessageList: React.FC = ({ currentUserId, messages, user ); }; -export default MessageList; +export default MessageList; \ No newline at end of file diff --git a/src/components/MyProfilePage/UserProfile.tsx b/src/components/MyProfilePage/UserProfile.tsx index 797aa33..92fc03f 100644 --- a/src/components/MyProfilePage/UserProfile.tsx +++ b/src/components/MyProfilePage/UserProfile.tsx @@ -1,9 +1,11 @@ import { useNavigate } from 'react-router-dom'; import profileIcon from "../../assets/MyProfile/my_profile.svg"; import multiProfileIcon from "../../assets/MyProfile/multiProfile.svg"; +import { useUser } from '../../contexts/UserContext'; const UserProfile = () => { const navigate = useNavigate(); + const { currentUser, toggleUser } = useUser(); const handleProfileClick = () => { navigate('/my'); @@ -17,10 +19,18 @@ const UserProfile = () => {
profileImg

- 김태양 + {currentUser?.userName}

- setMultiProfile + setMultiProfile { + e.stopPropagation(); // 부모 클릭 이벤트 방지 + toggleUser(); // 전역 상태에서 유저 토글 + }} + className='cursor-pointer' + />
); } diff --git a/src/contexts/UserContext.tsx b/src/contexts/UserContext.tsx new file mode 100644 index 0000000..357d5d0 --- /dev/null +++ b/src/contexts/UserContext.tsx @@ -0,0 +1,54 @@ +import React, { createContext, useState, useContext, ReactNode } from 'react'; +import { UserData } from '../lib/UserData'; + +interface User { + userId: number; + userName: string; + phoneNumber: string; + email: string; + sns: string; +} + +interface UserContextType { + currentUser: User | null; + opponentUser: User | null; + toggleUser: () => void; +} + +const UserContext = createContext(undefined); + +interface UserProviderProps { + children: ReactNode; +} + +export const UserProvider = ({ children }: UserProviderProps) => { + const [currentUser, setCurrentUser] = useState( + UserData.find(user => user.userId === 0) || null + ); + + // currentUser의 userId에 따라 opponentUser 설정 + const opponentUser: User | null = currentUser?.userId === 0 + ? UserData.find(user => user.userId === 1) || null + : UserData.find(user => user.userId === 0) || null; + + const toggleUser = () => { + const newUser = currentUser?.userId === 0 + ? UserData.find(user => user.userId === 1) + : UserData.find(user => user.userId === 0); + if (newUser) setCurrentUser(newUser); + }; + + return ( + + {children} + + ); +}; + +export const useUser = (): UserContextType => { + const context = useContext(UserContext); + if (!context) { + throw new Error("error"); + } + return context; +}; diff --git a/src/lib/UserData.tsx b/src/lib/UserData.tsx index f45f30c..9ee2f74 100644 --- a/src/lib/UserData.tsx +++ b/src/lib/UserData.tsx @@ -2,29 +2,50 @@ export const UserData = [ { userId: 0, userName: '김태양', + phoneNumber: '2052-8337', + email: 'tangerin2601@naver.com', + sns: '@taeyaaaaaaang', }, { userId: 1, userName: '이가빈', + phoneNumber: '1886-1029', + email: 'billy@gmail.com', + sns: '@billyboo', }, { userId: 2, userName: '김민지', + phoneNumber: '2004-0507', + email: 'minji@gmail.com', + sns: '@newjeans_official', }, { userId: 3, userName: '팜하니', + phoneNumber: '2004-1006', + email: 'hanni@gmail.com', + sns: '@newjeans_official', }, { userId: 4, - userName: '다니엘', + userName: '모지혜', + phoneNumber: '2005-0411', + email: 'danielle@gmail.com', + sns: '@newjeans_official', }, { userId: 5, userName: '강해린', + phoneNumber: '2006-0515', + email: 'haerin@gmail.com', + sns: '@newjeans_official', }, { userId: 6, userName: '이혜인', + phoneNumber: '2008-0421', + email: 'hyein@gmail.com', + sns: '@newjeans_official', }, ]; \ No newline at end of file diff --git a/src/pages/ChatRoomListPage.tsx b/src/pages/ChatRoomListPage.tsx index 8b29ffd..4d20054 100644 --- a/src/pages/ChatRoomListPage.tsx +++ b/src/pages/ChatRoomListPage.tsx @@ -7,6 +7,7 @@ import Header from '../components/ChatRoomListPage/Header'; import Line from '../components/common/Line'; import ChatRoomComponent from '../components/ChatRoomListPage/ChatRoomComponent'; import { UserData } from '../lib/UserData'; +import { useUser } from '../contexts/UserContext'; interface Message { senderId: number; @@ -16,6 +17,7 @@ interface Message { const ChatRoomListPage: React.FC = () => { const navigate = useNavigate(); + const { currentUser } = useUser(); const [lastMessages, setLastMessages] = useState<{ [userId: number]: Message | null }>({}); useEffect(() => { @@ -23,23 +25,23 @@ const ChatRoomListPage: React.FC = () => { UserData.forEach(user => { // 각 유저별 메시지 불러오기 - const savedMessages = localStorage.getItem(`messages_${user.userId}`); - if (savedMessages) { - const parsedMessages: Message[] = JSON.parse(savedMessages).map((msg: any) => ({ - ...msg, - timestamp: new Date(msg.timestamp), - })); + if (currentUser && user.userId !== currentUser.userId) { + const savedMessages = localStorage.getItem(`messages_${user.userId}`); + if (savedMessages) { + const parsedMessages: Message[] = JSON.parse(savedMessages).map((msg: any) => ({ + ...msg, + timestamp: new Date(msg.timestamp), + })); - // 마지막 메시지 설정 - lastMessagesByUser[user.userId] = parsedMessages.length > 0 ? parsedMessages[parsedMessages.length - 1] : null; - } else { - // 메시지가 없는 경우 null 설정 - lastMessagesByUser[user.userId] = null; + lastMessagesByUser[user.userId] = parsedMessages.length > 0 ? parsedMessages[parsedMessages.length - 1] : null; + } else { + lastMessagesByUser[user.userId] = null; + } } }); setLastMessages(lastMessagesByUser); - }, []); + }, [currentUser]); const handleChatRoomClick = (userId: number) => { // 클릭한 채팅방으로 이동 @@ -51,7 +53,7 @@ const ChatRoomListPage: React.FC = () => {
- {UserData.map(user => ( + {UserData.filter(user => currentUser && user.userId !== currentUser.userId).map(user => ( lastMessages[user.userId] && ( { const { userId } = useParams<{ userId: string }>(); - const opponentUser = UserData.find(user => user.userId === parseInt(userId || '')); - const [currentUser] = useState(UserData.find(user => user.userId === 0)); + const { currentUser, opponentUser } = useUser(); const [messages, setMessages] = useState([]); // 초기 메시지 및 로컬스토리지 메시지 불러오기 @@ -48,16 +42,10 @@ const ChatRoomPage: React.FC = () => { // 초기 메시지 로컬스토리지에 저장 localStorage.setItem(`messages_${opponentUser.userId}`, JSON.stringify(initialMessages)); + } }, [opponentUser, currentUser]); - // // 유저 토글 전환 - // const toggleUser = () => { - // setCurrentUser(prevUser => - // prevUser.userId === 0 ? UserData[1] : UserData[0] - // ); - // }; - // 메시지 전송 핸들러 const handleSendMessage = (message: string) => { const newMessage: Message = { senderId: currentUser?.userId || 0, text: message, timestamp: new Date() }; @@ -78,7 +66,7 @@ const ChatRoomPage: React.FC = () => {
- +
diff --git a/src/pages/MyProfilePage.tsx b/src/pages/MyProfilePage.tsx index 685e618..db7726e 100644 --- a/src/pages/MyProfilePage.tsx +++ b/src/pages/MyProfilePage.tsx @@ -6,17 +6,24 @@ import Header from '../components/MyProfilePage/Header'; import UserProfile from '../components/MyProfilePage/UserProfile'; import Line from '../components/common/Line'; import ProfileInfo from '../components/MyProfilePage/ProfileInfo'; +import { useUser } from '../contexts/UserContext'; const MyProfilePage = () => { + const { currentUser } = useUser(); + return (
- - - + {currentUser && ( + <> + + + + + )}
From 18ba32a627bc9661a1e19c09362d6c28f0c445e6 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Tue, 29 Oct 2024 19:35:41 +0900 Subject: [PATCH 46/54] =?UTF-8?q?Feat:=20UserData=EC=97=90=20=EC=9E=88?= =?UTF-8?q?=EB=8A=94=20=EB=AA=A8=EB=93=A0=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=EC=99=80=20=EC=B1=84=ED=8C=85=20=EA=B0=80=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 2 +- src/components/ChatRoomPage/MessageList.tsx | 2 +- src/components/FriendListPage/FriendList.tsx | 15 ++++---- src/pages/ChatRoomListPage.tsx | 11 ++++-- src/pages/ChatRoomPage.tsx | 36 +++++++++++++------- 5 files changed, 44 insertions(+), 22 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index c74cfd2..e2deab6 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -12,7 +12,7 @@ function App() {
- }> + }> }> }> diff --git a/src/components/ChatRoomPage/MessageList.tsx b/src/components/ChatRoomPage/MessageList.tsx index 0e486be..0be4a92 100644 --- a/src/components/ChatRoomPage/MessageList.tsx +++ b/src/components/ChatRoomPage/MessageList.tsx @@ -18,7 +18,7 @@ const groupMessages = (messages: Message[]) => { return messages.reduce((arr, message, index) => { const timeKey = formatTime(message.timestamp); const prevMessage = messages[index - 1]; - const isSameSender = prevMessage && prevMessage.senderId === message.senderId; + const isSameSender = prevMessage && prevMessage?.senderId === message.senderId; const isSameMinute = prevMessage && formatTime(prevMessage.timestamp) === timeKey; if (!isSameSender || !isSameMinute) { diff --git a/src/components/FriendListPage/FriendList.tsx b/src/components/FriendListPage/FriendList.tsx index 286cd34..e0fedcc 100644 --- a/src/components/FriendListPage/FriendList.tsx +++ b/src/components/FriendListPage/FriendList.tsx @@ -4,22 +4,25 @@ import profileIcon from "../../assets/ChatRoom/profile.svg"; import foldIcon from "../../assets/FriendList/up_arrow.svg"; import unfoldIcon from "../../assets/FriendList/down_arrow.svg"; import { UserData } from '../../lib/UserData'; - -interface User { - userId: number; - userName: string; -} +import { useUser } from '../../contexts/UserContext'; const FriendList: React.FC = () => { const [isFolded, setIsFolded] = useState(false); const navigate = useNavigate(); + const { currentUser } = useUser(); const toggleFold = () => { setIsFolded(!isFolded); }; const handleProfileClick = (userId: number) => { - navigate(`/chat/${userId}`); + if (!currentUser) return; + + // chatKey 생성 + const chatKey = `${Math.min(currentUser.userId, userId)}_${Math.max(currentUser.userId, userId)}`; + + // 클릭한 채팅방으로 이동 + navigate(`/chat/${chatKey}`); }; return ( diff --git a/src/pages/ChatRoomListPage.tsx b/src/pages/ChatRoomListPage.tsx index 4d20054..1b4944a 100644 --- a/src/pages/ChatRoomListPage.tsx +++ b/src/pages/ChatRoomListPage.tsx @@ -26,7 +26,9 @@ const ChatRoomListPage: React.FC = () => { UserData.forEach(user => { // 각 유저별 메시지 불러오기 if (currentUser && user.userId !== currentUser.userId) { - const savedMessages = localStorage.getItem(`messages_${user.userId}`); + // `currentUser`와 `user` 간의 공통 대화 키 생성 + const chatKey = `messages_${Math.min(currentUser.userId, user.userId)}_${Math.max(currentUser.userId, user.userId)}`; + const savedMessages = localStorage.getItem(chatKey); if (savedMessages) { const parsedMessages: Message[] = JSON.parse(savedMessages).map((msg: any) => ({ ...msg, @@ -44,8 +46,13 @@ const ChatRoomListPage: React.FC = () => { }, [currentUser]); const handleChatRoomClick = (userId: number) => { + if (!currentUser) return; + + // chatKey 생성 + const chatKey = `${Math.min(currentUser.userId, userId)}_${Math.max(currentUser.userId, userId)}`; + // 클릭한 채팅방으로 이동 - navigate(`/chat/${userId}`); + navigate(`/chat/${chatKey}`); }; return ( diff --git a/src/pages/ChatRoomPage.tsx b/src/pages/ChatRoomPage.tsx index b9f3eec..33ff25a 100644 --- a/src/pages/ChatRoomPage.tsx +++ b/src/pages/ChatRoomPage.tsx @@ -6,6 +6,7 @@ import HomeIndicator from '../components/common/HomeIndicatior'; import TopBar from '../components/common/TopBar'; import MessageList from '../components/ChatRoomPage/MessageList'; import { MessageData } from '../lib/MessageData'; +import { UserData } from '../lib/UserData'; import { useUser } from '../contexts/UserContext'; interface Message { @@ -15,25 +16,31 @@ interface Message { } const ChatRoomPage: React.FC = () => { - const { userId } = useParams<{ userId: string }>(); - const { currentUser, opponentUser } = useUser(); + const { chatKey } = useParams<{ chatKey: string }>(); + const { currentUser } = useUser(); const [messages, setMessages] = useState([]); + + // chatKey에서 userId 추출 + const [user1Id, user2Id] = chatKey?.split('_').map(Number) || []; + const opponentUser = UserData.find(user => user.userId === (currentUser?.userId === user1Id ? user2Id : user1Id)); // 초기 메시지 및 로컬스토리지 메시지 불러오기 useEffect(() => { - if (!opponentUser) return; + if (!chatKey) return; + + const isDefaultChatKey = chatKey === '0_1' || chatKey === '1_0'; - const savedMessages = localStorage.getItem(`messages_${opponentUser.userId}`); + const savedMessages = localStorage.getItem(`messages_${chatKey}`); if (savedMessages) { const parsedMessages: Message[] = JSON.parse(savedMessages).map((msg: any) => ({ ...msg, timestamp: new Date(msg.timestamp), })); setMessages(parsedMessages); - } else { + } else if (isDefaultChatKey) { // 기본 메시지 설정 const initialMessages: Message[] = MessageData.filter( - msg => msg.senderId === opponentUser.userId || msg.senderId === currentUser?.userId + msg => msg.senderId === opponentUser?.userId || msg.senderId === currentUser?.userId ).map(msg => ({ ...msg, timestamp: new Date(msg.timestamp), @@ -41,21 +48,26 @@ const ChatRoomPage: React.FC = () => { setMessages(initialMessages); // 초기 메시지 로컬스토리지에 저장 - localStorage.setItem(`messages_${opponentUser.userId}`, JSON.stringify(initialMessages)); + localStorage.setItem(`messages_${chatKey}`, JSON.stringify(initialMessages)); } - }, [opponentUser, currentUser]); + }, [chatKey, opponentUser, currentUser]); // 메시지 전송 핸들러 const handleSendMessage = (message: string) => { - const newMessage: Message = { senderId: currentUser?.userId || 0, text: message, timestamp: new Date() }; + if (!chatKey || !currentUser) return; + + const newMessage: Message = { + senderId: currentUser.userId, + text: message, + timestamp: new Date() + }; setMessages((prevMessages) => { const updatedMessages = [...prevMessages, newMessage]; // 로컬 스토리지에 저장 - if (opponentUser) { - localStorage.setItem(`messages_${opponentUser.userId}`, JSON.stringify(updatedMessages)); - } + localStorage.setItem(`messages_${chatKey}`, JSON.stringify(updatedMessages)); + return updatedMessages; }); }; From de8abefda46df20f5945b60ec79898b588dc4dba Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Tue, 29 Oct 2024 19:39:59 +0900 Subject: [PATCH 47/54] =?UTF-8?q?Fix:=20=EC=B9=9C=EA=B5=AC=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=EC=97=90=EC=84=9C=20=EB=B3=B8=EC=9D=B8=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=ED=95=84=EC=9D=80=20=EC=A0=9C=EC=99=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/FriendListPage/FriendList.tsx | 2 +- src/pages/ChatRoomListPage.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/FriendListPage/FriendList.tsx b/src/components/FriendListPage/FriendList.tsx index e0fedcc..03e9ff7 100644 --- a/src/components/FriendListPage/FriendList.tsx +++ b/src/components/FriendListPage/FriendList.tsx @@ -38,7 +38,7 @@ const FriendList: React.FC = () => {
{!isFolded && (
- {UserData.map((user) => ( + {UserData.filter(user => user.userId !== currentUser?.userId).map((user) => (
{ UserData.forEach(user => { // 각 유저별 메시지 불러오기 if (currentUser && user.userId !== currentUser.userId) { - // `currentUser`와 `user` 간의 공통 대화 키 생성 + // currentUser와 user 간의 공통 대화 키 생성 const chatKey = `messages_${Math.min(currentUser.userId, user.userId)}_${Math.max(currentUser.userId, user.userId)}`; const savedMessages = localStorage.getItem(chatKey); if (savedMessages) { @@ -56,7 +56,7 @@ const ChatRoomListPage: React.FC = () => { }; return ( -
+
From 8636ed92f8c12c42c9920fcd093321685fe6923f Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Tue, 29 Oct 2024 20:15:59 +0900 Subject: [PATCH 48/54] =?UTF-8?q?Feat:=20currentUser=20=EB=A1=9C=EC=BB=AC?= =?UTF-8?q?=EC=8A=A4=ED=86=A0=EB=A6=AC=EC=A7=80=EC=97=90=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ChatRoomListPage/ChatRoomComponent.tsx | 11 +++++--- src/contexts/UserContext.tsx | 17 +++++++++--- src/lib/MessageData.tsx | 4 +++ src/pages/ChatRoomListPage.tsx | 26 +++++++++++++++++-- 4 files changed, 49 insertions(+), 9 deletions(-) diff --git a/src/components/ChatRoomListPage/ChatRoomComponent.tsx b/src/components/ChatRoomListPage/ChatRoomComponent.tsx index c103776..d0f0b28 100644 --- a/src/components/ChatRoomListPage/ChatRoomComponent.tsx +++ b/src/components/ChatRoomListPage/ChatRoomComponent.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React from 'react'; import profileIcon from "../../assets/ChatRoom/profile.svg"; import { UserData } from '../../lib/UserData'; import { formatTimeForChatList } from '../../utils/ClockUtils'; @@ -12,9 +12,10 @@ interface ComponentProps { userId: number; lastMessage?: LastMessage; onClick: () => void; + unread: number; } -const ChatRoomComponent: React.FC = ({ userId, lastMessage, onClick }) => { +const ChatRoomComponent: React.FC = ({ userId, lastMessage, onClick, unread }) => { const user = UserData.find(user => user.userId === userId); return ( @@ -26,7 +27,11 @@ const ChatRoomComponent: React.FC = ({ userId, lastMessage, onCl
{lastMessage ? formatTimeForChatList(lastMessage.timestamp) : ''} - 1 + {unread > 0 && ( + + {unread} + + )}
); diff --git a/src/contexts/UserContext.tsx b/src/contexts/UserContext.tsx index 357d5d0..71fdbcd 100644 --- a/src/contexts/UserContext.tsx +++ b/src/contexts/UserContext.tsx @@ -1,4 +1,4 @@ -import React, { createContext, useState, useContext, ReactNode } from 'react'; +import React, { createContext, useState, useContext, ReactNode, useEffect } from 'react'; import { UserData } from '../lib/UserData'; interface User { @@ -22,9 +22,18 @@ interface UserProviderProps { } export const UserProvider = ({ children }: UserProviderProps) => { - const [currentUser, setCurrentUser] = useState( - UserData.find(user => user.userId === 0) || null - ); + // 로컬스토리지에서 currentUser 가져오기 + const storedUser = localStorage.getItem('currentUser'); + const initialUser = storedUser ? JSON.parse(storedUser) : UserData.find(user => user.userId === 0) || null; + + const [currentUser, setCurrentUser] = useState(initialUser); + + // currentUser가 변경될 때마다 로컬스토리지에 저장 + useEffect(() => { + if (currentUser) { + localStorage.setItem('currentUser', JSON.stringify(currentUser)); + } + }, [currentUser]); // currentUser의 userId에 따라 opponentUser 설정 const opponentUser: User | null = currentUser?.userId === 0 diff --git a/src/lib/MessageData.tsx b/src/lib/MessageData.tsx index 1cc074b..4cf8d9e 100644 --- a/src/lib/MessageData.tsx +++ b/src/lib/MessageData.tsx @@ -3,20 +3,24 @@ export const MessageData = [ senderId: 0, text: "안녕하세요!", timestamp: new Date('2024-09-25T10:30:00'), + read: true, }, { senderId: 0, text: "1주차 세션 팀구성이 궁금합니다!", timestamp: new Date('2024-09-25T10:30:00'), + read: true, }, { senderId: 1, text: "안녕하세요!", timestamp: new Date('2024-09-25T10:35:00'), + read: true, }, { senderId: 1, text: "세오스 공개용 노션에 비상관제시어 관련하여 공지 업로드 했습니다. 참고해주세요!", timestamp: new Date('2024-09-25T10:35:00'), + read: true, }, ]; diff --git a/src/pages/ChatRoomListPage.tsx b/src/pages/ChatRoomListPage.tsx index 950a4da..126167f 100644 --- a/src/pages/ChatRoomListPage.tsx +++ b/src/pages/ChatRoomListPage.tsx @@ -13,14 +13,17 @@ interface Message { senderId: number; text: string; timestamp: Date; + read: boolean; } const ChatRoomListPage: React.FC = () => { const navigate = useNavigate(); const { currentUser } = useUser(); const [lastMessages, setLastMessages] = useState<{ [userId: number]: Message | null }>({}); + const [unread, setUnread] = useState<{ [userId: number]: number }>({}); useEffect(() => { + const newUnread: { [userId: number]: number } = {}; const lastMessagesByUser: { [userId: number]: Message | null } = {}; UserData.forEach(user => { @@ -36,23 +39,41 @@ const ChatRoomListPage: React.FC = () => { })); lastMessagesByUser[user.userId] = parsedMessages.length > 0 ? parsedMessages[parsedMessages.length - 1] : null; + newUnread[user.userId] = parsedMessages.filter(msg => !msg.read && msg.senderId !== currentUser.userId).length; } else { lastMessagesByUser[user.userId] = null; + newUnread[user.userId] = 0; } } }); setLastMessages(lastMessagesByUser); + setUnread(newUnread); }, [currentUser]); const handleChatRoomClick = (userId: number) => { if (!currentUser) return; // chatKey 생성 - const chatKey = `${Math.min(currentUser.userId, userId)}_${Math.max(currentUser.userId, userId)}`; + const chatKey = `messages_${Math.min(currentUser.userId, userId)}_${Math.max(currentUser.userId, userId)}`; + // 해당 채팅방의 안 읽은 메시지 개수 0으로 초기화 + setUnread(prevUnread => ({ + ...prevUnread, + [userId]: 0 + })); + + // 로컬스토리지에서 해당 채팅방의 모든 메시지를 읽음으로 표시 + const savedMessages = localStorage.getItem(chatKey); + if (savedMessages) { + const messages: Message[] = (JSON.parse(savedMessages) as Message[]).map((msg: Message) => + msg.senderId !== currentUser.userId ? { ...msg, read: true } : msg + ); + localStorage.setItem(chatKey, JSON.stringify(messages)); + } + // 클릭한 채팅방으로 이동 - navigate(`/chat/${chatKey}`); + navigate(`/chat/${Math.min(currentUser.userId, userId)}_${Math.max(currentUser.userId, userId)}`); }; return ( @@ -67,6 +88,7 @@ const ChatRoomListPage: React.FC = () => { userId={user.userId} lastMessage={lastMessages[user.userId] || undefined} onClick={() => handleChatRoomClick(user.userId)} + unread={unread[user.userId] || 0} /> ) ))} From 2856851fe7be3c78b1aad0fe31f39d78e19dc7bc Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Tue, 29 Oct 2024 20:41:33 +0900 Subject: [PATCH 49/54] =?UTF-8?q?Feat:=20NavBar=EC=97=90=20=EC=95=88=20?= =?UTF-8?q?=EC=9D=BD=EC=9D=80=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EA=B0=9C?= =?UTF-8?q?=EC=88=98=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 27 ++++++++++-------- src/components/common/NavBar.tsx | 12 ++++++-- src/contexts/UnreadContext.tsx | 47 ++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 14 deletions(-) create mode 100644 src/contexts/UnreadContext.tsx diff --git a/src/App.tsx b/src/App.tsx index e2deab6..81d6f6f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,24 +5,27 @@ import { Route, Routes } from 'react-router-dom'; import MyProfilePage from './pages/MyProfilePage'; import NotYetPage from './pages/NotYetPage'; import { UserProvider } from './contexts/UserContext'; +import { UnreadProvider } from './contexts/UnreadContext'; function App() { return ( -
-
- - }> - }> + +
+
+ + }> + }> - }> - }> - }> - }> - }> - + }> + }> + }> + }> + }> + +
-
+ ); } diff --git a/src/components/common/NavBar.tsx b/src/components/common/NavBar.tsx index 67d1da3..1f9836e 100644 --- a/src/components/common/NavBar.tsx +++ b/src/components/common/NavBar.tsx @@ -5,12 +5,14 @@ import { ReactComponent as ChatIcon } from "../../assets/ChatRoomList/chatting_i import { ReactComponent as OpenedChatIcon } from "../../assets/ChatRoomList/openedChat_icon.svg"; import { ReactComponent as ShoppingIcon } from "../../assets/ChatRoomList/shopping_icon.svg"; import { ReactComponent as MoreIcon } from "../../assets/ChatRoomList/more_icon.svg"; +import { useUnread } from '../../contexts/UnreadContext'; const NavBar: React.FC = () => { const basicBtnStyle = "text-[9px] font-['Pretendard'] flex flex-col items-center cursor-pointer"; const navigate = useNavigate(); const location = useLocation(); const [activePath, setActivePath] = useState(location.pathname); + const { totalUnread } = useUnread(); useEffect(() => { setActivePath(location.pathname); @@ -39,8 +41,14 @@ const NavBar: React.FC = () => {
onBtnClick("/friends")} className={getBtnStyle("/friends")} style={{color: getIconStyle("/friends")}}> 친구
-
onBtnClick("/chatlist")} className={getBtnStyle("/chatlist")} style={{color: getIconStyle("/chatlist")}}> - 채팅 +
onBtnClick("/chatlist")} className={`${getBtnStyle("/chatlist")} relative`} style={{color: getIconStyle("/chatlist")}}> + + {totalUnread > 0 && ( +
+ {totalUnread} +
+ )} + 채팅
onBtnClick("/openedChat")} className={getBtnStyle("/openedChat")} style={{color: getIconStyle("/openedChat")}}> 오픈채팅 diff --git a/src/contexts/UnreadContext.tsx b/src/contexts/UnreadContext.tsx new file mode 100644 index 0000000..f9a4a68 --- /dev/null +++ b/src/contexts/UnreadContext.tsx @@ -0,0 +1,47 @@ +import React, { createContext, useState, useEffect, useContext, ReactNode } from 'react'; +import { useUser } from './UserContext'; +import { UserData } from '../lib/UserData'; + +interface UnreadContextType { + totalUnread: number; +} + +const UnreadContext = createContext(undefined); + +export const UnreadProvider: React.FC<{ children: ReactNode }> = ({ children }) => { + const { currentUser } = useUser(); + const [totalUnread, setTotalUnread] = useState(0); + + useEffect(() => { + const calculateUnread = () => { + if (!currentUser) return; + let cnt = 0; + UserData.forEach(user => { + if (user.userId !== currentUser.userId) { + const chatKey = `messages_${Math.min(currentUser.userId, user.userId)}_${Math.max(currentUser.userId, user.userId)}`; + const savedMessages = localStorage.getItem(chatKey); + if (savedMessages) { + const parsedMessages = JSON.parse(savedMessages); + cnt += parsedMessages.filter((msg: any) => !msg.read && msg.senderId !== currentUser.userId).length; + } + } + }); + setTotalUnread(cnt); + }; + calculateUnread(); + }, [currentUser]); + + return ( + + {children} + + ); +}; + +export const useUnread = (): UnreadContextType => { + const context = useContext(UnreadContext); + if (!context) { + throw new Error("error"); + } + return context; +}; From 2b82cd7af4473e29de290376dada0d0a86d3c9cf Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Tue, 29 Oct 2024 20:52:20 +0900 Subject: [PATCH 50/54] =?UTF-8?q?Fix:=20NavBar=20=EC=95=88=20=EC=9D=BD?= =?UTF-8?q?=EC=9D=80=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EA=B0=9C=EC=88=98=20?= =?UTF-8?q?=EB=B0=98=EC=98=81=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/contexts/UnreadContext.tsx | 36 ++++++++++++++++++---------------- src/pages/ChatRoomListPage.tsx | 3 +++ 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/contexts/UnreadContext.tsx b/src/contexts/UnreadContext.tsx index f9a4a68..9af8edd 100644 --- a/src/contexts/UnreadContext.tsx +++ b/src/contexts/UnreadContext.tsx @@ -4,6 +4,7 @@ import { UserData } from '../lib/UserData'; interface UnreadContextType { totalUnread: number; + calculateUnread: () => void; } const UnreadContext = createContext(undefined); @@ -12,27 +13,28 @@ export const UnreadProvider: React.FC<{ children: ReactNode }> = ({ children }) const { currentUser } = useUser(); const [totalUnread, setTotalUnread] = useState(0); - useEffect(() => { - const calculateUnread = () => { - if (!currentUser) return; - let cnt = 0; - UserData.forEach(user => { - if (user.userId !== currentUser.userId) { - const chatKey = `messages_${Math.min(currentUser.userId, user.userId)}_${Math.max(currentUser.userId, user.userId)}`; - const savedMessages = localStorage.getItem(chatKey); - if (savedMessages) { - const parsedMessages = JSON.parse(savedMessages); - cnt += parsedMessages.filter((msg: any) => !msg.read && msg.senderId !== currentUser.userId).length; - } + const calculateUnread = () => { + if (!currentUser) return; + let cnt = 0; + UserData.forEach(user => { + if (user.userId !== currentUser.userId) { + const chatKey = `messages_${Math.min(currentUser.userId, user.userId)}_${Math.max(currentUser.userId, user.userId)}`; + const savedMessages = localStorage.getItem(chatKey); + if (savedMessages) { + const parsedMessages = JSON.parse(savedMessages); + cnt += parsedMessages.filter((msg: any) => !msg.read && msg.senderId !== currentUser.userId).length; } - }); - setTotalUnread(cnt); - }; + } + }); + setTotalUnread(cnt); + }; + + useEffect(() => { calculateUnread(); }, [currentUser]); return ( - + {children} ); @@ -44,4 +46,4 @@ export const useUnread = (): UnreadContextType => { throw new Error("error"); } return context; -}; +}; \ No newline at end of file diff --git a/src/pages/ChatRoomListPage.tsx b/src/pages/ChatRoomListPage.tsx index 126167f..5549347 100644 --- a/src/pages/ChatRoomListPage.tsx +++ b/src/pages/ChatRoomListPage.tsx @@ -8,6 +8,7 @@ import Line from '../components/common/Line'; import ChatRoomComponent from '../components/ChatRoomListPage/ChatRoomComponent'; import { UserData } from '../lib/UserData'; import { useUser } from '../contexts/UserContext'; +import { useUnread } from '../contexts/UnreadContext'; interface Message { senderId: number; @@ -21,6 +22,7 @@ const ChatRoomListPage: React.FC = () => { const { currentUser } = useUser(); const [lastMessages, setLastMessages] = useState<{ [userId: number]: Message | null }>({}); const [unread, setUnread] = useState<{ [userId: number]: number }>({}); + const { calculateUnread } = useUnread(); useEffect(() => { const newUnread: { [userId: number]: number } = {}; @@ -70,6 +72,7 @@ const ChatRoomListPage: React.FC = () => { msg.senderId !== currentUser.userId ? { ...msg, read: true } : msg ); localStorage.setItem(chatKey, JSON.stringify(messages)); + calculateUnread(); } // 클릭한 채팅방으로 이동 From a4986c76e9ff56b783eba687138250c360d86d8e Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Tue, 29 Oct 2024 20:58:27 +0900 Subject: [PATCH 51/54] =?UTF-8?q?Fix:=20=ED=8E=91=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=ED=94=84=EB=A1=9C=ED=95=84=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/FriendListPage/Peong.tsx | 6 ++++-- src/pages/ChatRoomListPage.tsx | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/FriendListPage/Peong.tsx b/src/components/FriendListPage/Peong.tsx index a7b5bc2..a7fa3c5 100644 --- a/src/components/FriendListPage/Peong.tsx +++ b/src/components/FriendListPage/Peong.tsx @@ -29,9 +29,11 @@ const Peong = () => { makePeong

만들기

-
+
userPeong -

CEOS

+

+ + CEOS

)} diff --git a/src/pages/ChatRoomListPage.tsx b/src/pages/ChatRoomListPage.tsx index 5549347..4894a98 100644 --- a/src/pages/ChatRoomListPage.tsx +++ b/src/pages/ChatRoomListPage.tsx @@ -25,6 +25,7 @@ const ChatRoomListPage: React.FC = () => { const { calculateUnread } = useUnread(); useEffect(() => { + //localStorage.clear(); const newUnread: { [userId: number]: number } = {}; const lastMessagesByUser: { [userId: number]: Message | null } = {}; From 960ed2d5f2d70b298acb0a5d3291b082f1ea631e Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Tue, 29 Oct 2024 20:59:36 +0900 Subject: [PATCH 52/54] =?UTF-8?q?Fix:=20totalUnread=20=EC=9C=84=EC=B9=98?= =?UTF-8?q?=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/NavBar.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/common/NavBar.tsx b/src/components/common/NavBar.tsx index 1f9836e..ea2079f 100644 --- a/src/components/common/NavBar.tsx +++ b/src/components/common/NavBar.tsx @@ -44,7 +44,7 @@ const NavBar: React.FC = () => {
onBtnClick("/chatlist")} className={`${getBtnStyle("/chatlist")} relative`} style={{color: getIconStyle("/chatlist")}}> {totalUnread > 0 && ( -
+
{totalUnread}
)} From 3811d60f22ce0c4ca5bb0141c8e6465ef8de65b3 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Fri, 1 Nov 2024 15:41:32 +0900 Subject: [PATCH 53/54] =?UTF-8?q?Feat:=20=EB=A6=AC=EC=95=A1=EC=85=98=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 1 + src/assets/Reactions/angry.svg | 9 ++ src/assets/Reactions/heart.svg | 9 ++ src/assets/Reactions/oh.svg | 9 ++ src/assets/Reactions/plus.svg | 4 + src/assets/Reactions/smile.svg | 9 ++ src/assets/Reactions/tear.svg | 9 ++ src/assets/Reactions/thumb.svg | 9 ++ src/components/ChatRoomPage/MessageList.tsx | 148 ++++++++++++++++---- 9 files changed, 177 insertions(+), 30 deletions(-) create mode 100644 src/assets/Reactions/angry.svg create mode 100644 src/assets/Reactions/heart.svg create mode 100644 src/assets/Reactions/oh.svg create mode 100644 src/assets/Reactions/plus.svg create mode 100644 src/assets/Reactions/smile.svg create mode 100644 src/assets/Reactions/tear.svg create mode 100644 src/assets/Reactions/thumb.svg diff --git a/src/App.tsx b/src/App.tsx index 81d6f6f..d70c7c2 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -14,6 +14,7 @@ function App() {
+ }> }> }> diff --git a/src/assets/Reactions/angry.svg b/src/assets/Reactions/angry.svg new file mode 100644 index 0000000..78033c9 --- /dev/null +++ b/src/assets/Reactions/angry.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/Reactions/heart.svg b/src/assets/Reactions/heart.svg new file mode 100644 index 0000000..3496d30 --- /dev/null +++ b/src/assets/Reactions/heart.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/Reactions/oh.svg b/src/assets/Reactions/oh.svg new file mode 100644 index 0000000..c92037b --- /dev/null +++ b/src/assets/Reactions/oh.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/Reactions/plus.svg b/src/assets/Reactions/plus.svg new file mode 100644 index 0000000..80c523f --- /dev/null +++ b/src/assets/Reactions/plus.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/Reactions/smile.svg b/src/assets/Reactions/smile.svg new file mode 100644 index 0000000..277eead --- /dev/null +++ b/src/assets/Reactions/smile.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/Reactions/tear.svg b/src/assets/Reactions/tear.svg new file mode 100644 index 0000000..eafd494 --- /dev/null +++ b/src/assets/Reactions/tear.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/Reactions/thumb.svg b/src/assets/Reactions/thumb.svg new file mode 100644 index 0000000..99122a7 --- /dev/null +++ b/src/assets/Reactions/thumb.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/components/ChatRoomPage/MessageList.tsx b/src/components/ChatRoomPage/MessageList.tsx index 0be4a92..ea58771 100644 --- a/src/components/ChatRoomPage/MessageList.tsx +++ b/src/components/ChatRoomPage/MessageList.tsx @@ -1,12 +1,20 @@ -import React, { useEffect, useRef } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import profileIcon from "../../assets/ChatRoom/profile.svg"; import { formatTime } from '../../utils/ClockUtils'; import { useUser } from '../../contexts/UserContext'; +import heartIcon from "../../assets/Reactions/heart.svg"; +import smileIcon from "../../assets/Reactions/smile.svg"; +import ohIcon from "../../assets/Reactions/oh.svg"; +import tearIcon from "../../assets/Reactions/tear.svg"; +import angerIcon from "../../assets/Reactions/angry.svg"; +import thumbIcon from "../../assets/Reactions/thumb.svg"; +import plusIcon from "../../assets/Reactions/plus.svg"; interface Message { senderId: number; text: string; timestamp: Date; + emoji?: string; } interface MessageListProps { @@ -34,17 +42,46 @@ const groupMessages = (messages: Message[]) => { const MessageList: React.FC = ({ messages }) => { const { currentUser, opponentUser } = useUser(); const scrollRef = useRef(null); + const [reactions, setReactions] = useState<{ [key: number]: string | undefined }>({}); + const [showReactions, setShowReactions] = useState(null); + // 렌더링 시 로컬스토리지에서 리액션 데이터 가져오기 useEffect(() => { - if (scrollRef.current) { - scrollRef.current.scrollIntoView({ behavior: 'smooth' }); + const storedReactions = localStorage.getItem('messageReactions'); + if (storedReactions) { + setReactions(JSON.parse(storedReactions)); } - }, [messages]); + }, []); + + // 로컬스토리지에 리액션 저장 + const saveReactionsToLocalStorage = (updatedReactions: { [key: number]: string | undefined }) => { + localStorage.setItem('messageReactions', JSON.stringify(updatedReactions)); + }; + + + const handleDoubleClick = (index: number, event: React.MouseEvent) => { + event.preventDefault(); // 드래그 방지 + setShowReactions(index === showReactions ? null : index); + }; + + const handleSelectEmoji = (index: number, emoji: string) => { + const currentReaction = reactions[index]; + const updatedReactions = { ...reactions, [index]: currentReaction === emoji ? undefined : emoji }; + setReactions(updatedReactions); + saveReactionsToLocalStorage(updatedReactions); + setShowReactions(null); + }; const groupedMessages = groupMessages(messages); let lastTimeDisplayed: string | null = null; + useEffect(() => { + if (scrollRef.current) { + scrollRef.current.scrollIntoView({ behavior: 'smooth' }); + } + }, [messages]); + return (
{groupedMessages.map((group, groupIndex) => { @@ -59,33 +96,84 @@ const MessageList: React.FC = ({ messages }) => {
)} - {group.messages.map((message, idx) => ( -
- {message.senderId !== currentUser?.userId && ( -
- {idx === 0 && ( -
- Profile -

- {opponentUser?.userName || '(알 수 없음)'} -

-
- )} -

- {message.text} -

-
- )} - {message.senderId === currentUser?.userId && ( -

- {message.text} -

- )} +{group.messages.map((message, idx) => { + const messageIndex = groupIndex * 100 + idx; + const isCurrentUser = message.senderId === currentUser?.userId; + + return ( +
handleDoubleClick(messageIndex, e)} + style={{ userSelect: 'none'}} + > + {/* 상대방 메시지 렌더링 */} + {!isCurrentUser && ( +
+ {idx === 0 && ( +
+ Profile +

+ {opponentUser?.userName || '(알 수 없음)'} +

+
+ )} +
+

+ {message.text} +

+ {reactions[messageIndex] && ( +
+
+ Selected Reaction +
- ))} + )} +
+ {/* 리액션 바 */} + {showReactions === messageIndex && ( +
+ {[heartIcon, smileIcon, ohIcon, tearIcon, angerIcon, thumbIcon].map((emoji, i) => ( + handleSelectEmoji(messageIndex, emoji)} + > + Reaction + + ))} + AddReaction +
+ )} +
+ )} + + {/* 본인 메시지 렌더링 */} + {isCurrentUser && ( +
+

+ {message.text} +

+ {reactions[messageIndex] && ( +
+
+ Selected Reaction +
+
+ )} +
+ )} +
+ ); +})}
); })} From 5a45108ee0bd0f8dbaed75c22442e69f2f95ee84 Mon Sep 17 00:00:00 2001 From: Gabin Lee Date: Fri, 1 Nov 2024 16:58:47 +0900 Subject: [PATCH 54/54] =?UTF-8?q?Remove:=20=EC=95=88=20=EC=93=B0=EB=8A=94?= =?UTF-8?q?=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20?= =?UTF-8?q?=ED=8F=B4=EB=8D=94=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/data/messages.json | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 public/data/messages.json diff --git a/public/data/messages.json b/public/data/messages.json deleted file mode 100644 index 591c93a..0000000 --- a/public/data/messages.json +++ /dev/null @@ -1,12 +0,0 @@ -[ - { - "senderId": 0, - "text": "안녕하세요!", - "timestamp": "2024-09-25T12:34:56Z" - }, - { - "senderId": 1, - "text": "네~안녕하세용", - "timestamp": "2024-09-25T12:35:00Z" - } -] \ No newline at end of file