From d9ffa5ee8c5cba1268adfe6888b312064373f728 Mon Sep 17 00:00:00 2001 From: 14Kgun Date: Sat, 15 Jul 2023 20:55:21 +0900 Subject: [PATCH 01/17] Move: pages/Chatting to components --- .../chatting-components}/Container/index.tsx | 0 .../Header/FullChatHeader.jsx | 2 +- .../Header/HeaderBody.jsx | 0 .../Header/Popup/PopupCancel.jsx | 0 .../Header/Popup/PopupContainer.jsx | 0 .../Header/Popup/PopupPay.jsx | 0 .../Header/Popup/PopupSend.jsx | 0 .../Header/SideChatHeader.jsx | 0 .../chatting-components}/Header/index.tsx | 0 .../MessageForm/FullChatMessageForm.tsx | 10 +- .../MessageForm/NewMessage.tsx | 0 .../MessageForm/Popup/PopupAccount.tsx | 0 .../MessageForm/index.tsx | 6 +- .../MessagesBody/ChatDate.jsx | 0 .../MessagesBody/ChatInOut.jsx | 0 .../MessagesBody/ChatPaySettle.tsx | 0 .../MessagesBody/ChatSet.jsx | 2 +- .../MessagesBody/ImageFullscreen.jsx | 0 .../MessagesBody/index.jsx | 14 +-- .../chatting-hooks/useSendMessage.tsx | 68 ++++++++++++++ .../Chatting/chatting-utils/chats.ts} | 6 +- .../Chatting/chatting-utils/scroll.ts | 16 ++++ src/components/Chatting/index.tsx | 94 +++++++++++++++++++ src/pages/Chatting/FullChat.tsx | 16 ---- src/pages/Chatting/SideChat.tsx | 25 ----- src/pages/Chatting/{index.jsx => dump.jsx} | 0 src/pages/Chatting/index.tsx | 10 ++ src/pages/Myroom/R2Myroom.jsx | 5 +- src/routes.ts | 2 +- 29 files changed, 212 insertions(+), 64 deletions(-) rename src/{pages/Chatting => components/Chatting/chatting-components}/Container/index.tsx (100%) rename src/{pages/Chatting => components/Chatting/chatting-components}/Header/FullChatHeader.jsx (98%) rename src/{pages/Chatting => components/Chatting/chatting-components}/Header/HeaderBody.jsx (100%) rename src/{pages/Chatting => components/Chatting/chatting-components}/Header/Popup/PopupCancel.jsx (100%) rename src/{pages/Chatting => components/Chatting/chatting-components}/Header/Popup/PopupContainer.jsx (100%) rename src/{pages/Chatting => components/Chatting/chatting-components}/Header/Popup/PopupPay.jsx (100%) rename src/{pages/Chatting => components/Chatting/chatting-components}/Header/Popup/PopupSend.jsx (100%) rename src/{pages/Chatting => components/Chatting/chatting-components}/Header/SideChatHeader.jsx (100%) rename src/{pages/Chatting => components/Chatting/chatting-components}/Header/index.tsx (100%) rename src/{pages/Chatting => components/Chatting/chatting-components}/MessageForm/FullChatMessageForm.tsx (95%) rename src/{pages/Chatting => components/Chatting/chatting-components}/MessageForm/NewMessage.tsx (100%) rename src/{pages/Chatting => components/Chatting/chatting-components}/MessageForm/Popup/PopupAccount.tsx (100%) rename src/{pages/Chatting => components/Chatting/chatting-components}/MessageForm/index.tsx (90%) rename src/{pages/Chatting => components/Chatting/chatting-components}/MessagesBody/ChatDate.jsx (100%) rename src/{pages/Chatting => components/Chatting/chatting-components}/MessagesBody/ChatInOut.jsx (100%) rename src/{pages/Chatting => components/Chatting/chatting-components}/MessagesBody/ChatPaySettle.tsx (100%) rename src/{pages/Chatting => components/Chatting/chatting-components}/MessagesBody/ChatSet.jsx (99%) rename src/{pages/Chatting => components/Chatting/chatting-components}/MessagesBody/ImageFullscreen.jsx (100%) rename src/{pages/Chatting => components/Chatting/chatting-components}/MessagesBody/index.jsx (89%) create mode 100644 src/components/Chatting/chatting-hooks/useSendMessage.tsx rename src/{pages/Chatting/utils.ts => components/Chatting/chatting-utils/chats.ts} (67%) create mode 100644 src/components/Chatting/chatting-utils/scroll.ts create mode 100644 src/components/Chatting/index.tsx delete mode 100644 src/pages/Chatting/FullChat.tsx delete mode 100644 src/pages/Chatting/SideChat.tsx rename src/pages/Chatting/{index.jsx => dump.jsx} (100%) create mode 100644 src/pages/Chatting/index.tsx diff --git a/src/pages/Chatting/Container/index.tsx b/src/components/Chatting/chatting-components/Container/index.tsx similarity index 100% rename from src/pages/Chatting/Container/index.tsx rename to src/components/Chatting/chatting-components/Container/index.tsx diff --git a/src/pages/Chatting/Header/FullChatHeader.jsx b/src/components/Chatting/chatting-components/Header/FullChatHeader.jsx similarity index 98% rename from src/pages/Chatting/Header/FullChatHeader.jsx rename to src/components/Chatting/chatting-components/Header/FullChatHeader.jsx index c31408999..1998c64e1 100644 --- a/src/pages/Chatting/Header/FullChatHeader.jsx +++ b/src/components/Chatting/chatting-components/Header/FullChatHeader.jsx @@ -1,6 +1,6 @@ import PropTypes from "prop-types"; import { useEffect, useRef, useState } from "react"; -import { useHistory } from "react-router"; +import { useHistory } from "react-router-dom"; import { useR2state } from "hooks/useReactiveState"; diff --git a/src/pages/Chatting/Header/HeaderBody.jsx b/src/components/Chatting/chatting-components/Header/HeaderBody.jsx similarity index 100% rename from src/pages/Chatting/Header/HeaderBody.jsx rename to src/components/Chatting/chatting-components/Header/HeaderBody.jsx diff --git a/src/pages/Chatting/Header/Popup/PopupCancel.jsx b/src/components/Chatting/chatting-components/Header/Popup/PopupCancel.jsx similarity index 100% rename from src/pages/Chatting/Header/Popup/PopupCancel.jsx rename to src/components/Chatting/chatting-components/Header/Popup/PopupCancel.jsx diff --git a/src/pages/Chatting/Header/Popup/PopupContainer.jsx b/src/components/Chatting/chatting-components/Header/Popup/PopupContainer.jsx similarity index 100% rename from src/pages/Chatting/Header/Popup/PopupContainer.jsx rename to src/components/Chatting/chatting-components/Header/Popup/PopupContainer.jsx diff --git a/src/pages/Chatting/Header/Popup/PopupPay.jsx b/src/components/Chatting/chatting-components/Header/Popup/PopupPay.jsx similarity index 100% rename from src/pages/Chatting/Header/Popup/PopupPay.jsx rename to src/components/Chatting/chatting-components/Header/Popup/PopupPay.jsx diff --git a/src/pages/Chatting/Header/Popup/PopupSend.jsx b/src/components/Chatting/chatting-components/Header/Popup/PopupSend.jsx similarity index 100% rename from src/pages/Chatting/Header/Popup/PopupSend.jsx rename to src/components/Chatting/chatting-components/Header/Popup/PopupSend.jsx diff --git a/src/pages/Chatting/Header/SideChatHeader.jsx b/src/components/Chatting/chatting-components/Header/SideChatHeader.jsx similarity index 100% rename from src/pages/Chatting/Header/SideChatHeader.jsx rename to src/components/Chatting/chatting-components/Header/SideChatHeader.jsx diff --git a/src/pages/Chatting/Header/index.tsx b/src/components/Chatting/chatting-components/Header/index.tsx similarity index 100% rename from src/pages/Chatting/Header/index.tsx rename to src/components/Chatting/chatting-components/Header/index.tsx diff --git a/src/pages/Chatting/MessageForm/FullChatMessageForm.tsx b/src/components/Chatting/chatting-components/MessageForm/FullChatMessageForm.tsx similarity index 95% rename from src/pages/Chatting/MessageForm/FullChatMessageForm.tsx rename to src/components/Chatting/chatting-components/MessageForm/FullChatMessageForm.tsx index 739daa83e..694429eb5 100644 --- a/src/pages/Chatting/MessageForm/FullChatMessageForm.tsx +++ b/src/components/Chatting/chatting-components/MessageForm/FullChatMessageForm.tsx @@ -65,9 +65,9 @@ const BtnLeft = (props: BtnLeftProps) => { }; type FullChatMessageFormProps = { - handleSendMessage: (message: string) => boolean; - handleSendImage: (image: File) => void; - handleSendAccount: (account: string) => boolean; + handleSendMessage: (message: string) => Promise; + handleSendImage: (image: File) => Promise; + handleSendAccount: (account: string) => Promise; setContHeight: (height: PixelValue) => void; }; @@ -85,10 +85,10 @@ const FullChatMessageForm = (props: FullChatMessageFormProps) => { const isMessageValid = () => { return regExpTest.chatMsg(message); }; - const onSend = () => { + const onSend = async () => { textareaRef.current?.focus(); if (isMessageValid()) { - const result = props.handleSendMessage(message); + const result = await props.handleSendMessage(message); if (result) setMessage(""); } }; diff --git a/src/pages/Chatting/MessageForm/NewMessage.tsx b/src/components/Chatting/chatting-components/MessageForm/NewMessage.tsx similarity index 100% rename from src/pages/Chatting/MessageForm/NewMessage.tsx rename to src/components/Chatting/chatting-components/MessageForm/NewMessage.tsx diff --git a/src/pages/Chatting/MessageForm/Popup/PopupAccount.tsx b/src/components/Chatting/chatting-components/MessageForm/Popup/PopupAccount.tsx similarity index 100% rename from src/pages/Chatting/MessageForm/Popup/PopupAccount.tsx rename to src/components/Chatting/chatting-components/MessageForm/Popup/PopupAccount.tsx diff --git a/src/pages/Chatting/MessageForm/index.tsx b/src/components/Chatting/chatting-components/MessageForm/index.tsx similarity index 90% rename from src/pages/Chatting/MessageForm/index.tsx rename to src/components/Chatting/chatting-components/MessageForm/index.tsx index d4ea3379f..d64840134 100644 --- a/src/pages/Chatting/MessageForm/index.tsx +++ b/src/components/Chatting/chatting-components/MessageForm/index.tsx @@ -11,9 +11,9 @@ import theme from "tools/theme"; type MessageFormProps = { layoutType: "sidechat" | "fullchat"; showNewMessage: boolean; - handleSendMessage: (message: string) => boolean; - handleSendImage: (image: File) => void; - handleSendAccount: (account: string) => boolean; + handleSendMessage: (message: string) => Promise; + handleSendImage: (image: File) => Promise; + handleSendAccount: (account: string) => Promise; onClickNewMessage: () => void; setContHeight: (height: PixelValue) => void; }; diff --git a/src/pages/Chatting/MessagesBody/ChatDate.jsx b/src/components/Chatting/chatting-components/MessagesBody/ChatDate.jsx similarity index 100% rename from src/pages/Chatting/MessagesBody/ChatDate.jsx rename to src/components/Chatting/chatting-components/MessagesBody/ChatDate.jsx diff --git a/src/pages/Chatting/MessagesBody/ChatInOut.jsx b/src/components/Chatting/chatting-components/MessagesBody/ChatInOut.jsx similarity index 100% rename from src/pages/Chatting/MessagesBody/ChatInOut.jsx rename to src/components/Chatting/chatting-components/MessagesBody/ChatInOut.jsx diff --git a/src/pages/Chatting/MessagesBody/ChatPaySettle.tsx b/src/components/Chatting/chatting-components/MessagesBody/ChatPaySettle.tsx similarity index 100% rename from src/pages/Chatting/MessagesBody/ChatPaySettle.tsx rename to src/components/Chatting/chatting-components/MessagesBody/ChatPaySettle.tsx diff --git a/src/pages/Chatting/MessagesBody/ChatSet.jsx b/src/components/Chatting/chatting-components/MessagesBody/ChatSet.jsx similarity index 99% rename from src/pages/Chatting/MessagesBody/ChatSet.jsx rename to src/components/Chatting/chatting-components/MessagesBody/ChatSet.jsx index 8518b9992..fdc655780 100644 --- a/src/pages/Chatting/MessagesBody/ChatSet.jsx +++ b/src/components/Chatting/chatting-components/MessagesBody/ChatSet.jsx @@ -4,9 +4,9 @@ import { useCallback, useEffect, useState } from "react"; import LinkCopy from "components/Link/LinkCopy"; import ModalReportInChatting from "components/ModalPopup/ModalReportInChatting"; import ProfileImg from "components/User/ProfileImg"; -import ImageFullscreen from "pages/Chatting/MessagesBody/ImageFullscreen"; import ChatPaySettle from "./ChatPaySettle"; +import ImageFullscreen from "./ImageFullscreen"; import hoverEventSet from "tools/hoverEventSet"; import moment from "tools/moment"; diff --git a/src/pages/Chatting/MessagesBody/ImageFullscreen.jsx b/src/components/Chatting/chatting-components/MessagesBody/ImageFullscreen.jsx similarity index 100% rename from src/pages/Chatting/MessagesBody/ImageFullscreen.jsx rename to src/components/Chatting/chatting-components/MessagesBody/ImageFullscreen.jsx diff --git a/src/pages/Chatting/MessagesBody/index.jsx b/src/components/Chatting/chatting-components/MessagesBody/index.jsx similarity index 89% rename from src/pages/Chatting/MessagesBody/index.jsx rename to src/components/Chatting/chatting-components/MessagesBody/index.jsx index 1a31cf790..bc121b01d 100644 --- a/src/pages/Chatting/MessagesBody/index.jsx +++ b/src/components/Chatting/chatting-components/MessagesBody/index.jsx @@ -1,7 +1,7 @@ import PropTypes from "prop-types"; import { useMemo } from "react"; -import { getChatUnquewKey } from "../utils"; +import { getChatUniquewKey } from "../../chatting-utils/chats"; import ChatDate from "./ChatDate"; import ChatInOut from "./ChatInOut"; import ChatSet from "./ChatSet"; @@ -33,7 +33,7 @@ const MessagesBody = (props) => { if (chatsCache) { list.push( @@ -54,7 +54,7 @@ const MessagesBody = (props) => { if (chatsCache) { list.push( @@ -70,7 +70,7 @@ const MessagesBody = (props) => { if (chatsCache) { list.push( @@ -79,7 +79,7 @@ const MessagesBody = (props) => { } list.push( @@ -97,7 +97,7 @@ const MessagesBody = (props) => { ) { list.push( @@ -112,7 +112,7 @@ const MessagesBody = (props) => { if (chatsCache) { list.push( diff --git a/src/components/Chatting/chatting-hooks/useSendMessage.tsx b/src/components/Chatting/chatting-hooks/useSendMessage.tsx new file mode 100644 index 000000000..34dfe8c11 --- /dev/null +++ b/src/components/Chatting/chatting-hooks/useSendMessage.tsx @@ -0,0 +1,68 @@ +import { MutableRefObject, useCallback } from "react"; + +import { useAxios } from "hooks/useTaxiAPI"; + +import alertAtom from "atoms/alert"; +import { useSetRecoilState } from "recoil"; + +import convertImg from "tools/convertImg"; +import regExpTest from "tools/regExpTest"; + +export default ( + roomId: string, + isSendingMessage: MutableRefObject +) => { + const axios = useAxios(); + const setAlert = useSetRecoilState(alertAtom); + return useCallback( + async ( + type: "text" | "account" | "image", + { text, file }: { text?: string; file?: File } + ): Promise => { + // 메시지 전송 중이라면 중복 전송을 막습니다. + if (isSendingMessage.current) return false; + + try { + if (["text", "account"].includes(type)) { + // 메시지가 정규식 검사에서 통과하지 못했다면 전송을 막습니다. + if (!text) throw new Error(); + if (type === "text" && !regExpTest.chatMsg(text)) throw new Error(); + if (type === "account" && !regExpTest.account(text)) + throw new Error(); + + isSendingMessage.current = true; + const { result } = await axios({ + url: "/chats/send", + method: "post", + data: { roomId, type, content: text }, + }); + if (result) return true; + } + + if (type === "image") { + isSendingMessage.current = true; + const image = await convertImg(file); + if (!image) throw new Error(); + + // TODO : 이미지 전송 + // axios({ + // url: "chats/uploadChatImg/getPUrl", + // method: "post", + // data: { roomId, type: image.type }, + // onSuccess: ({ url, fields, id }) => { + + // }, + // }); + return true; + } + } catch (e) { + console.error(e); + } + + setAlert("메시지 전송에 실패하였습니다."); + isSendingMessage.current = false; + return false; + }, + [roomId, axios, setAlert] + ); +}; diff --git a/src/pages/Chatting/utils.ts b/src/components/Chatting/chatting-utils/chats.ts similarity index 67% rename from src/pages/Chatting/utils.ts rename to src/components/Chatting/chatting-utils/chats.ts index ee6255802..c664f37b9 100644 --- a/src/pages/Chatting/utils.ts +++ b/src/components/Chatting/chatting-utils/chats.ts @@ -1,10 +1,12 @@ export const checkoutChat = { type: "inf-checkout" }; export type CheckoutChat = typeof checkoutChat; -export const getChatUnquewKey = (chat: Chat): string => { +// 채팅 메시지의 문자열 고유 값을 반환합니다. +export const getChatUniquewKey = (chat: Chat): string => { return `${chat.type}-${chat.authorId}-${chat.time}`; }; +// 중복된 채팅 메시지를 제거 후, 채팅 메시지 배열을 반환합니다. export const getCleanupChats = ( chats: Array ): Array => { @@ -13,7 +15,7 @@ export const getCleanupChats = ( chats.forEach((chat) => { if (chat.type !== "inf-checkout") { - const key = getChatUnquewKey(chat as Chat); + const key = getChatUniquewKey(chat as Chat); if (keySet.has(key)) return; keySet.add(key); } diff --git a/src/components/Chatting/chatting-utils/scroll.ts b/src/components/Chatting/chatting-utils/scroll.ts new file mode 100644 index 000000000..408e16242 --- /dev/null +++ b/src/components/Chatting/chatting-utils/scroll.ts @@ -0,0 +1,16 @@ +// 스크롤이 페이지 상단에 있는지 여부를 반환 (tol = 허용오차) +export const isTopOnScroll = (element: HTMLDivElement, tol: number = 0) => { + if (!element) return false; + const scrollTop = Math.max(element.scrollTop, 0); + return scrollTop <= tol; +}; + +// 스크롤이 페이지 하단에 있는지 여부를 반환 (tol = 허용오차) +export const isBottomOnScroll = (element: HTMLDivElement, tol: number = 0) => { + if (!element) return false; + const scrollHeight = element.scrollHeight; + const scrollTop = Math.max(element.scrollTop, 0); + const clientHeight = element.clientHeight; + const scrollBottom = Math.max(scrollHeight - clientHeight - scrollTop, 0); + return scrollBottom <= tol; +}; diff --git a/src/components/Chatting/index.tsx b/src/components/Chatting/index.tsx new file mode 100644 index 000000000..55658342c --- /dev/null +++ b/src/components/Chatting/index.tsx @@ -0,0 +1,94 @@ +import { useRef, useState } from "react"; + +import useDateToken from "hooks/useDateToken"; +import useDisableScrollEffect from "hooks/useDisableScrollEffect"; +import useQuery from "hooks/useTaxiAPI"; + +import Container from "./chatting-components/Container"; +import Header from "./chatting-components/Header"; +import MessageForm from "./chatting-components/MessageForm"; +import MessagesBody from "./chatting-components/MessagesBody"; +import useSendMessage from "./chatting-hooks/useSendMessage"; + +import theme from "tools/theme"; + +type ChattingProps = { + roomId: string; + layoutType: "sidechat" | "fullchat"; +}; +type FullChatProps = { + roomId: ChattingProps["roomId"]; +}; +type SideChatProps = { + roomId: ChattingProps["roomId"]; +}; + +const Chatting = ({ roomId, layoutType }: ChattingProps) => { + const isSendingMessage = useRef(false); // 메시지 전송 중인지 여부 + + // Remove me - move to child + const sendMessage = useSendMessage(roomId, isSendingMessage); + const handleSendMessage = (text: string) => sendMessage("text", { text }); + const handleSendAccount = (account: string) => + sendMessage("account", { text: account }); + const handleSendImage = (image: File) => + sendMessage("image", { file: image }); + + // Remove me - move to child + const [headerInfoToken, fetchHeaderInfo] = useDateToken(); + const [, headerInfo] = useQuery.get(`/rooms/info?id=${roomId}`, {}, [ + headerInfoToken, + ]); + + // Remove me - for test + const chats: Array = []; + const [isDisplayNewMessage] = useState(false); + + return ( + +
+ true} + // scrollToBottom={() => scrollToBottom(false)} + /> + {}} + setContHeight={() => {}} + /> + + ); +}; + +export const FullChat = ({ roomId }: FullChatProps) => { + // 전체화면 챗에서는 body의 스크롤을 막습니다. + useDisableScrollEffect(true); + + return ; +}; + +export const SideChat = ({ roomId }: SideChatProps) => ( +
+ +
+); diff --git a/src/pages/Chatting/FullChat.tsx b/src/pages/Chatting/FullChat.tsx deleted file mode 100644 index df4b4b4a2..000000000 --- a/src/pages/Chatting/FullChat.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { useParams } from "react-router-dom"; - -import useDisableScrollEffect from "hooks/useDisableScrollEffect"; - -import Chatting from "./index"; - -const FullChat = () => { - const { roomId } = useParams() as { roomId: string }; - - // 전체화면 챗에서는 body의 스크롤을 막습니다. - useDisableScrollEffect(true); - - return ; -}; - -export default FullChat; diff --git a/src/pages/Chatting/SideChat.tsx b/src/pages/Chatting/SideChat.tsx deleted file mode 100644 index afccf5580..000000000 --- a/src/pages/Chatting/SideChat.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import Chatting from "./index"; - -import theme from "tools/theme"; - -type SideChatProps = { - roomId: string; -}; - -const SideChat = ({ roomId }: SideChatProps) => ( -
- -
-); - -export default SideChat; diff --git a/src/pages/Chatting/index.jsx b/src/pages/Chatting/dump.jsx similarity index 100% rename from src/pages/Chatting/index.jsx rename to src/pages/Chatting/dump.jsx diff --git a/src/pages/Chatting/index.tsx b/src/pages/Chatting/index.tsx new file mode 100644 index 000000000..f7c76a8fa --- /dev/null +++ b/src/pages/Chatting/index.tsx @@ -0,0 +1,10 @@ +import { useParams } from "react-router-dom"; + +import { FullChat } from "components/Chatting"; + +const Chatting = () => { + const { roomId } = useParams() as { roomId: string }; + return ; +}; + +export default Chatting; diff --git a/src/pages/Myroom/R2Myroom.jsx b/src/pages/Myroom/R2Myroom.jsx index 7fbf5e885..84d1783bd 100644 --- a/src/pages/Myroom/R2Myroom.jsx +++ b/src/pages/Myroom/R2Myroom.jsx @@ -5,6 +5,7 @@ import { Link, useHistory } from "react-router-dom"; import useDateToken from "hooks/useDateToken"; import { useQuery } from "hooks/useTaxiAPI"; +import { SideChat } from "components/Chatting"; import DottedLine from "components/DottedLine"; import Empty from "components/Empty"; import { ModalRoomShare } from "components/ModalPopup"; @@ -13,8 +14,6 @@ import RLayout from "components/RLayout"; import Room from "components/Room"; import Title from "components/Title"; import WhiteContainer from "components/WhiteContainer"; -import ChatHeaderBody from "pages/Chatting/Header/HeaderBody"; -import SideChat from "pages/Chatting/SideChat"; import theme from "tools/theme"; @@ -66,7 +65,7 @@ const ChatHeader = (props) => { {isOpen && ( <> - + {/* TODO */} )} import("pages/Chatting/FullChat")), + component: lazy(() => import("pages/Chatting")), exact: true, }, { From 5ef96c32f3852a8dccc0ec2b139098104158b439 Mon Sep 17 00:00:00 2001 From: 14Kgun Date: Sun, 16 Jul 2023 04:55:17 +0900 Subject: [PATCH 02/17] Refactor: chatting-components/Header/SideChatHeader --- .../Header/FullChatHeader.jsx | 153 ----------- .../chatting-components/Header/HeaderBody.jsx | 249 ------------------ .../Header/SideChatHeader.jsx | 62 ----- .../chatting-components/Header/SideMenu.tsx | 40 +++ .../chatting-components/Header/index.tsx | 119 ++++++++- src/components/Chatting/index.tsx | 10 +- .../Skeleton/CSSVariablesProvider.tsx | 11 + src/components/Skeleton/index.tsx | 4 +- src/pages/Myroom/R2Myroom.jsx | 97 +------ src/pages/Myroom/index.jsx | 2 +- src/types/global.d.ts | 3 + 11 files changed, 184 insertions(+), 566 deletions(-) delete mode 100644 src/components/Chatting/chatting-components/Header/FullChatHeader.jsx delete mode 100644 src/components/Chatting/chatting-components/Header/HeaderBody.jsx delete mode 100644 src/components/Chatting/chatting-components/Header/SideChatHeader.jsx create mode 100644 src/components/Chatting/chatting-components/Header/SideMenu.tsx diff --git a/src/components/Chatting/chatting-components/Header/FullChatHeader.jsx b/src/components/Chatting/chatting-components/Header/FullChatHeader.jsx deleted file mode 100644 index 1998c64e1..000000000 --- a/src/components/Chatting/chatting-components/Header/FullChatHeader.jsx +++ /dev/null @@ -1,153 +0,0 @@ -import PropTypes from "prop-types"; -import { useEffect, useRef, useState } from "react"; -import { useHistory } from "react-router-dom"; - -import { useR2state } from "hooks/useReactiveState"; - -import DottedLine from "components/DottedLine"; -import { ModalRoomShare } from "components/ModalPopup"; - -import HeaderBody from "./HeaderBody"; - -import theme from "tools/theme"; - -import ArrowBackRoundedIcon from "@mui/icons-material/ArrowBackRounded"; -import CloseFullscreenRoundedIcon from "@mui/icons-material/CloseFullscreenRounded"; -import ShareRoundedIcon from "@mui/icons-material/ShareRounded"; -import UnfoldLessRoundedIcon from "@mui/icons-material/UnfoldLessRounded"; -import UnfoldMoreRoundedIcon from "@mui/icons-material/UnfoldMoreRounded"; - -const Header = (props) => { - const bodyRef = useRef(); - const [isOpen, setOpen] = useState(false); - const [isOpenShare, setIsOpenShare] = useState(false); - const [bodyHeight, setBodyHeight] = useState(0); - const history = useHistory(); - const reactiveState = useR2state(); - - const style = { - height: "calc(64px + max(5px, env(safe-area-inset-top)))", - }; - const styleBgd = { - position: "fixed", - top: "5px", - width: "100%", - height: "100%", - background: theme.black_40, - zIndex: theme.zIndex_nav - 1, - pointerEvents: isOpen ? "auto" : "none", - opacity: isOpen ? 1 : 0, - transition: "opacity 0.3s", - }; - const styleHeader = { - position: "absolute", - width: "100%", - overflow: "hidden", - background: theme.white, - boxShadow: theme.shadow_3, - zIndex: theme.zIndex_nav, - height: `${64 + (isOpen ? bodyHeight : 0)}px`, - paddingTop: "max(5px, env(safe-area-inset-top))", - transition: "height 0.3s", - }; - const styleHeaderTop = { - display: "flex", - justifyContent: "space-between", - alignItems: "center", - padding: "12px 20px", - minHeight: "40px", - }; - const styleIcon = { - fill: theme.purple, - ...theme.cursor(), - }; - const styleInfo = { - width: "100%", - rowGap: "5px", - margin: "0 8px 0 16px", - display: "flex", - flexDirection: "column", - minWidth: 0, - }; - const styleText = { - whiteSpace: "nowrap", - textOverflow: "ellipsis", - overflow: "hidden", - }; - - const resizeEvent = () => { - setBodyHeight(bodyRef.current?.clientHeight); - }; - useEffect(() => { - resizeEvent(); - window.addEventListener("resize", resizeEvent); - return () => window.removeEventListener("resize", resizeEvent); - }, [props.info]); - - return ( -
-
setOpen(false)} /> -
-
- history.replace("/myroom") - : () => history.goBack() - } - /> -
-
- {props.info?.name} -
-
- {props?.info?.from?.koName}  →   - {props?.info?.to?.koName} -
-
- setIsOpenShare(true)} - /> - {reactiveState !== 3 && ( - history.replace(`/myroom/${props.info?._id}`)} - /> - )} - {isOpen ? ( - setOpen(!isOpen)} - /> - ) : ( - setOpen(!isOpen)} - /> - )} -
-
- -
-
- -
-
- -
- ); -}; -Header.propTypes = { - info: PropTypes.any, - recallEvent: PropTypes.func, -}; - -export default Header; diff --git a/src/components/Chatting/chatting-components/Header/HeaderBody.jsx b/src/components/Chatting/chatting-components/Header/HeaderBody.jsx deleted file mode 100644 index f40e02849..000000000 --- a/src/components/Chatting/chatting-components/Header/HeaderBody.jsx +++ /dev/null @@ -1,249 +0,0 @@ -import PropTypes from "prop-types"; -import { useMemo, useState } from "react"; - -import ProfileImg from "components/User/ProfileImg"; - -import PopupCancel from "./Popup/PopupCancel"; -import PopupPay from "./Popup/PopupPay"; -import PopupSend from "./Popup/PopupSend"; - -import loginInfoAtom from "atoms/loginInfo"; -import { useRecoilValue } from "recoil"; - -import { date2str } from "tools/moment"; -import theme from "tools/theme"; - -import SendRoundedIcon from "@material-ui/icons/SendRounded"; -import LogoutRoundedIcon from "@mui/icons-material/LogoutRounded"; -import PaymentRoundedIcon from "@mui/icons-material/PaymentRounded"; - -const Info = (props) => ( -
-
- {props.title} -
-
- {props.children} -
-
-); -Info.propTypes = { - title: PropTypes.string, - alignDirection: PropTypes.oneOf(["left", "right"]), - children: PropTypes.node, -}; - -const User = (props) => { - const isSettlement = - props.info?.isSettlement === "paid" || props.info?.isSettlement === "sent"; - return ( -
-
- -
-
- {props.info?.nickname} - {props.isDeparted && !isSettlement ? ( - (미정산) - ) : null} -
-
- ); -}; -User.propTypes = { - info: PropTypes.object, - isDeparted: PropTypes.bool, -}; - -const ButtonBody = (props) => { - const style = { - display: "flex", - alignItems: "center", - columnGap: "4px", - borderRadius: "6px", - padding: "3px 5px 3px 6px", - background: props.disabled ? theme.gray_background : theme.purple, - ...theme.cursor(props.disabled), - }; - const styleText = { - ...theme.font10, - color: props.disabled ? theme.gray_text : theme.white, - }; - const styleIcon = { - fontSize: "15px", - fill: props.disabled ? theme.gray_text : theme.white, - }; - - const getIcon = (type) => { - switch (type) { - case "탑승취소": - return ; - case "결제하기" || "결제완료": - return ; - case "정산하기" || "정산완료": - return ; - } - }; - - return ( -
-
{props.type}
- {getIcon(props.type)} -
- ); -}; -ButtonBody.propTypes = { - type: PropTypes.string, - onClick: PropTypes.func, - disabled: PropTypes.bool, -}; -ButtonBody.defaultProps = { - onClick: () => {}, - disabled: false, -}; - -const Button = (props) => { - const [popupCancel, setPopupCancel] = useState(false); - const [popupPay, setPopupPay] = useState(false); - const [popupSend, setPopupSend] = useState(false); - return ( - <> -
- {!props.info?.isDeparted ? ( - setPopupCancel(true)} /> - ) : !props.info?.settlementTotal ? ( - setPopupPay(true)} /> - ) : props.isSettlementForMe === "paid" ? ( - - ) : props.isSettlementForMe === "send-required" ? ( - setPopupSend(true)} /> - ) : props.isSettlementForMe === "sent" ? ( - - ) : ( - <> - )} -
- setPopupCancel(false)} - /> - setPopupPay(false)} - recallEvent={props.recallEvent} - /> - setPopupSend(false)} - recallEvent={props.recallEvent} - /> - - ); -}; -Button.propTypes = { - isSettlementForMe: PropTypes.string, - recallEvent: PropTypes.func, - info: PropTypes.object, -}; - -const HeaderBody = (props) => { - const loginInfo = useRecoilValue(loginInfoAtom); - const users = props.info?.part ?? []; - const isSettlementForMe = useMemo( - () => - users.filter((user) => user._id === loginInfo?.oid)?.[0]?.isSettlement, - [loginInfo?.oid, JSON.stringify(users)] - ); - - return ( -
-
- - {date2str(props.info?.time)} - - - {props.info?.part.length}명 / {props.info?.maxPartLength}명 - -
-
-
- {users.map((item) => ( - - ))} -
-
-
- ); -}; - -HeaderBody.propTypes = { - info: PropTypes.any, - recallEvent: PropTypes.func, -}; -HeaderBody.defaultProps = { - recallEvent: () => {}, -}; - -export default HeaderBody; diff --git a/src/components/Chatting/chatting-components/Header/SideChatHeader.jsx b/src/components/Chatting/chatting-components/Header/SideChatHeader.jsx deleted file mode 100644 index 66b383189..000000000 --- a/src/components/Chatting/chatting-components/Header/SideChatHeader.jsx +++ /dev/null @@ -1,62 +0,0 @@ -import PropTypes from "prop-types"; -import { Link, useHistory } from "react-router-dom"; - -import theme from "tools/theme"; - -import ArrowBackRoundedIcon from "@mui/icons-material/ArrowBackRounded"; -import OpenInFullRoundedIcon from "@mui/icons-material/OpenInFullRounded"; - -const SideChatHeader = (props) => { - const history = useHistory(); - - const styleBox = { - background: theme.purple, - boxShadow: theme.shadow_3, - display: "flex", - alignItems: "center", - justifyContent: "space-between", - padding: "12px 20px", - }; - const styleIcon = { color: theme.white, ...theme.cursor() }; - const styleInfoWrap = { - display: "flex", - flexDirection: "column", - rowGap: "5px", - width: "100%", - margin: "0 8px 0 16px", - minWidth: "0px", - }; - const styleInfo = { - color: theme.white, - overflow: "hidden", - whiteSpace: "nowrap", - textOverflow: "ellipsis", - }; - - return ( -
- history.goBack()} - /> -
-
{props.info?.name}
-
- {props?.info?.from?.koName}  →  {props?.info?.to?.koName} -
-
- - - -
- ); -}; - -SideChatHeader.propTypes = { - info: PropTypes.object, -}; -SideChatHeader.defaultProps = { - info: {}, -}; - -export default SideChatHeader; diff --git a/src/components/Chatting/chatting-components/Header/SideMenu.tsx b/src/components/Chatting/chatting-components/Header/SideMenu.tsx new file mode 100644 index 000000000..81de690ef --- /dev/null +++ b/src/components/Chatting/chatting-components/Header/SideMenu.tsx @@ -0,0 +1,40 @@ +import theme from "tools/theme"; + +type SideMenuProps = { + isOpen: boolean; + setIsOpen: (x: boolean) => void; +}; + +const SideMenu = ({ isOpen, setIsOpen }: SideMenuProps) => { + const styleBackground = { + position: "absolute" as any, + top: 0, + left: 0, + width: "100%", + height: "100%", + background: theme.black_40, + zIndex: theme.zIndex_background, + pointerEvents: isOpen ? "auto" : ("none" as any), + opacity: isOpen ? 1 : 0, + transition: "opacity 0.3s", + }; + const style = { + position: "absolute" as any, + top: 0, + right: isOpen ? 0 : "calc(-100% + 60px)", + width: "calc(100% - 60px)", + height: "100%", + background: theme.white, + zIndex: theme.zIndex_background, + transition: "right 0.3s", + }; + + return ( + <> +
setIsOpen(false)}>
+
+ + ); +}; + +export default SideMenu; diff --git a/src/components/Chatting/chatting-components/Header/index.tsx b/src/components/Chatting/chatting-components/Header/index.tsx index 226293c35..554fb1c76 100644 --- a/src/components/Chatting/chatting-components/Header/index.tsx +++ b/src/components/Chatting/chatting-components/Header/index.tsx @@ -1,17 +1,118 @@ -import FullChatHeader from "./FullChatHeader"; -import SideChatHeader from "./SideChatHeader"; +import { useState } from "react"; +import { Link, useHistory } from "react-router-dom"; + +import { useR2state } from "hooks/useReactiveState"; + +import SideMenu from "./SideMenu"; + +import theme from "tools/theme"; + +import ArrowBackRoundedIcon from "@mui/icons-material/ArrowBackRounded"; +import CloseFullscreenRoundedIcon from "@mui/icons-material/CloseFullscreenRounded"; +import MenuRoundedIcon from "@mui/icons-material/MenuRounded"; +import OpenInFullRoundedIcon from "@mui/icons-material/OpenInFullRounded"; type HeaderProps = { layoutType: "sidechat" | "fullchat"; - info: any; // fixme - recallEvent?: () => void; // fixme + roomInfo: Nullable; + fetchRoomInfo: () => void; }; -const Header = ({ layoutType, info, recallEvent }: HeaderProps) => - layoutType === "sidechat" ? ( - - ) : ( - +const Header = ({ layoutType, roomInfo, fetchRoomInfo }: HeaderProps) => { + const history = useHistory(); + const reactiveState = useR2state(); + const [isOpenSideMenu, setIsOpenSideMenu] = useState(false); + + const style = { + overflow: "hidden", + background: layoutType === "fullchat" ? theme.white : theme.purple, + boxShadow: theme.shadow_3, + zIndex: theme.zIndex_nav, + height: "40px", + padding: "calc(max(5px, env(safe-area-inset-top)) + 12px) 20px 12px", + transition: "height 0.3s", + display: "flex", + gap: "16px", + alignItems: "center", + }; + const styleIconLarge = { + fill: layoutType === "fullchat" ? theme.purple : theme.white, + ...theme.cursor(), + width: "24px", + height: "24px", + }; + const styleIconSmall = { + ...styleIconLarge, + width: "22px", + height: "22px", + }; + const styleInfo = { + flexGrow: 1, + height: "40px", + display: "flex", + overflow: "hidden", + flexDirection: "column" as any, + justifyContent: "space-between", + }; + const styleName = { + color: layoutType === "fullchat" ? theme.purple : theme.white, + whiteSpace: "nowrap" as any, + textOverflow: "ellipsis", + overflow: "hidden", + ...theme.font18, + }; + const styleFromTo = { + color: layoutType === "fullchat" ? theme.gray_text : theme.white, + width: "100%", + whiteSpace: "nowrap" as any, + textOverflow: "ellipsis", + overflow: "hidden", + ...theme.font12, + }; + + if (!roomInfo) return null; + return ( + <> + +
+ history.replace("/myroom") + : () => history.goBack() + } + /> +
+
{roomInfo?.name}
+
+ {roomInfo?.from?.koName}  →   + {roomInfo?.to?.koName} +
+
+ {layoutType === "fullchat" && reactiveState !== 3 && ( + ({ + ...location, + pathname: `/myroom/${roomInfo?._id}`, + })} + replace + > + + + )} + {layoutType === "sidechat" && ( + + + + )} + setIsOpenSideMenu(true)} + /> +
+ ); +}; export default Header; diff --git a/src/components/Chatting/index.tsx b/src/components/Chatting/index.tsx index 55658342c..8ca9a6b97 100644 --- a/src/components/Chatting/index.tsx +++ b/src/components/Chatting/index.tsx @@ -35,9 +35,9 @@ const Chatting = ({ roomId, layoutType }: ChattingProps) => { sendMessage("image", { file: image }); // Remove me - move to child - const [headerInfoToken, fetchHeaderInfo] = useDateToken(); - const [, headerInfo] = useQuery.get(`/rooms/info?id=${roomId}`, {}, [ - headerInfoToken, + const [roomInfoToken, fetchRoomInfo] = useDateToken(); + const [, roomInfo] = useQuery.get(`/rooms/info?id=${roomId}`, {}, [ + roomInfoToken, ]); // Remove me - for test @@ -48,8 +48,8 @@ const Chatting = ({ roomId, layoutType }: ChattingProps) => {
{ ); }; +const syncScroll = () => { + const scrollY = Math.max(window.scrollY || 0, 0); + document.documentElement.style.setProperty( + "--window-scroll-y", + `${scrollY}px` + ); +}; + const CSSVariablesProvider = () => { useEffect(() => { syncHeight(); + syncScroll(); window.addEventListener("resize", syncHeight); + window.addEventListener("scroll", syncScroll); visualViewport?.addEventListener("resize", syncHeight); return () => { window.removeEventListener("resize", syncHeight); + window.removeEventListener("scroll", syncScroll); visualViewport?.removeEventListener("resize", syncHeight); }; }, []); diff --git a/src/components/Skeleton/index.tsx b/src/components/Skeleton/index.tsx index 2bfd0889c..568c95ab1 100644 --- a/src/components/Skeleton/index.tsx +++ b/src/components/Skeleton/index.tsx @@ -49,12 +49,10 @@ const Skeleton = ({ children }: SkeletonProps) => { agreeOnTermsOfService: isAgreeOnTermsOfService, deviceType, } = useValueRecoilState("loginInfo") || {}; + const { pathname } = useLocation(); const error = useRecoilValue(errorAtom); const isLoading = userId === null; - const location = useLocation(); - const { pathname } = location; - const [cookies, setCookies] = useCookies(["isOpposeSuggestApp"]); const isOpposeSuggestApp = !!cookies?.isOpposeSuggestApp; const isApp = useRecoilValue(isAppAtom) || deviceType === "app"; diff --git a/src/pages/Myroom/R2Myroom.jsx b/src/pages/Myroom/R2Myroom.jsx index 84d1783bd..27ff41592 100644 --- a/src/pages/Myroom/R2Myroom.jsx +++ b/src/pages/Myroom/R2Myroom.jsx @@ -1,14 +1,9 @@ import PropTypes from "prop-types"; -import { useState } from "react"; import { Link, useHistory } from "react-router-dom"; -import useDateToken from "hooks/useDateToken"; -import { useQuery } from "hooks/useTaxiAPI"; - import { SideChat } from "components/Chatting"; import DottedLine from "components/DottedLine"; import Empty from "components/Empty"; -import { ModalRoomShare } from "components/ModalPopup"; import Pagination, { PAGE_MAX_ITEMS } from "components/Pagination"; import RLayout from "components/RLayout"; import Room from "components/Room"; @@ -17,70 +12,6 @@ import WhiteContainer from "components/WhiteContainer"; import theme from "tools/theme"; -import ShareRoundedIcon from "@mui/icons-material/ShareRounded"; -import UnfoldLessRoundedIcon from "@mui/icons-material/UnfoldLessRounded"; -import UnfoldMoreRoundedIcon from "@mui/icons-material/UnfoldMoreRounded"; - -const ChatHeader = (props) => { - const [isOpen, setIsOpen] = useState(false); - const [isOpenShare, setIsOpenShare] = useState(false); - const [headerInfoToken, fetchHeaderInfo] = useDateToken(); - const [, headerInfo] = useQuery.get(`/rooms/info?id=${props.roomId}`, {}, [ - headerInfoToken, - ]); - - return ( - -
- 채팅 창 - setIsOpenShare(true)} - /> - {isOpen ? ( - setIsOpen(false)} - /> - ) : ( - setIsOpen(true)} - /> - )} -
- {isOpen && ( - <> - - {/* TODO */} - - )} - -
- ); -}; - -ChatHeader.propTypes = { - roomId: PropTypes.string, -}; - const LinkRoom = (props) => { const history = useHistory(); @@ -88,7 +19,10 @@ const LinkRoom = (props) => {
history.goBack()}>{props.children}
) : ( ({ + ...location, + pathname: `/myroom/${props.id}`, + })} replace={props.currentId ? true : false} style={{ textDecoration: "none" }} > @@ -116,10 +50,10 @@ const R2Myroom = (props) => { > 내 방 보기 -
+
참여 중인 방 -
+
{props.ongoing.length === 0 ? ( 참여 중인 방이 없습니다 @@ -142,7 +76,7 @@ const R2Myroom = (props) => { 과거 참여 방 -
+
{props.done.length === 0 ? ( 과거 참여했던 방이 없습니다 @@ -180,24 +114,19 @@ const R2Myroom = (props) => { right={ props.roomId ? (
- -
- - - -
+ + +
) : null } diff --git a/src/pages/Myroom/index.jsx b/src/pages/Myroom/index.jsx index f4b14f3ae..c0ac0477f 100644 --- a/src/pages/Myroom/index.jsx +++ b/src/pages/Myroom/index.jsx @@ -31,7 +31,7 @@ const Myroom = () => { if (reactiveState == 3 && roomId) { history.replace(`/chatting/${roomId}`); } - }, [reactiveState, roomId, history]); + }, [reactiveState, roomId]); return !isLogin ? ( diff --git a/src/types/global.d.ts b/src/types/global.d.ts index 720d2a040..739ada007 100644 --- a/src/types/global.d.ts +++ b/src/types/global.d.ts @@ -1,9 +1,11 @@ +import { Location as _RouterLocation } from "history"; import { CSSProperties } from "react"; export {}; declare global { type Nullable = T | null | undefined; + type RouterLocation = _RouterLocation; type CSS = CSSProperties; type PixelValue = "0" | `${number}px`; type Margin = @@ -24,6 +26,7 @@ declare global { profileImageUrl: string; }; type Room = { + _id: string; name: string; from: Location; to: Location; From 8698d4c922242f1e371a66631365baef976f2f43 Mon Sep 17 00:00:00 2001 From: 14Kgun Date: Sun, 16 Jul 2023 14:50:26 +0900 Subject: [PATCH 03/17] Add: useSocketChatEffect --- .../chatting-components/Header/SideMenu.tsx | 36 +++++- .../chatting-components/Header/index.tsx | 17 ++- .../chatting-hooks/useSocketChatEffect.tsx | 106 ++++++++++++++++++ .../Chatting/chatting-utils/chats.ts | 1 + src/components/Chatting/index.tsx | 18 ++- 5 files changed, 165 insertions(+), 13 deletions(-) create mode 100644 src/components/Chatting/chatting-hooks/useSocketChatEffect.tsx diff --git a/src/components/Chatting/chatting-components/Header/SideMenu.tsx b/src/components/Chatting/chatting-components/Header/SideMenu.tsx index 81de690ef..cd8a8d0ed 100644 --- a/src/components/Chatting/chatting-components/Header/SideMenu.tsx +++ b/src/components/Chatting/chatting-components/Header/SideMenu.tsx @@ -1,11 +1,22 @@ +import DottedLine from "components/DottedLine"; + import theme from "tools/theme"; +import ArrowForwardRounded from "@mui/icons-material/ArrowForwardRounded"; + type SideMenuProps = { + roomInfo: Room; + fetchRoomInfo: () => void; isOpen: boolean; setIsOpen: (x: boolean) => void; }; -const SideMenu = ({ isOpen, setIsOpen }: SideMenuProps) => { +const SideMenu = ({ + roomInfo, + fetchRoomInfo, + isOpen, + setIsOpen, +}: SideMenuProps) => { const styleBackground = { position: "absolute" as any, top: 0, @@ -24,15 +35,34 @@ const SideMenu = ({ isOpen, setIsOpen }: SideMenuProps) => { right: isOpen ? 0 : "calc(-100% + 60px)", width: "calc(100% - 60px)", height: "100%", + padding: "16px", + boxSizing: "border-box" as any, background: theme.white, - zIndex: theme.zIndex_background, + zIndex: theme.zIndex_modal - 1, transition: "right 0.3s", }; + const styleNameSection = { + margin: "0 8px 16px", + display: "flex", + alignItems: "center", + gap: "12px", + }; return ( <>
setIsOpen(false)}>
-
+
+
+ setIsOpen(false)} + /> +
+ {roomInfo.name} +
+
+ +
); }; diff --git a/src/components/Chatting/chatting-components/Header/index.tsx b/src/components/Chatting/chatting-components/Header/index.tsx index 554fb1c76..df68506fb 100644 --- a/src/components/Chatting/chatting-components/Header/index.tsx +++ b/src/components/Chatting/chatting-components/Header/index.tsx @@ -73,7 +73,12 @@ const Header = ({ layoutType, roomInfo, fetchRoomInfo }: HeaderProps) => { if (!roomInfo) return null; return ( <> - +
{ } />
-
{roomInfo?.name}
+
{roomInfo.name}
- {roomInfo?.from?.koName}  →   - {roomInfo?.to?.koName} + {roomInfo.from?.koName}  →   + {roomInfo.to?.koName}
{layoutType === "fullchat" && reactiveState !== 3 && ( ({ ...location, - pathname: `/myroom/${roomInfo?._id}`, + pathname: `/myroom/${roomInfo._id}`, })} replace > @@ -102,7 +107,7 @@ const Header = ({ layoutType, roomInfo, fetchRoomInfo }: HeaderProps) => { )} {layoutType === "sidechat" && ( - + )} diff --git a/src/components/Chatting/chatting-hooks/useSocketChatEffect.tsx b/src/components/Chatting/chatting-hooks/useSocketChatEffect.tsx new file mode 100644 index 000000000..54714eb84 --- /dev/null +++ b/src/components/Chatting/chatting-hooks/useSocketChatEffect.tsx @@ -0,0 +1,106 @@ +import { MutableRefObject, useEffect } from "react"; + +import { useValueRecoilState } from "hooks/useFetchRecoilState"; +import { useAxios } from "hooks/useTaxiAPI"; + +import { Chats, checkoutChat, getCleanupChats } from "../chatting-utils/chats"; + +import { + registerSocketEventListener, + resetSocketEventListener, + socketReady, +} from "tools/socket"; + +export default ( + roomId: string, + setChats: any, // fixme + setDisplayNewMessage: any, + isSendingMessage: MutableRefObject, + isCallingInfScroll: MutableRefObject +) => { + const axios = useAxios(); + const { oid: userOid } = useValueRecoilState("loginInfo") || {}; + + // remove me + const scrollToBottom = (x?: boolean) => {}; + const isBottomOnScroll = () => true; + + useEffect(() => { + let isExpired: boolean = false; + isSendingMessage.current = true; + + socketReady(() => { + if (isExpired) return; + + // socket event listener 등록 + registerSocketEventListener({ + initListener: (chats) => { + if (isExpired) return; + isSendingMessage.current = false; + + setChats(getCleanupChats(chats), () => { + scrollToBottom(); + isCallingInfScroll.current = false; + }); + }, + reconnectListener: () => { + if (isExpired) return; + setChats((prevChats: Chats) => { + const lastMsg = prevChats[prevChats.length - 1] as Chat; + axios({ + url: "/chats/load/after", + method: "post", + data: { roomId, lastMsgDate: lastMsg.time }, + }); + return prevChats; + }); + }, + pushBackListener: (chats) => { + if (isExpired) return; + + const isMyMsg = chats.some((chat) => chat.authorId === userOid); + if (isMyMsg) isSendingMessage.current = false; + + if (chats.length > 10) { + axios({ + url: "/chats/load/after", + method: "post", + data: { + roomId, + lastMsgDate: chats[chats.length - 1].time, + }, + }); + } + setChats( + (prevChats: Chats) => getCleanupChats([...prevChats, ...chats]), + isMyMsg || isBottomOnScroll() + ? () => scrollToBottom(true) + : () => setDisplayNewMessage(true) + ); + }, + pushFrontListener: (chats) => { + if (isExpired) return; + + if (chats.length === 0) { + isCallingInfScroll.current = false; + return; + } + setChats((prevChats: Chats) => + getCleanupChats([...chats, checkoutChat, ...prevChats]) + ); + }, + }); + + // 채팅 로드 API 호출 + axios({ + url: "/chats", + method: "post", + data: { roomId }, + }); + }); + return () => { + isExpired = true; + resetSocketEventListener(); + }; + }, [roomId, setChats, setDisplayNewMessage]); +}; diff --git a/src/components/Chatting/chatting-utils/chats.ts b/src/components/Chatting/chatting-utils/chats.ts index c664f37b9..ef908910c 100644 --- a/src/components/Chatting/chatting-utils/chats.ts +++ b/src/components/Chatting/chatting-utils/chats.ts @@ -1,5 +1,6 @@ export const checkoutChat = { type: "inf-checkout" }; export type CheckoutChat = typeof checkoutChat; +export type Chats = Array; // 채팅 메시지의 문자열 고유 값을 반환합니다. export const getChatUniquewKey = (chat: Chat): string => { diff --git a/src/components/Chatting/index.tsx b/src/components/Chatting/index.tsx index 8ca9a6b97..cbcaa2afd 100644 --- a/src/components/Chatting/index.tsx +++ b/src/components/Chatting/index.tsx @@ -1,4 +1,5 @@ import { useRef, useState } from "react"; +import { useStateWithCallbackLazy } from "use-state-with-callback"; import useDateToken from "hooks/useDateToken"; import useDisableScrollEffect from "hooks/useDisableScrollEffect"; @@ -9,6 +10,8 @@ import Header from "./chatting-components/Header"; import MessageForm from "./chatting-components/MessageForm"; import MessagesBody from "./chatting-components/MessagesBody"; import useSendMessage from "./chatting-hooks/useSendMessage"; +import useSocketChatEffect from "./chatting-hooks/useSocketChatEffect"; +import { Chats } from "./chatting-utils/chats"; import theme from "tools/theme"; @@ -24,7 +27,18 @@ type SideChatProps = { }; const Chatting = ({ roomId, layoutType }: ChattingProps) => { + const [chats, setChats] = useStateWithCallbackLazy([]); // 채팅 메시지 배열 + const [isDisplayNewMessage, setDisplayNewMessage] = useState(false); // 새로운 메시지 버튼 표시 여부 const isSendingMessage = useRef(false); // 메시지 전송 중인지 여부 + const isCallingInfScroll = useRef(false); // 무한 스크롤 메시지 요청 중인지 여부 + + useSocketChatEffect( + roomId, + setChats, + setDisplayNewMessage, + isSendingMessage, + isCallingInfScroll + ); // Remove me - move to child const sendMessage = useSendMessage(roomId, isSendingMessage); @@ -40,10 +54,6 @@ const Chatting = ({ roomId, layoutType }: ChattingProps) => { roomInfoToken, ]); - // Remove me - for test - const chats: Array = []; - const [isDisplayNewMessage] = useState(false); - return (
Date: Tue, 18 Jul 2023 12:19:50 +0900 Subject: [PATCH 04/17] Add: https://github.com/sparcs-kaist/taxi-front/pull/594 --- .eslintrc.json | 5 +- .prettierrc.json | 1 + .../chatting-components/Header/index.tsx | 4 +- .../{FullChatMessageForm.tsx => Form.tsx} | 31 +- .../MessageForm/NewMessage.tsx | 50 ++- .../chatting-components/MessageForm/index.tsx | 79 ++--- .../MessagesBody/index.tsx | 33 ++ .../useBodyScrollControllerEffect.tsx | 59 ++++ .../useChatsForBody.tsx} | 80 ++--- .../chatting-hooks/useSocketChatEffect.tsx | 63 ++-- .../Chatting/chatting-utils/scroll.ts | 20 +- src/components/Chatting/index.tsx | 49 +-- src/pages/Chatting/dump.jsx | 332 ------------------ src/types/chatting.d.ts | 1 + 14 files changed, 279 insertions(+), 528 deletions(-) rename src/components/Chatting/chatting-components/MessageForm/{FullChatMessageForm.tsx => Form.tsx} (88%) create mode 100644 src/components/Chatting/chatting-components/MessagesBody/index.tsx create mode 100644 src/components/Chatting/chatting-hooks/useBodyScrollControllerEffect.tsx rename src/components/Chatting/{chatting-components/MessagesBody/index.jsx => chatting-hooks/useChatsForBody.tsx} (63%) delete mode 100644 src/pages/Chatting/dump.jsx create mode 100644 src/types/chatting.d.ts diff --git a/.eslintrc.json b/.eslintrc.json index 2952d687d..867e5a0fb 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -24,10 +24,7 @@ "rules": { "no-unused-vars": 1, "react/react-in-jsx-scope": "off", - "react/no-unknown-property": [ - "error", - { "ignore": ["chatcheckout", "css"] } - ] + "react/no-unknown-property": ["error", { "ignore": ["css"] }] }, "overrides": [ { diff --git a/.prettierrc.json b/.prettierrc.json index 36a276f06..fdda59da3 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -14,6 +14,7 @@ "singleQuote": false, "importOrder": [ "", + "^types/", "^hooks/", "^components/|^pages/", "^[./]", diff --git a/src/components/Chatting/chatting-components/Header/index.tsx b/src/components/Chatting/chatting-components/Header/index.tsx index df68506fb..4693e8420 100644 --- a/src/components/Chatting/chatting-components/Header/index.tsx +++ b/src/components/Chatting/chatting-components/Header/index.tsx @@ -1,6 +1,8 @@ import { useState } from "react"; import { Link, useHistory } from "react-router-dom"; +import { LayoutType } from "types/chatting"; + import { useR2state } from "hooks/useReactiveState"; import SideMenu from "./SideMenu"; @@ -13,7 +15,7 @@ import MenuRoundedIcon from "@mui/icons-material/MenuRounded"; import OpenInFullRoundedIcon from "@mui/icons-material/OpenInFullRounded"; type HeaderProps = { - layoutType: "sidechat" | "fullchat"; + layoutType: LayoutType; roomInfo: Nullable; fetchRoomInfo: () => void; }; diff --git a/src/components/Chatting/chatting-components/MessageForm/FullChatMessageForm.tsx b/src/components/Chatting/chatting-components/MessageForm/Form.tsx similarity index 88% rename from src/components/Chatting/chatting-components/MessageForm/FullChatMessageForm.tsx rename to src/components/Chatting/chatting-components/MessageForm/Form.tsx index 694429eb5..3175a10ff 100644 --- a/src/components/Chatting/chatting-components/MessageForm/FullChatMessageForm.tsx +++ b/src/components/Chatting/chatting-components/MessageForm/Form.tsx @@ -1,5 +1,6 @@ import { useEffect, useRef, useState } from "react"; +import useSendMessage from "../../chatting-hooks/useSendMessage"; import PopupAccount from "./Popup/PopupAccount"; import regExpTest from "tools/regExpTest"; @@ -15,8 +16,8 @@ type BtnSendProps = { }; const BtnSend = (props: BtnSendProps) => { - const style: CSS = { - position: "absolute", + const style = { + position: "absolute" as any, width: "28px", height: "28px", bottom: "2px", @@ -27,7 +28,7 @@ const BtnSend = (props: BtnSendProps) => { ...theme.cursor(!props.enable), }; return ( -
+
{ }; const styleIcon = { width: "100%", height: "100%", fill: theme.gray_text }; return ( -
+
{props.type === "image" ? ( ) : ( @@ -65,13 +66,10 @@ const BtnLeft = (props: BtnLeftProps) => { }; type FullChatMessageFormProps = { - handleSendMessage: (message: string) => Promise; - handleSendImage: (image: File) => Promise; - handleSendAccount: (account: string) => Promise; - setContHeight: (height: PixelValue) => void; + sendMessage: ReturnType; }; -const FullChatMessageForm = (props: FullChatMessageFormProps) => { +const FullChatMessageForm = ({ sendMessage }: FullChatMessageFormProps) => { const textareaContRef = useRef(null); const textareaRef = useRef(null); const inputImage = useRef(null); @@ -88,7 +86,7 @@ const FullChatMessageForm = (props: FullChatMessageFormProps) => { const onSend = async () => { textareaRef.current?.focus(); if (isMessageValid()) { - const result = await props.handleSendMessage(message); + const result = await sendMessage("text", { text: message }); if (result) setMessage(""); } }; @@ -104,7 +102,7 @@ const FullChatMessageForm = (props: FullChatMessageFormProps) => { const onChangeImage = (e: React.ChangeEvent) => { const image = e.target?.files?.[0]; if (!image) return; - props.handleSendImage(image); + sendMessage("image", { file: image }); }; const onKeyDown = (e: React.KeyboardEvent) => { @@ -144,13 +142,10 @@ const FullChatMessageForm = (props: FullChatMessageFormProps) => { useEffect(() => { resizeEvent(); }, [message]); - useEffect(() => { - props.setContHeight(`calc(16px + ${formHeight})` as PixelValue); - }, [formHeight]); return (
{ onClickClose={() => setPopupAccount(false)} onClickOk={(account: string) => { setPopupAccount(false); - props.handleSendAccount(account); + sendMessage("account", { text: account }); }} /> { setPopupAccount(true)} />
{ onChange={onChangeMessage} onKeyDown={onKeyDown} onKeyUp={onKeyUp} - style={{ + css={{ width: "calc(100% - 30px)", height: "100%", background: "none", diff --git a/src/components/Chatting/chatting-components/MessageForm/NewMessage.tsx b/src/components/Chatting/chatting-components/MessageForm/NewMessage.tsx index d3939da82..bd123740c 100644 --- a/src/components/Chatting/chatting-components/MessageForm/NewMessage.tsx +++ b/src/components/Chatting/chatting-components/MessageForm/NewMessage.tsx @@ -3,34 +3,32 @@ import theme from "tools/theme"; import ArrowDownwardRoundedIcon from "@mui/icons-material/ArrowDownwardRounded"; type newMessageProps = { - show: boolean; + isDisplay: boolean; onClick: () => void; }; -const NewMessage = (props: newMessageProps) => { - const style = { - marginBottom: props.show ? "12px" : "-26px", - opacity: props.show ? "1" : "0", - padding: "6px 10px 5px 8px", - borderRadius: "13px", - background: theme.white, - border: `0.5px solid ${theme.purple}`, - boxShadow: theme.shadow_clicked, - color: theme.purple, - ...theme.font12, - transition: "all 0.3s", - columnGap: "4px", - display: "flex", - ...theme.cursor(), - }; - return ( -
- - 새로운 메시지 -
- ); -}; +const NewMessage = ({ isDisplay, onClick }: newMessageProps) => ( +
+ + 새로운 메시지 +
+); export default NewMessage; diff --git a/src/components/Chatting/chatting-components/MessageForm/index.tsx b/src/components/Chatting/chatting-components/MessageForm/index.tsx index d64840134..df25ea900 100644 --- a/src/components/Chatting/chatting-components/MessageForm/index.tsx +++ b/src/components/Chatting/chatting-components/MessageForm/index.tsx @@ -1,6 +1,10 @@ -import { useEffect, useState } from "react"; +import { RefObject, memo } from "react"; -import FullChatMessageForm from "./FullChatMessageForm"; +import { LayoutType } from "types/chatting"; + +import useSendMessage from "../../chatting-hooks/useSendMessage"; +import { scrollToBottom } from "../../chatting-utils/scroll"; +import Form from "./Form"; import NewMessage from "./NewMessage"; import isVirtualKeyboardDetectedAtom from "atoms/isVirtualKeyboardDetected"; @@ -9,52 +13,45 @@ import { useRecoilValue } from "recoil"; import theme from "tools/theme"; type MessageFormProps = { - layoutType: "sidechat" | "fullchat"; - showNewMessage: boolean; - handleSendMessage: (message: string) => Promise; - handleSendImage: (image: File) => Promise; - handleSendAccount: (account: string) => Promise; - onClickNewMessage: () => void; - setContHeight: (height: PixelValue) => void; + layoutType: LayoutType; + isDisplayNewMessage: boolean; + messageBodyRef: RefObject; + sendMessage: ReturnType; }; -const MessageForm = (props: MessageFormProps) => { +const MessageForm = ({ + layoutType, + isDisplayNewMessage, + messageBodyRef, + sendMessage, +}: MessageFormProps) => { const isVKDetected = useRecoilValue(isVirtualKeyboardDetectedAtom); - const [contHeight, setContHeight] = useState("48px"); - useEffect(() => { - props.setContHeight(contHeight); - }, [contHeight]); + const onClickNewMessage = () => { + if (!messageBodyRef.current) return; + scrollToBottom(messageBodyRef.current, true); + }; + + const style = { + zIndex: theme.zIndex_nav - 2, + display: "flex", + flexDirection: "column" as any, + justifyContent: "flex-end", + alignItems: "center" as any, + boxShadow: theme.shadow_clicked, + backgroundColor: theme.white, + paddingBottom: + layoutType === "sidechat" || isVKDetected + ? "0px" + : "env(safe-area-inset-bottom)", + }; return ( -
- - +
+ +
); }; -export default MessageForm; +export default memo(MessageForm); diff --git a/src/components/Chatting/chatting-components/MessagesBody/index.tsx b/src/components/Chatting/chatting-components/MessagesBody/index.tsx new file mode 100644 index 000000000..65278273f --- /dev/null +++ b/src/components/Chatting/chatting-components/MessagesBody/index.tsx @@ -0,0 +1,33 @@ +import { ForwardedRef, forwardRef } from "react"; + +import { LayoutType } from "types/chatting"; + +import useChatsForBody from "../../chatting-hooks/useChatsForBody"; +import { Chats } from "../../chatting-utils/chats"; + +type MessagesBodyProps = { + layoutType: LayoutType; + chats: Chats; +}; + +const MessagesBody = ( + { layoutType, chats: _chats }: MessagesBodyProps, + ref: ForwardedRef +) => ( +
+ {useChatsForBody(_chats, layoutType)} +
+); + +export default forwardRef(MessagesBody); diff --git a/src/components/Chatting/chatting-hooks/useBodyScrollControllerEffect.tsx b/src/components/Chatting/chatting-hooks/useBodyScrollControllerEffect.tsx new file mode 100644 index 000000000..23bad363f --- /dev/null +++ b/src/components/Chatting/chatting-hooks/useBodyScrollControllerEffect.tsx @@ -0,0 +1,59 @@ +import { MutableRefObject, RefObject, useEffect, useLayoutEffect } from "react"; + +import { Chats } from "../chatting-utils/chats"; +import { isBottomOnScroll, scrollToBottom } from "../chatting-utils/scroll"; + +export default ( + roomId: string, + chats: Chats, + setDisplayNewMessage: (value: boolean) => void, + chatBodyRef: RefObject, + isCallingInfScroll: MutableRefObject +) => { + useLayoutEffect(() => { + // @todo, @fixme 테스트 필요 + // if (!isCallingInfScroll.current) return; + // isCallingInfScroll.current = false; + // let scrollTop = -34; // 34는 ChatDate의 높이 + // const bodyChildren = messagesBody.current.children; + // for (const children of bodyChildren) { + // if (children.getAttribute("chatcheckout")) break; + // scrollTop += children.clientHeight; + // } + // messagesBody.current.scrollTop = scrollTop; + }, [chats]); + + useEffect(() => { + const chatBody = chatBodyRef?.current; + let isBottomOnScrollCache: boolean = true; + + if (!chatBody) return; + + const resizeEvent = () => { + if (isBottomOnScrollCache) scrollToBottom(chatBody); + }; + const scrollEvent = () => { + if (isBottomOnScroll(chatBody)) { + setDisplayNewMessage(false); + isBottomOnScrollCache = true; + } else { + isBottomOnScrollCache = false; + } + // @todo, @fixme 테스트 필요 + // if (isTopOnScroll(chatBody)) { + // console.log("top"); + // 무한 스크롤 구현 및 API 호출 + // } + }; + + const resizeObserver = new ResizeObserver(resizeEvent); + resizeEvent(); + scrollEvent(); + resizeObserver.observe(chatBody); + chatBody.addEventListener("scroll", scrollEvent); + return () => { + resizeObserver.disconnect(); + chatBody.removeEventListener("scroll", scrollEvent); + }; + }, [roomId, chatBodyRef]); +}; diff --git a/src/components/Chatting/chatting-components/MessagesBody/index.jsx b/src/components/Chatting/chatting-hooks/useChatsForBody.tsx similarity index 63% rename from src/components/Chatting/chatting-components/MessagesBody/index.jsx rename to src/components/Chatting/chatting-hooks/useChatsForBody.tsx index bc121b01d..f56015682 100644 --- a/src/components/Chatting/chatting-components/MessagesBody/index.jsx +++ b/src/components/Chatting/chatting-hooks/useChatsForBody.tsx @@ -1,34 +1,39 @@ -import PropTypes from "prop-types"; import { useMemo } from "react"; -import { getChatUniquewKey } from "../../chatting-utils/chats"; -import ChatDate from "./ChatDate"; -import ChatInOut from "./ChatInOut"; -import ChatSet from "./ChatSet"; +import { LayoutType } from "types/chatting"; + +import ChatDate from "../chatting-components/MessagesBody/ChatDate"; +import ChatInOut from "../chatting-components/MessagesBody/ChatInOut"; +import ChatSet from "../chatting-components/MessagesBody/ChatSet"; +import { Chats, getChatUniquewKey } from "../chatting-utils/chats"; import loginInfoAtom from "atoms/loginInfo"; import { useRecoilValue } from "recoil"; import moment from "tools/moment"; -const MessagesBody = (props) => { +export default (_chats: Chats, layoutType: LayoutType) => { const { oid: userOid } = useRecoilValue(loginInfoAtom) || {}; - const chats = useMemo(() => { + // remove me + const isBottomOnScroll = () => true; + const scrollToBottom = () => {}; + + return useMemo(() => { const list = []; - let momentCache = null; - let chatsCache = null; + let momentCache: any = null; // fixme, todo + let chatsCache: Nullable> = null; const dateFormat = "YYYY.MM.DD"; const minFormat = "YYYY.MM.DD HH:mm"; const chatSetCommonProps = { authorId: userOid, - isBottomOnScroll: props.isBottomOnScroll, - scrollToBottom: props.scrollToBottom, - isSideChat: props.layoutType === "sidechat", + isBottomOnScroll, + scrollToBottom, + isSideChat: layoutType === "sidechat", // fixme }; - props.chats.forEach((item) => { + _chats.forEach((item) => { if (item.type === "inf-checkout") { if (chatsCache) { list.push( @@ -41,11 +46,13 @@ const MessagesBody = (props) => { } chatsCache = null; - list.push(
); + list.push( +
+ ); return; } - const currentMoment = moment(item.time); + const currentMoment = moment((item as Chat).time); if (!momentCache) { momentCache = currentMoment.clone(); momentCache.subtract(1, "years"); @@ -79,9 +86,9 @@ const MessagesBody = (props) => { } list.push( ); } else if ( @@ -91,7 +98,7 @@ const MessagesBody = (props) => { ) { if ( chatsCache && - (chatsCache[0].authorId !== item.authorId || + (chatsCache[0].authorId !== (item as Chat).authorId || moment(chatsCache[0].time).format(minFormat) !== currentMoment.format(minFormat)) ) { @@ -105,7 +112,7 @@ const MessagesBody = (props) => { chatsCache = null; } if (!chatsCache) chatsCache = []; - chatsCache.push(item); + chatsCache.push(item as Chat); } momentCache = currentMoment.clone(); }); @@ -119,38 +126,5 @@ const MessagesBody = (props) => { ); } return list; - }, [props.chats, userOid]); - - return ( -
- {chats} -
- ); + }, [_chats, layoutType, userOid]); }; - -MessagesBody.propTypes = { - layoutType: PropTypes.string, - chats: PropTypes.array, - forwardedRef: PropTypes.any, - handleScroll: PropTypes.func, - isBottomOnScroll: PropTypes.func, - scrollToBottom: PropTypes.func, -}; - -MessagesBody.defaultProps = { - chats: [], -}; - -export default MessagesBody; diff --git a/src/components/Chatting/chatting-hooks/useSocketChatEffect.tsx b/src/components/Chatting/chatting-hooks/useSocketChatEffect.tsx index 54714eb84..f3f3d310d 100644 --- a/src/components/Chatting/chatting-hooks/useSocketChatEffect.tsx +++ b/src/components/Chatting/chatting-hooks/useSocketChatEffect.tsx @@ -1,9 +1,11 @@ -import { MutableRefObject, useEffect } from "react"; +import { MutableRefObject, RefObject, useEffect } from "react"; +import { useStateWithCallbackLazy } from "use-state-with-callback"; import { useValueRecoilState } from "hooks/useFetchRecoilState"; import { useAxios } from "hooks/useTaxiAPI"; import { Chats, checkoutChat, getCleanupChats } from "../chatting-utils/chats"; +import { isBottomOnScroll, scrollToBottom } from "../chatting-utils/scroll"; import { registerSocketEventListener, @@ -13,18 +15,15 @@ import { export default ( roomId: string, - setChats: any, // fixme - setDisplayNewMessage: any, + setChats: ReturnType>[1], + setDisplayNewMessage: (value: boolean) => void, + chatBodyRef: RefObject, isSendingMessage: MutableRefObject, isCallingInfScroll: MutableRefObject ) => { const axios = useAxios(); const { oid: userOid } = useValueRecoilState("loginInfo") || {}; - // remove me - const scrollToBottom = (x?: boolean) => {}; - const isBottomOnScroll = () => true; - useEffect(() => { let isExpired: boolean = false; isSendingMessage.current = true; @@ -39,27 +38,31 @@ export default ( isSendingMessage.current = false; setChats(getCleanupChats(chats), () => { - scrollToBottom(); + if (chatBodyRef?.current) scrollToBottom(chatBodyRef?.current); isCallingInfScroll.current = false; }); }, reconnectListener: () => { if (isExpired) return; - setChats((prevChats: Chats) => { - const lastMsg = prevChats[prevChats.length - 1] as Chat; - axios({ - url: "/chats/load/after", - method: "post", - data: { roomId, lastMsgDate: lastMsg.time }, - }); - return prevChats; - }); + setChats( + (prevChats: Chats) => { + const lastMsg = prevChats[prevChats.length - 1] as Chat; + axios({ + url: "/chats/load/after", + method: "post", + data: { roomId, lastMsgDate: lastMsg.time }, + }); + return prevChats; + }, + () => {} + ); }, pushBackListener: (chats) => { - if (isExpired) return; + chats = chats.filter((chat) => chat.roomId === roomId); + if (isExpired || chats.length <= 0) return; - const isMyMsg = chats.some((chat) => chat.authorId === userOid); - if (isMyMsg) isSendingMessage.current = false; + const isMyMessage = chats.some((chat) => chat.authorId === userOid); + if (isMyMessage) isSendingMessage.current = false; if (chats.length > 10) { axios({ @@ -73,20 +76,24 @@ export default ( } setChats( (prevChats: Chats) => getCleanupChats([...prevChats, ...chats]), - isMyMsg || isBottomOnScroll() - ? () => scrollToBottom(true) + isMyMessage || + (chatBodyRef?.current && isBottomOnScroll(chatBodyRef?.current)) + ? () => { + if (chatBodyRef?.current) + scrollToBottom(chatBodyRef?.current, true); + } : () => setDisplayNewMessage(true) ); }, pushFrontListener: (chats) => { if (isExpired) return; - if (chats.length === 0) { - isCallingInfScroll.current = false; - return; - } - setChats((prevChats: Chats) => - getCleanupChats([...chats, checkoutChat, ...prevChats]) + if (chats.length === 0) return; + // { isCallingInfScroll.current = false; return; } // 지워도 되는 거겠지? @todo @fixme + setChats( + (prevChats: Chats) => + getCleanupChats([...chats, checkoutChat, ...prevChats]), + () => {} ); }, }); diff --git a/src/components/Chatting/chatting-utils/scroll.ts b/src/components/Chatting/chatting-utils/scroll.ts index 408e16242..9191f8184 100644 --- a/src/components/Chatting/chatting-utils/scroll.ts +++ b/src/components/Chatting/chatting-utils/scroll.ts @@ -6,7 +6,7 @@ export const isTopOnScroll = (element: HTMLDivElement, tol: number = 0) => { }; // 스크롤이 페이지 하단에 있는지 여부를 반환 (tol = 허용오차) -export const isBottomOnScroll = (element: HTMLDivElement, tol: number = 0) => { +export const isBottomOnScroll = (element: HTMLDivElement, tol: number = 20) => { if (!element) return false; const scrollHeight = element.scrollHeight; const scrollTop = Math.max(element.scrollTop, 0); @@ -14,3 +14,21 @@ export const isBottomOnScroll = (element: HTMLDivElement, tol: number = 0) => { const scrollBottom = Math.max(scrollHeight - clientHeight - scrollTop, 0); return scrollBottom <= tol; }; + +// 스크롤을 페이지 하단으로 이동 +export const scrollToBottom = ( + element: HTMLDivElement, + doAnimation = false +) => { + if (!element) return; + // setShowNewMessage(false); // 이거 자동으로 되지 않나? @todo @fixme + const scrollTop = element.scrollHeight - element.clientHeight; + if (doAnimation) { + element.scroll({ + behavior: "smooth", + top: scrollTop, + }); + } else { + element.scrollTop = scrollTop; + } +}; diff --git a/src/components/Chatting/index.tsx b/src/components/Chatting/index.tsx index cbcaa2afd..6cbbe0894 100644 --- a/src/components/Chatting/index.tsx +++ b/src/components/Chatting/index.tsx @@ -1,6 +1,8 @@ import { useRef, useState } from "react"; import { useStateWithCallbackLazy } from "use-state-with-callback"; +import { LayoutType } from "types/chatting"; + import useDateToken from "hooks/useDateToken"; import useDisableScrollEffect from "hooks/useDisableScrollEffect"; import useQuery from "hooks/useTaxiAPI"; @@ -9,6 +11,7 @@ import Container from "./chatting-components/Container"; import Header from "./chatting-components/Header"; import MessageForm from "./chatting-components/MessageForm"; import MessagesBody from "./chatting-components/MessagesBody"; +import useBodyScrollControllerEffect from "./chatting-hooks/useBodyScrollControllerEffect"; import useSendMessage from "./chatting-hooks/useSendMessage"; import useSocketChatEffect from "./chatting-hooks/useSocketChatEffect"; import { Chats } from "./chatting-utils/chats"; @@ -17,7 +20,7 @@ import theme from "tools/theme"; type ChattingProps = { roomId: string; - layoutType: "sidechat" | "fullchat"; + layoutType: LayoutType; }; type FullChatProps = { roomId: ChattingProps["roomId"]; @@ -29,30 +32,34 @@ type SideChatProps = { const Chatting = ({ roomId, layoutType }: ChattingProps) => { const [chats, setChats] = useStateWithCallbackLazy([]); // 채팅 메시지 배열 const [isDisplayNewMessage, setDisplayNewMessage] = useState(false); // 새로운 메시지 버튼 표시 여부 + const messageBodyRef = useRef(null); // 스크롤 되는 메시지 HTML 요소 const isSendingMessage = useRef(false); // 메시지 전송 중인지 여부 const isCallingInfScroll = useRef(false); // 무한 스크롤 메시지 요청 중인지 여부 + const sendMessage = useSendMessage(roomId, isSendingMessage); // 메시지 전송 핸들러 + + // 방 정보 조회 + const [roomInfoToken, fetchRoomInfo] = useDateToken(); + const [, roomInfo] = useQuery.get(`/rooms/info?id=${roomId}`, {}, [ + roomInfoToken, + ]); + // socket.io를 통해 채팅 전송 및 수신 useSocketChatEffect( roomId, setChats, setDisplayNewMessage, + messageBodyRef, isSendingMessage, isCallingInfScroll ); - // Remove me - move to child - const sendMessage = useSendMessage(roomId, isSendingMessage); - const handleSendMessage = (text: string) => sendMessage("text", { text }); - const handleSendAccount = (account: string) => - sendMessage("account", { text: account }); - const handleSendImage = (image: File) => - sendMessage("image", { file: image }); - - // Remove me - move to child - const [roomInfoToken, fetchRoomInfo] = useDateToken(); - const [, roomInfo] = useQuery.get(`/rooms/info?id=${roomId}`, {}, [ - roomInfoToken, - ]); + useBodyScrollControllerEffect( + roomId, + chats, + setDisplayNewMessage, + messageBodyRef, + isCallingInfScroll + ); return ( @@ -64,19 +71,13 @@ const Chatting = ({ roomId, layoutType }: ChattingProps) => { true} - // scrollToBottom={() => scrollToBottom(false)} + ref={messageBodyRef} /> {}} - setContHeight={() => {}} + isDisplayNewMessage={isDisplayNewMessage} + messageBodyRef={messageBodyRef} + sendMessage={sendMessage} /> ); diff --git a/src/pages/Chatting/dump.jsx b/src/pages/Chatting/dump.jsx deleted file mode 100644 index 08ec9c1e8..000000000 --- a/src/pages/Chatting/dump.jsx +++ /dev/null @@ -1,332 +0,0 @@ -import axiosOri from "axios"; -import PropTypes from "prop-types"; -import { useEffect, useLayoutEffect, useRef, useState } from "react"; -import { useHistory } from "react-router-dom"; -import { useStateWithCallbackLazy } from "use-state-with-callback"; - -import useDateToken from "hooks/useDateToken"; -import { useValueRecoilState } from "hooks/useFetchRecoilState"; -import { useR2state } from "hooks/useReactiveState"; -import { useAxios, useQuery } from "hooks/useTaxiAPI"; - -import Container from "./Container"; -import Header from "./Header"; -import MessageForm from "./MessageForm"; -import MessagesBody from "./MessagesBody"; -import { checkoutChat, getCleanupChats } from "./utils"; - -import alertAtom from "atoms/alert"; -import { useSetRecoilState } from "recoil"; - -import convertImg from "tools/convertImg"; -import regExpTest from "tools/regExpTest"; -import { - registerSocketEventListener, - resetSocketEventListener, - socketReady, -} from "tools/socket"; - -const Chatting = ({ roomId, layoutType }) => { - const sendingMessage = useRef(); - const callingInfScroll = useRef(); - const isBottomOnScrollCache = useRef(true); - const messagesBody = useRef(); - const history = useHistory(); - const axios = useAxios(); - - const [chats, setChats] = useStateWithCallbackLazy([]); - const [showNewMessage, setShowNewMessage] = useState(false); - const [, setMessageFormHeight] = useStateWithCallbackLazy("48px"); - - const reactiveState = useR2state(); - const prevReactiveState = useRef(reactiveState); - const setAlert = useSetRecoilState(alertAtom); - const { oid: userOid } = useValueRecoilState("loginInfo") || {}; - const [headerInfoToken, fetchHeaderInfo] = useDateToken(); - const [, headerInfo] = useQuery.get(`/rooms/info?id=${roomId}`, {}, [ - headerInfoToken, - ]); - - useLayoutEffect(() => { - if (!callingInfScroll.current) return; - - callingInfScroll.current = false; - let scrollTop = -34; // 34는 ChatDate의 높이 - const bodyChildren = messagesBody.current.children; - for (const children of bodyChildren) { - if (children.getAttribute("chatcheckout")) break; - scrollTop += children.clientHeight; - } - messagesBody.current.scrollTop = scrollTop; - }, [chats]); - - useEffect(() => { - if (reactiveState !== 3 && prevReactiveState.current === 3) { - history.replace(`/myroom/${roomId}`); - } - if (reactiveState === 3 && prevReactiveState.current !== 3) - prevReactiveState.current = reactiveState; - }, [reactiveState]); - - // scroll event - const isTopOnScroll = (tol = 0) => { - if (messagesBody.current) { - const scrollTop = Math.max(messagesBody.current.scrollTop, 0); - if (scrollTop <= tol) { - return true; - } - } - return false; - }; - const isBottomOnScroll = (tol = 20) => { - if (messagesBody.current) { - const scrollHeight = messagesBody.current.scrollHeight; - const scrollTop = Math.max(messagesBody.current.scrollTop, 0); - const clientHeight = messagesBody.current.clientHeight; - const scrollBottom = Math.max(scrollHeight - clientHeight - scrollTop, 0); - if (scrollBottom <= tol) { - return true; - } - } - return false; - }; - const handleScroll = () => { - if (isBottomOnScroll()) { - if (showNewMessage) setShowNewMessage(false); - isBottomOnScrollCache.current = true; - } else { - isBottomOnScrollCache.current = false; - } - - if ( - isTopOnScroll() && - chats.length > 0 && - callingInfScroll.current == false - ) { - callingInfScroll.current = true; - socketReady(() => { - axios({ - url: "/chats/load/before", - method: "post", - data: { roomId, lastMsgDate: chats[0].time }, - }); - }); - } - }; - - // message Body auto scroll functions - const scrollToBottom = (doAnimation = false) => { - setShowNewMessage(false); - if (messagesBody.current) { - const scrollTop = - messagesBody.current.scrollHeight - messagesBody.current.clientHeight; - if (doAnimation) { - messagesBody.current.scroll({ - behavior: "smooth", - top: scrollTop, - }); - } else { - messagesBody.current.scrollTop = scrollTop; - } - } - }; - - // messageForm Height function - const handleMessageFormHeight = (height) => { - let isBottom = isBottomOnScroll(); - setMessageFormHeight(height, () => { - if (isBottom) scrollToBottom(); - }); - }; - - // socket event - useEffect(() => { - let isExpired = false; - sendingMessage.current = true; - - socketReady(() => { - if (isExpired) return; - - // socket event listener 등록 - registerSocketEventListener({ - initListener: (chats) => { - if (isExpired) return; - sendingMessage.current = null; - - setChats(getCleanupChats(chats), () => { - scrollToBottom(); - callingInfScroll.current = false; - }); - }, - reconnectListener: () => { - if (isExpired) return; - setChats((prevChats) => { - axios({ - url: "/chats/load/after", - method: "post", - data: { - roomId, - lastMsgDate: prevChats[prevChats.length - 1].time, - }, - }); - return prevChats; - }); - }, - pushBackListener: (chats) => { - if (isExpired) return; - - const isMyMsg = chats.some((chat) => chat.authorId === userOid); - if (isMyMsg) sendingMessage.current = null; - - if (chats.length > 10) { - axios({ - url: "/chats/load/after", - method: "post", - data: { - roomId, - lastMsgDate: chats[chats.length - 1].time, - }, - }); - } - setChats( - (prevChats) => getCleanupChats([...prevChats, ...chats]), - isMyMsg || isBottomOnScroll() - ? () => scrollToBottom(true) - : () => setShowNewMessage(true) - ); - }, - pushFrontListener: (chats) => { - if (isExpired) return; - - if (chats.length === 0) { - callingInfScroll.current = null; - return; - } - setChats((prevChats) => - getCleanupChats([...chats, checkoutChat, ...prevChats]) - ); - }, - }); - - // 채팅 로드 API 호출 - axios({ - url: "/chats", - method: "post", - data: { roomId }, - }); - }); - return () => { - isExpired = true; - resetSocketEventListener(); - }; - }, [roomId]); - - // resize event - const resizeEvent = () => { - if (isBottomOnScrollCache.current) scrollToBottom(); - }; - useEffect(() => { - resizeEvent(); - window.addEventListener("resize", resizeEvent); - visualViewport?.addEventListener("resize", resizeEvent); - return () => { - window.removeEventListener("resize", resizeEvent); - visualViewport?.removeEventListener("resize", resizeEvent); - }; - }, []); - - // message function - const sendMessage = (type, content) => { - if (sendingMessage.current) return false; - if (type === "text" && !regExpTest.chatMsg(content)) return false; - if (type === "account" && !regExpTest.account(content)) return false; - - sendingMessage.current = true; - axios({ - url: "/chats/send", - method: "post", - data: { roomId, type, content }, - onError: () => { - sendingMessage.current = null; - setAlert("메시지 전송에 실패하였습니다."); - }, - }); - return true; - }; - const handleSendMessage = (text) => sendMessage("text", text); - const handleSendAccount = (account) => sendMessage("account", account); - const handleSendImage = async (image) => { - if (sendingMessage.current) return; - sendingMessage.current = true; - const onFail = () => { - sendingMessage.current = null; - setAlert("이미지 전송에 실패하였습니다."); - }; - try { - image = await convertImg(image); - if (!image) return onFail(); - axios({ - url: "chats/uploadChatImg/getPUrl", - method: "post", - data: { roomId, type: image.type }, - onSuccess: async ({ url, fields, id }) => { - if (!url || !fields) return onFail(); - const formData = new FormData(); - for (const key in fields) { - formData.append(key, fields[key]); - } - formData.append("file", image); - const { status: s3Status } = await axiosOri.post(url, formData); - if (s3Status !== 204) return onFail(); - axios({ - url: "chats/uploadChatImg/done", - method: "post", - data: { id }, - onSuccess: ({ result }) => { - if (!result) onFail(); - }, - onError: onFail, - }); - }, - onError: onFail, - }); - } catch (e) { - console.error(e); - onFail(); - } - }; - - return ( - -
- scrollToBottom(false)} - /> - scrollToBottom(true)} - setContHeight={handleMessageFormHeight} - /> - - ); -}; - -Chatting.propTypes = { - layoutType: PropTypes.oneOf(["sidechat", "fullchat"]), - roomId: PropTypes.string, -}; - -export default Chatting; diff --git a/src/types/chatting.d.ts b/src/types/chatting.d.ts new file mode 100644 index 000000000..4b5afa257 --- /dev/null +++ b/src/types/chatting.d.ts @@ -0,0 +1 @@ +export type LayoutType = "sidechat" | "fullchat"; From dd5b9c03c0c37f579cea76965b2d4d14da44309c Mon Sep 17 00:00:00 2001 From: 14Kgun Date: Tue, 18 Jul 2023 19:04:58 +0900 Subject: [PATCH 05/17] Rename: Chat --- .../chat-components}/Container/index.tsx | 0 .../Header/Popup/PopupCancel.jsx | 0 .../Header/Popup/PopupContainer.jsx | 0 .../Header/Popup/PopupPay.jsx | 0 .../Header/Popup/PopupSend.jsx | 0 .../chat-components}/Header/SideMenu.tsx | 4 +- .../chat-components}/Header/index.tsx | 0 .../chat-components}/MessageForm/Form.tsx | 2 +- .../MessageForm/NewMessage.tsx | 0 .../MessageForm/Popup/PopupAccount.tsx | 0 .../chat-components}/MessageForm/index.tsx | 4 +- .../MessagesBody/ChatDate.jsx | 0 .../MessagesBody/ChatInOut.jsx | 0 .../MessagesBody/ChatPaySettle.tsx | 0 .../chat-components}/MessagesBody/ChatSet.jsx | 0 .../MessagesBody/ImageFullscreen.jsx | 0 .../chat-components}/MessagesBody/index.tsx | 4 +- .../useBodyScrollControllerEffect.tsx | 4 +- .../chat-hooks}/useChatsForBody.tsx | 8 +-- .../chat-hooks}/useSendMessage.tsx | 0 .../chat-hooks}/useSocketChatEffect.tsx | 6 +-- .../chat-utils}/chats.ts | 0 .../chat-utils}/scroll.ts | 0 src/components/{Chatting => Chat}/index.tsx | 52 +++++-------------- src/components/RLayout.jsx | 6 +-- src/pages/Chatting/index.tsx | 4 +- src/pages/Myroom/R2Myroom.jsx | 4 +- 27 files changed, 37 insertions(+), 61 deletions(-) rename src/components/{Chatting/chatting-components => Chat/chat-components}/Container/index.tsx (100%) rename src/components/{Chatting/chatting-components => Chat/chat-components}/Header/Popup/PopupCancel.jsx (100%) rename src/components/{Chatting/chatting-components => Chat/chat-components}/Header/Popup/PopupContainer.jsx (100%) rename src/components/{Chatting/chatting-components => Chat/chat-components}/Header/Popup/PopupPay.jsx (100%) rename src/components/{Chatting/chatting-components => Chat/chat-components}/Header/Popup/PopupSend.jsx (100%) rename src/components/{Chatting/chatting-components => Chat/chat-components}/Header/SideMenu.tsx (93%) rename src/components/{Chatting/chatting-components => Chat/chat-components}/Header/index.tsx (100%) rename src/components/{Chatting/chatting-components => Chat/chat-components}/MessageForm/Form.tsx (98%) rename src/components/{Chatting/chatting-components => Chat/chat-components}/MessageForm/NewMessage.tsx (100%) rename src/components/{Chatting/chatting-components => Chat/chat-components}/MessageForm/Popup/PopupAccount.tsx (100%) rename src/components/{Chatting/chatting-components => Chat/chat-components}/MessageForm/index.tsx (91%) rename src/components/{Chatting/chatting-components => Chat/chat-components}/MessagesBody/ChatDate.jsx (100%) rename src/components/{Chatting/chatting-components => Chat/chat-components}/MessagesBody/ChatInOut.jsx (100%) rename src/components/{Chatting/chatting-components => Chat/chat-components}/MessagesBody/ChatPaySettle.tsx (100%) rename src/components/{Chatting/chatting-components => Chat/chat-components}/MessagesBody/ChatSet.jsx (100%) rename src/components/{Chatting/chatting-components => Chat/chat-components}/MessagesBody/ImageFullscreen.jsx (100%) rename src/components/{Chatting/chatting-components => Chat/chat-components}/MessagesBody/index.tsx (84%) rename src/components/{Chatting/chatting-hooks => Chat/chat-hooks}/useBodyScrollControllerEffect.tsx (93%) rename src/components/{Chatting/chatting-hooks => Chat/chat-hooks}/useChatsForBody.tsx (92%) rename src/components/{Chatting/chatting-hooks => Chat/chat-hooks}/useSendMessage.tsx (100%) rename src/components/{Chatting/chatting-hooks => Chat/chat-hooks}/useSocketChatEffect.tsx (93%) rename src/components/{Chatting/chatting-utils => Chat/chat-utils}/chats.ts (100%) rename src/components/{Chatting/chatting-utils => Chat/chat-utils}/scroll.ts (100%) rename src/components/{Chatting => Chat}/index.tsx (62%) diff --git a/src/components/Chatting/chatting-components/Container/index.tsx b/src/components/Chat/chat-components/Container/index.tsx similarity index 100% rename from src/components/Chatting/chatting-components/Container/index.tsx rename to src/components/Chat/chat-components/Container/index.tsx diff --git a/src/components/Chatting/chatting-components/Header/Popup/PopupCancel.jsx b/src/components/Chat/chat-components/Header/Popup/PopupCancel.jsx similarity index 100% rename from src/components/Chatting/chatting-components/Header/Popup/PopupCancel.jsx rename to src/components/Chat/chat-components/Header/Popup/PopupCancel.jsx diff --git a/src/components/Chatting/chatting-components/Header/Popup/PopupContainer.jsx b/src/components/Chat/chat-components/Header/Popup/PopupContainer.jsx similarity index 100% rename from src/components/Chatting/chatting-components/Header/Popup/PopupContainer.jsx rename to src/components/Chat/chat-components/Header/Popup/PopupContainer.jsx diff --git a/src/components/Chatting/chatting-components/Header/Popup/PopupPay.jsx b/src/components/Chat/chat-components/Header/Popup/PopupPay.jsx similarity index 100% rename from src/components/Chatting/chatting-components/Header/Popup/PopupPay.jsx rename to src/components/Chat/chat-components/Header/Popup/PopupPay.jsx diff --git a/src/components/Chatting/chatting-components/Header/Popup/PopupSend.jsx b/src/components/Chat/chat-components/Header/Popup/PopupSend.jsx similarity index 100% rename from src/components/Chatting/chatting-components/Header/Popup/PopupSend.jsx rename to src/components/Chat/chat-components/Header/Popup/PopupSend.jsx diff --git a/src/components/Chatting/chatting-components/Header/SideMenu.tsx b/src/components/Chat/chat-components/Header/SideMenu.tsx similarity index 93% rename from src/components/Chatting/chatting-components/Header/SideMenu.tsx rename to src/components/Chat/chat-components/Header/SideMenu.tsx index cd8a8d0ed..637151ae6 100644 --- a/src/components/Chatting/chatting-components/Header/SideMenu.tsx +++ b/src/components/Chat/chat-components/Header/SideMenu.tsx @@ -32,8 +32,8 @@ const SideMenu = ({ const style = { position: "absolute" as any, top: 0, - right: isOpen ? 0 : "calc(-100% + 60px)", - width: "calc(100% - 60px)", + right: isOpen ? 0 : "max(calc(-100% + 60px), -370px)", + width: "min(calc(100% - 60px), 370px)", height: "100%", padding: "16px", boxSizing: "border-box" as any, diff --git a/src/components/Chatting/chatting-components/Header/index.tsx b/src/components/Chat/chat-components/Header/index.tsx similarity index 100% rename from src/components/Chatting/chatting-components/Header/index.tsx rename to src/components/Chat/chat-components/Header/index.tsx diff --git a/src/components/Chatting/chatting-components/MessageForm/Form.tsx b/src/components/Chat/chat-components/MessageForm/Form.tsx similarity index 98% rename from src/components/Chatting/chatting-components/MessageForm/Form.tsx rename to src/components/Chat/chat-components/MessageForm/Form.tsx index 3175a10ff..80874f56b 100644 --- a/src/components/Chatting/chatting-components/MessageForm/Form.tsx +++ b/src/components/Chat/chat-components/MessageForm/Form.tsx @@ -1,6 +1,6 @@ import { useEffect, useRef, useState } from "react"; -import useSendMessage from "../../chatting-hooks/useSendMessage"; +import useSendMessage from "../../chat-hooks/useSendMessage"; import PopupAccount from "./Popup/PopupAccount"; import regExpTest from "tools/regExpTest"; diff --git a/src/components/Chatting/chatting-components/MessageForm/NewMessage.tsx b/src/components/Chat/chat-components/MessageForm/NewMessage.tsx similarity index 100% rename from src/components/Chatting/chatting-components/MessageForm/NewMessage.tsx rename to src/components/Chat/chat-components/MessageForm/NewMessage.tsx diff --git a/src/components/Chatting/chatting-components/MessageForm/Popup/PopupAccount.tsx b/src/components/Chat/chat-components/MessageForm/Popup/PopupAccount.tsx similarity index 100% rename from src/components/Chatting/chatting-components/MessageForm/Popup/PopupAccount.tsx rename to src/components/Chat/chat-components/MessageForm/Popup/PopupAccount.tsx diff --git a/src/components/Chatting/chatting-components/MessageForm/index.tsx b/src/components/Chat/chat-components/MessageForm/index.tsx similarity index 91% rename from src/components/Chatting/chatting-components/MessageForm/index.tsx rename to src/components/Chat/chat-components/MessageForm/index.tsx index df25ea900..fc0af24cb 100644 --- a/src/components/Chatting/chatting-components/MessageForm/index.tsx +++ b/src/components/Chat/chat-components/MessageForm/index.tsx @@ -2,8 +2,8 @@ import { RefObject, memo } from "react"; import { LayoutType } from "types/chatting"; -import useSendMessage from "../../chatting-hooks/useSendMessage"; -import { scrollToBottom } from "../../chatting-utils/scroll"; +import useSendMessage from "../../chat-hooks/useSendMessage"; +import { scrollToBottom } from "../../chat-utils/scroll"; import Form from "./Form"; import NewMessage from "./NewMessage"; diff --git a/src/components/Chatting/chatting-components/MessagesBody/ChatDate.jsx b/src/components/Chat/chat-components/MessagesBody/ChatDate.jsx similarity index 100% rename from src/components/Chatting/chatting-components/MessagesBody/ChatDate.jsx rename to src/components/Chat/chat-components/MessagesBody/ChatDate.jsx diff --git a/src/components/Chatting/chatting-components/MessagesBody/ChatInOut.jsx b/src/components/Chat/chat-components/MessagesBody/ChatInOut.jsx similarity index 100% rename from src/components/Chatting/chatting-components/MessagesBody/ChatInOut.jsx rename to src/components/Chat/chat-components/MessagesBody/ChatInOut.jsx diff --git a/src/components/Chatting/chatting-components/MessagesBody/ChatPaySettle.tsx b/src/components/Chat/chat-components/MessagesBody/ChatPaySettle.tsx similarity index 100% rename from src/components/Chatting/chatting-components/MessagesBody/ChatPaySettle.tsx rename to src/components/Chat/chat-components/MessagesBody/ChatPaySettle.tsx diff --git a/src/components/Chatting/chatting-components/MessagesBody/ChatSet.jsx b/src/components/Chat/chat-components/MessagesBody/ChatSet.jsx similarity index 100% rename from src/components/Chatting/chatting-components/MessagesBody/ChatSet.jsx rename to src/components/Chat/chat-components/MessagesBody/ChatSet.jsx diff --git a/src/components/Chatting/chatting-components/MessagesBody/ImageFullscreen.jsx b/src/components/Chat/chat-components/MessagesBody/ImageFullscreen.jsx similarity index 100% rename from src/components/Chatting/chatting-components/MessagesBody/ImageFullscreen.jsx rename to src/components/Chat/chat-components/MessagesBody/ImageFullscreen.jsx diff --git a/src/components/Chatting/chatting-components/MessagesBody/index.tsx b/src/components/Chat/chat-components/MessagesBody/index.tsx similarity index 84% rename from src/components/Chatting/chatting-components/MessagesBody/index.tsx rename to src/components/Chat/chat-components/MessagesBody/index.tsx index 65278273f..11e774054 100644 --- a/src/components/Chatting/chatting-components/MessagesBody/index.tsx +++ b/src/components/Chat/chat-components/MessagesBody/index.tsx @@ -2,8 +2,8 @@ import { ForwardedRef, forwardRef } from "react"; import { LayoutType } from "types/chatting"; -import useChatsForBody from "../../chatting-hooks/useChatsForBody"; -import { Chats } from "../../chatting-utils/chats"; +import useChatsForBody from "../../chat-hooks/useChatsForBody"; +import { Chats } from "../../chat-utils/chats"; type MessagesBodyProps = { layoutType: LayoutType; diff --git a/src/components/Chatting/chatting-hooks/useBodyScrollControllerEffect.tsx b/src/components/Chat/chat-hooks/useBodyScrollControllerEffect.tsx similarity index 93% rename from src/components/Chatting/chatting-hooks/useBodyScrollControllerEffect.tsx rename to src/components/Chat/chat-hooks/useBodyScrollControllerEffect.tsx index 23bad363f..a8ceb25e3 100644 --- a/src/components/Chatting/chatting-hooks/useBodyScrollControllerEffect.tsx +++ b/src/components/Chat/chat-hooks/useBodyScrollControllerEffect.tsx @@ -1,7 +1,7 @@ import { MutableRefObject, RefObject, useEffect, useLayoutEffect } from "react"; -import { Chats } from "../chatting-utils/chats"; -import { isBottomOnScroll, scrollToBottom } from "../chatting-utils/scroll"; +import { Chats } from "../chat-utils/chats"; +import { isBottomOnScroll, scrollToBottom } from "../chat-utils/scroll"; export default ( roomId: string, diff --git a/src/components/Chatting/chatting-hooks/useChatsForBody.tsx b/src/components/Chat/chat-hooks/useChatsForBody.tsx similarity index 92% rename from src/components/Chatting/chatting-hooks/useChatsForBody.tsx rename to src/components/Chat/chat-hooks/useChatsForBody.tsx index f56015682..e551f31c2 100644 --- a/src/components/Chatting/chatting-hooks/useChatsForBody.tsx +++ b/src/components/Chat/chat-hooks/useChatsForBody.tsx @@ -2,10 +2,10 @@ import { useMemo } from "react"; import { LayoutType } from "types/chatting"; -import ChatDate from "../chatting-components/MessagesBody/ChatDate"; -import ChatInOut from "../chatting-components/MessagesBody/ChatInOut"; -import ChatSet from "../chatting-components/MessagesBody/ChatSet"; -import { Chats, getChatUniquewKey } from "../chatting-utils/chats"; +import ChatDate from "../chat-components/MessagesBody/ChatDate"; +import ChatInOut from "../chat-components/MessagesBody/ChatInOut"; +import ChatSet from "../chat-components/MessagesBody/ChatSet"; +import { Chats, getChatUniquewKey } from "../chat-utils/chats"; import loginInfoAtom from "atoms/loginInfo"; import { useRecoilValue } from "recoil"; diff --git a/src/components/Chatting/chatting-hooks/useSendMessage.tsx b/src/components/Chat/chat-hooks/useSendMessage.tsx similarity index 100% rename from src/components/Chatting/chatting-hooks/useSendMessage.tsx rename to src/components/Chat/chat-hooks/useSendMessage.tsx diff --git a/src/components/Chatting/chatting-hooks/useSocketChatEffect.tsx b/src/components/Chat/chat-hooks/useSocketChatEffect.tsx similarity index 93% rename from src/components/Chatting/chatting-hooks/useSocketChatEffect.tsx rename to src/components/Chat/chat-hooks/useSocketChatEffect.tsx index f3f3d310d..55b1f3d12 100644 --- a/src/components/Chatting/chatting-hooks/useSocketChatEffect.tsx +++ b/src/components/Chat/chat-hooks/useSocketChatEffect.tsx @@ -4,8 +4,8 @@ import { useStateWithCallbackLazy } from "use-state-with-callback"; import { useValueRecoilState } from "hooks/useFetchRecoilState"; import { useAxios } from "hooks/useTaxiAPI"; -import { Chats, checkoutChat, getCleanupChats } from "../chatting-utils/chats"; -import { isBottomOnScroll, scrollToBottom } from "../chatting-utils/scroll"; +import { Chats, checkoutChat, getCleanupChats } from "../chat-utils/chats"; +import { isBottomOnScroll, scrollToBottom } from "../chat-utils/scroll"; import { registerSocketEventListener, @@ -58,7 +58,7 @@ export default ( ); }, pushBackListener: (chats) => { - chats = chats.filter((chat) => chat.roomId === roomId); + // chats = chats.filter((chat) => chat.roomId === roomId); if (isExpired || chats.length <= 0) return; const isMyMessage = chats.some((chat) => chat.authorId === userOid); diff --git a/src/components/Chatting/chatting-utils/chats.ts b/src/components/Chat/chat-utils/chats.ts similarity index 100% rename from src/components/Chatting/chatting-utils/chats.ts rename to src/components/Chat/chat-utils/chats.ts diff --git a/src/components/Chatting/chatting-utils/scroll.ts b/src/components/Chat/chat-utils/scroll.ts similarity index 100% rename from src/components/Chatting/chatting-utils/scroll.ts rename to src/components/Chat/chat-utils/scroll.ts diff --git a/src/components/Chatting/index.tsx b/src/components/Chat/index.tsx similarity index 62% rename from src/components/Chatting/index.tsx rename to src/components/Chat/index.tsx index 6cbbe0894..b64db81e2 100644 --- a/src/components/Chatting/index.tsx +++ b/src/components/Chat/index.tsx @@ -7,29 +7,21 @@ import useDateToken from "hooks/useDateToken"; import useDisableScrollEffect from "hooks/useDisableScrollEffect"; import useQuery from "hooks/useTaxiAPI"; -import Container from "./chatting-components/Container"; -import Header from "./chatting-components/Header"; -import MessageForm from "./chatting-components/MessageForm"; -import MessagesBody from "./chatting-components/MessagesBody"; -import useBodyScrollControllerEffect from "./chatting-hooks/useBodyScrollControllerEffect"; -import useSendMessage from "./chatting-hooks/useSendMessage"; -import useSocketChatEffect from "./chatting-hooks/useSocketChatEffect"; -import { Chats } from "./chatting-utils/chats"; +import Container from "./chat-components/Container"; +import Header from "./chat-components/Header"; +import MessageForm from "./chat-components/MessageForm"; +import MessagesBody from "./chat-components/MessagesBody"; +import useBodyScrollControllerEffect from "./chat-hooks/useBodyScrollControllerEffect"; +import useSendMessage from "./chat-hooks/useSendMessage"; +import useSocketChatEffect from "./chat-hooks/useSocketChatEffect"; +import { Chats } from "./chat-utils/chats"; -import theme from "tools/theme"; - -type ChattingProps = { +type ChatProps = { roomId: string; layoutType: LayoutType; }; -type FullChatProps = { - roomId: ChattingProps["roomId"]; -}; -type SideChatProps = { - roomId: ChattingProps["roomId"]; -}; -const Chatting = ({ roomId, layoutType }: ChattingProps) => { +const Chat = ({ roomId, layoutType }: ChatProps) => { const [chats, setChats] = useStateWithCallbackLazy([]); // 채팅 메시지 배열 const [isDisplayNewMessage, setDisplayNewMessage] = useState(false); // 새로운 메시지 버튼 표시 여부 const messageBodyRef = useRef(null); // 스크롤 되는 메시지 HTML 요소 @@ -61,6 +53,9 @@ const Chatting = ({ roomId, layoutType }: ChattingProps) => { isCallingInfScroll ); + // 전체화면 챗에서는 body의 스크롤을 막습니다. + useDisableScrollEffect(layoutType === "fullchat"); + return (
{ ); }; -export const FullChat = ({ roomId }: FullChatProps) => { - // 전체화면 챗에서는 body의 스크롤을 막습니다. - useDisableScrollEffect(true); - - return ; -}; - -export const SideChat = ({ roomId }: SideChatProps) => ( -
- -
-); +export default Chat; diff --git a/src/components/RLayout.jsx b/src/components/RLayout.jsx index 1fd5588ec..349978e3a 100644 --- a/src/components/RLayout.jsx +++ b/src/components/RLayout.jsx @@ -6,7 +6,7 @@ const R1 = (props) => { const state = useR1state(); return (
{ const styleColumn = { width: state === 1 ? "390px" : "calc(50% - 27.5px)" }; return (
{ const state = usePopupstate(props.width); return (
{ const { roomId } = useParams() as { roomId: string }; - return ; + return ; }; export default Chatting; diff --git a/src/pages/Myroom/R2Myroom.jsx b/src/pages/Myroom/R2Myroom.jsx index 27ff41592..bbc42af3c 100644 --- a/src/pages/Myroom/R2Myroom.jsx +++ b/src/pages/Myroom/R2Myroom.jsx @@ -1,7 +1,7 @@ import PropTypes from "prop-types"; import { Link, useHistory } from "react-router-dom"; -import { SideChat } from "components/Chatting"; +import Chat from "components/Chat"; import DottedLine from "components/DottedLine"; import Empty from "components/Empty"; import Pagination, { PAGE_MAX_ITEMS } from "components/Pagination"; @@ -125,7 +125,7 @@ const R2Myroom = (props) => { }} > - +
) : null From c22b3d5f9cbd6bd55e56d0dad37371c2b5a9d07f Mon Sep 17 00:00:00 2001 From: 14Kgun Date: Wed, 19 Jul 2023 16:22:56 +0900 Subject: [PATCH 06/17] Move: Chat --- .../{chat-components => }/Container/index.tsx | 0 .../Header/Popup/PopupCancel.jsx | 0 .../Header/Popup/PopupContainer.jsx | 0 .../Header/Popup/PopupPay.jsx | 0 .../Header/Popup/PopupSend.jsx | 0 .../{chat-components => }/Header/SideMenu.tsx | 0 .../{chat-components => }/Header/index.tsx | 0 .../MessageForm/Form.tsx | 3 +- .../MessageForm/NewMessage.tsx | 0 .../MessageForm/Popup/PopupAccount.tsx | 0 .../MessageForm/index.tsx | 5 ++- .../MessagesBody/ChatPaySettle.tsx | 0 .../MessagesBody/ChatSet.jsx | 0 .../MessagesBody/ImageFullscreen.jsx | 0 .../Chat/MessagesBody/MessageDate.tsx | 34 +++++++++++++++ .../Chat/MessagesBody/MessageInOut.tsx | 29 +++++++++++++ .../Chat/MessagesBody/MessageSet/index.tsx | 3 ++ .../MessagesBody/index.tsx | 5 ++- .../chat-components/MessagesBody/ChatDate.jsx | 41 ------------------- .../MessagesBody/ChatInOut.jsx | 32 --------------- src/components/Chat/index.tsx | 17 ++++---- .../chat}/useBodyScrollControllerEffect.tsx | 4 +- .../chat}/useChatsForBody.tsx | 16 +++++--- .../chat}/useSendMessage.tsx | 0 .../chat}/useSocketChatEffect.tsx | 5 +-- .../Chat/chat-utils => tools/chat}/chats.ts | 0 .../Chat/chat-utils => tools/chat}/scroll.ts | 0 src/tools/day.ts | 9 ++-- 28 files changed, 102 insertions(+), 101 deletions(-) rename src/components/Chat/{chat-components => }/Container/index.tsx (100%) rename src/components/Chat/{chat-components => }/Header/Popup/PopupCancel.jsx (100%) rename src/components/Chat/{chat-components => }/Header/Popup/PopupContainer.jsx (100%) rename src/components/Chat/{chat-components => }/Header/Popup/PopupPay.jsx (100%) rename src/components/Chat/{chat-components => }/Header/Popup/PopupSend.jsx (100%) rename src/components/Chat/{chat-components => }/Header/SideMenu.tsx (100%) rename src/components/Chat/{chat-components => }/Header/index.tsx (100%) rename src/components/Chat/{chat-components => }/MessageForm/Form.tsx (98%) rename src/components/Chat/{chat-components => }/MessageForm/NewMessage.tsx (100%) rename src/components/Chat/{chat-components => }/MessageForm/Popup/PopupAccount.tsx (100%) rename src/components/Chat/{chat-components => }/MessageForm/index.tsx (92%) rename src/components/Chat/{chat-components => }/MessagesBody/ChatPaySettle.tsx (100%) rename src/components/Chat/{chat-components => }/MessagesBody/ChatSet.jsx (100%) rename src/components/Chat/{chat-components => }/MessagesBody/ImageFullscreen.jsx (100%) create mode 100644 src/components/Chat/MessagesBody/MessageDate.tsx create mode 100644 src/components/Chat/MessagesBody/MessageInOut.tsx create mode 100644 src/components/Chat/MessagesBody/MessageSet/index.tsx rename src/components/Chat/{chat-components => }/MessagesBody/index.tsx (85%) delete mode 100644 src/components/Chat/chat-components/MessagesBody/ChatDate.jsx delete mode 100644 src/components/Chat/chat-components/MessagesBody/ChatInOut.jsx rename src/{components/Chat/chat-hooks => hooks/chat}/useBodyScrollControllerEffect.tsx (93%) rename src/{components/Chat/chat-hooks => hooks/chat}/useChatsForBody.tsx (88%) rename src/{components/Chat/chat-hooks => hooks/chat}/useSendMessage.tsx (100%) rename src/{components/Chat/chat-hooks => hooks/chat}/useSocketChatEffect.tsx (95%) rename src/{components/Chat/chat-utils => tools/chat}/chats.ts (100%) rename src/{components/Chat/chat-utils => tools/chat}/scroll.ts (100%) diff --git a/src/components/Chat/chat-components/Container/index.tsx b/src/components/Chat/Container/index.tsx similarity index 100% rename from src/components/Chat/chat-components/Container/index.tsx rename to src/components/Chat/Container/index.tsx diff --git a/src/components/Chat/chat-components/Header/Popup/PopupCancel.jsx b/src/components/Chat/Header/Popup/PopupCancel.jsx similarity index 100% rename from src/components/Chat/chat-components/Header/Popup/PopupCancel.jsx rename to src/components/Chat/Header/Popup/PopupCancel.jsx diff --git a/src/components/Chat/chat-components/Header/Popup/PopupContainer.jsx b/src/components/Chat/Header/Popup/PopupContainer.jsx similarity index 100% rename from src/components/Chat/chat-components/Header/Popup/PopupContainer.jsx rename to src/components/Chat/Header/Popup/PopupContainer.jsx diff --git a/src/components/Chat/chat-components/Header/Popup/PopupPay.jsx b/src/components/Chat/Header/Popup/PopupPay.jsx similarity index 100% rename from src/components/Chat/chat-components/Header/Popup/PopupPay.jsx rename to src/components/Chat/Header/Popup/PopupPay.jsx diff --git a/src/components/Chat/chat-components/Header/Popup/PopupSend.jsx b/src/components/Chat/Header/Popup/PopupSend.jsx similarity index 100% rename from src/components/Chat/chat-components/Header/Popup/PopupSend.jsx rename to src/components/Chat/Header/Popup/PopupSend.jsx diff --git a/src/components/Chat/chat-components/Header/SideMenu.tsx b/src/components/Chat/Header/SideMenu.tsx similarity index 100% rename from src/components/Chat/chat-components/Header/SideMenu.tsx rename to src/components/Chat/Header/SideMenu.tsx diff --git a/src/components/Chat/chat-components/Header/index.tsx b/src/components/Chat/Header/index.tsx similarity index 100% rename from src/components/Chat/chat-components/Header/index.tsx rename to src/components/Chat/Header/index.tsx diff --git a/src/components/Chat/chat-components/MessageForm/Form.tsx b/src/components/Chat/MessageForm/Form.tsx similarity index 98% rename from src/components/Chat/chat-components/MessageForm/Form.tsx rename to src/components/Chat/MessageForm/Form.tsx index 80874f56b..d2f33dc14 100644 --- a/src/components/Chat/chat-components/MessageForm/Form.tsx +++ b/src/components/Chat/MessageForm/Form.tsx @@ -1,6 +1,7 @@ import { useEffect, useRef, useState } from "react"; -import useSendMessage from "../../chat-hooks/useSendMessage"; +import useSendMessage from "hooks/chat/useSendMessage"; + import PopupAccount from "./Popup/PopupAccount"; import regExpTest from "tools/regExpTest"; diff --git a/src/components/Chat/chat-components/MessageForm/NewMessage.tsx b/src/components/Chat/MessageForm/NewMessage.tsx similarity index 100% rename from src/components/Chat/chat-components/MessageForm/NewMessage.tsx rename to src/components/Chat/MessageForm/NewMessage.tsx diff --git a/src/components/Chat/chat-components/MessageForm/Popup/PopupAccount.tsx b/src/components/Chat/MessageForm/Popup/PopupAccount.tsx similarity index 100% rename from src/components/Chat/chat-components/MessageForm/Popup/PopupAccount.tsx rename to src/components/Chat/MessageForm/Popup/PopupAccount.tsx diff --git a/src/components/Chat/chat-components/MessageForm/index.tsx b/src/components/Chat/MessageForm/index.tsx similarity index 92% rename from src/components/Chat/chat-components/MessageForm/index.tsx rename to src/components/Chat/MessageForm/index.tsx index fc0af24cb..7415ac134 100644 --- a/src/components/Chat/chat-components/MessageForm/index.tsx +++ b/src/components/Chat/MessageForm/index.tsx @@ -2,14 +2,15 @@ import { RefObject, memo } from "react"; import { LayoutType } from "types/chatting"; -import useSendMessage from "../../chat-hooks/useSendMessage"; -import { scrollToBottom } from "../../chat-utils/scroll"; +import useSendMessage from "hooks/chat/useSendMessage"; + import Form from "./Form"; import NewMessage from "./NewMessage"; import isVirtualKeyboardDetectedAtom from "atoms/isVirtualKeyboardDetected"; import { useRecoilValue } from "recoil"; +import { scrollToBottom } from "tools/chat/scroll"; import theme from "tools/theme"; type MessageFormProps = { diff --git a/src/components/Chat/chat-components/MessagesBody/ChatPaySettle.tsx b/src/components/Chat/MessagesBody/ChatPaySettle.tsx similarity index 100% rename from src/components/Chat/chat-components/MessagesBody/ChatPaySettle.tsx rename to src/components/Chat/MessagesBody/ChatPaySettle.tsx diff --git a/src/components/Chat/chat-components/MessagesBody/ChatSet.jsx b/src/components/Chat/MessagesBody/ChatSet.jsx similarity index 100% rename from src/components/Chat/chat-components/MessagesBody/ChatSet.jsx rename to src/components/Chat/MessagesBody/ChatSet.jsx diff --git a/src/components/Chat/chat-components/MessagesBody/ImageFullscreen.jsx b/src/components/Chat/MessagesBody/ImageFullscreen.jsx similarity index 100% rename from src/components/Chat/chat-components/MessagesBody/ImageFullscreen.jsx rename to src/components/Chat/MessagesBody/ImageFullscreen.jsx diff --git a/src/components/Chat/MessagesBody/MessageDate.tsx b/src/components/Chat/MessagesBody/MessageDate.tsx new file mode 100644 index 000000000..753aeb13c --- /dev/null +++ b/src/components/Chat/MessagesBody/MessageDate.tsx @@ -0,0 +1,34 @@ +import DottedLine from "components/DottedLine"; + +import { Dayjs } from "tools/day"; +import theme from "tools/theme"; + +type MessageDateProps = { + date: Dayjs; +}; + +const MessageDate = ({ date }: MessageDateProps) => ( +
+ +
+ {date.format("YYYY년 M월 D일")} +
+
+); + +export default MessageDate; diff --git a/src/components/Chat/MessagesBody/MessageInOut.tsx b/src/components/Chat/MessagesBody/MessageInOut.tsx new file mode 100644 index 000000000..e3d14b82d --- /dev/null +++ b/src/components/Chat/MessagesBody/MessageInOut.tsx @@ -0,0 +1,29 @@ +import theme from "tools/theme"; + +type MessageInOutProps = { + type: "in" | "out"; + users: Array; +}; + +const MessageInOut = ({ type, users = [] }: MessageInOutProps) => ( +
+
+ {`${users.join(" 님, ")} 님이 ${ + type === "in" ? "입장하였습니다" : "퇴장하였습니다" + }`} +
+
+); + +export default MessageInOut; diff --git a/src/components/Chat/MessagesBody/MessageSet/index.tsx b/src/components/Chat/MessagesBody/MessageSet/index.tsx new file mode 100644 index 000000000..610878669 --- /dev/null +++ b/src/components/Chat/MessagesBody/MessageSet/index.tsx @@ -0,0 +1,3 @@ +const MessageSet = () => {}; + +export default MessageSet; diff --git a/src/components/Chat/chat-components/MessagesBody/index.tsx b/src/components/Chat/MessagesBody/index.tsx similarity index 85% rename from src/components/Chat/chat-components/MessagesBody/index.tsx rename to src/components/Chat/MessagesBody/index.tsx index 11e774054..e2ef1fa91 100644 --- a/src/components/Chat/chat-components/MessagesBody/index.tsx +++ b/src/components/Chat/MessagesBody/index.tsx @@ -2,8 +2,9 @@ import { ForwardedRef, forwardRef } from "react"; import { LayoutType } from "types/chatting"; -import useChatsForBody from "../../chat-hooks/useChatsForBody"; -import { Chats } from "../../chat-utils/chats"; +import useChatsForBody from "hooks/chat//useChatsForBody"; + +import { Chats } from "tools/chat/chats"; type MessagesBodyProps = { layoutType: LayoutType; diff --git a/src/components/Chat/chat-components/MessagesBody/ChatDate.jsx b/src/components/Chat/chat-components/MessagesBody/ChatDate.jsx deleted file mode 100644 index 9a2025be1..000000000 --- a/src/components/Chat/chat-components/MessagesBody/ChatDate.jsx +++ /dev/null @@ -1,41 +0,0 @@ -import PropTypes from "prop-types"; - -import DottedLine from "components/DottedLine"; - -import theme from "tools/theme"; - -const ChatDate = (props) => { - const year = props.date.year(); - const month = props.date.month() + 1; - const date = props.date.date(); - - return ( -
- -
- {year}년 {month}월 {date}일 -
- -
- ); -}; -ChatDate.propTypes = { - date: PropTypes.any, -}; - -export default ChatDate; diff --git a/src/components/Chat/chat-components/MessagesBody/ChatInOut.jsx b/src/components/Chat/chat-components/MessagesBody/ChatInOut.jsx deleted file mode 100644 index 3b7ea4b3e..000000000 --- a/src/components/Chat/chat-components/MessagesBody/ChatInOut.jsx +++ /dev/null @@ -1,32 +0,0 @@ -import PropTypes from "prop-types"; - -import theme from "tools/theme"; - -const ChatInOut = (props) => { - const endText = props.type === "in" ? "입장하였습니다" : "퇴장하였습니다"; - return ( -
-
- {props.users.join(" 님, ")} 님이 {endText} -
-
- ); -}; - -ChatInOut.propTypes = { - type: PropTypes.string, - users: PropTypes.array, -}; - -export default ChatInOut; diff --git a/src/components/Chat/index.tsx b/src/components/Chat/index.tsx index b64db81e2..3f51f2888 100644 --- a/src/components/Chat/index.tsx +++ b/src/components/Chat/index.tsx @@ -3,18 +3,19 @@ import { useStateWithCallbackLazy } from "use-state-with-callback"; import { LayoutType } from "types/chatting"; +import useBodyScrollControllerEffect from "hooks/chat/useBodyScrollControllerEffect"; +import useSendMessage from "hooks/chat/useSendMessage"; +import useSocketChatEffect from "hooks/chat/useSocketChatEffect"; import useDateToken from "hooks/useDateToken"; import useDisableScrollEffect from "hooks/useDisableScrollEffect"; import useQuery from "hooks/useTaxiAPI"; -import Container from "./chat-components/Container"; -import Header from "./chat-components/Header"; -import MessageForm from "./chat-components/MessageForm"; -import MessagesBody from "./chat-components/MessagesBody"; -import useBodyScrollControllerEffect from "./chat-hooks/useBodyScrollControllerEffect"; -import useSendMessage from "./chat-hooks/useSendMessage"; -import useSocketChatEffect from "./chat-hooks/useSocketChatEffect"; -import { Chats } from "./chat-utils/chats"; +import Container from "./Container"; +import Header from "./Header"; +import MessageForm from "./MessageForm"; +import MessagesBody from "./MessagesBody"; + +import { Chats } from "tools/chat/chats"; type ChatProps = { roomId: string; diff --git a/src/components/Chat/chat-hooks/useBodyScrollControllerEffect.tsx b/src/hooks/chat/useBodyScrollControllerEffect.tsx similarity index 93% rename from src/components/Chat/chat-hooks/useBodyScrollControllerEffect.tsx rename to src/hooks/chat/useBodyScrollControllerEffect.tsx index a8ceb25e3..e94b743ba 100644 --- a/src/components/Chat/chat-hooks/useBodyScrollControllerEffect.tsx +++ b/src/hooks/chat/useBodyScrollControllerEffect.tsx @@ -1,7 +1,7 @@ import { MutableRefObject, RefObject, useEffect, useLayoutEffect } from "react"; -import { Chats } from "../chat-utils/chats"; -import { isBottomOnScroll, scrollToBottom } from "../chat-utils/scroll"; +import { Chats } from "tools/chat/chats"; +import { isBottomOnScroll, scrollToBottom } from "tools/chat/scroll"; export default ( roomId: string, diff --git a/src/components/Chat/chat-hooks/useChatsForBody.tsx b/src/hooks/chat/useChatsForBody.tsx similarity index 88% rename from src/components/Chat/chat-hooks/useChatsForBody.tsx rename to src/hooks/chat/useChatsForBody.tsx index e551f31c2..f389a88c7 100644 --- a/src/components/Chat/chat-hooks/useChatsForBody.tsx +++ b/src/hooks/chat/useChatsForBody.tsx @@ -2,14 +2,15 @@ import { useMemo } from "react"; import { LayoutType } from "types/chatting"; -import ChatDate from "../chat-components/MessagesBody/ChatDate"; -import ChatInOut from "../chat-components/MessagesBody/ChatInOut"; -import ChatSet from "../chat-components/MessagesBody/ChatSet"; -import { Chats, getChatUniquewKey } from "../chat-utils/chats"; +import ChatSet from "components/Chat/MessagesBody/ChatSet"; +import MessageDate from "components/Chat/MessagesBody/MessageDate"; +import MessageInOut from "components/Chat/MessagesBody/MessageInOut"; import loginInfoAtom from "atoms/loginInfo"; import { useRecoilValue } from "recoil"; +import { Chats, getChatUniquewKey } from "tools/chat/chats"; +import dayjs from "tools/day"; import moment from "tools/moment"; export default (_chats: Chats, layoutType: LayoutType) => { @@ -70,7 +71,10 @@ export default (_chats: Chats, layoutType: LayoutType) => { } list.push( - + ); } if (item.type === "in" || item.type === "out") { @@ -85,7 +89,7 @@ export default (_chats: Chats, layoutType: LayoutType) => { chatsCache = null; } list.push( - { }; // 서버의 시각을 클라이언트의 시각으로 변환합니다. -export const dayServerToClient = (serverTime: dayjs.ConfigType) => { +export const dayServerToClient = (serverTime: ConfigType) => { const timeDiff = timeDiffWithServer ?? 0; return dayjs(serverTime).add(timeDiff, "millisecond"); }; // 클라이언트의 시각을 서버의 시각으로 변환합니다. -export const dayClientToServer = (clientTime: dayjs.ConfigType) => { +export const dayClientToServer = (clientTime: ConfigType) => { const timeDiff = timeDiffWithServer ?? 0; return dayjs(clientTime).subtract(timeDiff, "millisecond"); }; // 시각을 문자열로 변환합니다. -export const day2str = (day: dayjs.Dayjs, format = "LLLL") => { +export const day2str = (day: Dayjs, format = "LLLL") => { return day.format(format); }; +export type { Dayjs }; export default dayjs; From b693b4e1a20127862a121bf115ace54e37e87463 Mon Sep 17 00:00:00 2001 From: 14Kgun Date: Tue, 25 Jul 2023 03:05:26 +0900 Subject: [PATCH 07/17] Fix: package.json --- craco.config.js | 12 - package.json | 20 +- pnpm-lock.yaml | 831 +++++++++--------- src/components/Modal/ModalProvider.tsx | 8 +- .../ModalPopup/ModalReportInChatting.tsx | 2 + src/{index.js => index.tsx} | 0 src/types/report.d.ts | 7 + tsconfig.json | 1 - tsconfig.paths.json | 6 - 9 files changed, 435 insertions(+), 452 deletions(-) rename src/{index.js => index.tsx} (100%) create mode 100644 src/types/report.d.ts delete mode 100644 tsconfig.paths.json diff --git a/craco.config.js b/craco.config.js index a55b0fef5..b5114e18e 100644 --- a/craco.config.js +++ b/craco.config.js @@ -1,16 +1,4 @@ -const CracoAlias = require("craco-alias"); - module.exports = { - plugins: [ - { - plugin: CracoAlias, - options: { - baseUrl: "./src", - source: "tsconfig", - tsConfigPath: "./tsconfig.paths.json", - }, - }, - ], babel: { presets: [ [ diff --git a/package.json b/package.json index 40ec69bca..e35a04ed1 100644 --- a/package.json +++ b/package.json @@ -13,12 +13,9 @@ "@mui/icons-material": "^5.3.1", "@mui/material": "^5.4.1", "@svgr/webpack": "5.5.0", - "@types/qs": "^6.9.7", - "@types/react": "^17.0.0", "antd": "^5.4.6", "axios": "^0.21.1", "browser-image-compression": "^2.0.0", - "craco-alias": "^3.0.1", "cross-env": "^7.0.3", "dayjs": "^1.11.7", "dotenv": "^16.0.0", @@ -31,11 +28,11 @@ "qs": "^6.11.0", "react": "^18.2.0", "react-cookie": "^4.1.1", - "react-dom": "^18.0.4", + "react-dom": "^18.2.0", "react-ga4": "^1.4.1", "react-i18next": "^12.0.0", "react-qr-code": "^2.0.11", - "react-router-dom": "^5.3.4", + "react-router-dom": "^5.3.3", "recoil": "^0.7.5", "socket.io-client": "^4.3.2", "use-state-with-callback": "^3.0.2" @@ -67,12 +64,13 @@ "devDependencies": { "@trivago/prettier-plugin-sort-imports": "^4.1.1", "@types/craco__craco": "^6.4.0", - "@types/react": "^18.2.0", + "@types/qs": "^6.9.7", + "@types/react": "^18.2.15", + "@types/react-dom": "^18.2.7", + "@types/react-router-dom": "^5.3.3", "@types/eslint": "^8.44.0", "@types/eslint-config-prettier": "^6.11.0", "@types/prop-types": "^15.7.5", - "@types/react-dom": "^18.0.4", - "@types/react-router-dom": "^5.3.4", "@typescript-eslint/eslint-plugin": "^5.37.0", "@typescript-eslint/parser": "^5.37.0", "cypress": "^10.3.1", @@ -85,6 +83,10 @@ "eslint-plugin-jsx-a11y": "^6.4.1", "eslint-plugin-react": "^7.26.1", "eslint-plugin-react-hooks": "^4.2.0", - "typescript": "^4.7.4" + "typescript": "^5.1.6" + }, + "resolutions": { + "@types/react": "^17.0.2", + "@types/react-dom": "^17.0.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f25f90985..bced7a2bf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,13 +4,17 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + '@types/react': 17.0.2 + '@types/react-dom': 17.0.2 + dependencies: '@babel/preset-react': specifier: 7.12.5 version: 7.12.5(@babel/core@7.21.3) '@craco/craco': specifier: ^6.4.3 - version: 6.4.5(@types/node@18.15.10)(react-scripts@4.0.3)(typescript@4.9.5) + version: 6.4.5(@types/node@18.15.10)(react-scripts@4.0.3)(typescript@5.1.6) '@emotion/babel-plugin': specifier: ^11.10.6 version: 11.10.6 @@ -19,40 +23,31 @@ dependencies: version: 11.10.6 '@emotion/react': specifier: ^11.10.6 - version: 11.10.6(@types/react@17.0.0)(react@18.2.0) + version: 11.10.6(@types/react@17.0.2)(react@18.2.0) '@emotion/styled': specifier: ^11.10.6 - version: 11.10.6(@emotion/react@11.10.6)(@types/react@17.0.0)(react@18.2.0) + version: 11.10.6(@emotion/react@11.10.6)(@types/react@17.0.2)(react@18.2.0) '@material-ui/icons': specifier: ^4.11.2 - version: 4.11.3(@material-ui/core@4.12.4)(@types/react@17.0.0)(react-dom@18.1.0)(react@18.2.0) + version: 4.11.3(@material-ui/core@4.12.4)(@types/react@17.0.2)(react-dom@18.2.0)(react@18.2.0) '@mui/icons-material': specifier: ^5.3.1 - version: 5.11.11(@mui/material@5.11.15)(@types/react@17.0.0)(react@18.2.0) + version: 5.11.11(@mui/material@5.11.15)(@types/react@17.0.2)(react@18.2.0) '@mui/material': specifier: ^5.4.1 - version: 5.11.15(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@17.0.0)(react-dom@18.1.0)(react@18.2.0) + version: 5.11.15(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@17.0.2)(react-dom@18.2.0)(react@18.2.0) '@svgr/webpack': specifier: 5.5.0 version: 5.5.0 - '@types/qs': - specifier: ^6.9.7 - version: 6.9.7 - '@types/react': - specifier: ^17.0.0 - version: 17.0.0 antd: specifier: ^5.4.6 - version: 5.4.6(moment@2.29.4)(react-dom@18.1.0)(react@18.2.0) + version: 5.4.6(moment@2.29.4)(react-dom@18.2.0)(react@18.2.0) axios: specifier: ^0.21.1 version: 0.21.4 browser-image-compression: specifier: ^2.0.0 version: 2.0.2 - craco-alias: - specifier: ^3.0.1 - version: 3.0.1 cross-env: specifier: ^7.0.3 version: 7.0.3 @@ -90,14 +85,14 @@ dependencies: specifier: ^4.1.1 version: 4.1.1(react@18.2.0) react-dom: - specifier: ^18.0.4 - version: 18.1.0(react@18.2.0) + specifier: ^18.2.0 + version: 18.2.0(react@18.2.0) react-ga4: specifier: ^1.4.1 version: 1.4.1 react-i18next: specifier: ^12.0.0 - version: 12.2.0(i18next@22.4.13)(react-dom@18.1.0)(react@18.2.0) + version: 12.2.0(i18next@22.4.13)(react-dom@18.2.0)(react@18.2.0) react-qr-code: specifier: ^2.0.11 version: 2.0.11(react@18.2.0) @@ -106,13 +101,13 @@ dependencies: version: 5.3.4(react@18.2.0) recoil: specifier: ^0.7.5 - version: 0.7.7(react-dom@18.1.0)(react@18.2.0) + version: 0.7.7(react-dom@18.2.0)(react@18.2.0) socket.io-client: specifier: ^4.3.2 version: 4.6.1 use-state-with-callback: specifier: ^3.0.2 - version: 3.0.2(react-dom@18.1.0)(react@18.2.0) + version: 3.0.2(react-dom@18.2.0)(react@18.2.0) devDependencies: '@trivago/prettier-plugin-sort-imports': @@ -130,18 +125,24 @@ devDependencies: '@types/prop-types': specifier: ^15.7.5 version: 15.7.5 + '@types/qs': + specifier: ^6.9.7 + version: 6.9.7 + '@types/react': + specifier: 17.0.2 + version: 17.0.2 '@types/react-dom': - specifier: ^18.0.4 - version: 18.0.4 + specifier: 17.0.2 + version: 17.0.2 '@types/react-router-dom': specifier: ^5.3.3 version: 5.3.3 '@typescript-eslint/eslint-plugin': specifier: ^5.37.0 - version: 5.57.0(@typescript-eslint/parser@5.57.0)(eslint@7.32.0)(typescript@4.9.5) + version: 5.57.0(@typescript-eslint/parser@5.57.0)(eslint@7.32.0)(typescript@5.1.6) '@typescript-eslint/parser': specifier: ^5.37.0 - version: 5.57.0(eslint@7.32.0)(typescript@4.9.5) + version: 5.57.0(eslint@7.32.0)(typescript@5.1.6) cypress: specifier: ^10.3.1 version: 10.11.0 @@ -173,8 +174,8 @@ devDependencies: specifier: ^4.2.0 version: 4.6.0(eslint@7.32.0) typescript: - specifier: ^4.7.4 - version: 4.9.5 + specifier: ^5.1.6 + version: 5.1.6 packages: @@ -192,7 +193,7 @@ packages: '@ctrl/tinycolor': 3.6.0 dev: false - /@ant-design/cssinjs@1.9.1(react-dom@18.1.0)(react@18.2.0): + /@ant-design/cssinjs@1.9.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-CZt1vCMs/sY7RoacYuIkZwQmb8Bhp99ReNNE9Y8lnUzik8fmCdKAQA7ecvVOFwmNFdcBHga7ye/XIRrsbkiqWw==} peerDependencies: react: '>=16.0.0' @@ -203,9 +204,9 @@ packages: '@emotion/unitless': 0.7.5 classnames: 2.3.2 csstype: 3.1.2 - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) stylis: 4.1.3 dev: false @@ -213,7 +214,7 @@ packages: resolution: {integrity: sha512-EB0iwlKDGpG93hW8f85CTJTs4SvMX7tt5ceupvhALp1IF44SeUFOMhKUOYqpsoYWQKAOuTRDMqn75rEaKDp0Xw==} dev: false - /@ant-design/icons@5.0.1(react-dom@18.1.0)(react@18.2.0): + /@ant-design/icons@5.0.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-ZyF4ksXCcdtwA/1PLlnFLcF/q8/MhwxXhKHh4oCHDA4Ip+ZzAHoICtyp4wZWfiCVDP0yuz3HsjyvuldHFb3wjA==} engines: {node: '>=8'} peerDependencies: @@ -224,9 +225,9 @@ packages: '@ant-design/icons-svg': 4.2.1 '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false /@ant-design/react-slick@1.0.0(react@18.2.0): @@ -1815,7 +1816,7 @@ packages: dev: true optional: true - /@craco/craco@6.4.5(@types/node@18.15.10)(react-scripts@4.0.3)(typescript@4.9.5): + /@craco/craco@6.4.5(@types/node@18.15.10)(react-scripts@4.0.3)(typescript@5.1.6): resolution: {integrity: sha512-8F2rIAao8sEh0FPP52ViEvDM9GjJ7acq0knu1c8UgI+EuZMD5/ZB270ol6jV4iNY7it9Umg/RoGBvNRUNr8U8w==} engines: {node: '>=6'} hasBin: true @@ -1823,10 +1824,10 @@ packages: react-scripts: ^4.0.0 dependencies: cosmiconfig: 7.1.0 - cosmiconfig-typescript-loader: 1.0.9(@types/node@18.15.10)(cosmiconfig@7.1.0)(typescript@4.9.5) + cosmiconfig-typescript-loader: 1.0.9(@types/node@18.15.10)(cosmiconfig@7.1.0)(typescript@5.1.6) cross-spawn: 7.0.3 lodash: 4.17.21 - react-scripts: 4.0.3(eslint@7.32.0)(react@18.2.0)(typescript@4.9.5) + react-scripts: 4.0.3(eslint@7.32.0)(react@18.2.0)(typescript@5.1.6) semver: 7.3.8 webpack-merge: 4.2.2 transitivePeerDependencies: @@ -1968,7 +1969,7 @@ packages: resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} dev: false - /@emotion/react@11.10.6(@types/react@17.0.0)(react@18.2.0): + /@emotion/react@11.10.6(@types/react@17.0.2)(react@18.2.0): resolution: {integrity: sha512-6HT8jBmcSkfzO7mc+N1L9uwvOnlcGoix8Zn7srt+9ga0MjREo6lRpuVX0kzo6Jp6oTqDhREOFsygN6Ew4fEQbw==} peerDependencies: '@types/react': '*' @@ -1984,7 +1985,7 @@ packages: '@emotion/use-insertion-effect-with-fallbacks': 1.0.0(react@18.2.0) '@emotion/utils': 1.2.0 '@emotion/weak-memoize': 0.3.0 - '@types/react': 17.0.0 + '@types/react': 17.0.2 hoist-non-react-statics: 3.3.2 react: 18.2.0 dev: false @@ -2013,7 +2014,7 @@ packages: resolution: {integrity: sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==} dev: false - /@emotion/styled@11.10.6(@emotion/react@11.10.6)(@types/react@17.0.0)(react@18.2.0): + /@emotion/styled@11.10.6(@emotion/react@11.10.6)(@types/react@17.0.2)(react@18.2.0): resolution: {integrity: sha512-OXtBzOmDSJo5Q0AFemHCfl+bUueT8BIcPSxu0EGTpGk6DmI5dnhSzQANm1e1ze0YZL7TDyAyy6s/b/zmGOS3Og==} peerDependencies: '@emotion/react': ^11.0.0-rc.0 @@ -2026,11 +2027,11 @@ packages: '@babel/runtime': 7.21.0 '@emotion/babel-plugin': 11.11.0 '@emotion/is-prop-valid': 1.2.0 - '@emotion/react': 11.10.6(@types/react@17.0.0)(react@18.2.0) + '@emotion/react': 11.10.6(@types/react@17.0.2)(react@18.2.0) '@emotion/serialize': 1.1.1 '@emotion/use-insertion-effect-with-fallbacks': 1.0.0(react@18.2.0) '@emotion/utils': 1.2.0 - '@types/react': 17.0.0 + '@types/react': 17.0.2 react: 18.2.0 dev: false @@ -2888,7 +2889,7 @@ packages: '@jridgewell/sourcemap-codec': 1.4.14 dev: false - /@material-ui/core@4.12.4(@types/react@17.0.0)(react-dom@18.1.0)(react@18.2.0): + /@material-ui/core@4.12.4(@types/react@17.0.2)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-tr7xekNlM9LjA6pagJmL8QCgZXaubWUwkJnoYcMKd4gw/t4XiyvnTkjdGrUVicyB2BsdaAv1tvow45bPM4sSwQ==} engines: {node: '>=8.0.0'} deprecated: Material UI v4 doesn't receive active development since September 2021. See the guide https://mui.com/material-ui/migration/migration-v4/ to upgrade to v5. @@ -2901,23 +2902,23 @@ packages: optional: true dependencies: '@babel/runtime': 7.21.0 - '@material-ui/styles': 4.11.5(@types/react@17.0.0)(react-dom@18.1.0)(react@18.2.0) - '@material-ui/system': 4.12.2(@types/react@17.0.0)(react-dom@18.1.0)(react@18.2.0) - '@material-ui/types': 5.1.0(@types/react@17.0.0) - '@material-ui/utils': 4.11.3(react-dom@18.1.0)(react@18.2.0) - '@types/react': 17.0.0 + '@material-ui/styles': 4.11.5(@types/react@17.0.2)(react-dom@18.2.0)(react@18.2.0) + '@material-ui/system': 4.12.2(@types/react@17.0.2)(react-dom@18.2.0)(react@18.2.0) + '@material-ui/types': 5.1.0(@types/react@17.0.2) + '@material-ui/utils': 4.11.3(react-dom@18.2.0)(react@18.2.0) + '@types/react': 17.0.2 '@types/react-transition-group': 4.4.5 clsx: 1.2.1 hoist-non-react-statics: 3.3.2 popper.js: 1.16.1-lts prop-types: 15.8.1 react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) react-is: 17.0.2 - react-transition-group: 4.4.5(react-dom@18.1.0)(react@18.2.0) + react-transition-group: 4.4.5(react-dom@18.2.0)(react@18.2.0) dev: false - /@material-ui/icons@4.11.3(@material-ui/core@4.12.4)(@types/react@17.0.0)(react-dom@18.1.0)(react@18.2.0): + /@material-ui/icons@4.11.3(@material-ui/core@4.12.4)(@types/react@17.0.2)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-IKHlyx6LDh8n19vzwH5RtHIOHl9Tu90aAAxcbWME6kp4dmvODM3UvOHJeMIDzUbd4muuJKHmlNoBN+mDY4XkBA==} engines: {node: '>=8.0.0'} peerDependencies: @@ -2930,13 +2931,13 @@ packages: optional: true dependencies: '@babel/runtime': 7.21.0 - '@material-ui/core': 4.12.4(@types/react@17.0.0)(react-dom@18.1.0)(react@18.2.0) - '@types/react': 17.0.0 + '@material-ui/core': 4.12.4(@types/react@17.0.2)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 17.0.2 react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /@material-ui/styles@4.11.5(@types/react@17.0.0)(react-dom@18.1.0)(react@18.2.0): + /@material-ui/styles@4.11.5(@types/react@17.0.2)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-o/41ot5JJiUsIETME9wVLAJrmIWL3j0R0Bj2kCOLbSfqEkKf0fmaPt+5vtblUh5eXr2S+J/8J3DaCb10+CzPGA==} engines: {node: '>=8.0.0'} deprecated: Material UI v4 doesn't receive active development since September 2021. See the guide https://mui.com/material-ui/migration/migration-v4/ to upgrade to v5. @@ -2950,9 +2951,9 @@ packages: dependencies: '@babel/runtime': 7.21.0 '@emotion/hash': 0.8.0 - '@material-ui/types': 5.1.0(@types/react@17.0.0) - '@material-ui/utils': 4.11.3(react-dom@18.1.0)(react@18.2.0) - '@types/react': 17.0.0 + '@material-ui/types': 5.1.0(@types/react@17.0.2) + '@material-ui/utils': 4.11.3(react-dom@18.2.0)(react@18.2.0) + '@types/react': 17.0.2 clsx: 1.2.1 csstype: 2.6.21 hoist-non-react-statics: 3.3.2 @@ -2966,10 +2967,10 @@ packages: jss-plugin-vendor-prefixer: 10.10.0 prop-types: 15.8.1 react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /@material-ui/system@4.12.2(@types/react@17.0.0)(react-dom@18.1.0)(react@18.2.0): + /@material-ui/system@4.12.2(@types/react@17.0.2)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-6CSKu2MtmiJgcCGf6nBQpM8fLkuB9F55EKfbdTC80NND5wpTmKzwdhLYLH3zL4cLlK0gVaaltW7/wMuyTnN0Lw==} engines: {node: '>=8.0.0'} peerDependencies: @@ -2981,15 +2982,15 @@ packages: optional: true dependencies: '@babel/runtime': 7.21.0 - '@material-ui/utils': 4.11.3(react-dom@18.1.0)(react@18.2.0) - '@types/react': 17.0.0 + '@material-ui/utils': 4.11.3(react-dom@18.2.0)(react@18.2.0) + '@types/react': 17.0.2 csstype: 2.6.21 prop-types: 15.8.1 react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /@material-ui/types@5.1.0(@types/react@17.0.0): + /@material-ui/types@5.1.0(@types/react@17.0.2): resolution: {integrity: sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==} peerDependencies: '@types/react': '*' @@ -2997,10 +2998,10 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 17.0.0 + '@types/react': 17.0.2 dev: false - /@material-ui/utils@4.11.3(react-dom@18.1.0)(react@18.2.0): + /@material-ui/utils@4.11.3(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-ZuQPV4rBK/V1j2dIkSSEcH5uT6AaHuKWFfotADHsC0wVL1NLd2WkFCm4ZZbX33iO4ydl6V0GPngKm8HZQ2oujg==} engines: {node: '>=8.0.0'} peerDependencies: @@ -3010,11 +3011,11 @@ packages: '@babel/runtime': 7.21.0 prop-types: 15.8.1 react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) react-is: 17.0.2 dev: false - /@mui/base@5.0.0-alpha.123(@types/react@17.0.0)(react-dom@18.1.0)(react@18.2.0): + /@mui/base@5.0.0-alpha.123(@types/react@17.0.2)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-pxzcAfET3I6jvWqS4kijiLMn1OmdMw+mGmDa0SqmDZo3bXXdvLhpCCPqCkULG3UykhvFCOcU5HclOX3JCA+Zhg==} engines: {node: '>=12.0.0'} peerDependencies: @@ -3027,14 +3028,14 @@ packages: dependencies: '@babel/runtime': 7.21.0 '@emotion/is-prop-valid': 1.2.0 - '@mui/types': 7.2.3(@types/react@17.0.0) + '@mui/types': 7.2.3(@types/react@17.0.2) '@mui/utils': 5.11.13(react@18.2.0) '@popperjs/core': 2.11.7 - '@types/react': 17.0.0 + '@types/react': 17.0.2 clsx: 1.2.1 prop-types: 15.8.1 react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) react-is: 18.2.0 dev: false @@ -3042,7 +3043,7 @@ packages: resolution: {integrity: sha512-Q0e2oBsjHyIWWj1wLzl14btunvBYC0yl+px7zL9R69tF87uenj6q72ieS369BJ6jxYpJwvXfR6/f+TC+ZUsKKg==} dev: false - /@mui/icons-material@5.11.11(@mui/material@5.11.15)(@types/react@17.0.0)(react@18.2.0): + /@mui/icons-material@5.11.11(@mui/material@5.11.15)(@types/react@17.0.2)(react@18.2.0): resolution: {integrity: sha512-Eell3ADmQVE8HOpt/LZ3zIma8JSvPh3XgnhwZLT0k5HRqZcd6F/QDHc7xsWtgz09t+UEFvOYJXjtrwKmLdwwpw==} engines: {node: '>=12.0.0'} peerDependencies: @@ -3054,12 +3055,12 @@ packages: optional: true dependencies: '@babel/runtime': 7.21.0 - '@mui/material': 5.11.15(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@17.0.0)(react-dom@18.1.0)(react@18.2.0) - '@types/react': 17.0.0 + '@mui/material': 5.11.15(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@17.0.2)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 17.0.2 react: 18.2.0 dev: false - /@mui/material@5.11.15(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@17.0.0)(react-dom@18.1.0)(react@18.2.0): + /@mui/material@5.11.15(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@17.0.2)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-E5RbLq9/OvRKmGyeZawdnmFBCvhKkI/Zqgr0xFqW27TGwKLxObq/BreJc6Uu5Sbv8Fjj34vEAbRx6otfOyxn5w==} engines: {node: '>=12.0.0'} peerDependencies: @@ -3077,25 +3078,25 @@ packages: optional: true dependencies: '@babel/runtime': 7.21.0 - '@emotion/react': 11.10.6(@types/react@17.0.0)(react@18.2.0) - '@emotion/styled': 11.10.6(@emotion/react@11.10.6)(@types/react@17.0.0)(react@18.2.0) - '@mui/base': 5.0.0-alpha.123(@types/react@17.0.0)(react-dom@18.1.0)(react@18.2.0) + '@emotion/react': 11.10.6(@types/react@17.0.2)(react@18.2.0) + '@emotion/styled': 11.10.6(@emotion/react@11.10.6)(@types/react@17.0.2)(react@18.2.0) + '@mui/base': 5.0.0-alpha.123(@types/react@17.0.2)(react-dom@18.2.0)(react@18.2.0) '@mui/core-downloads-tracker': 5.11.15 - '@mui/system': 5.11.15(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@17.0.0)(react@18.2.0) - '@mui/types': 7.2.3(@types/react@17.0.0) + '@mui/system': 5.11.15(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@17.0.2)(react@18.2.0) + '@mui/types': 7.2.3(@types/react@17.0.2) '@mui/utils': 5.11.13(react@18.2.0) - '@types/react': 17.0.0 + '@types/react': 17.0.2 '@types/react-transition-group': 4.4.5 clsx: 1.2.1 csstype: 3.1.2 prop-types: 15.8.1 react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) react-is: 18.2.0 - react-transition-group: 4.4.5(react-dom@18.1.0)(react@18.2.0) + react-transition-group: 4.4.5(react-dom@18.2.0)(react@18.2.0) dev: false - /@mui/private-theming@5.11.13(@types/react@17.0.0)(react@18.2.0): + /@mui/private-theming@5.11.13(@types/react@17.0.2)(react@18.2.0): resolution: {integrity: sha512-PJnYNKzW5LIx3R+Zsp6WZVPs6w5sEKJ7mgLNnUXuYB1zo5aX71FVLtV7geyPXRcaN2tsoRNK7h444ED0t7cIjA==} engines: {node: '>=12.0.0'} peerDependencies: @@ -3107,7 +3108,7 @@ packages: dependencies: '@babel/runtime': 7.21.0 '@mui/utils': 5.11.13(react@18.2.0) - '@types/react': 17.0.0 + '@types/react': 17.0.2 prop-types: 15.8.1 react: 18.2.0 dev: false @@ -3127,14 +3128,14 @@ packages: dependencies: '@babel/runtime': 7.21.0 '@emotion/cache': 11.10.5 - '@emotion/react': 11.10.6(@types/react@17.0.0)(react@18.2.0) - '@emotion/styled': 11.10.6(@emotion/react@11.10.6)(@types/react@17.0.0)(react@18.2.0) + '@emotion/react': 11.10.6(@types/react@17.0.2)(react@18.2.0) + '@emotion/styled': 11.10.6(@emotion/react@11.10.6)(@types/react@17.0.2)(react@18.2.0) csstype: 3.1.2 prop-types: 15.8.1 react: 18.2.0 dev: false - /@mui/system@5.11.15(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@17.0.0)(react@18.2.0): + /@mui/system@5.11.15(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(@types/react@17.0.2)(react@18.2.0): resolution: {integrity: sha512-vCatoWCTnAPquoNifHbqMCMnOElEbLosVUeW0FQDyjCq+8yMABD9E6iY0s14O7iq1wD+qqU7rFAuDIVvJ/AzzA==} engines: {node: '>=12.0.0'} peerDependencies: @@ -3151,20 +3152,20 @@ packages: optional: true dependencies: '@babel/runtime': 7.21.0 - '@emotion/react': 11.10.6(@types/react@17.0.0)(react@18.2.0) - '@emotion/styled': 11.10.6(@emotion/react@11.10.6)(@types/react@17.0.0)(react@18.2.0) - '@mui/private-theming': 5.11.13(@types/react@17.0.0)(react@18.2.0) + '@emotion/react': 11.10.6(@types/react@17.0.2)(react@18.2.0) + '@emotion/styled': 11.10.6(@emotion/react@11.10.6)(@types/react@17.0.2)(react@18.2.0) + '@mui/private-theming': 5.11.13(@types/react@17.0.2)(react@18.2.0) '@mui/styled-engine': 5.11.11(@emotion/react@11.10.6)(@emotion/styled@11.10.6)(react@18.2.0) - '@mui/types': 7.2.3(@types/react@17.0.0) + '@mui/types': 7.2.3(@types/react@17.0.2) '@mui/utils': 5.11.13(react@18.2.0) - '@types/react': 17.0.0 + '@types/react': 17.0.2 clsx: 1.2.1 csstype: 3.1.2 prop-types: 15.8.1 react: 18.2.0 dev: false - /@mui/types@7.2.3(@types/react@17.0.0): + /@mui/types@7.2.3(@types/react@17.0.2): resolution: {integrity: sha512-tZ+CQggbe9Ol7e/Fs5RcKwg/woU+o8DCtOnccX6KmbBc7YrfqMYEYuaIcXHuhpT880QwNkZZ3wQwvtlDFA2yOw==} peerDependencies: '@types/react': '*' @@ -3172,7 +3173,7 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 17.0.0 + '@types/react': 17.0.2 dev: false /@mui/utils@5.11.13(react@18.2.0): @@ -3307,16 +3308,16 @@ packages: resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} dev: false - /@rc-component/context@1.3.0(react-dom@18.1.0)(react@18.2.0): + /@rc-component/context@1.3.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-6QdaCJ7Wn5UZLJs15IEfqy4Ru3OaL5ctqpQYWd5rlfV9wwzrzdt6+kgAQZV/qdB0MUPN4nhyBfRembQCIvBf+w==} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' dependencies: '@babel/runtime': 7.21.0 - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false /@rc-component/mini-decimal@1.0.1: @@ -3326,7 +3327,7 @@ packages: '@babel/runtime': 7.21.0 dev: false - /@rc-component/mutate-observer@1.0.0(react-dom@18.1.0)(react@18.2.0): + /@rc-component/mutate-observer@1.0.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-okqRJSfNisXdI6CUeOLZC5ukBW/8kir2Ii4PJiKpUt+3+uS7dxwJUMxsUZquxA1rQuL8YcEmKVp/TCnR+yUdZA==} engines: {node: '>=8.x'} peerDependencies: @@ -3335,12 +3336,12 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /@rc-component/portal@1.1.1(react-dom@18.1.0)(react@18.2.0): + /@rc-component/portal@1.1.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-m8w3dFXX0H6UkJ4wtfrSwhe2/6M08uz24HHrF8pWfAXPwA9hwCuTE5per/C86KwNLouRpwFGcr7LfpHaa1F38g==} engines: {node: '>=8.x'} peerDependencies: @@ -3349,12 +3350,12 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /@rc-component/tour@1.8.0(react-dom@18.1.0)(react@18.2.0): + /@rc-component/tour@1.8.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-rrRGioHTLQlGca27G2+lw7QpRb3uuMYCUIJjj31/B44VCJS0P2tqYhOgtzvWQmaLMlWH3ZlpzotkKX13NT4XEA==} engines: {node: '>=8.x'} peerDependencies: @@ -3362,15 +3363,15 @@ packages: react-dom: '>=16.9.0' dependencies: '@babel/runtime': 7.21.0 - '@rc-component/portal': 1.1.1(react-dom@18.1.0)(react@18.2.0) - '@rc-component/trigger': 1.10.0(react-dom@18.1.0)(react@18.2.0) + '@rc-component/portal': 1.1.1(react-dom@18.2.0)(react@18.2.0) + '@rc-component/trigger': 1.10.0(react-dom@18.2.0)(react@18.2.0) classnames: 2.3.2 - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /@rc-component/trigger@1.10.0(react-dom@18.1.0)(react@18.2.0): + /@rc-component/trigger@1.10.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-kDnsBBUIX+oCk1nhZ8vwCFiq15sIXqvYlRLTnSWXDTgec8SRjHxIA2T47FbWVlZ9PtlT1NIVWH8q3GbiSRKWUA==} engines: {node: '>=8.x'} peerDependencies: @@ -3378,14 +3379,14 @@ packages: react-dom: '>=16.9.0' dependencies: '@babel/runtime': 7.21.0 - '@rc-component/portal': 1.1.1(react-dom@18.1.0)(react@18.2.0) + '@rc-component/portal': 1.1.1(react-dom@18.2.0)(react@18.2.0) classnames: 2.3.2 - rc-align: 4.0.15(react-dom@18.1.0)(react@18.2.0) - rc-motion: 2.7.3(react-dom@18.1.0)(react@18.2.0) - rc-resize-observer: 1.3.1(react-dom@18.1.0)(react@18.2.0) - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-align: 4.0.15(react-dom@18.2.0)(react@18.2.0) + rc-motion: 2.7.3(react-dom@18.2.0)(react@18.2.0) + rc-resize-observer: 1.3.1(react-dom@18.2.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false /@rollup/plugin-node-resolve@7.1.3(rollup@1.32.1): @@ -3779,7 +3780,7 @@ packages: /@types/hoist-non-react-statics@3.3.1: resolution: {integrity: sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==} dependencies: - '@types/react': 17.0.0 + '@types/react': 17.0.2 hoist-non-react-statics: 3.3.2 dev: false @@ -3860,28 +3861,29 @@ packages: /@types/qs@6.9.7: resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} + dev: true /@types/range-parser@1.2.4: resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} dev: true - /@types/react-dom@18.0.4: - resolution: {integrity: sha512-FgTtbqPOCI3dzZPZoC2T/sx3L34qxy99ITWn4eoSA95qPyXDMH0ALoAqUp49ITniiJFsXUVBtalh/KffMpg21Q==} + /@types/react-dom@17.0.2: + resolution: {integrity: sha512-Icd9KEgdnFfJs39KyRyr0jQ7EKhq8U6CcHRMGAS45fp5qgUvxL3ujUCfWFttUK2UErqZNj97t9gsVPNAqcwoCg==} dependencies: - '@types/react': 17.0.0 + '@types/react': 17.0.2 dev: true /@types/react-is@17.0.3: resolution: {integrity: sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==} dependencies: - '@types/react': 17.0.0 + '@types/react': 17.0.2 dev: false /@types/react-router-dom@5.3.3: resolution: {integrity: sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==} dependencies: '@types/history': 4.7.11 - '@types/react': 18.2.14 + '@types/react': 17.0.2 '@types/react-router': 5.1.20 dev: true @@ -3889,28 +3891,20 @@ packages: resolution: {integrity: sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==} dependencies: '@types/history': 4.7.11 - '@types/react': 17.0.0 + '@types/react': 17.0.2 dev: true /@types/react-transition-group@4.4.5: resolution: {integrity: sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==} dependencies: - '@types/react': 17.0.0 + '@types/react': 17.0.2 dev: false - /@types/react@17.0.0: - resolution: {integrity: sha512-aj/L7RIMsRlWML3YB6KZiXB3fV2t41+5RBGYF8z+tAKU43Px8C3cYUZsDvf1/+Bm4FK21QWBrDutu8ZJ/70qOw==} - dependencies: - '@types/prop-types': 15.7.5 - csstype: 3.1.2 - - /@types/react@18.2.14: - resolution: {integrity: sha512-A0zjq+QN/O0Kpe30hA1GidzyFjatVvrpIvWLxD+xv67Vt91TWWgco9IvrJBkeyHm1trGaFS/FSGqPlhyeZRm0g==} + /@types/react@17.0.2: + resolution: {integrity: sha512-Xt40xQsrkdvjn1EyWe1Bc0dJLcil/9x2vAuW7ya+PuQip4UYUaXyhzWmAbwRsdMgwOFHpfp7/FFZebDU6Y8VHA==} dependencies: '@types/prop-types': 15.7.5 - '@types/scheduler': 0.16.3 csstype: 3.1.2 - dev: true /@types/resolve@0.0.8: resolution: {integrity: sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==} @@ -3918,10 +3912,6 @@ packages: '@types/node': 18.15.10 dev: false - /@types/scheduler@0.16.3: - resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==} - dev: true - /@types/semver@7.3.13: resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==} dev: true @@ -4016,7 +4006,7 @@ packages: dev: true optional: true - /@typescript-eslint/eslint-plugin@4.33.0(@typescript-eslint/parser@4.33.0)(eslint@7.32.0)(typescript@4.9.5): + /@typescript-eslint/eslint-plugin@4.33.0(@typescript-eslint/parser@4.33.0)(eslint@7.32.0)(typescript@5.1.6): resolution: {integrity: sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -4027,8 +4017,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/experimental-utils': 4.33.0(eslint@7.32.0)(typescript@4.9.5) - '@typescript-eslint/parser': 4.33.0(eslint@7.32.0)(typescript@4.9.5) + '@typescript-eslint/experimental-utils': 4.33.0(eslint@7.32.0)(typescript@5.1.6) + '@typescript-eslint/parser': 4.33.0(eslint@7.32.0)(typescript@5.1.6) '@typescript-eslint/scope-manager': 4.33.0 debug: 4.3.4(supports-color@6.1.0) eslint: 7.32.0 @@ -4036,13 +4026,13 @@ packages: ignore: 5.2.4 regexpp: 3.2.0 semver: 7.3.8 - tsutils: 3.21.0(typescript@4.9.5) - typescript: 4.9.5 + tsutils: 3.21.0(typescript@5.1.6) + typescript: 5.1.6 transitivePeerDependencies: - supports-color dev: false - /@typescript-eslint/eslint-plugin@5.57.0(@typescript-eslint/parser@5.57.0)(eslint@7.32.0)(typescript@4.9.5): + /@typescript-eslint/eslint-plugin@5.57.0(@typescript-eslint/parser@5.57.0)(eslint@7.32.0)(typescript@5.1.6): resolution: {integrity: sha512-itag0qpN6q2UMM6Xgk6xoHa0D0/P+M17THnr4SVgqn9Rgam5k/He33MA7/D7QoJcdMxHFyX7U9imaBonAX/6qA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -4054,23 +4044,23 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.4.1 - '@typescript-eslint/parser': 5.57.0(eslint@7.32.0)(typescript@4.9.5) + '@typescript-eslint/parser': 5.57.0(eslint@7.32.0)(typescript@5.1.6) '@typescript-eslint/scope-manager': 5.57.0 - '@typescript-eslint/type-utils': 5.57.0(eslint@7.32.0)(typescript@4.9.5) - '@typescript-eslint/utils': 5.57.0(eslint@7.32.0)(typescript@4.9.5) + '@typescript-eslint/type-utils': 5.57.0(eslint@7.32.0)(typescript@5.1.6) + '@typescript-eslint/utils': 5.57.0(eslint@7.32.0)(typescript@5.1.6) debug: 4.3.4(supports-color@6.1.0) eslint: 7.32.0 grapheme-splitter: 1.0.4 ignore: 5.2.4 natural-compare-lite: 1.4.0 semver: 7.3.8 - tsutils: 3.21.0(typescript@4.9.5) - typescript: 4.9.5 + tsutils: 3.21.0(typescript@5.1.6) + typescript: 5.1.6 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/experimental-utils@3.10.1(eslint@7.32.0)(typescript@4.9.5): + /@typescript-eslint/experimental-utils@3.10.1(eslint@7.32.0)(typescript@5.1.6): resolution: {integrity: sha512-DewqIgscDzmAfd5nOGe4zm6Bl7PKtMG2Ad0KG8CUZAHlXfAKTF9Ol5PXhiMh39yRL2ChRH1cuuUGOcVyyrhQIw==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -4078,7 +4068,7 @@ packages: dependencies: '@types/json-schema': 7.0.11 '@typescript-eslint/types': 3.10.1 - '@typescript-eslint/typescript-estree': 3.10.1(typescript@4.9.5) + '@typescript-eslint/typescript-estree': 3.10.1(typescript@5.1.6) eslint: 7.32.0 eslint-scope: 5.1.1 eslint-utils: 2.1.0 @@ -4087,7 +4077,7 @@ packages: - typescript dev: false - /@typescript-eslint/experimental-utils@4.33.0(eslint@7.32.0)(typescript@4.9.5): + /@typescript-eslint/experimental-utils@4.33.0(eslint@7.32.0)(typescript@5.1.6): resolution: {integrity: sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -4096,7 +4086,7 @@ packages: '@types/json-schema': 7.0.11 '@typescript-eslint/scope-manager': 4.33.0 '@typescript-eslint/types': 4.33.0 - '@typescript-eslint/typescript-estree': 4.33.0(typescript@4.9.5) + '@typescript-eslint/typescript-estree': 4.33.0(typescript@5.1.6) eslint: 7.32.0 eslint-scope: 5.1.1 eslint-utils: 3.0.0(eslint@7.32.0) @@ -4105,7 +4095,7 @@ packages: - typescript dev: false - /@typescript-eslint/parser@4.33.0(eslint@7.32.0)(typescript@4.9.5): + /@typescript-eslint/parser@4.33.0(eslint@7.32.0)(typescript@5.1.6): resolution: {integrity: sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -4117,15 +4107,15 @@ packages: dependencies: '@typescript-eslint/scope-manager': 4.33.0 '@typescript-eslint/types': 4.33.0 - '@typescript-eslint/typescript-estree': 4.33.0(typescript@4.9.5) + '@typescript-eslint/typescript-estree': 4.33.0(typescript@5.1.6) debug: 4.3.4(supports-color@6.1.0) eslint: 7.32.0 - typescript: 4.9.5 + typescript: 5.1.6 transitivePeerDependencies: - supports-color dev: false - /@typescript-eslint/parser@5.57.0(eslint@7.32.0)(typescript@4.9.5): + /@typescript-eslint/parser@5.57.0(eslint@7.32.0)(typescript@5.1.6): resolution: {integrity: sha512-orrduvpWYkgLCyAdNtR1QIWovcNZlEm6yL8nwH/eTxWLd8gsP+25pdLHYzL2QdkqrieaDwLpytHqycncv0woUQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -4137,10 +4127,10 @@ packages: dependencies: '@typescript-eslint/scope-manager': 5.57.0 '@typescript-eslint/types': 5.57.0 - '@typescript-eslint/typescript-estree': 5.57.0(typescript@4.9.5) + '@typescript-eslint/typescript-estree': 5.57.0(typescript@5.1.6) debug: 4.3.4(supports-color@6.1.0) eslint: 7.32.0 - typescript: 4.9.5 + typescript: 5.1.6 transitivePeerDependencies: - supports-color dev: true @@ -4161,7 +4151,7 @@ packages: '@typescript-eslint/visitor-keys': 5.57.0 dev: true - /@typescript-eslint/type-utils@5.57.0(eslint@7.32.0)(typescript@4.9.5): + /@typescript-eslint/type-utils@5.57.0(eslint@7.32.0)(typescript@5.1.6): resolution: {integrity: sha512-kxXoq9zOTbvqzLbdNKy1yFrxLC6GDJFE2Yuo3KqSwTmDOFjUGeWSakgoXT864WcK5/NAJkkONCiKb1ddsqhLXQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -4171,12 +4161,12 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.57.0(typescript@4.9.5) - '@typescript-eslint/utils': 5.57.0(eslint@7.32.0)(typescript@4.9.5) + '@typescript-eslint/typescript-estree': 5.57.0(typescript@5.1.6) + '@typescript-eslint/utils': 5.57.0(eslint@7.32.0)(typescript@5.1.6) debug: 4.3.4(supports-color@6.1.0) eslint: 7.32.0 - tsutils: 3.21.0(typescript@4.9.5) - typescript: 4.9.5 + tsutils: 3.21.0(typescript@5.1.6) + typescript: 5.1.6 transitivePeerDependencies: - supports-color dev: true @@ -4196,7 +4186,7 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/typescript-estree@3.10.1(typescript@4.9.5): + /@typescript-eslint/typescript-estree@3.10.1(typescript@5.1.6): resolution: {integrity: sha512-QbcXOuq6WYvnB3XPsZpIwztBoquEYLXh2MtwVU+kO8jgYCiv4G5xrSP/1wg4tkvrEE+esZVquIPX/dxPlePk1w==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -4212,13 +4202,13 @@ packages: is-glob: 4.0.3 lodash: 4.17.21 semver: 7.3.8 - tsutils: 3.21.0(typescript@4.9.5) - typescript: 4.9.5 + tsutils: 3.21.0(typescript@5.1.6) + typescript: 5.1.6 transitivePeerDependencies: - supports-color dev: false - /@typescript-eslint/typescript-estree@4.33.0(typescript@4.9.5): + /@typescript-eslint/typescript-estree@4.33.0(typescript@5.1.6): resolution: {integrity: sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -4233,13 +4223,13 @@ packages: globby: 11.1.0 is-glob: 4.0.3 semver: 7.3.8 - tsutils: 3.21.0(typescript@4.9.5) - typescript: 4.9.5 + tsutils: 3.21.0(typescript@5.1.6) + typescript: 5.1.6 transitivePeerDependencies: - supports-color dev: false - /@typescript-eslint/typescript-estree@5.57.0(typescript@4.9.5): + /@typescript-eslint/typescript-estree@5.57.0(typescript@5.1.6): resolution: {integrity: sha512-LTzQ23TV82KpO8HPnWuxM2V7ieXW8O142I7hQTxWIHDcCEIjtkat6H96PFkYBQqGFLW/G/eVVOB9Z8rcvdY/Vw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -4254,13 +4244,13 @@ packages: globby: 11.1.0 is-glob: 4.0.3 semver: 7.3.8 - tsutils: 3.21.0(typescript@4.9.5) - typescript: 4.9.5 + tsutils: 3.21.0(typescript@5.1.6) + typescript: 5.1.6 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils@5.57.0(eslint@7.32.0)(typescript@4.9.5): + /@typescript-eslint/utils@5.57.0(eslint@7.32.0)(typescript@5.1.6): resolution: {integrity: sha512-ps/4WohXV7C+LTSgAL5CApxvxbMkl9B9AUZRtnEFonpIxZDIT7wC1xfvuJONMidrkB9scs4zhtRyIwHh4+18kw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -4271,7 +4261,7 @@ packages: '@types/semver': 7.3.13 '@typescript-eslint/scope-manager': 5.57.0 '@typescript-eslint/types': 5.57.0 - '@typescript-eslint/typescript-estree': 5.57.0(typescript@4.9.5) + '@typescript-eslint/typescript-estree': 5.57.0(typescript@5.1.6) eslint: 7.32.0 eslint-scope: 5.1.1 semver: 7.3.8 @@ -4603,59 +4593,59 @@ packages: dependencies: color-convert: 2.0.1 - /antd@5.4.6(moment@2.29.4)(react-dom@18.1.0)(react@18.2.0): + /antd@5.4.6(moment@2.29.4)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-va8fmtigdSoyO5BTrOQXRI2N22rWqtmd6FNGPlU4xV2S7Bi13/IJvm0BxO+WaNAVrcZuKIruZ+1EI3UHU80/vw==} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' dependencies: '@ant-design/colors': 7.0.0 - '@ant-design/cssinjs': 1.9.1(react-dom@18.1.0)(react@18.2.0) - '@ant-design/icons': 5.0.1(react-dom@18.1.0)(react@18.2.0) + '@ant-design/cssinjs': 1.9.1(react-dom@18.2.0)(react@18.2.0) + '@ant-design/icons': 5.0.1(react-dom@18.2.0)(react@18.2.0) '@ant-design/react-slick': 1.0.0(react@18.2.0) '@babel/runtime': 7.21.0 '@ctrl/tinycolor': 3.6.0 - '@rc-component/mutate-observer': 1.0.0(react-dom@18.1.0)(react@18.2.0) - '@rc-component/tour': 1.8.0(react-dom@18.1.0)(react@18.2.0) - '@rc-component/trigger': 1.10.0(react-dom@18.1.0)(react@18.2.0) + '@rc-component/mutate-observer': 1.0.0(react-dom@18.2.0)(react@18.2.0) + '@rc-component/tour': 1.8.0(react-dom@18.2.0)(react@18.2.0) + '@rc-component/trigger': 1.10.0(react-dom@18.2.0)(react@18.2.0) classnames: 2.3.2 copy-to-clipboard: 3.3.3 dayjs: 1.11.7 qrcode.react: 3.1.0(react@18.2.0) - rc-cascader: 3.10.3(react-dom@18.1.0)(react@18.2.0) - rc-checkbox: 3.0.0(react-dom@18.1.0)(react@18.2.0) - rc-collapse: 3.5.2(react-dom@18.1.0)(react@18.2.0) - rc-dialog: 9.1.0(react-dom@18.1.0)(react@18.2.0) - rc-drawer: 6.1.5(react-dom@18.1.0)(react@18.2.0) - rc-dropdown: 4.0.1(react-dom@18.1.0)(react@18.2.0) - rc-field-form: 1.30.0(react-dom@18.1.0)(react@18.2.0) - rc-image: 5.16.0(react-dom@18.1.0)(react@18.2.0) - rc-input: 1.0.4(react-dom@18.1.0)(react@18.2.0) - rc-input-number: 7.4.2(react-dom@18.1.0)(react@18.2.0) - rc-mentions: 2.2.0(react-dom@18.1.0)(react@18.2.0) - rc-menu: 9.8.4(react-dom@18.1.0)(react@18.2.0) - rc-motion: 2.7.3(react-dom@18.1.0)(react@18.2.0) - rc-notification: 5.0.3(react-dom@18.1.0)(react@18.2.0) - rc-pagination: 3.3.1(react-dom@18.1.0)(react@18.2.0) - rc-picker: 3.6.2(dayjs@1.11.7)(moment@2.29.4)(react-dom@18.1.0)(react@18.2.0) - rc-progress: 3.4.1(react-dom@18.1.0)(react@18.2.0) - rc-rate: 2.10.0(react-dom@18.1.0)(react@18.2.0) - rc-resize-observer: 1.3.1(react-dom@18.1.0)(react@18.2.0) - rc-segmented: 2.1.2(react-dom@18.1.0)(react@18.2.0) - rc-select: 14.4.3(react-dom@18.1.0)(react@18.2.0) - rc-slider: 10.1.1(react-dom@18.1.0)(react@18.2.0) - rc-steps: 6.0.0(react-dom@18.1.0)(react@18.2.0) - rc-switch: 4.1.0(react-dom@18.1.0)(react@18.2.0) - rc-table: 7.31.1(react-dom@18.1.0)(react@18.2.0) - rc-tabs: 12.5.10(react-dom@18.1.0)(react@18.2.0) - rc-textarea: 1.2.2(react-dom@18.1.0)(react@18.2.0) - rc-tooltip: 6.0.1(react-dom@18.1.0)(react@18.2.0) - rc-tree: 5.7.3(react-dom@18.1.0)(react@18.2.0) - rc-tree-select: 5.8.0(react-dom@18.1.0)(react@18.2.0) - rc-upload: 4.3.4(react-dom@18.1.0)(react@18.2.0) - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-cascader: 3.10.3(react-dom@18.2.0)(react@18.2.0) + rc-checkbox: 3.0.0(react-dom@18.2.0)(react@18.2.0) + rc-collapse: 3.5.2(react-dom@18.2.0)(react@18.2.0) + rc-dialog: 9.1.0(react-dom@18.2.0)(react@18.2.0) + rc-drawer: 6.1.5(react-dom@18.2.0)(react@18.2.0) + rc-dropdown: 4.0.1(react-dom@18.2.0)(react@18.2.0) + rc-field-form: 1.30.0(react-dom@18.2.0)(react@18.2.0) + rc-image: 5.16.0(react-dom@18.2.0)(react@18.2.0) + rc-input: 1.0.4(react-dom@18.2.0)(react@18.2.0) + rc-input-number: 7.4.2(react-dom@18.2.0)(react@18.2.0) + rc-mentions: 2.2.0(react-dom@18.2.0)(react@18.2.0) + rc-menu: 9.8.4(react-dom@18.2.0)(react@18.2.0) + rc-motion: 2.7.3(react-dom@18.2.0)(react@18.2.0) + rc-notification: 5.0.3(react-dom@18.2.0)(react@18.2.0) + rc-pagination: 3.3.1(react-dom@18.2.0)(react@18.2.0) + rc-picker: 3.6.2(dayjs@1.11.7)(moment@2.29.4)(react-dom@18.2.0)(react@18.2.0) + rc-progress: 3.4.1(react-dom@18.2.0)(react@18.2.0) + rc-rate: 2.10.0(react-dom@18.2.0)(react@18.2.0) + rc-resize-observer: 1.3.1(react-dom@18.2.0)(react@18.2.0) + rc-segmented: 2.1.2(react-dom@18.2.0)(react@18.2.0) + rc-select: 14.4.3(react-dom@18.2.0)(react@18.2.0) + rc-slider: 10.1.1(react-dom@18.2.0)(react@18.2.0) + rc-steps: 6.0.0(react-dom@18.2.0)(react@18.2.0) + rc-switch: 4.1.0(react-dom@18.2.0)(react@18.2.0) + rc-table: 7.31.1(react-dom@18.2.0)(react@18.2.0) + rc-tabs: 12.5.10(react-dom@18.2.0)(react@18.2.0) + rc-textarea: 1.2.2(react-dom@18.2.0)(react@18.2.0) + rc-tooltip: 6.0.1(react-dom@18.2.0)(react@18.2.0) + rc-tree: 5.7.3(react-dom@18.2.0)(react@18.2.0) + rc-tree-select: 5.8.0(react-dom@18.2.0)(react@18.2.0) + rc-upload: 4.3.4(react-dom@18.2.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) scroll-into-view-if-needed: 3.0.10 throttle-debounce: 5.0.0 transitivePeerDependencies: @@ -6043,7 +6033,7 @@ packages: /core-util-is@1.0.2: resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} - /cosmiconfig-typescript-loader@1.0.9(@types/node@18.15.10)(cosmiconfig@7.1.0)(typescript@4.9.5): + /cosmiconfig-typescript-loader@1.0.9(@types/node@18.15.10)(cosmiconfig@7.1.0)(typescript@5.1.6): resolution: {integrity: sha512-tRuMRhxN4m1Y8hP9SNYfz7jRwt8lZdWxdjg/ohg5esKmsndJIn4yT96oJVcf5x0eA11taXl+sIp+ielu529k6g==} engines: {node: '>=12', npm: '>=6'} peerDependencies: @@ -6053,8 +6043,8 @@ packages: dependencies: '@types/node': 18.15.10 cosmiconfig: 7.1.0 - ts-node: 10.9.1(@types/node@18.15.10)(typescript@4.9.5) - typescript: 4.9.5 + ts-node: 10.9.1(@types/node@18.15.10)(typescript@5.1.6) + typescript: 5.1.6 transitivePeerDependencies: - '@swc/core' - '@swc/wasm' @@ -6081,11 +6071,6 @@ packages: yaml: 1.10.2 dev: false - /craco-alias@3.0.1: - resolution: {integrity: sha512-N+Qaf/Gr/f3o5ZH2TQjMu5NhR9PnT1ZYsfejpNvZPpB0ujdrhsSr4Ct6GVjnV5ostCVquhTKJpIVBKyL9qDQYA==} - deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. - dev: false - /create-ecdh@4.0.4: resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==} dependencies: @@ -7171,7 +7156,7 @@ packages: eslint: 7.32.0 dev: true - /eslint-config-react-app@6.0.0(@typescript-eslint/eslint-plugin@4.33.0)(@typescript-eslint/parser@4.33.0)(babel-eslint@10.1.0)(eslint-plugin-flowtype@5.10.0)(eslint-plugin-import@2.27.5)(eslint-plugin-jest@24.7.0)(eslint-plugin-jsx-a11y@6.7.1)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.32.2)(eslint-plugin-testing-library@3.10.2)(eslint@7.32.0)(typescript@4.9.5): + /eslint-config-react-app@6.0.0(@typescript-eslint/eslint-plugin@4.33.0)(@typescript-eslint/parser@4.33.0)(babel-eslint@10.1.0)(eslint-plugin-flowtype@5.10.0)(eslint-plugin-import@2.27.5)(eslint-plugin-jest@24.7.0)(eslint-plugin-jsx-a11y@6.7.1)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.32.2)(eslint-plugin-testing-library@3.10.2)(eslint@7.32.0)(typescript@5.1.6): resolution: {integrity: sha512-bpoAAC+YRfzq0dsTk+6v9aHm/uqnDwayNAXleMypGl6CpxI9oXXscVHo4fk3eJPIn+rsbtNetB4r/ZIidFIE8A==} engines: {node: ^10.12.0 || >=12.0.0} peerDependencies: @@ -7195,19 +7180,19 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/eslint-plugin': 4.33.0(@typescript-eslint/parser@4.33.0)(eslint@7.32.0)(typescript@4.9.5) - '@typescript-eslint/parser': 4.33.0(eslint@7.32.0)(typescript@4.9.5) + '@typescript-eslint/eslint-plugin': 4.33.0(@typescript-eslint/parser@4.33.0)(eslint@7.32.0)(typescript@5.1.6) + '@typescript-eslint/parser': 4.33.0(eslint@7.32.0)(typescript@5.1.6) babel-eslint: 10.1.0(eslint@7.32.0) confusing-browser-globals: 1.0.11 eslint: 7.32.0 eslint-plugin-flowtype: 5.10.0(eslint@7.32.0) eslint-plugin-import: 2.27.5(@typescript-eslint/parser@4.33.0)(eslint@7.32.0) - eslint-plugin-jest: 24.7.0(@typescript-eslint/eslint-plugin@4.33.0)(eslint@7.32.0)(typescript@4.9.5) + eslint-plugin-jest: 24.7.0(@typescript-eslint/eslint-plugin@4.33.0)(eslint@7.32.0)(typescript@5.1.6) eslint-plugin-jsx-a11y: 6.7.1(eslint@7.32.0) eslint-plugin-react: 7.32.2(eslint@7.32.0) eslint-plugin-react-hooks: 4.6.0(eslint@7.32.0) - eslint-plugin-testing-library: 3.10.2(eslint@7.32.0)(typescript@4.9.5) - typescript: 4.9.5 + eslint-plugin-testing-library: 3.10.2(eslint@7.32.0)(typescript@5.1.6) + typescript: 5.1.6 dev: false /eslint-import-resolver-node@0.3.7: @@ -7240,7 +7225,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 4.33.0(eslint@7.32.0)(typescript@4.9.5) + '@typescript-eslint/parser': 4.33.0(eslint@7.32.0)(typescript@5.1.6) debug: 3.2.7(supports-color@6.1.0) eslint: 7.32.0 eslint-import-resolver-node: 0.3.7 @@ -7269,7 +7254,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.57.0(eslint@7.32.0)(typescript@4.9.5) + '@typescript-eslint/parser': 5.57.0(eslint@7.32.0)(typescript@5.1.6) debug: 3.2.7(supports-color@6.1.0) eslint: 7.32.0 eslint-import-resolver-node: 0.3.7 @@ -7307,7 +7292,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 4.33.0(eslint@7.32.0)(typescript@4.9.5) + '@typescript-eslint/parser': 4.33.0(eslint@7.32.0)(typescript@5.1.6) array-includes: 3.1.6 array.prototype.flat: 1.3.1 array.prototype.flatmap: 1.3.1 @@ -7340,7 +7325,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.57.0(eslint@7.32.0)(typescript@4.9.5) + '@typescript-eslint/parser': 5.57.0(eslint@7.32.0)(typescript@5.1.6) array-includes: 3.1.6 array.prototype.flat: 1.3.1 array.prototype.flatmap: 1.3.1 @@ -7363,7 +7348,7 @@ packages: - supports-color dev: true - /eslint-plugin-jest@24.7.0(@typescript-eslint/eslint-plugin@4.33.0)(eslint@7.32.0)(typescript@4.9.5): + /eslint-plugin-jest@24.7.0(@typescript-eslint/eslint-plugin@4.33.0)(eslint@7.32.0)(typescript@5.1.6): resolution: {integrity: sha512-wUxdF2bAZiYSKBclsUMrYHH6WxiBreNjyDxbRv345TIvPeoCEgPNEn3Sa+ZrSqsf1Dl9SqqSREXMHExlMMu1DA==} engines: {node: '>=10'} peerDependencies: @@ -7373,8 +7358,8 @@ packages: '@typescript-eslint/eslint-plugin': optional: true dependencies: - '@typescript-eslint/eslint-plugin': 4.33.0(@typescript-eslint/parser@4.33.0)(eslint@7.32.0)(typescript@4.9.5) - '@typescript-eslint/experimental-utils': 4.33.0(eslint@7.32.0)(typescript@4.9.5) + '@typescript-eslint/eslint-plugin': 4.33.0(@typescript-eslint/parser@4.33.0)(eslint@7.32.0)(typescript@5.1.6) + '@typescript-eslint/experimental-utils': 4.33.0(eslint@7.32.0)(typescript@5.1.6) eslint: 7.32.0 transitivePeerDependencies: - supports-color @@ -7436,13 +7421,13 @@ packages: semver: 6.3.0 string.prototype.matchall: 4.0.8 - /eslint-plugin-testing-library@3.10.2(eslint@7.32.0)(typescript@4.9.5): + /eslint-plugin-testing-library@3.10.2(eslint@7.32.0)(typescript@5.1.6): resolution: {integrity: sha512-WAmOCt7EbF1XM8XfbCKAEzAPnShkNSwcIsAD2jHdsMUT9mZJPjLCG7pMzbcC8kK366NOuGip8HKLDC+Xk4yIdA==} engines: {node: ^10.12.0 || >=12.0.0, npm: '>=6'} peerDependencies: eslint: ^5 || ^6 || ^7 dependencies: - '@typescript-eslint/experimental-utils': 3.10.1(eslint@7.32.0)(typescript@4.9.5) + '@typescript-eslint/experimental-utils': 3.10.1(eslint@7.32.0)(typescript@5.1.6) eslint: 7.32.0 transitivePeerDependencies: - supports-color @@ -8034,7 +8019,7 @@ packages: resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} dev: true - /fork-ts-checker-webpack-plugin@4.1.6(eslint@7.32.0)(typescript@4.9.5)(webpack@4.44.2): + /fork-ts-checker-webpack-plugin@4.1.6(eslint@7.32.0)(typescript@5.1.6)(webpack@4.44.2): resolution: {integrity: sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw==} engines: {node: '>=6.11.5', yarn: '>=1.0.0'} peerDependencies: @@ -8055,7 +8040,7 @@ packages: minimatch: 3.1.2 semver: 5.7.1 tapable: 1.1.3 - typescript: 4.9.5 + typescript: 5.1.6 webpack: 4.44.2 worker-rpc: 0.1.1 transitivePeerDependencies: @@ -11296,11 +11281,11 @@ packages: find-up: 3.0.0 dev: false - /pnp-webpack-plugin@1.6.4(typescript@4.9.5): + /pnp-webpack-plugin@1.6.4(typescript@5.1.6): resolution: {integrity: sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==} engines: {node: '>=6'} dependencies: - ts-pnp: 1.2.0(typescript@4.9.5) + ts-pnp: 1.2.0(typescript@5.1.6) transitivePeerDependencies: - typescript dev: false @@ -12260,7 +12245,7 @@ packages: unpipe: 1.0.0 dev: false - /rc-align@4.0.15(react-dom@18.1.0)(react@18.2.0): + /rc-align@4.0.15(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-wqJtVH60pka/nOX7/IspElA8gjPNQKIx/ZqJ6heATCkXpe1Zg4cPVrMD2vC96wjsFFL8WsmhPbx9tdMo1qqlIA==} peerDependencies: react: '>=16.9.0' @@ -12269,13 +12254,13 @@ packages: '@babel/runtime': 7.21.0 classnames: 2.3.2 dom-align: 1.12.4 - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) resize-observer-polyfill: 1.5.1 dev: false - /rc-cascader@3.10.3(react-dom@18.1.0)(react@18.2.0): + /rc-cascader@3.10.3(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-RBK1u59a2m/RKY8F+UvW9pUXdPv7bCxh2s2DAb81QjXX7TbwSX92Y0tICYo/Bo8fRsAh2g+7RXVf488/98ijkA==} peerDependencies: react: '>=16.9.0' @@ -12284,14 +12269,14 @@ packages: '@babel/runtime': 7.21.0 array-tree-filter: 2.1.0 classnames: 2.3.2 - rc-select: 14.4.3(react-dom@18.1.0)(react@18.2.0) - rc-tree: 5.7.3(react-dom@18.1.0)(react@18.2.0) - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-select: 14.4.3(react-dom@18.2.0)(react@18.2.0) + rc-tree: 5.7.3(react-dom@18.2.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-checkbox@3.0.0(react-dom@18.1.0)(react@18.2.0): + /rc-checkbox@3.0.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-tOEs1+wWDUei7DuP2EsJCZfam5vxMjKTCGcZdXVgsiOcNszc41Esycbo31P0/jFwUAPmd5oPYFWkcnFUCTLZxA==} peerDependencies: react: '>=16.9.0' @@ -12299,12 +12284,12 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-collapse@3.5.2(react-dom@18.1.0)(react@18.2.0): + /rc-collapse@3.5.2(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-/TNiT3DW1t3sUCiVD/DPUYooJZ3BLA93/2rZsB3eM2bGJCCla2X9D2E4tgm7LGMQGy5Atb2lMUn2FQuvQNvavQ==} peerDependencies: react: '>=16.9.0' @@ -12312,43 +12297,43 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-motion: 2.7.3(react-dom@18.1.0)(react@18.2.0) - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-motion: 2.7.3(react-dom@18.2.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-dialog@9.1.0(react-dom@18.1.0)(react@18.2.0): + /rc-dialog@9.1.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-5ry+JABAWEbaKyYsmITtrJbZbJys8CtMyzV8Xn4LYuXMeUx5XVHNyJRoqLFE4AzBuXXzOWeaC49cg+XkxK6kHA==} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' dependencies: '@babel/runtime': 7.21.0 - '@rc-component/portal': 1.1.1(react-dom@18.1.0)(react@18.2.0) + '@rc-component/portal': 1.1.1(react-dom@18.2.0)(react@18.2.0) classnames: 2.3.2 - rc-motion: 2.7.3(react-dom@18.1.0)(react@18.2.0) - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-motion: 2.7.3(react-dom@18.2.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-drawer@6.1.5(react-dom@18.1.0)(react@18.2.0): + /rc-drawer@6.1.5(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-MDRomQXFi+tvDuwsRAddJ2Oy2ayLCZ29weMzp3rJFO9UNEVLEVV7nuyx5lEgNJIdM//tE6wWQV95cTUiMVqD6w==} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' dependencies: '@babel/runtime': 7.21.0 - '@rc-component/portal': 1.1.1(react-dom@18.1.0)(react@18.2.0) + '@rc-component/portal': 1.1.1(react-dom@18.2.0)(react@18.2.0) classnames: 2.3.2 - rc-motion: 2.7.3(react-dom@18.1.0)(react@18.2.0) - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-motion: 2.7.3(react-dom@18.2.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-dropdown@4.0.1(react-dom@18.1.0)(react@18.2.0): + /rc-dropdown@4.0.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-OdpXuOcme1rm45cR0Jzgfl1otzmU4vuBVb+etXM8vcaULGokAKVpKlw8p6xzspG7jGd/XxShvq+N3VNEfk/l5g==} peerDependencies: react: '>=16.11.0' @@ -12356,13 +12341,13 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-trigger: 5.3.4(react-dom@18.1.0)(react@18.2.0) - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-trigger: 5.3.4(react-dom@18.2.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-field-form@1.30.0(react-dom@18.1.0)(react@18.2.0): + /rc-field-form@1.30.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-hCBa3/+m9SSuEPILSsxB/wd3ZFEmNTQfIhThhMaMp05fLwDDw+2K26lEZf5NuChQlx90VVNUOYmTslH6Ks4tpA==} engines: {node: '>=8.x'} peerDependencies: @@ -12371,28 +12356,28 @@ packages: dependencies: '@babel/runtime': 7.21.0 async-validator: 4.2.5 - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-image@5.16.0(react-dom@18.1.0)(react@18.2.0): + /rc-image@5.16.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-11DOye57IgTXh2yTsmxFNynZJG3tdx8RZnnaqb38eYWrBPPyhVHIuURxyiSZ8B68lEUAggR7SBA0Zb95KP/CyQ==} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' dependencies: '@babel/runtime': 7.21.0 - '@rc-component/portal': 1.1.1(react-dom@18.1.0)(react@18.2.0) + '@rc-component/portal': 1.1.1(react-dom@18.2.0)(react@18.2.0) classnames: 2.3.2 - rc-dialog: 9.1.0(react-dom@18.1.0)(react@18.2.0) - rc-motion: 2.7.3(react-dom@18.1.0)(react@18.2.0) - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-dialog: 9.1.0(react-dom@18.2.0)(react@18.2.0) + rc-motion: 2.7.3(react-dom@18.2.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-input-number@7.4.2(react-dom@18.1.0)(react@18.2.0): + /rc-input-number@7.4.2(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-yGturTw7WGP+M1GbJ+UTAO7L4buxeW6oilhL9Sq3DezsRS8/9qec4UiXUbeoiX9bzvRXH11JvgskBtxSp4YSNg==} peerDependencies: react: '>=16.9.0' @@ -12401,12 +12386,12 @@ packages: '@babel/runtime': 7.21.0 '@rc-component/mini-decimal': 1.0.1 classnames: 2.3.2 - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-input@1.0.4(react-dom@18.1.0)(react@18.2.0): + /rc-input@1.0.4(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-clY4oneVHRtKHYf/HCxT/MO+4BGzCIywSNLosXWOm7fcQAS0jQW7n0an8Raa8JMB8kpxc8m28p7SNwFZmlMj6g==} peerDependencies: react: '>=16.0.0' @@ -12414,29 +12399,29 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-mentions@2.2.0(react-dom@18.1.0)(react@18.2.0): + /rc-mentions@2.2.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-R7ncCldr02uKgJBBPlXdtnOGQIjZ9C3uoIMi4fabU3CPFdmefYlNF6QM4u2AzgcGt8V0KkoHTN5T6HPdUpet8g==} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' dependencies: '@babel/runtime': 7.21.0 - '@rc-component/trigger': 1.10.0(react-dom@18.1.0)(react@18.2.0) + '@rc-component/trigger': 1.10.0(react-dom@18.2.0)(react@18.2.0) classnames: 2.3.2 - rc-input: 1.0.4(react-dom@18.1.0)(react@18.2.0) - rc-menu: 9.8.4(react-dom@18.1.0)(react@18.2.0) - rc-textarea: 1.2.2(react-dom@18.1.0)(react@18.2.0) - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-input: 1.0.4(react-dom@18.2.0)(react@18.2.0) + rc-menu: 9.8.4(react-dom@18.2.0)(react@18.2.0) + rc-textarea: 1.2.2(react-dom@18.2.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-menu@9.8.4(react-dom@18.1.0)(react@18.2.0): + /rc-menu@9.8.4(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-lmw2j8I2fhdIzHmC9ajfImfckt0WDb2KVJJBBRIsxPEw2kGkEfjLMUoB1NgiNT/Q5cC8PdjGOGQjHJIJMwyNMw==} peerDependencies: react: '>=16.9.0' @@ -12444,15 +12429,15 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-motion: 2.7.3(react-dom@18.1.0)(react@18.2.0) - rc-overflow: 1.3.0(react-dom@18.1.0)(react@18.2.0) - rc-trigger: 5.3.4(react-dom@18.1.0)(react@18.2.0) - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-motion: 2.7.3(react-dom@18.2.0)(react@18.2.0) + rc-overflow: 1.3.0(react-dom@18.2.0)(react@18.2.0) + rc-trigger: 5.3.4(react-dom@18.2.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-motion@2.7.3(react-dom@18.1.0)(react@18.2.0): + /rc-motion@2.7.3(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-2xUvo8yGHdOHeQbdI8BtBsCIrWKchEmFEIskf0nmHtJsou+meLd/JE+vnvSX2JxcBrJtXY2LuBpxAOxrbY/wMQ==} peerDependencies: react: '>=16.9.0' @@ -12460,12 +12445,12 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-notification@5.0.3(react-dom@18.1.0)(react@18.2.0): + /rc-notification@5.0.3(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-+wHbHu6RiTNtsZYx42WxWA+tC5m0qyKvJAauO4/6LIEyJspK8fRlFQz+OCFgFwGuNs3cOdo9tLs+cPfztSZwbQ==} engines: {node: '>=8.x'} peerDependencies: @@ -12474,13 +12459,13 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-motion: 2.7.3(react-dom@18.1.0)(react@18.2.0) - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-motion: 2.7.3(react-dom@18.2.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-overflow@1.3.0(react-dom@18.1.0)(react@18.2.0): + /rc-overflow@1.3.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-p2Qt4SWPTHAYl4oAao1THy669Fm5q8pYBDBHRaFOekCvcdcrgIx0ByXQMEkyPm8wUDX4BK6aARWecvCRc/7CTA==} peerDependencies: react: '>=16.9.0' @@ -12488,13 +12473,13 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-resize-observer: 1.3.1(react-dom@18.1.0)(react@18.2.0) - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-resize-observer: 1.3.1(react-dom@18.2.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-pagination@3.3.1(react-dom@18.1.0)(react@18.2.0): + /rc-pagination@3.3.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-eI4dSeB3OrFxll7KzWa3ZH63LV2tHxt0AUmZmDwuI6vc3CK5lZhaKUYq0fRowb5586hN+L26j5WZoSz9cwEfjg==} peerDependencies: react: '>=16.9.0' @@ -12503,10 +12488,10 @@ packages: '@babel/runtime': 7.21.0 classnames: 2.3.2 react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-picker@3.6.2(dayjs@1.11.7)(moment@2.29.4)(react-dom@18.1.0)(react@18.2.0): + /rc-picker@3.6.2(dayjs@1.11.7)(moment@2.29.4)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-acLNCi2WTNAuvTtcEzKp72mU15ni0sqrIKVlEcj04KgLZxhlVPMabCS+Sc8VuOCPJbOcW0XeOydbNnJbWTvzxg==} engines: {node: '>=8.x'} peerDependencies: @@ -12527,16 +12512,16 @@ packages: optional: true dependencies: '@babel/runtime': 7.21.0 - '@rc-component/trigger': 1.10.0(react-dom@18.1.0)(react@18.2.0) + '@rc-component/trigger': 1.10.0(react-dom@18.2.0)(react@18.2.0) classnames: 2.3.2 dayjs: 1.11.7 moment: 2.29.4 - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-progress@3.4.1(react-dom@18.1.0)(react@18.2.0): + /rc-progress@3.4.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-eAFDHXlk8aWpoXl0llrenPMt9qKHQXphxcVsnKs0FHC6eCSk1ebJtyaVjJUzKe0233ogiLDeEFK1Uihz3s67hw==} peerDependencies: react: '>=16.9.0' @@ -12544,12 +12529,12 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-rate@2.10.0(react-dom@18.1.0)(react@18.2.0): + /rc-rate@2.10.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-TCjEpKPeN1m0EnGDDbb1KyxjNTJRzoReiPdtbrBJEey4Ryf/UGOQ6vqmz2yC6DJdYVDVUoZPdoz043ryh0t/nQ==} engines: {node: '>=8.x'} peerDependencies: @@ -12558,12 +12543,12 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-resize-observer@1.3.1(react-dom@18.1.0)(react@18.2.0): + /rc-resize-observer@1.3.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-iFUdt3NNhflbY3mwySv5CA1TC06zdJ+pfo0oc27xpf4PIOvfZwZGtD9Kz41wGYqC4SLio93RVAirSSpYlV/uYg==} peerDependencies: react: '>=16.9.0' @@ -12571,13 +12556,13 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) resize-observer-polyfill: 1.5.1 dev: false - /rc-segmented@2.1.2(react-dom@18.1.0)(react@18.2.0): + /rc-segmented@2.1.2(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-qGo1bCr83ESXpXVOCXjFe1QJlCAQXyi9KCiy8eX3rIMYlTeJr/ftySIaTnYsitL18SvWf5ZEHsfqIWoX0EMfFQ==} peerDependencies: react: '>=16.0.0' @@ -12585,13 +12570,13 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-motion: 2.7.3(react-dom@18.1.0)(react@18.2.0) - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-motion: 2.7.3(react-dom@18.2.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-select@14.4.3(react-dom@18.1.0)(react@18.2.0): + /rc-select@14.4.3(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-qoz4gNqm3SN+4dYKSCRiRkxKSEEdbS3jC6gdFYoYwEjDZ9sdQFo5jHlfQbF+hhai01HOoj1Hf8Gq6tpUvU+Gmw==} engines: {node: '>=8.x'} peerDependencies: @@ -12599,17 +12584,17 @@ packages: react-dom: '*' dependencies: '@babel/runtime': 7.21.0 - '@rc-component/trigger': 1.10.0(react-dom@18.1.0)(react@18.2.0) + '@rc-component/trigger': 1.10.0(react-dom@18.2.0)(react@18.2.0) classnames: 2.3.2 - rc-motion: 2.7.3(react-dom@18.1.0)(react@18.2.0) - rc-overflow: 1.3.0(react-dom@18.1.0)(react@18.2.0) - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) - rc-virtual-list: 3.4.13(react-dom@18.1.0)(react@18.2.0) + rc-motion: 2.7.3(react-dom@18.2.0)(react@18.2.0) + rc-overflow: 1.3.0(react-dom@18.2.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) + rc-virtual-list: 3.4.13(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-slider@10.1.1(react-dom@18.1.0)(react@18.2.0): + /rc-slider@10.1.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-gn8oXazZISEhnmRinI89Z/JD/joAaM35jp+gDtIVSTD/JJMCCBqThqLk1SVJmvtfeiEF/kKaFY0+qt4SDHFUDw==} engines: {node: '>=8.x'} peerDependencies: @@ -12618,12 +12603,12 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-steps@6.0.0(react-dom@18.1.0)(react@18.2.0): + /rc-steps@6.0.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-+KfMZIty40mYCQSDvYbZ1jwnuObLauTiIskT1hL4FFOBHP6ZOr8LK0m143yD3kEN5XKHSEX1DIwCj3AYZpoeNQ==} engines: {node: '>=8.x'} peerDependencies: @@ -12632,12 +12617,12 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-switch@4.1.0(react-dom@18.1.0)(react@18.2.0): + /rc-switch@4.1.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-TI8ufP2Az9oEbvyCeVE4+90PDSljGyuwix3fV58p7HV2o4wBnVToEyomJRVyTaZeqNPAp+vqeo4Wnj5u0ZZQBg==} peerDependencies: react: '>=16.9.0' @@ -12645,12 +12630,12 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-table@7.31.1(react-dom@18.1.0)(react@18.2.0): + /rc-table@7.31.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-KZPi35aGpv2VaL1Jbc58FBJo063HtKyVjhOFWX4AkBV7tjHHQokMdUoua5E+GPJh6QZUpK/a8PjKa9IZzPLIEA==} engines: {node: '>=8.x'} peerDependencies: @@ -12658,15 +12643,15 @@ packages: react-dom: '>=16.9.0' dependencies: '@babel/runtime': 7.21.0 - '@rc-component/context': 1.3.0(react-dom@18.1.0)(react@18.2.0) + '@rc-component/context': 1.3.0(react-dom@18.2.0)(react@18.2.0) classnames: 2.3.2 - rc-resize-observer: 1.3.1(react-dom@18.1.0)(react@18.2.0) - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-resize-observer: 1.3.1(react-dom@18.2.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-tabs@12.5.10(react-dom@18.1.0)(react@18.2.0): + /rc-tabs@12.5.10(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-Ay0l0jtd4eXepFH9vWBvinBjqOpqzcsJTerBGwJy435P2S90Uu38q8U/mvc1sxUEVOXX5ZCFbxcWPnfG3dH+tQ==} engines: {node: '>=8.x'} peerDependencies: @@ -12675,16 +12660,16 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-dropdown: 4.0.1(react-dom@18.1.0)(react@18.2.0) - rc-menu: 9.8.4(react-dom@18.1.0)(react@18.2.0) - rc-motion: 2.7.3(react-dom@18.1.0)(react@18.2.0) - rc-resize-observer: 1.3.1(react-dom@18.1.0)(react@18.2.0) - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-dropdown: 4.0.1(react-dom@18.2.0)(react@18.2.0) + rc-menu: 9.8.4(react-dom@18.2.0)(react@18.2.0) + rc-motion: 2.7.3(react-dom@18.2.0)(react@18.2.0) + rc-resize-observer: 1.3.1(react-dom@18.2.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-textarea@1.2.2(react-dom@18.1.0)(react@18.2.0): + /rc-textarea@1.2.2(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-S9fkiek5VezfwJe2McEs/NH63xgnnZ4iDh6a8n01mIfzyNJj0HkS0Uz6boyR3/eONYjmKaqhrpuJJuEClRDEBw==} peerDependencies: react: '>=16.9.0' @@ -12692,27 +12677,27 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-input: 1.0.4(react-dom@18.1.0)(react@18.2.0) - rc-resize-observer: 1.3.1(react-dom@18.1.0)(react@18.2.0) - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-input: 1.0.4(react-dom@18.2.0)(react@18.2.0) + rc-resize-observer: 1.3.1(react-dom@18.2.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-tooltip@6.0.1(react-dom@18.1.0)(react@18.2.0): + /rc-tooltip@6.0.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-MdvPlsD1fDSxKp9+HjXrc/CxLmA/s11QYIh1R7aExxfodKP7CZA++DG1AjrW80F8IUdHYcR43HAm0Y2BYPelHA==} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' dependencies: '@babel/runtime': 7.21.0 - '@rc-component/trigger': 1.10.0(react-dom@18.1.0)(react@18.2.0) + '@rc-component/trigger': 1.10.0(react-dom@18.2.0)(react@18.2.0) classnames: 2.3.2 react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-tree-select@5.8.0(react-dom@18.1.0)(react@18.2.0): + /rc-tree-select@5.8.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-NozrkVLR8k3cpx8R5/YFmJMptgOacR5zEQHZGMQg31bD6jEgGiJeOn2cGRI6x0Xdyvi1CSqCbUsIoqiej74wzw==} peerDependencies: react: '*' @@ -12720,14 +12705,14 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-select: 14.4.3(react-dom@18.1.0)(react@18.2.0) - rc-tree: 5.7.3(react-dom@18.1.0)(react@18.2.0) - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-select: 14.4.3(react-dom@18.2.0)(react@18.2.0) + rc-tree: 5.7.3(react-dom@18.2.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-tree@5.7.3(react-dom@18.1.0)(react@18.2.0): + /rc-tree@5.7.3(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-Oql2S9+ZmT+mfTp5SNo1XM0QvkENjc0mPRFsHWRFSPuKird0OYMZZKmLznUJ+0aGDeFFWN42wiUZJtMFhrLgLw==} engines: {node: '>=10.x'} peerDependencies: @@ -12736,14 +12721,14 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-motion: 2.7.3(react-dom@18.1.0)(react@18.2.0) - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) - rc-virtual-list: 3.4.13(react-dom@18.1.0)(react@18.2.0) + rc-motion: 2.7.3(react-dom@18.2.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) + rc-virtual-list: 3.4.13(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-trigger@5.3.4(react-dom@18.1.0)(react@18.2.0): + /rc-trigger@5.3.4(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-mQv+vas0TwKcjAO2izNPkqR4j86OemLRmvL2nOzdP9OWNWA1ivoTt5hzFqYNW9zACwmTezRiN8bttrC7cZzYSw==} engines: {node: '>=8.x'} peerDependencies: @@ -12752,14 +12737,14 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-align: 4.0.15(react-dom@18.1.0)(react@18.2.0) - rc-motion: 2.7.3(react-dom@18.1.0)(react@18.2.0) - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-align: 4.0.15(react-dom@18.2.0)(react@18.2.0) + rc-motion: 2.7.3(react-dom@18.2.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-upload@4.3.4(react-dom@18.1.0)(react@18.2.0): + /rc-upload@4.3.4(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-uVbtHFGNjHG/RyAfm9fluXB6pvArAGyAx8z7XzXXyorEgVIWj6mOlriuDm0XowDHYz4ycNK0nE0oP3cbFnzxiQ==} peerDependencies: react: '>=16.9.0' @@ -12767,12 +12752,12 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false - /rc-util@5.30.0(react-dom@18.1.0)(react@18.2.0): + /rc-util@5.30.0(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-uaWpF/CZGyXuhQG71MWxkU+0bWkPEgqZUxEv251Cu7p3kpHDNm5+Ygu/U8ux0a/zbfGW8PsKcJL0XVBOMrlIZg==} peerDependencies: react: '>=16.9.0' @@ -12780,11 +12765,11 @@ packages: dependencies: '@babel/runtime': 7.21.0 react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) react-is: 16.13.1 dev: false - /rc-virtual-list@3.4.13(react-dom@18.1.0)(react@18.2.0): + /rc-virtual-list@3.4.13(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-cPOVDmcNM7rH6ANotanMDilW/55XnFPw0Jh/GQYtrzZSy3AmWvCnqVNyNC/pgg3lfVmX2994dlzAhuUrd4jG7w==} engines: {node: '>=8.x'} peerDependencies: @@ -12793,10 +12778,10 @@ packages: dependencies: '@babel/runtime': 7.21.0 classnames: 2.3.2 - rc-resize-observer: 1.3.1(react-dom@18.1.0)(react@18.2.0) - rc-util: 5.30.0(react-dom@18.1.0)(react@18.2.0) + rc-resize-observer: 1.3.1(react-dom@18.2.0)(react@18.2.0) + rc-util: 5.30.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false /react-app-polyfill@2.0.0: @@ -12822,7 +12807,7 @@ packages: universal-cookie: 4.0.4 dev: false - /react-dev-utils@11.0.4(eslint@7.32.0)(typescript@4.9.5)(webpack@4.44.2): + /react-dev-utils@11.0.4(eslint@7.32.0)(typescript@5.1.6)(webpack@4.44.2): resolution: {integrity: sha512-dx0LvIGHcOPtKbeiSUM4jqpBl3TcY7CDjZdfOIcKeznE7BWr9dg0iPG90G5yfVQ+p/rGNMXdbfStvzQZEVEi4A==} engines: {node: '>=10'} peerDependencies: @@ -12841,7 +12826,7 @@ packages: escape-string-regexp: 2.0.0 filesize: 6.1.0 find-up: 4.1.0 - fork-ts-checker-webpack-plugin: 4.1.6(eslint@7.32.0)(typescript@4.9.5)(webpack@4.44.2) + fork-ts-checker-webpack-plugin: 4.1.6(eslint@7.32.0)(typescript@5.1.6)(webpack@4.44.2) global-modules: 2.0.0 globby: 11.0.1 gzip-size: 5.1.1 @@ -12856,7 +12841,7 @@ packages: shell-quote: 1.7.2 strip-ansi: 6.0.0 text-table: 0.2.0 - typescript: 4.9.5 + typescript: 5.1.6 webpack: 4.44.2 transitivePeerDependencies: - eslint @@ -12864,14 +12849,14 @@ packages: - vue-template-compiler dev: false - /react-dom@18.1.0(react@18.2.0): - resolution: {integrity: sha512-fU1Txz7Budmvamp7bshe4Zi32d0ll7ect+ccxNu9FlObT605GOEB8BfO4tmRJ39R5Zj831VCpvQ05QPBW5yb+w==} + /react-dom@18.2.0(react@18.2.0): + resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} peerDependencies: - react: ^18.1.0 + react: ^18.2.0 dependencies: loose-envify: 1.4.0 react: 18.2.0 - scheduler: 0.22.0 + scheduler: 0.23.0 dev: false /react-error-overlay@6.0.11: @@ -12882,7 +12867,7 @@ packages: resolution: {integrity: sha512-ioBMEIxd4ePw4YtaloTUgqhQGqz5ebDdC4slEpLgy2sLx1LuZBC9iYCwDymTXzcntw6K1dHX183ulP32nNdG7w==} dev: false - /react-i18next@12.2.0(i18next@22.4.13)(react-dom@18.1.0)(react@18.2.0): + /react-i18next@12.2.0(i18next@22.4.13)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-5XeVgSygaGfyFmDd2WcXvINRw2WEC1XviW1LXY/xLOEMzsCFRwKqfnHN+hUjla8ZipbVJR27GCMSuTr0BhBBBQ==} peerDependencies: i18next: '>= 19.0.0' @@ -12899,7 +12884,7 @@ packages: html-parse-stringify: 3.0.1 i18next: 22.4.13 react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false /react-is@16.13.1: @@ -12964,7 +12949,7 @@ packages: tiny-warning: 1.0.3 dev: false - /react-scripts@4.0.3(eslint@7.32.0)(react@18.2.0)(typescript@4.9.5): + /react-scripts@4.0.3(eslint@7.32.0)(react@18.2.0)(typescript@5.1.6): resolution: {integrity: sha512-S5eO4vjUzUisvkIPB7jVsKtuH2HhWcASREYWHAQ1FP5HyCv3xgn+wpILAEWkmy+A+tTNbSZClhxjT3qz6g4L1A==} engines: {node: ^10.12.0 || >=12.0.0} hasBin: true @@ -12979,8 +12964,8 @@ packages: '@babel/core': 7.12.3 '@pmmmwh/react-refresh-webpack-plugin': 0.4.3(react-refresh@0.8.3)(webpack-dev-server@3.11.1)(webpack@4.44.2) '@svgr/webpack': 5.5.0 - '@typescript-eslint/eslint-plugin': 4.33.0(@typescript-eslint/parser@4.33.0)(eslint@7.32.0)(typescript@4.9.5) - '@typescript-eslint/parser': 4.33.0(eslint@7.32.0)(typescript@4.9.5) + '@typescript-eslint/eslint-plugin': 4.33.0(@typescript-eslint/parser@4.33.0)(eslint@7.32.0)(typescript@5.1.6) + '@typescript-eslint/parser': 4.33.0(eslint@7.32.0)(typescript@5.1.6) babel-eslint: 10.1.0(eslint@7.32.0) babel-jest: 26.6.3(@babel/core@7.12.3) babel-loader: 8.1.0(@babel/core@7.12.3)(webpack@4.44.2) @@ -12993,14 +12978,14 @@ packages: dotenv: 8.2.0 dotenv-expand: 5.1.0 eslint: 7.32.0 - eslint-config-react-app: 6.0.0(@typescript-eslint/eslint-plugin@4.33.0)(@typescript-eslint/parser@4.33.0)(babel-eslint@10.1.0)(eslint-plugin-flowtype@5.10.0)(eslint-plugin-import@2.27.5)(eslint-plugin-jest@24.7.0)(eslint-plugin-jsx-a11y@6.7.1)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.32.2)(eslint-plugin-testing-library@3.10.2)(eslint@7.32.0)(typescript@4.9.5) + eslint-config-react-app: 6.0.0(@typescript-eslint/eslint-plugin@4.33.0)(@typescript-eslint/parser@4.33.0)(babel-eslint@10.1.0)(eslint-plugin-flowtype@5.10.0)(eslint-plugin-import@2.27.5)(eslint-plugin-jest@24.7.0)(eslint-plugin-jsx-a11y@6.7.1)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.32.2)(eslint-plugin-testing-library@3.10.2)(eslint@7.32.0)(typescript@5.1.6) eslint-plugin-flowtype: 5.10.0(eslint@7.32.0) eslint-plugin-import: 2.27.5(@typescript-eslint/parser@4.33.0)(eslint@7.32.0) - eslint-plugin-jest: 24.7.0(@typescript-eslint/eslint-plugin@4.33.0)(eslint@7.32.0)(typescript@4.9.5) + eslint-plugin-jest: 24.7.0(@typescript-eslint/eslint-plugin@4.33.0)(eslint@7.32.0)(typescript@5.1.6) eslint-plugin-jsx-a11y: 6.7.1(eslint@7.32.0) eslint-plugin-react: 7.32.2(eslint@7.32.0) eslint-plugin-react-hooks: 4.6.0(eslint@7.32.0) - eslint-plugin-testing-library: 3.10.2(eslint@7.32.0)(typescript@4.9.5) + eslint-plugin-testing-library: 3.10.2(eslint@7.32.0)(typescript@5.1.6) eslint-webpack-plugin: 2.7.0(eslint@7.32.0)(webpack@4.44.2) file-loader: 6.1.1(webpack@4.44.2) fs-extra: 9.1.0 @@ -13012,7 +12997,7 @@ packages: jest-watch-typeahead: 0.6.1(jest@26.6.0) mini-css-extract-plugin: 0.11.3(webpack@4.44.2) optimize-css-assets-webpack-plugin: 5.0.4(webpack@4.44.2) - pnp-webpack-plugin: 1.6.4(typescript@4.9.5) + pnp-webpack-plugin: 1.6.4(typescript@5.1.6) postcss-flexbugs-fixes: 4.2.1 postcss-loader: 3.0.0 postcss-normalize: 8.0.1 @@ -13021,7 +13006,7 @@ packages: prompts: 2.4.0 react: 18.2.0 react-app-polyfill: 2.0.0 - react-dev-utils: 11.0.4(eslint@7.32.0)(typescript@4.9.5)(webpack@4.44.2) + react-dev-utils: 11.0.4(eslint@7.32.0)(typescript@5.1.6)(webpack@4.44.2) react-refresh: 0.8.3 resolve: 1.18.1 resolve-url-loader: 3.1.5 @@ -13029,8 +13014,8 @@ packages: semver: 7.3.2 style-loader: 1.3.0(webpack@4.44.2) terser-webpack-plugin: 4.2.3(webpack@4.44.2) - ts-pnp: 1.2.0(typescript@4.9.5) - typescript: 4.9.5 + ts-pnp: 1.2.0(typescript@5.1.6) + typescript: 5.1.6 url-loader: 4.1.1(file-loader@6.1.1)(webpack@4.44.2) webpack: 4.44.2 webpack-dev-server: 3.11.1(webpack@4.44.2) @@ -13060,7 +13045,7 @@ packages: - webpack-plugin-serve dev: false - /react-transition-group@4.4.5(react-dom@18.1.0)(react@18.2.0): + /react-transition-group@4.4.5(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} peerDependencies: react: '>=16.6.0' @@ -13071,7 +13056,7 @@ packages: loose-envify: 1.4.0 prop-types: 15.8.1 react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false /react@18.2.0: @@ -13140,7 +13125,7 @@ packages: dev: false optional: true - /recoil@0.7.7(react-dom@18.1.0)(react@18.2.0): + /recoil@0.7.7(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-8Og5KPQW9LwC577Vc7Ug2P0vQshkv1y3zG3tSSkWMqkWSwHmE+by06L8JtnGocjW6gcCvfwB3YtrJG6/tWivNQ==} peerDependencies: react: '>=16.13.1' @@ -13154,7 +13139,7 @@ packages: dependencies: hamt_plus: 1.0.2 react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false /recursive-readdir@2.2.2: @@ -13578,8 +13563,8 @@ packages: xmlchars: 2.2.0 dev: false - /scheduler@0.22.0: - resolution: {integrity: sha512-6QAm1BgQI88NPYymgGQLCZgvep4FyePDWFpXVK+zNSUgHwlqpJy8VEh8Et0KxTACS4VWwMousBElAZOH9nkkoQ==} + /scheduler@0.23.0: + resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} dependencies: loose-envify: 1.4.0 dev: false @@ -14606,7 +14591,7 @@ packages: resolution: {integrity: sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==} dev: false - /ts-node@10.9.1(@types/node@18.15.10)(typescript@4.9.5): + /ts-node@10.9.1(@types/node@18.15.10)(typescript@5.1.6): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true peerDependencies: @@ -14632,12 +14617,12 @@ packages: create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 4.9.5 + typescript: 5.1.6 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 dev: false - /ts-pnp@1.2.0(typescript@4.9.5): + /ts-pnp@1.2.0(typescript@5.1.6): resolution: {integrity: sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==} engines: {node: '>=6'} peerDependencies: @@ -14646,7 +14631,7 @@ packages: typescript: optional: true dependencies: - typescript: 4.9.5 + typescript: 5.1.6 dev: false /tsconfig-paths@3.14.2: @@ -14663,14 +14648,14 @@ packages: /tslib@2.5.0: resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==} - /tsutils@3.21.0(typescript@4.9.5): + /tsutils@3.21.0(typescript@5.1.6): resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} peerDependencies: typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' dependencies: tslib: 1.14.1 - typescript: 4.9.5 + typescript: 5.1.6 /tty-browserify@0.0.0: resolution: {integrity: sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==} @@ -14760,9 +14745,9 @@ packages: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} dev: false - /typescript@4.9.5: - resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} - engines: {node: '>=4.2.0'} + /typescript@5.1.6: + resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==} + engines: {node: '>=14.17'} hasBin: true /unbox-primitive@1.0.2: @@ -14932,14 +14917,14 @@ packages: querystring: 0.2.0 dev: false - /use-state-with-callback@3.0.2(react-dom@18.1.0)(react@18.2.0): + /use-state-with-callback@3.0.2(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-gs6t5ilsbi2UvoYXdw8+dwQg6yT3QfO/sYhm5Wa3tfwcL6BSad85FiET8ZtTWid4gjul1T1TJ8ReV4Wk1B7UZg==} peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' dependencies: react: 18.2.0 - react-dom: 18.1.0(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) dev: false /use@3.1.1: diff --git a/src/components/Modal/ModalProvider.tsx b/src/components/Modal/ModalProvider.tsx index 8a44a14f0..a74f8c2d6 100644 --- a/src/components/Modal/ModalProvider.tsx +++ b/src/components/Modal/ModalProvider.tsx @@ -5,7 +5,13 @@ import { useRecoilValue } from "recoil"; const ModalProvider = () => { const modals = useRecoilValue(modalsAtom); - return modals.map(({ id, props }) => ); + return ( + <> + {modals.map(({ id, props }) => ( + + ))} + + ); }; export default ModalProvider; diff --git a/src/components/ModalPopup/ModalReportInChatting.tsx b/src/components/ModalPopup/ModalReportInChatting.tsx index bb35151ff..6052ac37c 100644 --- a/src/components/ModalPopup/ModalReportInChatting.tsx +++ b/src/components/ModalPopup/ModalReportInChatting.tsx @@ -1,5 +1,7 @@ import { ChangeEvent, FormEvent, useState } from "react"; +import type { Report } from "types/report"; + import { useAxios } from "hooks/useTaxiAPI"; import Button from "components/Button"; diff --git a/src/index.js b/src/index.tsx similarity index 100% rename from src/index.js rename to src/index.tsx diff --git a/src/types/report.d.ts b/src/types/report.d.ts new file mode 100644 index 000000000..44dfb20ed --- /dev/null +++ b/src/types/report.d.ts @@ -0,0 +1,7 @@ +export type ReportResponse = { status: number }; +export type Report = { + reportedId: string; + type: "no-settlement" | "no-show" | "etc-reason"; + etcDetail: string; + time: Date; +}; diff --git a/tsconfig.json b/tsconfig.json index a18286d6d..7c8e5949b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,4 @@ { - "extends": "./tsconfig.paths.json", "compilerOptions": { "target": "es5", "module": "esnext", diff --git a/tsconfig.paths.json b/tsconfig.paths.json deleted file mode 100644 index b881223ea..000000000 --- a/tsconfig.paths.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "compilerOptions": { - "baseUrl": "./src", - "paths": {} - } -} From 37cdb310b4deab3c42297b07d93283482355c1bf Mon Sep 17 00:00:00 2001 From: 14Kgun Date: Tue, 25 Jul 2023 03:24:56 +0900 Subject: [PATCH 08/17] Add: NODE_ENV to env.d.ts --- src/index.tsx | 5 ++++- src/types/env.d.ts | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/index.tsx b/src/index.tsx index 8a83f60a6..8fbcfcce2 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -43,7 +43,10 @@ const App = () => { }> {routes.map((route) => ( - + ))} diff --git a/src/types/env.d.ts b/src/types/env.d.ts index 9499f5ac3..af2c0c1be 100644 --- a/src/types/env.d.ts +++ b/src/types/env.d.ts @@ -1,4 +1,5 @@ type Env = { + NODE_ENV: "development" | "production"; REACT_APP_BACK_URL: string; REACT_APP_IO_URL?: string; REACT_APP_OG_URL?: string; From 583e758b5a94216d0fb2eba8f427e445d622fca6 Mon Sep 17 00:00:00 2001 From: 14Kgun Date: Thu, 27 Jul 2023 01:43:36 +0900 Subject: [PATCH 09/17] Refactor: index.tsx --- package.json | 3 +- pnpm-lock.yaml | 13 ++-- src/components/Chat/Header/SideMenu.tsx | 39 ++++++++++- .../Chat/MessagesBody/MessageDate.tsx | 3 +- .../Skeleton/Routes.tsx} | 16 ++++- src/components/Skeleton/index.tsx | 17 +++++ .../skeleton/useCSSVariablesEffect.tsx} | 5 +- .../useChannelTalkEffect}/channelService.js | 0 .../skeleton/useChannelTalkEffect}/index.tsx | 5 +- .../skeleton/useFirebaseMessagingEffect.tsx} | 6 +- .../useFlutterEventCommunicationEffect.tsx} | 6 +- .../skeleton/useGoogleAnalyticsEffect.tsx} | 6 +- .../skeleton/useI18nextEffect.tsx} | 6 +- .../useScrollRestorationEffect}/index.tsx | 6 +- .../useScrollRestorationEffect}/utils.ts | 0 .../useVirtualKeyboardDetectEffect.tsx} | 6 +- src/index.tsx | 67 ++++++------------- src/tools/sendEventToFlutter.ts | 9 +-- 18 files changed, 108 insertions(+), 105 deletions(-) rename src/{routes.ts => components/Skeleton/Routes.tsx} (82%) rename src/{components/Skeleton/CSSVariablesProvider.tsx => hooks/skeleton/useCSSVariablesEffect.tsx} (91%) rename src/{components/Skeleton/ChannelTalkProvider => hooks/skeleton/useChannelTalkEffect}/channelService.js (100%) rename src/{components/Skeleton/ChannelTalkProvider => hooks/skeleton/useChannelTalkEffect}/index.tsx (92%) rename src/{components/Skeleton/FirebaseMessagingProvider.tsx => hooks/skeleton/useFirebaseMessagingEffect.tsx} (96%) rename src/{components/Skeleton/FlutterEventCommunicationProvider.tsx => hooks/skeleton/useFlutterEventCommunicationEffect.tsx} (96%) rename src/{components/Skeleton/GoogleAnalyticsProvier.tsx => hooks/skeleton/useGoogleAnalyticsEffect.tsx} (90%) rename src/{components/Skeleton/I18nextProvider.jsx => hooks/skeleton/useI18nextEffect.tsx} (95%) rename src/{components/Skeleton/ScrollRestoration => hooks/skeleton/useScrollRestorationEffect}/index.tsx (94%) rename src/{components/Skeleton/ScrollRestoration => hooks/skeleton/useScrollRestorationEffect}/utils.ts (100%) rename src/{components/Skeleton/VirtualKeyboardDetector.tsx => hooks/skeleton/useVirtualKeyboardDetectEffect.tsx} (97%) diff --git a/package.json b/package.json index e35a04ed1..82097d727 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,6 @@ "typescript": "^5.1.6" }, "resolutions": { - "@types/react": "^17.0.2", - "@types/react-dom": "^17.0.2" + "@types/react": "^17.0.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bced7a2bf..aef294f3d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,8 +5,7 @@ settings: excludeLinksFromLockfile: false overrides: - '@types/react': 17.0.2 - '@types/react-dom': 17.0.2 + '@types/react': ^17.0.2 dependencies: '@babel/preset-react': @@ -129,11 +128,11 @@ devDependencies: specifier: ^6.9.7 version: 6.9.7 '@types/react': - specifier: 17.0.2 + specifier: ^17.0.2 version: 17.0.2 '@types/react-dom': - specifier: 17.0.2 - version: 17.0.2 + specifier: ^18.2.7 + version: 18.2.7 '@types/react-router-dom': specifier: ^5.3.3 version: 5.3.3 @@ -3867,8 +3866,8 @@ packages: resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} dev: true - /@types/react-dom@17.0.2: - resolution: {integrity: sha512-Icd9KEgdnFfJs39KyRyr0jQ7EKhq8U6CcHRMGAS45fp5qgUvxL3ujUCfWFttUK2UErqZNj97t9gsVPNAqcwoCg==} + /@types/react-dom@18.2.7: + resolution: {integrity: sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA==} dependencies: '@types/react': 17.0.2 dev: true diff --git a/src/components/Chat/Header/SideMenu.tsx b/src/components/Chat/Header/SideMenu.tsx index 637151ae6..225f61d52 100644 --- a/src/components/Chat/Header/SideMenu.tsx +++ b/src/components/Chat/Header/SideMenu.tsx @@ -2,7 +2,10 @@ import DottedLine from "components/DottedLine"; import theme from "tools/theme"; -import ArrowForwardRounded from "@mui/icons-material/ArrowForwardRounded"; +import ArrowForwardRoundedIcon from "@mui/icons-material/ArrowForwardRounded"; +import LocationOnRoundedIcon from "@mui/icons-material/LocationOnRounded"; +import CalendarTodayRounded from "@mui/icons-material/CalendarTodayRounded"; +import PeopleAltRoundedIcon from "@mui/icons-material/PeopleAltRounded"; type SideMenuProps = { roomInfo: Room; @@ -47,13 +50,25 @@ const SideMenu = ({ alignItems: "center", gap: "12px", }; + const styleIcon = { + width: "16px", + height: "16px", + fill: theme.black, + }; + const styleInfoSection = { + padding: "20px 0", + }; + const styleInfo = { + ...theme.font14, + color: theme.black, + }; return ( <>
setIsOpen(false)}>
- setIsOpen(false)} /> @@ -62,6 +77,26 @@ const SideMenu = ({
+
+
+ +
+ {roomInfo.from?.koName}  →  {roomInfo.to?.koName} +
+
+
+
+ +
{roomInfo.time}
+
+
+ +
+
+ +
탑승인원 : ?명 / ?명
+
+
); diff --git a/src/components/Chat/MessagesBody/MessageDate.tsx b/src/components/Chat/MessagesBody/MessageDate.tsx index 753aeb13c..fa3e733c4 100644 --- a/src/components/Chat/MessagesBody/MessageDate.tsx +++ b/src/components/Chat/MessagesBody/MessageDate.tsx @@ -26,8 +26,9 @@ const MessageDate = ({ date }: MessageDateProps) => ( minWidth: "fit-content", }} > - {date.format("YYYY년 M월 D일")} + {date.format("YYYY년 M월 D일 (ddd)")}
+
); diff --git a/src/routes.ts b/src/components/Skeleton/Routes.tsx similarity index 82% rename from src/routes.ts rename to src/components/Skeleton/Routes.tsx index b43e6a833..deada43fc 100644 --- a/src/routes.ts +++ b/src/components/Skeleton/Routes.tsx @@ -1,6 +1,7 @@ import { lazy } from "react"; +import { Route, Switch } from "react-router-dom"; -const routes = [ +const routeProps = [ { path: "/login", component: lazy(() => import("pages/Login")), exact: true }, { path: "/login/fail", @@ -63,4 +64,15 @@ const routes = [ }, ]; -export default routes; +const Routes = () => ( + + {routeProps.map((route) => ( + + ))} + +); + +export default Routes; diff --git a/src/components/Skeleton/index.tsx b/src/components/Skeleton/index.tsx index 568c95ab1..d52cbe0a1 100644 --- a/src/components/Skeleton/index.tsx +++ b/src/components/Skeleton/index.tsx @@ -2,6 +2,14 @@ import { ReactNode, useCallback, useEffect, useMemo, useState } from "react"; import { useCookies } from "react-cookie"; import { useLocation } from "react-router-dom"; +import useI18nextEffect from "hooks/skeleton/useI18nextEffect"; +import useScrollRestorationEffect from "hooks/skeleton/useScrollRestorationEffect"; +import useCSSVariablesEffect from "hooks/skeleton/useCSSVariablesEffect"; +import useVirtualKeyboardDetectEffect from "hooks/skeleton/useVirtualKeyboardDetectEffect"; +import useChannelTalkEffect from "hooks/skeleton/useChannelTalkEffect"; +import useGoogleAnalyticsEffect from "hooks/skeleton/useGoogleAnalyticsEffect"; +import useFirebaseMessagingEffect from "hooks/skeleton/useFirebaseMessagingEffect"; +import useFlutterEventCommunicationEffect from "hooks/skeleton/useFlutterEventCommunicationEffect"; import { useSyncRecoilStateEffect, useValueRecoilState, @@ -84,6 +92,15 @@ const Skeleton = ({ children }: SkeletonProps) => { // loginIngo, taxiLocations, myRooms, notificationOptions 초기화 및 동기화 useSyncRecoilStateEffect(); + useI18nextEffect(); + useScrollRestorationEffect(); + useCSSVariablesEffect(); + useVirtualKeyboardDetectEffect(); + useChannelTalkEffect(); + useGoogleAnalyticsEffect(); + useFirebaseMessagingEffect(); + useFlutterEventCommunicationEffect(); + if (error) { return ( diff --git a/src/components/Skeleton/CSSVariablesProvider.tsx b/src/hooks/skeleton/useCSSVariablesEffect.tsx similarity index 91% rename from src/components/Skeleton/CSSVariablesProvider.tsx rename to src/hooks/skeleton/useCSSVariablesEffect.tsx index 945381f3e..22bf47ec9 100644 --- a/src/components/Skeleton/CSSVariablesProvider.tsx +++ b/src/hooks/skeleton/useCSSVariablesEffect.tsx @@ -22,7 +22,7 @@ const syncScroll = () => { ); }; -const CSSVariablesProvider = () => { +export default () => { useEffect(() => { syncHeight(); syncScroll(); @@ -36,7 +36,4 @@ const CSSVariablesProvider = () => { visualViewport?.removeEventListener("resize", syncHeight); }; }, []); - return null; }; - -export default CSSVariablesProvider; diff --git a/src/components/Skeleton/ChannelTalkProvider/channelService.js b/src/hooks/skeleton/useChannelTalkEffect/channelService.js similarity index 100% rename from src/components/Skeleton/ChannelTalkProvider/channelService.js rename to src/hooks/skeleton/useChannelTalkEffect/channelService.js diff --git a/src/components/Skeleton/ChannelTalkProvider/index.tsx b/src/hooks/skeleton/useChannelTalkEffect/index.tsx similarity index 92% rename from src/components/Skeleton/ChannelTalkProvider/index.tsx rename to src/hooks/skeleton/useChannelTalkEffect/index.tsx index a75b3ad72..fffe335ca 100644 --- a/src/components/Skeleton/ChannelTalkProvider/index.tsx +++ b/src/hooks/skeleton/useChannelTalkEffect/index.tsx @@ -9,7 +9,7 @@ import { useRecoilValue } from "recoil"; import { channelTalkPluginKey } from "loadenv"; -const ChannelTalkProvider = () => { +export default () => { const location = useLocation(); const pathname = location.pathname; const loginInfo = useRecoilValue(loginInfoAtom); @@ -36,7 +36,4 @@ const ChannelTalkProvider = () => { }); } }, [pathname, error]); - return null; }; - -export default ChannelTalkProvider; diff --git a/src/components/Skeleton/FirebaseMessagingProvider.tsx b/src/hooks/skeleton/useFirebaseMessagingEffect.tsx similarity index 96% rename from src/components/Skeleton/FirebaseMessagingProvider.tsx rename to src/hooks/skeleton/useFirebaseMessagingEffect.tsx index 82c41fe71..5b028f15c 100644 --- a/src/components/Skeleton/FirebaseMessagingProvider.tsx +++ b/src/hooks/skeleton/useFirebaseMessagingEffect.tsx @@ -12,7 +12,7 @@ import { firebaseConfig } from "loadenv"; const firebaseApp = firebaseConfig && initializeApp(firebaseConfig); -const FirebaseMessagingProvider = () => { +export default () => { const axios = useAxios(); const { id: userId, deviceToken } = useValueRecoilState("loginInfo") || {}; const fetchLoginInfo = useFetchRecoilState("loginInfo"); @@ -78,8 +78,4 @@ const FirebaseMessagingProvider = () => { document.addEventListener("touchend", registerEvent, { once: true }); } }, [userId, deviceToken]); - - return null; }; - -export default FirebaseMessagingProvider; diff --git a/src/components/Skeleton/FlutterEventCommunicationProvider.tsx b/src/hooks/skeleton/useFlutterEventCommunicationEffect.tsx similarity index 96% rename from src/components/Skeleton/FlutterEventCommunicationProvider.tsx rename to src/hooks/skeleton/useFlutterEventCommunicationEffect.tsx index ae6bd68fc..2112f09a4 100644 --- a/src/components/Skeleton/FlutterEventCommunicationProvider.tsx +++ b/src/hooks/skeleton/useFlutterEventCommunicationEffect.tsx @@ -11,7 +11,7 @@ import { useSetRecoilState } from "recoil"; // global flag variable to check if the webview is in Flutter let isWebViewInFlutter: boolean = false; -const FlutterEventCommunicationProvider = () => { +export default () => { const setAlert = useSetRecoilState(alertAtom); const setError = useSetRecoilState(errorAtom); const setIsApp = useSetRecoilState(isAppAtom); @@ -62,12 +62,8 @@ const FlutterEventCommunicationProvider = () => { window.removeEventListener(name, listner) ); }, []); - - return null; }; -export default FlutterEventCommunicationProvider; - // 로그인 정보 변동 시 Flutter에 이벤트를 전달합니다 export const sendAuthUpdateEventToFlutter = async ( loginInfo: LoginInfoType diff --git a/src/components/Skeleton/GoogleAnalyticsProvier.tsx b/src/hooks/skeleton/useGoogleAnalyticsEffect.tsx similarity index 90% rename from src/components/Skeleton/GoogleAnalyticsProvier.tsx rename to src/hooks/skeleton/useGoogleAnalyticsEffect.tsx index 5fe833189..2b336da3f 100644 --- a/src/components/Skeleton/GoogleAnalyticsProvier.tsx +++ b/src/hooks/skeleton/useGoogleAnalyticsEffect.tsx @@ -7,7 +7,7 @@ import { useRecoilValue } from "recoil"; import { gaTrackingId, nodeEnv } from "loadenv"; -const GoogleAnalyticsProvier = () => { +export default () => { const gaInitialized = useRef(false); const location = useLocation(); @@ -34,8 +34,4 @@ const GoogleAnalyticsProvier = () => { reactGA.set({ userId }); } }, [userId]); - - return null; }; - -export default GoogleAnalyticsProvier; diff --git a/src/components/Skeleton/I18nextProvider.jsx b/src/hooks/skeleton/useI18nextEffect.tsx similarity index 95% rename from src/components/Skeleton/I18nextProvider.jsx rename to src/hooks/skeleton/useI18nextEffect.tsx index 585ac36d1..6e1a9d095 100644 --- a/src/components/Skeleton/I18nextProvider.jsx +++ b/src/hooks/skeleton/useI18nextEffect.tsx @@ -46,7 +46,7 @@ i18n defaultNS: "mypage", // default namespace }); -const I18nextProvider = () => { +export default () => { const { i18n: i18nt } = useTranslation(); useEffect(() => { @@ -54,8 +54,4 @@ const I18nextProvider = () => { i18nt.changeLanguage("ko"); } }, []); - - return null; }; - -export default I18nextProvider; diff --git a/src/components/Skeleton/ScrollRestoration/index.tsx b/src/hooks/skeleton/useScrollRestorationEffect/index.tsx similarity index 94% rename from src/components/Skeleton/ScrollRestoration/index.tsx rename to src/hooks/skeleton/useScrollRestorationEffect/index.tsx index b772a75bc..e21b6f006 100644 --- a/src/components/Skeleton/ScrollRestoration/index.tsx +++ b/src/hooks/skeleton/useScrollRestorationEffect/index.tsx @@ -5,7 +5,7 @@ import { getScrollPage, isBothStartsWith, scrollTo } from "./utils"; const defaultKey = "init-enter"; -const ScrollRestoration = () => { +export default () => { const visitedUrl = useRef(new Map()); const history = useHistory(); const location = useLocation(); @@ -51,8 +51,4 @@ const ScrollRestoration = () => { } prevLocation.current = location; }, [location.pathname, location.search, location.hash]); - - return null; }; - -export default ScrollRestoration; diff --git a/src/components/Skeleton/ScrollRestoration/utils.ts b/src/hooks/skeleton/useScrollRestorationEffect/utils.ts similarity index 100% rename from src/components/Skeleton/ScrollRestoration/utils.ts rename to src/hooks/skeleton/useScrollRestorationEffect/utils.ts diff --git a/src/components/Skeleton/VirtualKeyboardDetector.tsx b/src/hooks/skeleton/useVirtualKeyboardDetectEffect.tsx similarity index 97% rename from src/components/Skeleton/VirtualKeyboardDetector.tsx rename to src/hooks/skeleton/useVirtualKeyboardDetectEffect.tsx index f0b350c5f..cc0c4db98 100644 --- a/src/components/Skeleton/VirtualKeyboardDetector.tsx +++ b/src/hooks/skeleton/useVirtualKeyboardDetectEffect.tsx @@ -5,7 +5,7 @@ import { useSetRecoilState } from "recoil"; import isMobile from "tools/isMobile"; -const VirtualKeyboardDetector = () => { +export default () => { const setIsVKDetected = useSetRecoilState(isVirtualKeyboardDetectedAtom); const [isAndroid, isIOS] = isMobile(); @@ -93,8 +93,4 @@ const VirtualKeyboardDetector = () => { }; } }, []); - - return null; }; - -export default VirtualKeyboardDetector; diff --git a/src/index.tsx b/src/index.tsx index 8fbcfcce2..817c9309c 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,60 +1,37 @@ import { Suspense } from "react"; import { CookiesProvider } from "react-cookie"; -import ReactDOM from "react-dom"; -import { Route, BrowserRouter as Router, Switch } from "react-router-dom"; -import routes from "routes"; +import { createRoot } from "react-dom/client"; +import { BrowserRouter as Router } from "react-router-dom"; import Loading from "components/Loading"; import ModalProvider from "components/Modal/ModalProvider"; import Skeleton from "components/Skeleton"; import AlertProvider from "components/Skeleton/AlertProvider"; -import CSSVariablesProvider from "components/Skeleton/CSSVariablesProvider"; -import ChannelTalkProvider from "components/Skeleton/ChannelTalkProvider"; -import FirebaseMessagingProvider from "components/Skeleton/FirebaseMessagingProvider"; -import FlutterEventCommunicationProvider from "components/Skeleton/FlutterEventCommunicationProvider"; -import GoogleAnalyticsProvier from "components/Skeleton/GoogleAnalyticsProvier"; -import I18nextProvider from "components/Skeleton/I18nextProvider"; -import ScrollRestoration from "components/Skeleton/ScrollRestoration"; import SocketToastProvider from "components/Skeleton/SocketToastProvider"; -import VirtualKeyboardDetector from "components/Skeleton/VirtualKeyboardDetector"; +import Routes from "components/Skeleton/Routes"; import "./App.css"; import "./Font.css"; import { RecoilRoot } from "recoil"; -const App = () => { - return ( - - - - - - - - - - - - - - - - }> - - {routes.map((route) => ( - - ))} - - - - - - - ); -}; +const App = () => ( + + + + + + + + }> + + + + + + +); -ReactDOM.render(, document.getElementById("root")); +// create a root to display React components inside a browser DOM node +const root = createRoot(document.getElementById("root") as HTMLElement); +root.render(); diff --git a/src/tools/sendEventToFlutter.ts b/src/tools/sendEventToFlutter.ts index 080d4ee0e..9acc734f6 100644 --- a/src/tools/sendEventToFlutter.ts +++ b/src/tools/sendEventToFlutter.ts @@ -1,13 +1,6 @@ -import { - sendAuthLogoutEventToFlutter, - sendAuthUpdateEventToFlutter, - sendClipboardCopyEventToFlutter, - sendTryNotificationEventToFlutter, -} from "components/Skeleton/FlutterEventCommunicationProvider"; - export { sendAuthUpdateEventToFlutter, sendAuthLogoutEventToFlutter, sendTryNotificationEventToFlutter, sendClipboardCopyEventToFlutter, -}; +} from "hooks/skeleton/useFlutterEventCommunicationEffect"; From 4efc7b5032220034762cb5e1bd2bf1252006d61a Mon Sep 17 00:00:00 2001 From: 14Kgun Date: Thu, 27 Jul 2023 19:43:03 +0900 Subject: [PATCH 10/17] Refactor: MessageForm --- .prettierrc.json | 1 + .../Chat/Header/Popup/PopupCancel.jsx | 85 ------- .../Chat/Header/Popup/PopupContainer.jsx | 57 ----- src/components/Chat/Header/Popup/PopupPay.jsx | 86 ------- .../Chat/Header/Popup/PopupSend.jsx | 86 ------- src/components/Chat/Header/SideMenu.tsx | 130 +++++++++-- src/components/Chat/MessageForm/Form.tsx | 216 ------------------ src/components/Chat/MessageForm/InputText.tsx | 142 ++++++++++++ .../Chat/MessageForm/NewMessage.tsx | 16 +- .../Chat/MessageForm/ToolSheet/ToolButton.tsx | 76 ++++++ .../Chat/MessageForm/ToolSheet/index.tsx | 68 ++++++ .../Chat/MessageForm/ToolSheetOpenButton.tsx | 29 +++ src/components/Chat/MessageForm/index.tsx | 57 +++-- src/components/Chat/index.tsx | 4 + src/components/Skeleton/index.tsx | 8 +- .../chat/useBodyScrollControllerEffect.tsx | 9 + src/index.tsx | 2 +- 17 files changed, 497 insertions(+), 575 deletions(-) delete mode 100644 src/components/Chat/Header/Popup/PopupCancel.jsx delete mode 100644 src/components/Chat/Header/Popup/PopupContainer.jsx delete mode 100644 src/components/Chat/Header/Popup/PopupPay.jsx delete mode 100644 src/components/Chat/Header/Popup/PopupSend.jsx delete mode 100644 src/components/Chat/MessageForm/Form.tsx create mode 100644 src/components/Chat/MessageForm/InputText.tsx create mode 100644 src/components/Chat/MessageForm/ToolSheet/ToolButton.tsx create mode 100644 src/components/Chat/MessageForm/ToolSheet/index.tsx create mode 100644 src/components/Chat/MessageForm/ToolSheetOpenButton.tsx diff --git a/.prettierrc.json b/.prettierrc.json index fdda59da3..018d593fd 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -12,6 +12,7 @@ "requirePragma": false, "semi": true, "singleQuote": false, + "plugins": ["@trivago/prettier-plugin-sort-imports"], "importOrder": [ "", "^types/", diff --git a/src/components/Chat/Header/Popup/PopupCancel.jsx b/src/components/Chat/Header/Popup/PopupCancel.jsx deleted file mode 100644 index 4efe883f1..000000000 --- a/src/components/Chat/Header/Popup/PopupCancel.jsx +++ /dev/null @@ -1,85 +0,0 @@ -import PropTypes from "prop-types"; -import { useHistory } from "react-router-dom"; - -import { useFetchRecoilState } from "hooks/useFetchRecoilState"; -import { useAxios } from "hooks/useTaxiAPI"; - -import PopupContainer from "./PopupContainer"; - -import alertAtom from "atoms/alert"; -import { useSetRecoilState } from "recoil"; - -const PopupCancel = (props) => { - const axios = useAxios(); - - const styleTextCont = { - textAlign: "center", - }; - const styleTextCont2 = { - textAlign: "center", - lineHieght: "12px", - paddingTop: "6px", - fontSize: "10px", - color: "888888", - }; - const styleTxt1 = { - fontSize: "16px", - fontWeight: "bold", - }; - const styleTxt2 = { - fontSize: "16px", - fontWeight: 300, - }; - const styleTxt3 = { - fontSize: "16px", - fontWeight: "bold", - color: "#6E3678", - }; - - const history = useHistory(); - const setAlert = useSetRecoilState(alertAtom); - const fetchMyrooms = useFetchRecoilState("myRooms"); - - const onClick = () => - axios({ - url: "/rooms/abort", - method: "post", - data: { - roomId: props.roomId, - }, - onSuccess: () => { - fetchMyrooms(); - history.replace("/myroom"); - }, - onError: () => setAlert("탑승 취소에 실패하였습니다"), - }); - - return ( - -
- 탑승 - - 취소 - 하시겠습니까? -
-
- 취소 후 재탑승이 가능합니다. -
- 다만, 혼자 탑승 중인 경우에는 방이 사라집니다. -
-
- ); -}; - -PopupCancel.propTypes = { - roomId: PropTypes.string, - popup: PropTypes.bool, - onClickClose: PropTypes.func, -}; - -export default PopupCancel; diff --git a/src/components/Chat/Header/Popup/PopupContainer.jsx b/src/components/Chat/Header/Popup/PopupContainer.jsx deleted file mode 100644 index 5dc44d4bf..000000000 --- a/src/components/Chat/Header/Popup/PopupContainer.jsx +++ /dev/null @@ -1,57 +0,0 @@ -import PropTypes from "prop-types"; - -import Button from "components/Button"; -import Modal from "components/Modal"; - -import theme from "tools/theme"; - -const PopupContainer = (props) => { - return ( - -
{props.children}
-
- - -
-
- ); -}; - -PopupContainer.propTypes = { - popup: PropTypes.bool, - onClickClose: PropTypes.func, - onClickOk: PropTypes.func, - children: PropTypes.node, - nameOk: PropTypes.string, -}; - -export default PopupContainer; diff --git a/src/components/Chat/Header/Popup/PopupPay.jsx b/src/components/Chat/Header/Popup/PopupPay.jsx deleted file mode 100644 index 1c182d571..000000000 --- a/src/components/Chat/Header/Popup/PopupPay.jsx +++ /dev/null @@ -1,86 +0,0 @@ -import PropTypes from "prop-types"; - -import { useFetchRecoilState } from "hooks/useFetchRecoilState"; -import { useAxios } from "hooks/useTaxiAPI"; - -import PopupContainer from "./PopupContainer"; - -import alertAtom from "atoms/alert"; -import { useSetRecoilState } from "recoil"; - -const PopupPay = (props) => { - const axios = useAxios(); - - const styleTextCont = { - textAlign: "center", - }; - const styleTextCont2 = { - textAlign: "center", - lineHieght: "12px", - paddingTop: "6px", - fontSize: "10px", - color: "888888", - }; - const styleTxt1 = { - fontSize: "16px", - fontWeight: "bold", - }; - const styleTxt2 = { - fontSize: "16px", - fontWeight: 300, - }; - const styleTxt3 = { - fontSize: "16px", - fontWeight: "bold", - color: "#6E3678", - }; - - const setAlert = useSetRecoilState(alertAtom); - const fetchMyRooms = useFetchRecoilState("myRooms"); - - const onClick = () => { - axios({ - url: "/rooms/commitPayment", - method: "post", - data: { - roomId: props.roomId, - }, - onSuccess: () => { - fetchMyRooms(); - props.recallEvent(); - props.onClickClose(); - }, - onError: () => setAlert("결제 완료를 실패하였습니다"), - }); - }; - - return ( - -
- 결제 - - 완료 - 하시겠습니까? -
-
- 꼭 택시비를 결제한 본인만 완료해주세요. -
- 완료 후 취소는 불가능합니다. -
-
- ); -}; - -PopupPay.propTypes = { - roomId: PropTypes.string, - popup: PropTypes.bool, - onClickClose: PropTypes.func, - recallEvent: PropTypes.func, -}; - -export default PopupPay; diff --git a/src/components/Chat/Header/Popup/PopupSend.jsx b/src/components/Chat/Header/Popup/PopupSend.jsx deleted file mode 100644 index 0140e30cf..000000000 --- a/src/components/Chat/Header/Popup/PopupSend.jsx +++ /dev/null @@ -1,86 +0,0 @@ -import PropTypes from "prop-types"; - -import { useFetchRecoilState } from "hooks/useFetchRecoilState"; -import { useAxios } from "hooks/useTaxiAPI"; - -import PopupContainer from "./PopupContainer"; - -import alertAtom from "atoms/alert"; -import { useSetRecoilState } from "recoil"; - -const PopupSend = (props) => { - const axios = useAxios(); - - const styleTextCont = { - textAlign: "center", - }; - const styleTextCont2 = { - textAlign: "center", - lineHieght: "12px", - paddingTop: "6px", - fontSize: "10px", - color: "888888", - }; - const styleTxt1 = { - fontSize: "16px", - fontWeight: "bold", - }; - const styleTxt2 = { - fontSize: "16px", - fontWeight: 300, - }; - const styleTxt3 = { - fontSize: "16px", - fontWeight: "bold", - color: "#6E3678", - }; - - const setAlert = useSetRecoilState(alertAtom); - const fetchMyRooms = useFetchRecoilState("myRooms"); - - const onClick = () => { - axios({ - url: "/rooms/commitSettlement", - method: "post", - data: { - roomId: props.roomId, - }, - onSuccess: async () => { - fetchMyRooms(); - props.recallEvent(); - props.onClickClose(); - }, - onError: () => setAlert("정산 완료를 실패하였습니다"), - }); - }; - - return ( - -
- 정산 - - 완료 - 하시겠습니까? -
-
- 결제자에게 송금 후 완료해주세요. -
- 완료 후 취소는 불가능합니다. -
-
- ); -}; - -PopupSend.propTypes = { - roomId: PropTypes.string, - popup: PropTypes.bool, - onClickClose: PropTypes.func, - recallEvent: PropTypes.func, -}; - -export default PopupSend; diff --git a/src/components/Chat/Header/SideMenu.tsx b/src/components/Chat/Header/SideMenu.tsx index 225f61d52..4838f6029 100644 --- a/src/components/Chat/Header/SideMenu.tsx +++ b/src/components/Chat/Header/SideMenu.tsx @@ -1,11 +1,25 @@ +import { memo, useState } from "react"; + import DottedLine from "components/DottedLine"; +import { ModalRoomShare } from "components/ModalPopup"; +import User from "components/User"; import theme from "tools/theme"; import ArrowForwardRoundedIcon from "@mui/icons-material/ArrowForwardRounded"; -import LocationOnRoundedIcon from "@mui/icons-material/LocationOnRounded"; import CalendarTodayRounded from "@mui/icons-material/CalendarTodayRounded"; +import KeyboardArrowRightRoundedIcon from "@mui/icons-material/KeyboardArrowRightRounded"; +import LocalTaxiRoundedIcon from "@mui/icons-material/LocalTaxiRounded"; +import LocationOnRoundedIcon from "@mui/icons-material/LocationOnRounded"; +import LogoutOutlinedIcon from "@mui/icons-material/LogoutOutlined"; import PeopleAltRoundedIcon from "@mui/icons-material/PeopleAltRounded"; +import ReportGmailerrorredRoundedIcon from "@mui/icons-material/ReportGmailerrorredRounded"; +import ShareRoundedIcon from "@mui/icons-material/ShareRounded"; + +type SideMenuButtonProps = { + type: "share" | "report" | "taxi"; + onClick?: () => void; +}; type SideMenuProps = { roomInfo: Room; @@ -14,12 +28,47 @@ type SideMenuProps = { setIsOpen: (x: boolean) => void; }; +const SideMenuButton = ({ type, onClick }: SideMenuButtonProps) => { + const style = { + padding: "16px 0", + cursor: "pointer", + display: "flex", + gap: "8px", + alignItems: "center", + }; + const styleIcon = { width: "16px", height: "16px", fill: theme.black }; + const styleText = { ...theme.font14, color: theme.black, flex: 1 }; + const styleArrow = { ...styleIcon, fill: theme.gray_text }; + + const { icon, text } = { + share: { icon: , text: "공유하기" }, + report: { + icon: , + text: "신고하기", + }, + taxi: { + icon: , + text: "택시 호출하기", + }, + }[type]; + + return ( +
+ {icon} +
{text}
+ +
+ ); +}; + const SideMenu = ({ roomInfo, fetchRoomInfo, isOpen, setIsOpen, }: SideMenuProps) => { + const [isOpenShare, setIsOpenShare] = useState(false); + const styleBackground = { position: "absolute" as any, top: 0, @@ -38,14 +87,16 @@ const SideMenu = ({ right: isOpen ? 0 : "max(calc(-100% + 60px), -370px)", width: "min(calc(100% - 60px), 370px)", height: "100%", - padding: "16px", + padding: "0 16px", boxSizing: "border-box" as any, background: theme.white, zIndex: theme.zIndex_modal - 1, transition: "right 0.3s", + display: "flex", + flexDirection: "column" as any, }; const styleNameSection = { - margin: "0 8px 16px", + margin: "16px 8px", display: "flex", alignItems: "center", gap: "12px", @@ -62,14 +113,21 @@ const SideMenu = ({ ...theme.font14, color: theme.black, }; + const styleUsers = { + paddingTop: "16px", + display: "flex", + flexDirection: "column" as any, + gap: "6px", + }; return ( <>
setIsOpen(false)}>
+
setIsOpen(false)} />
@@ -77,29 +135,63 @@ const SideMenu = ({
-
-
- -
- {roomInfo.from?.koName}  →  {roomInfo.to?.koName} +
+
+
+ +
+ {roomInfo.from?.koName}  →  {roomInfo.to?.koName} +
+
+
+
+ +
{roomInfo.time}
-
-
- -
{roomInfo.time}
+ +
+
+ +
+ 참여 / 최대 인원 :{" "} + {roomInfo.part.length}명{" "} + + / {roomInfo.maxPartLength}명 + +
+
+
+ {/* @fixme @todo 유저의 정산 정보 넘겨주나? */} + {roomInfo.part.map((item) => ( + + ))} +
+ + setIsOpenShare(true)} /> + {/* + + + */}
-
-
- -
탑승인원 : ?명 / ?명
-
+
+ setIsOpen(false)} + /> +
탑승 취소
+
+ ); }; -export default SideMenu; +export default memo(SideMenu); diff --git a/src/components/Chat/MessageForm/Form.tsx b/src/components/Chat/MessageForm/Form.tsx deleted file mode 100644 index d2f33dc14..000000000 --- a/src/components/Chat/MessageForm/Form.tsx +++ /dev/null @@ -1,216 +0,0 @@ -import { useEffect, useRef, useState } from "react"; - -import useSendMessage from "hooks/chat/useSendMessage"; - -import PopupAccount from "./Popup/PopupAccount"; - -import regExpTest from "tools/regExpTest"; -import theme from "tools/theme"; - -import ArrowUpwardRoundedIcon from "@mui/icons-material/ArrowUpwardRounded"; -import CropOriginalRoundedIcon from "@mui/icons-material/CropOriginalRounded"; -import LocalAtmIcon from "@mui/icons-material/LocalAtm"; - -type BtnSendProps = { - enable: boolean; - onClick: () => void; -}; - -const BtnSend = (props: BtnSendProps) => { - const style = { - position: "absolute" as any, - width: "28px", - height: "28px", - bottom: "2px", - right: "2px", - backgroundColor: props.enable ? theme.purple : theme.gray_background, - borderRadius: "14px", - boxShadow: theme.shadow_gray_input_inset, - ...theme.cursor(!props.enable), - }; - return ( -
- -
- ); -}; - -type BtnLeftProps = { - onClick: () => void; - type: "image" | "account"; -}; - -const BtnLeft = (props: BtnLeftProps) => { - const style = { - width: "22px", - minWidth: "22px", - height: "22px", - marginBottom: "5px", - ...theme.cursor(), - }; - const styleIcon = { width: "100%", height: "100%", fill: theme.gray_text }; - return ( -
- {props.type === "image" ? ( - - ) : ( - - )} -
- ); -}; - -type FullChatMessageFormProps = { - sendMessage: ReturnType; -}; - -const FullChatMessageForm = ({ sendMessage }: FullChatMessageFormProps) => { - const textareaContRef = useRef(null); - const textareaRef = useRef(null); - const inputImage = useRef(null); - const [message, setMessage] = useState(""); - const [formHeight, setFormHeight] = useState("28px"); - const [popupAccount, setPopupAccount] = useState(false); - - const enterPressed = useRef(false); - const shiftPressed = useRef(false); - - const isMessageValid = () => { - return regExpTest.chatMsg(message); - }; - const onSend = async () => { - textareaRef.current?.focus(); - if (isMessageValid()) { - const result = await sendMessage("text", { text: message }); - if (result) setMessage(""); - } - }; - - const onChangeMessage = (e: React.ChangeEvent) => { - if (enterPressed.current && !shiftPressed.current) { - onSend(); - return; - } - const msg = e.target.value; - setMessage(msg); - }; - const onChangeImage = (e: React.ChangeEvent) => { - const image = e.target?.files?.[0]; - if (!image) return; - sendMessage("image", { file: image }); - }; - - const onKeyDown = (e: React.KeyboardEvent) => { - if (e.code === "ShiftLeft" || e.code === "ShiftRight") - shiftPressed.current = true; - if (e.code === "Enter") enterPressed.current = true; - }; - const onKeyUp = (e: React.KeyboardEvent) => { - if (e.code === "ShiftLeft" || e.code === "ShiftRight") - shiftPressed.current = false; - if (e.code === "Enter") enterPressed.current = false; - }; - - // resizeEvent - const resizeEvent = () => { - if (!textareaContRef.current) return; - const cacheHeight = textareaContRef.current.style.height; - textareaContRef.current.style.height = "0"; - const newHeight = `${Math.max( - Math.min( - textareaRef.current ? textareaRef.current.scrollHeight : 0, - document.body.clientHeight / 3 - ), - 28 - )}px`; - textareaContRef.current.style.height = cacheHeight; - setFormHeight(newHeight); - }; - - useEffect(() => { - resizeEvent(); - window.addEventListener("resize", resizeEvent); - return () => { - window.removeEventListener("resize", resizeEvent); - }; - }, []); - useEffect(() => { - resizeEvent(); - }, [message]); - - return ( -
- setPopupAccount(false)} - onClickOk={(account: string) => { - setPopupAccount(false); - sendMessage("account", { text: account }); - }} - /> - - inputImage.current?.click()} /> - setPopupAccount(true)} /> -
-